e2k: very basic SIC emulation
This commit is contained in:
parent
8de04976c0
commit
dbc7cacc8d
285
hw/e2k/sic.c
285
hw/e2k/sic.c
|
@ -1,6 +1,8 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Alibek Omarov
|
||||
*
|
||||
* System Interchange Controller emulation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
|
@ -12,7 +14,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qemu/log.h"
|
||||
|
@ -30,79 +32,258 @@
|
|||
#define ES2_NSR_AREA_PHYS_BASE 0x0000000110000000UL /* node 0 */
|
||||
#define ES2_NBSR_AREA_SIZE 0x0000000000100000UL
|
||||
|
||||
enum SICRegsAddrs
|
||||
{
|
||||
SIC_node_offset = 0x4,
|
||||
|
||||
SIC_st_p = 0x0,
|
||||
|
||||
SIC_rt_lcfg0 = 0x10, /* node configuration, max nodes 4 */
|
||||
|
||||
SIC_rt_mhi0 = 0x20,
|
||||
|
||||
SIC_rt_mlo0 = 0x30,
|
||||
|
||||
SIC_rt_pcim0 = 0x40,
|
||||
|
||||
SIC_rt_pciio0 = 0x50,
|
||||
|
||||
SIC_rt_ioapic0 = 0x60,
|
||||
|
||||
SIC_rt_pcicfgb = 0x90,
|
||||
|
||||
SIC_st_core = 0x100, /* core configuration, max cores 16 */
|
||||
|
||||
/* IO link & RDMA */
|
||||
SIC_iol_csr = 0x900,
|
||||
|
||||
SIC_unknown_0x1040 = 0x1040,
|
||||
|
||||
SIC_unknown_0x1050 = 0x1050,
|
||||
|
||||
SIC_rt_ioapic10 = 0x1060,
|
||||
|
||||
/* Second IO link */
|
||||
SIC_iol_csr1 = 0x1900,
|
||||
};
|
||||
#define SIC_rt_msi 0xb0
|
||||
#define SIC_rt_msi_h 0xb4
|
||||
#define SIC_rt_pcim0 0x40
|
||||
#define SIC_rt_pcim1 0x44
|
||||
#define SIC_rt_pcim2 0x48
|
||||
#define SIC_rt_pcim3 0x4c
|
||||
#define SIC_rt_pciio0 0x50
|
||||
#define SIC_rt_pciio1 0x54
|
||||
#define SIC_rt_pciio2 0x58
|
||||
#define SIC_rt_pciio3 0x5c
|
||||
#define SIC_rt_pcimp_b0 0x70
|
||||
#define SIC_rt_pcimp_b1 0x74
|
||||
#define SIC_rt_pcimp_b2 0x78
|
||||
#define SIC_rt_pcimp_b3 0x7c
|
||||
#define SIC_rt_pcimp_e0 0x80
|
||||
#define SIC_rt_pcimp_e1 0x84
|
||||
#define SIC_rt_pcimp_e2 0x88
|
||||
#define SIC_rt_pcimp_e3 0x8c
|
||||
#define SIC_rt_pcicfgb 0x90
|
||||
#define SIC_prepic_ctrl2 0x8030
|
||||
#define SIC_prepic_err_stat 0x8040
|
||||
#define SIC_prepic_err_int 0x8060
|
||||
#define SIC_prepic_linp0 0x8c00
|
||||
#define SIC_prepic_linp1 0x8c04
|
||||
#define SIC_prepic_linp2 0x8c08
|
||||
#define SIC_prepic_linp3 0x8c0c
|
||||
#define SIC_prepic_linp4 0x8c10
|
||||
#define SIC_prepic_linp5 0x8c14
|
||||
#define SIC_iommu_ctrl 0x0380
|
||||
#define SIC_iommu_ba_lo 0x0390
|
||||
#define SIC_iommu_dtba_lo 0x0398
|
||||
#define SIC_iommu_err 0x03b0
|
||||
#define SIC_iommu_err_info_lo 0x03b8
|
||||
|
||||
static uint64_t sic_mem_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
// E2KMachineState *ms = opaque;
|
||||
uint64_t val;
|
||||
E2KMachineState *ms = opaque;
|
||||
SICState *regs = &ms->sicregs;
|
||||
uint64_t ret;
|
||||
int index;
|
||||
|
||||
if (size < 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
index = addr & (ES2_NBSR_AREA_SIZE - 1);
|
||||
switch (index) {
|
||||
case SIC_rt_msi:
|
||||
ret = regs->rt_msi & 0xffffffff;
|
||||
break;
|
||||
case SIC_rt_msi_h:
|
||||
ret = regs->rt_msi >> 32;
|
||||
break;
|
||||
case SIC_rt_pcim0:
|
||||
val = 0;
|
||||
ret = regs->rt_pcim0;
|
||||
break;
|
||||
case SIC_rt_pcim1:
|
||||
ret = regs->rt_pcim1;
|
||||
break;
|
||||
case SIC_rt_pcim2:
|
||||
ret = regs->rt_pcim2;
|
||||
break;
|
||||
case SIC_rt_pcim3:
|
||||
ret = regs->rt_pcim3;
|
||||
break;
|
||||
case SIC_rt_pciio0:
|
||||
val = 0;
|
||||
ret = regs->rt_pciio0;
|
||||
break;
|
||||
case SIC_rt_pciio1:
|
||||
ret = regs->rt_pciio1;
|
||||
break;
|
||||
case SIC_rt_pciio2:
|
||||
ret = regs->rt_pciio2;
|
||||
break;
|
||||
case SIC_rt_pciio3:
|
||||
ret = regs->rt_pciio3;
|
||||
break;
|
||||
case SIC_rt_pcimp_b0:
|
||||
ret = regs->rt_pcimp_b0;
|
||||
break;
|
||||
case SIC_rt_pcimp_b1:
|
||||
ret = regs->rt_pcimp_b1;
|
||||
break;
|
||||
case SIC_rt_pcimp_b2:
|
||||
ret = regs->rt_pcimp_b2;
|
||||
break;
|
||||
case SIC_rt_pcimp_b3:
|
||||
ret = regs->rt_pcimp_b3;
|
||||
break;
|
||||
case SIC_rt_pcimp_e0:
|
||||
ret = regs->rt_pcimp_e0;
|
||||
break;
|
||||
case SIC_rt_pcimp_e1:
|
||||
ret = regs->rt_pcimp_e1;
|
||||
break;
|
||||
case SIC_rt_pcimp_e2:
|
||||
ret = regs->rt_pcimp_e2;
|
||||
break;
|
||||
case SIC_rt_pcimp_e3:
|
||||
ret = regs->rt_pcimp_e3;
|
||||
break;
|
||||
case SIC_rt_pcicfgb:
|
||||
// TODO: io page address [48:12]
|
||||
// TODO: page + 0x8044 = 16-bit reg
|
||||
val = 0xdeadbeef000 >> 12;
|
||||
ret = regs->rt_pcicfgb;
|
||||
break;
|
||||
case SIC_prepic_ctrl2:
|
||||
ret = regs->prepic_ctrl2;
|
||||
break;
|
||||
case SIC_prepic_err_stat:
|
||||
ret = regs->prepic_err_stat;
|
||||
break;
|
||||
case SIC_prepic_err_int:
|
||||
ret = regs->prepic_err_int;
|
||||
break;
|
||||
case SIC_prepic_linp0:
|
||||
ret = regs->prepic_linp0;
|
||||
break;
|
||||
case SIC_prepic_linp1:
|
||||
ret = regs->prepic_linp1;
|
||||
break;
|
||||
case SIC_prepic_linp2:
|
||||
ret = regs->prepic_linp2;
|
||||
break;
|
||||
case SIC_prepic_linp3:
|
||||
ret = regs->prepic_linp3;
|
||||
break;
|
||||
case SIC_prepic_linp4:
|
||||
ret = regs->prepic_linp4;
|
||||
break;
|
||||
case SIC_prepic_linp5:
|
||||
ret = regs->prepic_linp5;
|
||||
break;
|
||||
case SIC_iommu_err:
|
||||
ret = regs->iommu_err;
|
||||
break;
|
||||
case SIC_iommu_err_info_lo:
|
||||
ret = regs->iommu_err_info;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
qemu_log_mask(LOG_UNIMP, "%s: unknown SIC register 0x%x\n", __FUNCTION__, index);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
trace_sic_mem_readl(addr, val);
|
||||
return val;
|
||||
trace_sic_mem_readl(addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sic_mem_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
unsigned size)
|
||||
{
|
||||
// E2KMachineState *ms = opaque;
|
||||
E2KMachineState *ms = opaque;
|
||||
SICState *regs = &ms->sicregs;
|
||||
int index;
|
||||
|
||||
trace_sic_mem_writel(addr, val);
|
||||
index = addr & (ES2_NBSR_AREA_SIZE - 1);
|
||||
|
||||
switch (index) {
|
||||
case SIC_rt_msi:
|
||||
regs->rt_msi = (regs->rt_msi & 0xffffffff00000000) | val;
|
||||
break;
|
||||
case SIC_rt_msi_h:
|
||||
regs->rt_msi = (regs->rt_msi & 0x00000000ffffffff) | (val << 32);
|
||||
break;
|
||||
case SIC_rt_pcim0:
|
||||
regs->rt_pcim0 = val;
|
||||
break;
|
||||
case SIC_rt_pcim1:
|
||||
regs->rt_pcim1 = val;
|
||||
break;
|
||||
case SIC_rt_pcim2:
|
||||
regs->rt_pcim2 = val;
|
||||
break;
|
||||
case SIC_rt_pcim3:
|
||||
regs->rt_pcim3 = val;
|
||||
break;
|
||||
case SIC_rt_pciio0:
|
||||
regs->rt_pciio0 = val;
|
||||
break;
|
||||
case SIC_rt_pciio1:
|
||||
regs->rt_pciio1 = val;
|
||||
break;
|
||||
case SIC_rt_pciio2:
|
||||
regs->rt_pciio2 = val;
|
||||
break;
|
||||
case SIC_rt_pciio3:
|
||||
regs->rt_pciio3 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_b0:
|
||||
regs->rt_pcimp_b0 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_b1:
|
||||
regs->rt_pcimp_b1 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_b2:
|
||||
regs->rt_pcimp_b2 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_b3:
|
||||
regs->rt_pcimp_b3 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_e0:
|
||||
regs->rt_pcimp_e0 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_e1:
|
||||
regs->rt_pcimp_e1 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_e2:
|
||||
regs->rt_pcimp_e2 = val;
|
||||
break;
|
||||
case SIC_rt_pcimp_e3:
|
||||
regs->rt_pcimp_e3 = val;
|
||||
break;
|
||||
case SIC_rt_pcicfgb:
|
||||
regs->rt_pcicfgb = val;
|
||||
break;
|
||||
case SIC_prepic_ctrl2:
|
||||
regs->prepic_ctrl2 = val;
|
||||
break;
|
||||
case SIC_prepic_err_stat:
|
||||
regs->prepic_err_stat = val;
|
||||
break;
|
||||
case SIC_prepic_err_int:
|
||||
regs->prepic_err_int = val;
|
||||
break;
|
||||
case SIC_prepic_linp0:
|
||||
regs->prepic_linp0 = val;
|
||||
break;
|
||||
case SIC_prepic_linp1:
|
||||
regs->prepic_linp1 = val;
|
||||
break;
|
||||
case SIC_prepic_linp2:
|
||||
regs->prepic_linp2 = val;
|
||||
break;
|
||||
case SIC_prepic_linp3:
|
||||
regs->prepic_linp3 = val;
|
||||
break;
|
||||
case SIC_prepic_linp4:
|
||||
regs->prepic_linp4 = val;
|
||||
break;
|
||||
case SIC_prepic_linp5:
|
||||
regs->prepic_linp5 = val;
|
||||
break;
|
||||
case SIC_iommu_ctrl:
|
||||
regs->iommu_ctrl = val;
|
||||
break;
|
||||
case SIC_iommu_ba_lo:
|
||||
regs->iommu_ptbar = val;
|
||||
break;
|
||||
case SIC_iommu_dtba_lo:
|
||||
regs->iommu_dtbar = val;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "%s: unknown SIC register 0x%x\n", __FUNCTION__, index);
|
||||
break;
|
||||
}
|
||||
|
||||
trace_sic_mem_writel(addr, val);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps sic_io_ops = {
|
||||
|
@ -121,6 +302,8 @@ void sic_init(E2KMachineState *ms)
|
|||
const hwaddr base = ES2_NSR_AREA_PHYS_BASE;
|
||||
const uint64_t size = ES2_NBSR_AREA_SIZE;
|
||||
|
||||
memset(&ms->sicregs, 0, sizeof(ms->sicregs));
|
||||
|
||||
io_memory = g_malloc(sizeof(*io_memory));
|
||||
memory_region_init_io(io_memory, OBJECT(ms), &sic_io_ops, ms, "sic-msi",
|
||||
size);
|
||||
|
|
|
@ -23,6 +23,41 @@
|
|||
#include "qom/object.h"
|
||||
#include "hw/e2k/ioapic.h"
|
||||
|
||||
typedef struct SICState {
|
||||
uint32_t rt_pcim0;
|
||||
uint32_t rt_pcim1;
|
||||
uint32_t rt_pcim2;
|
||||
uint32_t rt_pcim3;
|
||||
uint32_t rt_pciio0;
|
||||
uint32_t rt_pciio1;
|
||||
uint32_t rt_pciio2;
|
||||
uint32_t rt_pciio3;
|
||||
uint32_t rt_pcimp_b0;
|
||||
uint32_t rt_pcimp_b1;
|
||||
uint32_t rt_pcimp_b2;
|
||||
uint32_t rt_pcimp_b3;
|
||||
uint32_t rt_pcimp_e0;
|
||||
uint32_t rt_pcimp_e1;
|
||||
uint32_t rt_pcimp_e2;
|
||||
uint32_t rt_pcimp_e3;
|
||||
uint32_t rt_pcicfgb;
|
||||
uint64_t rt_msi;
|
||||
uint32_t iommu_ctrl;
|
||||
uint64_t iommu_ptbar;
|
||||
uint64_t iommu_dtbar;
|
||||
uint64_t iommu_err;
|
||||
uint64_t iommu_err_info;
|
||||
uint32_t prepic_ctrl2;
|
||||
uint32_t prepic_err_stat;
|
||||
uint32_t prepic_err_int;
|
||||
uint32_t prepic_linp0;
|
||||
uint32_t prepic_linp1;
|
||||
uint32_t prepic_linp2;
|
||||
uint32_t prepic_linp3;
|
||||
uint32_t prepic_linp4;
|
||||
uint32_t prepic_linp5;
|
||||
} SICState;
|
||||
|
||||
struct E2KMachineClass {
|
||||
/*< private >*/
|
||||
MachineClass parent;
|
||||
|
@ -36,6 +71,10 @@ struct E2KMachineState {
|
|||
|
||||
/*< public >*/
|
||||
qemu_irq *pic;
|
||||
|
||||
struct SICState sicregs;
|
||||
|
||||
AddressSpace *ioapic_as;
|
||||
};
|
||||
|
||||
#define TYPE_E2K_MACHINE MACHINE_TYPE_NAME("e2k")
|
||||
|
|
Loading…
Reference in New Issue