diff --git a/hw/e2k/sic.c b/hw/e2k/sic.c index 5cc80ccaed..3bf9c3bb06 100644 --- a/hw/e2k/sic.c +++ b/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 . - */ + */ #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); diff --git a/include/hw/e2k/e2k.h b/include/hw/e2k/e2k.h index d12d06b27b..92b43271a1 100644 --- a/include/hw/e2k/e2k.h +++ b/include/hw/e2k/e2k.h @@ -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")