From b5ea6754e8f913c82197dc26973d7d7ee4aef91f Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Fri, 30 Jun 2023 12:26:09 +0200 Subject: pnv/psi: Allow access to PSI registers through xscom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit skiboot only uses mmio to access the PSI registers (once the BAR is set) but we don't have any reason to block the accesses through xscom. This patch enables xscom access to the PSI registers. It converts the xscom addresses to mmio addresses, which requires a bit of care for the PSIHB, then reuse the existing mmio ops. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Message-ID: <20230630102609.193214-1-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_psi.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index 8aa09ab26b..46da58dff8 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -121,8 +121,12 @@ #define PSIHB9_BAR_MASK 0x00fffffffff00000ull #define PSIHB9_FSPBAR_MASK 0x00ffffff00000000ull +/* mmio address to xscom address */ #define PSIHB_REG(addr) (((addr) >> 3) + PSIHB_XSCOM_BAR) +/* xscom address to mmio address */ +#define PSIHB_MMIO(reg) ((reg - PSIHB_XSCOM_BAR) << 3) + static void pnv_psi_set_bar(PnvPsi *psi, uint64_t bar) { PnvPsiClass *ppc = PNV_PSI_GET_CLASS(psi); @@ -769,24 +773,31 @@ static const MemoryRegionOps pnv_psi_p9_mmio_ops = { static uint64_t pnv_psi_p9_xscom_read(void *opaque, hwaddr addr, unsigned size) { - /* No read are expected */ - qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom read at 0x%" PRIx64 "\n", addr); - return -1; + uint32_t reg = addr >> 3; + uint64_t val = -1; + + if (reg < PSIHB_XSCOM_BAR) { + /* FIR, not modeled */ + qemu_log_mask(LOG_UNIMP, "PSI: xscom read at 0x%08x\n", reg); + } else { + val = pnv_psi_p9_mmio_read(opaque, PSIHB_MMIO(reg), size); + } + return val; } static void pnv_psi_p9_xscom_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { PnvPsi *psi = PNV_PSI(opaque); + uint32_t reg = addr >> 3; - /* XSCOM is only used to set the PSIHB MMIO region */ - switch (addr >> 3) { - case PSIHB_XSCOM_BAR: + if (reg < PSIHB_XSCOM_BAR) { + /* FIR, not modeled */ + qemu_log_mask(LOG_UNIMP, "PSI: xscom write at 0x%08x\n", reg); + } else if (reg == PSIHB_XSCOM_BAR) { pnv_psi_set_bar(psi, val); - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, "PSI: xscom write at 0x%" PRIx64 "\n", - addr); + } else { + pnv_psi_p9_mmio_write(opaque, PSIHB_MMIO(reg), val, size); } } -- cgit v1.2.3 From a5ff7875a9e50180c354471f931f863a26283ce1 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sun, 25 Jun 2023 22:20:45 +1000 Subject: target/ppc: Make HDECR underflow edge triggered MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HDEC interrupts are edge-triggered on HDECR underflow (notably different from DEC which is level-triggered). HDEC interrupts already clear the irq on delivery so that does not need to be changed. Signed-off-by: Nicholas Piggin Reviewed-by: Cédric Le Goater Message-ID: <20230625122045.15544-1-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 82e4408c5c..0fc82bb175 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -788,8 +788,8 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, QEMUTimer *timer, void (*raise_excp)(void *), void (*lower_excp)(PowerPCCPU *), - target_ulong decr, target_ulong value, - int nr_bits) + uint32_t flags, target_ulong decr, + target_ulong value, int nr_bits) { CPUPPCState *env = &cpu->env; ppc_tb_t *tb_env = env->tb_env; @@ -819,15 +819,15 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers * an edge interrupt, so raise it here too. */ - if (((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) || - ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0 + if (((flags & PPC_DECR_UNDERFLOW_LEVEL) && signed_value < 0) || + ((flags & PPC_DECR_UNDERFLOW_TRIGGERED) && signed_value < 0 && signed_decr >= 0)) { (*raise_excp)(cpu); return; } /* On MSB level based systems a 0 for the MSB stops interrupt delivery */ - if (signed_value >= 0 && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) { + if (signed_value >= 0 && (flags & PPC_DECR_UNDERFLOW_LEVEL)) { (*lower_excp)(cpu); } @@ -846,8 +846,8 @@ static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, target_ulong decr, ppc_tb_t *tb_env = cpu->env.tb_env; __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer, - tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr, - value, nr_bits); + tb_env->decr_timer->cb, &cpu_ppc_decr_lower, + tb_env->flags, decr, value, nr_bits); } void cpu_ppc_store_decr(CPUPPCState *env, target_ulong value) @@ -876,8 +876,10 @@ static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, target_ulong hdecr, ppc_tb_t *tb_env = cpu->env.tb_env; if (tb_env->hdecr_timer != NULL) { + /* HDECR (Book3S 64bit) is edge-based, not level like DECR */ __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer, tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower, + PPC_DECR_UNDERFLOW_TRIGGERED, hdecr, value, nr_bits); } } -- cgit v1.2.3 From 2ad2e113deb5663e69a05dd6922cbfc6d7ea34d3 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 29 Jun 2023 12:07:13 +1000 Subject: hw/ppc: Fix clock update drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The clock update logic reads the clock twice to compute the new clock value, with a value derived from the later time subtracted from a value derived from the earlier time. The delta causes time to be lost. This can ultimately result in time becoming unsynchronized between CPUs and that can cause OS lockups, timeouts, watchdogs, etc. This can be seen running a KVM guest (that causes lots of TB updates) on a powernv SMP machine. Fix this by reading the clock once. Cc: qemu-stable@nongnu.org Fixes: dbdd25065e90 ("Implement time-base start/stop helpers.") Signed-off-by: Nicholas Piggin Reviewed-by: Cédric Le Goater Reviewed-by: Frederic Barrat Message-ID: <20230629020713.327745-1-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 0fc82bb175..0e0a3d93c3 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -535,23 +535,24 @@ static inline void cpu_ppc_store_tb(ppc_tb_t *tb_env, uint64_t vmclk, void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value) { ppc_tb_t *tb_env = env->tb_env; + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); + tb = cpu_ppc_get_tb(tb_env, clock, tb_env->tb_offset); tb &= 0xFFFFFFFF00000000ULL; - cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - &tb_env->tb_offset, tb | (uint64_t)value); + cpu_ppc_store_tb(tb_env, clock, &tb_env->tb_offset, tb | (uint64_t)value); } static inline void _cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value) { ppc_tb_t *tb_env = env->tb_env; + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset); + tb = cpu_ppc_get_tb(tb_env, clock, tb_env->tb_offset); tb &= 0x00000000FFFFFFFFULL; - cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - &tb_env->tb_offset, ((uint64_t)value << 32) | tb); + cpu_ppc_store_tb(tb_env, clock, &tb_env->tb_offset, + ((uint64_t)value << 32) | tb); } void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value) @@ -584,23 +585,24 @@ uint32_t cpu_ppc_load_atbu (CPUPPCState *env) void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value) { ppc_tb_t *tb_env = env->tb_env; + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); + tb = cpu_ppc_get_tb(tb_env, clock, tb_env->atb_offset); tb &= 0xFFFFFFFF00000000ULL; - cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - &tb_env->atb_offset, tb | (uint64_t)value); + cpu_ppc_store_tb(tb_env, clock, &tb_env->atb_offset, tb | (uint64_t)value); } void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value) { ppc_tb_t *tb_env = env->tb_env; + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset); + tb = cpu_ppc_get_tb(tb_env, clock, tb_env->atb_offset); tb &= 0x00000000FFFFFFFFULL; - cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - &tb_env->atb_offset, ((uint64_t)value << 32) | tb); + cpu_ppc_store_tb(tb_env, clock, &tb_env->atb_offset, + ((uint64_t)value << 32) | tb); } uint64_t cpu_ppc_load_vtb(CPUPPCState *env) @@ -622,14 +624,13 @@ void cpu_ppc_store_vtb(CPUPPCState *env, uint64_t value) void cpu_ppc_store_tbu40(CPUPPCState *env, uint64_t value) { ppc_tb_t *tb_env = env->tb_env; + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); uint64_t tb; - tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - tb_env->tb_offset); + tb = cpu_ppc_get_tb(tb_env, clock, tb_env->tb_offset); tb &= 0xFFFFFFUL; tb |= (value & ~0xFFFFFFUL); - cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), - &tb_env->tb_offset, tb); + cpu_ppc_store_tb(tb_env, clock, &tb_env->tb_offset, tb); } static void cpu_ppc_tb_stop (CPUPPCState *env) -- cgit v1.2.3 From 32be62a3d811fa9f389ff791ac6c5cecf69b2109 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Mon, 5 Jun 2023 23:51:45 +0200 Subject: mv64361: Add dummy gigabit ethernet PHY access registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't emulate the gigabit ethernet part of the chip but the MorphOS driver accesses these and expects to get some valid looking result otherwise it hangs. Add some minimal dummy implementation to avoid rhis. Signed-off-by: BALATON Zoltan Acked-by: Cédric Le Goater Message-ID: <20230605215145.29458746335@zero.eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/pci-host/mv64361.c | 6 ++++++ hw/pci-host/mv643xx.h | 3 +++ 2 files changed, 9 insertions(+) (limited to 'hw') diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c index 19e8031a3f..01bd8c887f 100644 --- a/hw/pci-host/mv64361.c +++ b/hw/pci-host/mv64361.c @@ -541,6 +541,12 @@ static uint64_t mv64361_read(void *opaque, hwaddr addr, unsigned int size) } } break; + case MV64340_ETH_PHY_ADDR: + ret = 0x98; + break; + case MV64340_ETH_SMI: + ret = BIT(27); + break; case MV64340_CUNIT_ARBITER_CONTROL_REG: ret = 0x11ff0000 | (s->gpp_int_level << 10); break; diff --git a/hw/pci-host/mv643xx.h b/hw/pci-host/mv643xx.h index cd26a43f18..f2e1baea88 100644 --- a/hw/pci-host/mv643xx.h +++ b/hw/pci-host/mv643xx.h @@ -656,6 +656,9 @@ /* Ethernet Unit Registers */ /****************************************/ +#define MV64340_ETH_PHY_ADDR 0x2000 +#define MV64340_ETH_SMI 0x2004 + /*******************************************/ /* CUNIT Registers */ /*******************************************/ -- cgit v1.2.3 From bc65beb3a412b3d6d7e16d9f11a9712a086aae02 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 26 Jun 2023 06:16:28 +1000 Subject: sungem: Add WOL MMIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apple sungem devices are expected to have WOL MMIO registers. Add a region to prevent transaction failures, and implement the WOL-disable CSR write because the Linux driver reset writes this. Signed-off-by: Nicholas Piggin Reviewed-by: Cédric Le Goater Reviewed-by: Joel Stanley Message-ID: <20230625201628.65231-1-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/net/sungem.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/net/trace-events | 2 ++ 2 files changed, 54 insertions(+) (limited to 'hw') diff --git a/hw/net/sungem.c b/hw/net/sungem.c index eb01520790..e0e8e5ae41 100644 --- a/hw/net/sungem.c +++ b/hw/net/sungem.c @@ -107,6 +107,15 @@ OBJECT_DECLARE_SIMPLE_TYPE(SunGEMState, SUNGEM) #define RXDMA_FTAG 0x0110UL /* RX FIFO Tag */ #define RXDMA_FSZ 0x0120UL /* RX FIFO Size */ +/* WOL Registers */ +#define SUNGEM_MMIO_WOL_SIZE 0x14 + +#define WOL_MATCH0 0x0000UL +#define WOL_MATCH1 0x0004UL +#define WOL_MATCH2 0x0008UL +#define WOL_MCOUNT 0x000CUL +#define WOL_WAKECSR 0x0010UL + /* MAC Registers */ #define SUNGEM_MMIO_MAC_SIZE 0x200 @@ -168,6 +177,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(SunGEMState, SUNGEM) #define SUNGEM_MMIO_PCS_SIZE 0x60 #define PCS_MIISTAT 0x0004UL /* PCS MII Status Register */ #define PCS_ISTAT 0x0018UL /* PCS Interrupt Status Reg */ + #define PCS_SSTATE 0x005CUL /* Serialink State Register */ /* Descriptors */ @@ -200,6 +210,7 @@ struct SunGEMState { MemoryRegion greg; MemoryRegion txdma; MemoryRegion rxdma; + MemoryRegion wol; MemoryRegion mac; MemoryRegion mif; MemoryRegion pcs; @@ -1076,6 +1087,43 @@ static const MemoryRegionOps sungem_mmio_rxdma_ops = { }, }; +static void sungem_mmio_wol_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ + trace_sungem_mmio_wol_write(addr, val); + + switch (addr) { + case WOL_WAKECSR: + if (val != 0) { + qemu_log_mask(LOG_UNIMP, "sungem: WOL not supported\n"); + } + break; + default: + qemu_log_mask(LOG_UNIMP, "sungem: WOL not supported\n"); + } +} + +static uint64_t sungem_mmio_wol_read(void *opaque, hwaddr addr, unsigned size) +{ + uint32_t val = -1; + + qemu_log_mask(LOG_UNIMP, "sungem: WOL not supported\n"); + + trace_sungem_mmio_wol_read(addr, val); + + return val; +} + +static const MemoryRegionOps sungem_mmio_wol_ops = { + .read = sungem_mmio_wol_read, + .write = sungem_mmio_wol_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static void sungem_mmio_mac_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -1344,6 +1392,10 @@ static void sungem_realize(PCIDevice *pci_dev, Error **errp) "sungem.rxdma", SUNGEM_MMIO_RXDMA_SIZE); memory_region_add_subregion(&s->sungem, 0x4000, &s->rxdma); + memory_region_init_io(&s->wol, OBJECT(s), &sungem_mmio_wol_ops, s, + "sungem.wol", SUNGEM_MMIO_WOL_SIZE); + memory_region_add_subregion(&s->sungem, 0x3000, &s->wol); + memory_region_init_io(&s->mac, OBJECT(s), &sungem_mmio_mac_ops, s, "sungem.mac", SUNGEM_MMIO_MAC_SIZE); memory_region_add_subregion(&s->sungem, 0x6000, &s->mac); diff --git a/hw/net/trace-events b/hw/net/trace-events index e4a98b2c7d..930e5b4293 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -350,6 +350,8 @@ sungem_mmio_txdma_write(uint64_t addr, uint64_t val) "MMIO txdma write to 0x%"PR sungem_mmio_txdma_read(uint64_t addr, uint64_t val) "MMIO txdma read from 0x%"PRIx64" val=0x%"PRIx64 sungem_mmio_rxdma_write(uint64_t addr, uint64_t val) "MMIO rxdma write to 0x%"PRIx64" val=0x%"PRIx64 sungem_mmio_rxdma_read(uint64_t addr, uint64_t val) "MMIO rxdma read from 0x%"PRIx64" val=0x%"PRIx64 +sungem_mmio_wol_write(uint64_t addr, uint64_t val) "MMIO wol write to 0x%"PRIx64" val=0x%"PRIx64 +sungem_mmio_wol_read(uint64_t addr, uint64_t val) "MMIO wol read from 0x%"PRIx64" val=0x%"PRIx64 sungem_mmio_mac_write(uint64_t addr, uint64_t val) "MMIO mac write to 0x%"PRIx64" val=0x%"PRIx64 sungem_mmio_mac_read(uint64_t addr, uint64_t val) "MMIO mac read from 0x%"PRIx64" val=0x%"PRIx64 sungem_mmio_mif_write(uint64_t addr, uint64_t val) "MMIO mif write to 0x%"PRIx64" val=0x%"PRIx64 -- cgit v1.2.3 From d73a17515035a006eb09272b8d554833e11140bb Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Mon, 26 Jun 2023 11:40:57 +0200 Subject: pnv/xive2: Allow indirect TIMA accesses of all sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Booting linux on the powernv10 machine logs a few errors like: Invalid read at addr 0x38, size 1, region 'xive-ic-tm-indirect', reason: invalid size (min:8 max:8) Invalid write at addr 0x38, size 1, region 'xive-ic-tm-indirect', reason: invalid size (min:8 max:8) Invalid read at addr 0x38, size 1, region 'xive-ic-tm-indirect', reason: invalid size (min:8 max:8) Those errors happen when linux is resetting XIVE. We're trying to read/write the enablement bit for the hardware context and qemu doesn't allow indirect TIMA accesses of less than 8 bytes. Direct TIMA access can go through though, as well as indirect TIMA accesses on P9. So even though there are some restrictions regarding the address/size combinations for TIMA access, the example above is perfectly valid. This patch lets indirect TIMA accesses of all sizes go through. The special operations will be intercepted and the default "raw" handlers will pick up all other requests and complain about invalid sizes as appropriate. Tested-by: Nicholas Piggin Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Message-ID: <20230626094057.1192473-1-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/intc/pnv_xive2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index ed438a20ed..e8ab176de6 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -1644,11 +1644,11 @@ static const MemoryRegionOps pnv_xive2_ic_tm_indirect_ops = { .write = pnv_xive2_ic_tm_indirect_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, .impl = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, }; -- cgit v1.2.3 From 694d3cb2ef2d7355ddaf413614f325f17da9716b Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Mon, 3 Jul 2023 10:08:58 +0200 Subject: pnv/xive2: Fix TIMA offset for indirect access MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Direct TIMA operations can be done through 4 pages, each with a different privilege level dictating what fields can be accessed. On the other hand, indirect TIMA accesses on P10 are done through a single page, which is the equivalent of the most privileged page of direct TIMA accesses. The offset in the IC bar of an indirect access specifies what hw thread is targeted (page shift bits) and the offset in the TIMA being accessed (the page offset bits). When the indirect access is calling the underlying direct access functions, it is therefore important to clearly separate the 2, as the direct functions assume any page shift bits define the privilege ring level. For indirect accesses, those bits must be 0. This patch fixes the offset passed to direct TIMA functions. It didn't matter for SMT1, as the 2 least significant bits of the page shift are part of the hw thread ID and always 0, so the direct TIMA functions were accessing the privilege ring 0 page. With SMT4/8, it is no longer true. The fix is specific to P10, as indirect TIMA access on P9 was handled differently. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Message-ID: <20230703080858.54060-1-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/intc/pnv_xive2.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index e8ab176de6..82fcd3ea22 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -1590,6 +1590,18 @@ static uint32_t pnv_xive2_ic_tm_get_pir(PnvXive2 *xive, hwaddr offset) return xive->chip->chip_id << 8 | offset >> xive->ic_shift; } +static uint32_t pnv_xive2_ic_tm_get_hw_page_offset(PnvXive2 *xive, + hwaddr offset) +{ + /* + * Indirect TIMA accesses are similar to direct accesses for + * privilege ring 0. So remove any traces of the hw thread ID from + * the offset in the IC BAR as it could be interpreted as the ring + * privilege when calling the underlying direct access functions. + */ + return offset & ((1ull << xive->ic_shift) - 1); +} + static XiveTCTX *pnv_xive2_get_indirect_tctx(PnvXive2 *xive, uint32_t pir) { PnvChip *chip = xive->chip; @@ -1612,14 +1624,16 @@ static uint64_t pnv_xive2_ic_tm_indirect_read(void *opaque, hwaddr offset, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + hwaddr hw_page_offset; uint32_t pir; XiveTCTX *tctx; uint64_t val = -1; pir = pnv_xive2_ic_tm_get_pir(xive, offset); + hw_page_offset = pnv_xive2_ic_tm_get_hw_page_offset(xive, offset); tctx = pnv_xive2_get_indirect_tctx(xive, pir); if (tctx) { - val = xive_tctx_tm_read(NULL, tctx, offset, size); + val = xive_tctx_tm_read(NULL, tctx, hw_page_offset, size); } return val; @@ -1629,13 +1643,15 @@ static void pnv_xive2_ic_tm_indirect_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + hwaddr hw_page_offset; uint32_t pir; XiveTCTX *tctx; pir = pnv_xive2_ic_tm_get_pir(xive, offset); + hw_page_offset = pnv_xive2_ic_tm_get_hw_page_offset(xive, offset); tctx = pnv_xive2_get_indirect_tctx(xive, pir); if (tctx) { - xive_tctx_tm_write(NULL, tctx, offset, val, size); + xive_tctx_tm_write(NULL, tctx, hw_page_offset, val, size); } } -- cgit v1.2.3 From a8da2e1424c2f716222582a4706117d2ca845fe1 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Mon, 3 Jul 2023 10:12:14 +0200 Subject: pnv/xive: Add property on xive sources to define PQ state on reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PQ state of a xive interrupt is always initialized to Q=1, which means the interrupt is disabled. Since a xive source can be embedded in many objects, this patch adds a property to allow that behavior to be refined if needed. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20230703081215.55252-2-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/intc/xive.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 84c079b034..f60c878345 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1232,8 +1232,7 @@ static void xive_source_reset(void *dev) /* Do not clear the LSI bitmap */ - /* PQs are initialized to 0b01 (Q=1) which corresponds to "ints off" */ - memset(xsrc->status, XIVE_ESB_OFF, xsrc->nr_irqs); + memset(xsrc->status, xsrc->reset_pq, xsrc->nr_irqs); } static void xive_source_realize(DeviceState *dev, Error **errp) @@ -1287,6 +1286,11 @@ static Property xive_source_properties[] = { DEFINE_PROP_UINT64("flags", XiveSource, esb_flags, 0), DEFINE_PROP_UINT32("nr-irqs", XiveSource, nr_irqs, 0), DEFINE_PROP_UINT32("shift", XiveSource, esb_shift, XIVE_ESB_64K_2PAGE), + /* + * By default, PQs are initialized to 0b01 (Q=1) which corresponds + * to "ints off" + */ + DEFINE_PROP_UINT8("reset-pq", XiveSource, reset_pq, XIVE_ESB_OFF), DEFINE_PROP_LINK("xive", XiveSource, xive, TYPE_XIVE_NOTIFIER, XiveNotifier *), DEFINE_PROP_END_OF_LIST(), -- cgit v1.2.3 From 4a1e9449e8d55c173f3eddd94ae363c2c2938fda Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Mon, 3 Jul 2023 10:12:15 +0200 Subject: pnv/psi: Initialize the PSIHB interrupts to match hardware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the powernv9 and powernv10 machines, the PSIHB interrupts are currently initialized with a PQ state of 0b01, i.e. interrupts are disabled. However real hardware initializes them to 0b00 for the PSIHB. This patch updates it, in case an hypervisor is in the mood of checking it. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20230703081215.55252-3-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_psi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw') diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index 46da58dff8..daaa2f0575 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -863,6 +863,8 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(xsrc), "nr-irqs", PSIHB9_NUM_IRQS, &error_fatal); object_property_set_link(OBJECT(xsrc), "xive", OBJECT(psi), &error_abort); + object_property_set_int(OBJECT(xsrc), "reset-pq", XIVE_ESB_RESET, + &error_abort); if (!qdev_realize(DEVICE(xsrc), NULL, errp)) { return; } -- cgit v1.2.3 From 19d197f5d1e12717310110389267f16986763e9a Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 4 Jul 2023 15:12:00 +0930 Subject: ppc/pnv: quad xscom callbacks are P9 specific MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the functions to include P9 in the name in preparation for adding P10 versions. Correct the unimp read message while we're changing the function. Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley Reviewed-by: Frederic Barrat Message-ID: <20230704054204.168547-2-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_core.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 0bc3ad41c8..0f451b3b6e 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -360,8 +360,8 @@ DEFINE_TYPES(pnv_core_infos) #define P9X_EX_NCU_SPEC_BAR 0x11010 -static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr, - unsigned int width) +static uint64_t pnv_quad_power9_xscom_read(void *opaque, hwaddr addr, + unsigned int width) { uint32_t offset = addr >> 3; uint64_t val = -1; @@ -372,15 +372,15 @@ static uint64_t pnv_quad_xscom_read(void *opaque, hwaddr addr, val = 0; break; default: - qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__, + qemu_log_mask(LOG_UNIMP, "%s: reading @0x%08x\n", __func__, offset); } return val; } -static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val, - unsigned int width) +static void pnv_quad_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val, + unsigned int width) { uint32_t offset = addr >> 3; @@ -394,9 +394,9 @@ static void pnv_quad_xscom_write(void *opaque, hwaddr addr, uint64_t val, } } -static const MemoryRegionOps pnv_quad_xscom_ops = { - .read = pnv_quad_xscom_read, - .write = pnv_quad_xscom_write, +static const MemoryRegionOps pnv_quad_power9_xscom_ops = { + .read = pnv_quad_power9_xscom_read, + .write = pnv_quad_power9_xscom_write, .valid.min_access_size = 8, .valid.max_access_size = 8, .impl.min_access_size = 8, @@ -410,7 +410,8 @@ static void pnv_quad_realize(DeviceState *dev, Error **errp) char name[32]; snprintf(name, sizeof(name), "xscom-quad.%d", eq->quad_id); - pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), &pnv_quad_xscom_ops, + pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), + &pnv_quad_power9_xscom_ops, eq, name, PNV9_XSCOM_EQ_SIZE); } -- cgit v1.2.3 From fdc2b46abaa81415a8e6d8439bdd0c3d1b930373 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 4 Jul 2023 15:12:01 +0930 Subject: ppc/pnv: Subclass quad xscom callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the existing pnv_quad_xscom_read/write be P9 specific, in preparation for a different P10 callback. Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley Reviewed-by: Frederic Barrat Message-ID: <20230704054204.168547-3-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv.c | 11 +++++++---- hw/ppc/pnv_core.c | 40 +++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 17 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index fc083173f3..c77fdb6747 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1429,14 +1429,15 @@ static void pnv_chip_power9_instance_init(Object *obj) } static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq, - PnvCore *pnv_core) + PnvCore *pnv_core, + const char *type) { char eq_name[32]; int core_id = CPU_CORE(pnv_core)->core_id; snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id); object_initialize_child_with_props(OBJECT(chip), eq_name, eq, - sizeof(*eq), TYPE_PNV_QUAD, + sizeof(*eq), type, &error_fatal, NULL); object_property_set_int(OBJECT(eq), "quad-id", core_id, &error_fatal); @@ -1454,7 +1455,8 @@ static void pnv_chip_quad_realize(Pnv9Chip *chip9, Error **errp) for (i = 0; i < chip9->nr_quads; i++) { PnvQuad *eq = &chip9->quads[i]; - pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4]); + pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4], + PNV_QUAD_TYPE_NAME("power9")); pnv_xscom_add_subregion(chip, PNV9_XSCOM_EQ_BASE(eq->quad_id), &eq->xscom_regs); @@ -1666,7 +1668,8 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp) for (i = 0; i < chip10->nr_quads; i++) { PnvQuad *eq = &chip10->quads[i]; - pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4]); + pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4], + PNV_QUAD_TYPE_NAME("power9")); pnv_xscom_add_subregion(chip, PNV10_XSCOM_EQ_BASE(eq->quad_id), &eq->xscom_regs); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 0f451b3b6e..73d25409c9 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -407,12 +407,14 @@ static const MemoryRegionOps pnv_quad_power9_xscom_ops = { static void pnv_quad_realize(DeviceState *dev, Error **errp) { PnvQuad *eq = PNV_QUAD(dev); + PnvQuadClass *pqc = PNV_QUAD_GET_CLASS(eq); char name[32]; snprintf(name, sizeof(name), "xscom-quad.%d", eq->quad_id); pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), - &pnv_quad_power9_xscom_ops, - eq, name, PNV9_XSCOM_EQ_SIZE); + pqc->xscom_ops, + eq, name, + pqc->xscom_size); } static Property pnv_quad_properties[] = { @@ -420,6 +422,14 @@ static Property pnv_quad_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void pnv_quad_power9_class_init(ObjectClass *oc, void *data) +{ + PnvQuadClass *pqc = PNV_QUAD_CLASS(oc); + + pqc->xscom_ops = &pnv_quad_power9_xscom_ops; + pqc->xscom_size = PNV9_XSCOM_EQ_SIZE; +} + static void pnv_quad_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -429,16 +439,20 @@ static void pnv_quad_class_init(ObjectClass *oc, void *data) dc->user_creatable = false; } -static const TypeInfo pnv_quad_info = { - .name = TYPE_PNV_QUAD, - .parent = TYPE_DEVICE, - .instance_size = sizeof(PnvQuad), - .class_init = pnv_quad_class_init, +static const TypeInfo pnv_quad_infos[] = { + { + .name = TYPE_PNV_QUAD, + .parent = TYPE_DEVICE, + .instance_size = sizeof(PnvQuad), + .class_size = sizeof(PnvQuadClass), + .class_init = pnv_quad_class_init, + .abstract = true, + }, + { + .parent = TYPE_PNV_QUAD, + .name = PNV_QUAD_TYPE_NAME("power9"), + .class_init = pnv_quad_power9_class_init, + }, }; -static void pnv_core_register_types(void) -{ - type_register_static(&pnv_quad_info); -} - -type_init(pnv_core_register_types) +DEFINE_TYPES(pnv_quad_infos); -- cgit v1.2.3 From a1d64b9efc8173e4e90aef5f48e89364c43118a5 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 4 Jul 2023 15:12:02 +0930 Subject: ppc/pnv: Add P10 quad xscom model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a PnvQuad class for the P10 powernv machine. No xscoms are implemented yet, but this allows them to be added. The size is reduced to avoid the quad region from overlapping with the core region. address-space: xscom-0 0000000000000000-00000003ffffffff (prio 0, i/o): xscom-0 0000000100000000-00000001000fffff (prio 0, i/o): xscom-quad.0 0000000100108000-0000000100907fff (prio 0, i/o): xscom-core.3 0000000100110000-000000010090ffff (prio 0, i/o): xscom-core.2 0000000100120000-000000010091ffff (prio 0, i/o): xscom-core.1 0000000100140000-000000010093ffff (prio 0, i/o): xscom-core.0 Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater Reviewed-by: Frederic Barrat Message-ID: <20230704054204.168547-4-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv.c | 2 +- hw/ppc/pnv_core.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index c77fdb6747..5f25fe985a 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1669,7 +1669,7 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp) PnvQuad *eq = &chip10->quads[i]; pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4], - PNV_QUAD_TYPE_NAME("power9")); + PNV_QUAD_TYPE_NAME("power10")); pnv_xscom_add_subregion(chip, PNV10_XSCOM_EQ_BASE(eq->quad_id), &eq->xscom_regs); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 73d25409c9..e4df435b15 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -404,6 +404,47 @@ static const MemoryRegionOps pnv_quad_power9_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +/* + * POWER10 Quads + */ + +static uint64_t pnv_quad_power10_xscom_read(void *opaque, hwaddr addr, + unsigned int width) +{ + uint32_t offset = addr >> 3; + uint64_t val = -1; + + switch (offset) { + default: + qemu_log_mask(LOG_UNIMP, "%s: reading @0x%08x\n", __func__, + offset); + } + + return val; +} + +static void pnv_quad_power10_xscom_write(void *opaque, hwaddr addr, + uint64_t val, unsigned int width) +{ + uint32_t offset = addr >> 3; + + switch (offset) { + default: + qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__, + offset); + } +} + +static const MemoryRegionOps pnv_quad_power10_xscom_ops = { + .read = pnv_quad_power10_xscom_read, + .write = pnv_quad_power10_xscom_write, + .valid.min_access_size = 8, + .valid.max_access_size = 8, + .impl.min_access_size = 8, + .impl.max_access_size = 8, + .endianness = DEVICE_BIG_ENDIAN, +}; + static void pnv_quad_realize(DeviceState *dev, Error **errp) { PnvQuad *eq = PNV_QUAD(dev); @@ -430,6 +471,14 @@ static void pnv_quad_power9_class_init(ObjectClass *oc, void *data) pqc->xscom_size = PNV9_XSCOM_EQ_SIZE; } +static void pnv_quad_power10_class_init(ObjectClass *oc, void *data) +{ + PnvQuadClass *pqc = PNV_QUAD_CLASS(oc); + + pqc->xscom_ops = &pnv_quad_power10_xscom_ops; + pqc->xscom_size = PNV10_XSCOM_EQ_SIZE; +} + static void pnv_quad_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -453,6 +502,11 @@ static const TypeInfo pnv_quad_infos[] = { .name = PNV_QUAD_TYPE_NAME("power9"), .class_init = pnv_quad_power9_class_init, }, + { + .parent = TYPE_PNV_QUAD, + .name = PNV_QUAD_TYPE_NAME("power10"), + .class_init = pnv_quad_power10_class_init, + }, }; DEFINE_TYPES(pnv_quad_infos); -- cgit v1.2.3 From 9a3942179d395d223531530d6ff71df25b00d064 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 4 Jul 2023 15:12:03 +0930 Subject: ppc/pnv: Add P10 core xscom model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like the quad xscoms, add a core model for P10 to allow future differentiation from P9. Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater Reviewed-by: Frederic Barrat Message-ID: <20230704054204.168547-5-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_core.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index e4df435b15..1eec28c88c 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -167,6 +167,47 @@ static const MemoryRegionOps pnv_core_power9_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +/* + * POWER10 core controls + */ + +static uint64_t pnv_core_power10_xscom_read(void *opaque, hwaddr addr, + unsigned int width) +{ + uint32_t offset = addr >> 3; + uint64_t val = 0; + + switch (offset) { + default: + qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", + addr); + } + + return val; +} + +static void pnv_core_power10_xscom_write(void *opaque, hwaddr addr, + uint64_t val, unsigned int width) +{ + uint32_t offset = addr >> 3; + + switch (offset) { + default: + qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n", + addr); + } +} + +static const MemoryRegionOps pnv_core_power10_xscom_ops = { + .read = pnv_core_power10_xscom_read, + .write = pnv_core_power10_xscom_write, + .valid.min_access_size = 8, + .valid.max_access_size = 8, + .impl.min_access_size = 8, + .impl.max_access_size = 8, + .endianness = DEVICE_BIG_ENDIAN, +}; + static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp) { CPUPPCState *env = &cpu->env; @@ -315,8 +356,7 @@ static void pnv_core_power10_class_init(ObjectClass *oc, void *data) { PnvCoreClass *pcc = PNV_CORE_CLASS(oc); - /* TODO: Use the P9 XSCOMs for now on P10 */ - pcc->xscom_ops = &pnv_core_power9_xscom_ops; + pcc->xscom_ops = &pnv_core_power10_xscom_ops; } static void pnv_core_class_init(ObjectClass *oc, void *data) -- cgit v1.2.3 From 53658074955efc7b4329999577464bd763ef4cbd Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 4 Jul 2023 15:12:04 +0930 Subject: ppc/pnv: Return zero for core thread state xscom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Firmware now warns if booting in LPAR per core mode (PPC bit 62). So this warning doesn't trigger, report the core thread state is 0. Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley Reviewed-by: Frederic Barrat Message-ID: <20230704054204.168547-6-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'hw') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 1eec28c88c..b7223bb445 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -116,6 +116,8 @@ static const MemoryRegionOps pnv_core_power8_xscom_ops = { #define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_HYP 0xf010d #define PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR 0xf010a +#define PNV9_XSCOM_EC_CORE_THREAD_STATE 0x10ab3 + static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr, unsigned int width) { @@ -134,6 +136,9 @@ static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr, case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR: val = 0x0; break; + case PNV9_XSCOM_EC_CORE_THREAD_STATE: + val = 0; + break; default: qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", addr); @@ -171,6 +176,8 @@ static const MemoryRegionOps pnv_core_power9_xscom_ops = { * POWER10 core controls */ +#define PNV10_XSCOM_EC_CORE_THREAD_STATE 0x412 + static uint64_t pnv_core_power10_xscom_read(void *opaque, hwaddr addr, unsigned int width) { @@ -178,6 +185,9 @@ static uint64_t pnv_core_power10_xscom_read(void *opaque, hwaddr addr, uint64_t val = 0; switch (offset) { + case PNV10_XSCOM_EC_CORE_THREAD_STATE: + val = 0; + break; default: qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", addr); -- cgit v1.2.3 From 053075097a053f7f9d8ce01f40ae1b1ad1845fea Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Tue, 4 Jul 2023 16:48:48 +0200 Subject: pnv/xive: Allow mmio operations of any size on the ESB CI pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently only allow 64-bit operations on the ESB CI pages. There's no real reason for that limitation, skiboot/linux didn't need more. However the hardware supports any size, so this patch relaxes that restriction. It impacts both the ESB pages for "normal" interrupts as well as the ESB pages for escalation interrupts defined for the ENDs. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Message-ID: <20230704144848.164287-1-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/intc/xive.c | 8 ++++---- hw/intc/xive2.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/intc/xive.c b/hw/intc/xive.c index f60c878345..c014e961a4 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1175,11 +1175,11 @@ static const MemoryRegionOps xive_source_esb_ops = { .write = xive_source_esb_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, .impl = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, }; @@ -2006,11 +2006,11 @@ static const MemoryRegionOps xive_end_source_ops = { .write = xive_end_source_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, .impl = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, }; diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 4d9ff41956..c37ef25d44 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -954,11 +954,11 @@ static const MemoryRegionOps xive2_end_source_ops = { .write = xive2_end_source_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, .impl = { - .min_access_size = 8, + .min_access_size = 1, .max_access_size = 8, }, }; -- cgit v1.2.3 From ebe0e9bbcbe432cd9fbcfbb4e2e9be86761ee606 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Tue, 4 Jul 2023 20:19:20 +0200 Subject: ppc/pegasos2: Add support for -initrd command line option This also changes type of sz local variable to ssize_t because it is used to store return value of load_elf() and load_image_targphys() that return ssize_t. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-ID: <20230704181920.27B58746335@zero.eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pegasos2.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index af5489de26..9c9944188b 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -44,6 +44,8 @@ #define PROM_ADDR 0xfff00000 #define PROM_SIZE 0x80000 +#define INITRD_MIN_ADDR 0x600000 + #define KVMPPC_HCALL_BASE 0xf000 #define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0) #define KVMPPC_H_VOF_CLIENT (KVMPPC_HCALL_BASE + 0x5) @@ -80,6 +82,8 @@ struct Pegasos2MachineState { uint64_t kernel_addr; uint64_t kernel_entry; uint64_t kernel_size; + uint64_t initrd_addr; + uint64_t initrd_size; }; static void *build_fdt(MachineState *machine, int *fdt_size); @@ -117,7 +121,8 @@ static void pegasos2_init(MachineState *machine) I2CBus *i2c_bus; const char *fwname = machine->firmware ?: PROM_FILENAME; char *filename; - int i, sz; + int i; + ssize_t sz; uint8_t *spd_data; /* init CPU */ @@ -213,6 +218,20 @@ static void pegasos2_init(MachineState *machine) warn_report("Using Virtual OpenFirmware but no -kernel option."); } + if (machine->initrd_filename) { + pm->initrd_addr = pm->kernel_addr + pm->kernel_size + 64 * KiB; + pm->initrd_addr = ROUND_UP(pm->initrd_addr, 4); + pm->initrd_addr = MAX(pm->initrd_addr, INITRD_MIN_ADDR); + sz = load_image_targphys(machine->initrd_filename, pm->initrd_addr, + machine->ram_size - pm->initrd_addr); + if (sz <= 0) { + error_report("Could not load initrd '%s'", + machine->initrd_filename); + exit(1); + } + pm->initrd_size = sz; + } + if (!pm->vof && machine->kernel_cmdline && machine->kernel_cmdline[0]) { warn_report("Option -append may be ineffective with -bios."); } @@ -335,6 +354,11 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason) error_report("Memory for kernel is in use"); exit(1); } + if (pm->initrd_size && + vof_claim(pm->vof, pm->initrd_addr, pm->initrd_size, 0) == -1) { + error_report("Memory for initrd is in use"); + exit(1); + } fdt = build_fdt(machine, &sz); /* FIXME: VOF assumes entry is same as load address */ d[0] = cpu_to_be64(pm->kernel_entry); @@ -966,6 +990,12 @@ static void *build_fdt(MachineState *machine, int *fdt_size) qemu_fdt_setprop_string(fdt, "/memory@0", "name", "memory"); qemu_fdt_add_subnode(fdt, "/chosen"); + if (pm->initrd_addr && pm->initrd_size) { + qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", + pm->initrd_addr + pm->initrd_size); + qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", + pm->initrd_addr); + } qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", machine->kernel_cmdline ?: ""); qemu_fdt_setprop_string(fdt, "/chosen", "name", "chosen"); -- cgit v1.2.3 From ff349cce8923d3c1713a6d58eb98ff692e6637f6 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Wed, 5 Jul 2023 13:00:39 +0200 Subject: pnv/xive: Print CPU target in all TIMA traces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the CPU target in the trace when reading/writing the TIMA space. It was already done for other TIMA ops (notify, accept, ...), only missing for those 2. Useful for debug and even more now that we experiment with SMT. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Message-ID: <20230705110039.231148-1-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/intc/trace-events | 4 ++-- hw/intc/xive.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 5c6094c457..36ff71f947 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -265,8 +265,8 @@ xive_source_esb_read(uint64_t addr, uint32_t srcno, uint64_t value) "@0x%"PRIx64 xive_source_esb_write(uint64_t addr, uint32_t srcno, uint64_t value) "@0x%"PRIx64" IRQ 0x%x val=0x%"PRIx64 xive_router_end_notify(uint8_t end_blk, uint32_t end_idx, uint32_t end_data) "END 0x%02x/0x%04x -> enqueue 0x%08x" xive_router_end_escalate(uint8_t end_blk, uint32_t end_idx, uint8_t esc_blk, uint32_t esc_idx, uint32_t end_data) "END 0x%02x/0x%04x -> escalate END 0x%02x/0x%04x data 0x%08x" -xive_tctx_tm_write(uint64_t offset, unsigned int size, uint64_t value) "@0x%"PRIx64" sz=%d val=0x%" PRIx64 -xive_tctx_tm_read(uint64_t offset, unsigned int size, uint64_t value) "@0x%"PRIx64" sz=%d val=0x%" PRIx64 +xive_tctx_tm_write(uint32_t index, uint64_t offset, unsigned int size, uint64_t value) "target=%d @0x%"PRIx64" sz=%d val=0x%" PRIx64 +xive_tctx_tm_read(uint32_t index, uint64_t offset, unsigned int size, uint64_t value) "target=%d @0x%"PRIx64" sz=%d val=0x%" PRIx64 xive_presenter_notify(uint8_t nvt_blk, uint32_t nvt_idx, uint8_t ring) "found NVT 0x%x/0x%x ring=0x%x" xive_end_source_read(uint8_t end_blk, uint32_t end_idx, uint64_t addr) "END 0x%x/0x%x @0x%"PRIx64 diff --git a/hw/intc/xive.c b/hw/intc/xive.c index c014e961a4..56670b2cac 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -566,7 +566,7 @@ void xive_tctx_tm_write(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, { const XiveTmOp *xto; - trace_xive_tctx_tm_write(offset, size, value); + trace_xive_tctx_tm_write(tctx->cs->cpu_index, offset, size, value); /* * TODO: check V bit in Q[0-3]W2 @@ -639,7 +639,7 @@ uint64_t xive_tctx_tm_read(XivePresenter *xptr, XiveTCTX *tctx, hwaddr offset, */ ret = xive_tm_raw_read(tctx, offset, size); out: - trace_xive_tctx_tm_read(offset, size, ret); + trace_xive_tctx_tm_read(tctx->cs->cpu_index, offset, size, ret); return ret; } -- cgit v1.2.3 From ed75a123579d56b5523f74868bb2c5877dc2c119 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Wed, 5 Jul 2023 10:14:00 +0200 Subject: pnv/xive2: Always pass a presenter object when accessing the TIMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The low-level functions to access the TIMA take a presenter object as a first argument. When accessing the TIMA from the IC BAR, i.e. indirect calls, we currently pass a NULL pointer for the presenter argument. While it appears ok with the current usage, it's dangerous. And it's pretty easy to figure out the presenter in that context, so this patch fixes it. Signed-off-by: Frederic Barrat Reviewed-by: Cédric Le Goater Message-ID: <20230705081400.218408-1-fbarrat@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- hw/intc/pnv_xive2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index 82fcd3ea22..bbb44a533c 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -1624,6 +1624,7 @@ static uint64_t pnv_xive2_ic_tm_indirect_read(void *opaque, hwaddr offset, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + XivePresenter *xptr = XIVE_PRESENTER(xive); hwaddr hw_page_offset; uint32_t pir; XiveTCTX *tctx; @@ -1633,7 +1634,7 @@ static uint64_t pnv_xive2_ic_tm_indirect_read(void *opaque, hwaddr offset, hw_page_offset = pnv_xive2_ic_tm_get_hw_page_offset(xive, offset); tctx = pnv_xive2_get_indirect_tctx(xive, pir); if (tctx) { - val = xive_tctx_tm_read(NULL, tctx, hw_page_offset, size); + val = xive_tctx_tm_read(xptr, tctx, hw_page_offset, size); } return val; @@ -1643,6 +1644,7 @@ static void pnv_xive2_ic_tm_indirect_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) { PnvXive2 *xive = PNV_XIVE2(opaque); + XivePresenter *xptr = XIVE_PRESENTER(xive); hwaddr hw_page_offset; uint32_t pir; XiveTCTX *tctx; @@ -1651,7 +1653,7 @@ static void pnv_xive2_ic_tm_indirect_write(void *opaque, hwaddr offset, hw_page_offset = pnv_xive2_ic_tm_get_hw_page_offset(xive, offset); tctx = pnv_xive2_get_indirect_tctx(xive, pir); if (tctx) { - xive_tctx_tm_write(NULL, tctx, hw_page_offset, val, size); + xive_tctx_tm_write(xptr, tctx, hw_page_offset, val, size); } } -- cgit v1.2.3 From 3401ea3cfe06ab5ab059ae19b662270e1357545e Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 5 Jul 2023 22:06:28 +1000 Subject: target/ppc: Add LPAR-per-core vs per-thread mode flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Power ISA has the concept of sub-processors: Hardware is allowed to sub-divide a multi-threaded processor into "sub-processors" that appear to privileged programs as multi-threaded processors with fewer threads. POWER9 and POWER10 have two modes, either every thread is a sub-processor or all threads appear as one multi-threaded processor. In the user manuals these are known as "LPAR per thread" / "Thread LPAR", and "LPAR per core" / "1 LPAR", respectively. The practical difference is: in thread LPAR mode, non-hypervisor SPRs are not shared between threads and msgsndp can not be used to message siblings. In 1 LPAR mode, some SPRs are shared and msgsndp is usable. Thrad LPAR allows multiple partitions to run concurrently on the same core, and is a requirement for KVM to run on POWER9/10 (which does not gang-schedule an LPAR on all threads of a core like POWER8 KVM). Traditionally, SMT in PAPR environments including PowerVM and the pseries QEMU machine with KVM acceleration behaves as in 1 LPAR mode. In OPAL systems, Thread LPAR is used. When adding SMT to the powernv machine, it is therefore preferable to emulate Thread LPAR. To account for this difference between pseries and powernv, an LPAR mode flag is added such that SPRs can be implemented as per-LPAR shared, and that becomes either per-thread or per-core depending on the flag. Reviewed-by: Joel Stanley Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Signed-off-by: Nicholas Piggin Message-ID: <20230705120631.27670-2-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr_cpu_core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'hw') diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index a4e3c2fadd..b482d9754a 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -270,6 +270,8 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, env->spr_cb[SPR_PIR].default_value = cs->cpu_index; env->spr_cb[SPR_TIR].default_value = thread_index; + cpu_ppc_set_1lpar(cpu); + /* Set time-base frequency to 512 MHz. vhyp must be set first. */ cpu_ppc_tb_init(env, SPAPR_TIMEBASE_FREQ); -- cgit v1.2.3 From 934676c7b726fe9cccac02a7a4fa23c1e6a4c91e Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 5 Jul 2023 22:06:30 +1000 Subject: ppc/pnv: SMT support for powernv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the TIR default value with the SMT thread index, and place some standard limits on SMT configurations. Now powernv is able to boot skiboot and Linux with a SMT topology, including booting a KVM guest. There are several SPRs and other features (e.g., broadcast msgsnd) that are not implemented, but not used by OPAL or Linux and can be added incrementally. Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Signed-off-by: Nicholas Piggin Message-ID: <20230705120631.27670-4-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv.c | 12 ++++++++++++ hw/ppc/pnv_core.c | 13 +++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 5f25fe985a..23740f9d07 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -887,6 +887,18 @@ static void pnv_init(MachineState *machine) pnv->num_chips = machine->smp.max_cpus / (machine->smp.cores * machine->smp.threads); + + if (machine->smp.threads > 8) { + error_report("Cannot support more than 8 threads/core " + "on a powernv machine"); + exit(1); + } + if (!is_power_of_2(machine->smp.threads)) { + error_report("Cannot support %d threads/core on a powernv" + "machine because it must be a power of 2", + machine->smp.threads); + exit(1); + } /* * TODO: should we decide on how many chips we can create based * on #cores and Venice vs. Murano vs. Naples chip type etc..., diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index b7223bb445..8a72171ce0 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -218,12 +218,13 @@ static const MemoryRegionOps pnv_core_power10_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp) +static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp, + int thread_index) { CPUPPCState *env = &cpu->env; int core_pir; - int thread_index = 0; /* TODO: TCG supports only one thread */ ppc_spr_t *pir = &env->spr_cb[SPR_PIR]; + ppc_spr_t *tir = &env->spr_cb[SPR_TIR]; Error *local_err = NULL; PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip); @@ -239,11 +240,7 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp) core_pir = object_property_get_uint(OBJECT(pc), "pir", &error_abort); - /* - * The PIR of a thread is the core PIR + the thread index. We will - * need to find a way to get the thread index when TCG supports - * more than 1. We could use the object name ? - */ + tir->default_value = thread_index; pir->default_value = core_pir + thread_index; /* Set time-base frequency to 512 MHz */ @@ -292,7 +289,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } for (j = 0; j < cc->nr_threads; j++) { - pnv_core_cpu_realize(pc, pc->threads[j], &local_err); + pnv_core_cpu_realize(pc, pc->threads[j], &local_err, j); if (local_err) { goto err; } -- cgit v1.2.3 From 339d13ce57a33d1536b0bae15ee633af11e6b116 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:45 +0200 Subject: ppc440: Change ppc460ex_pcie_init() parameter type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change parameter of ppc460ex_pcie_init() from env to cpu to allow further refactoring. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <1695d7cc1a9f1070ab498c078916e2389d6e9469.1688586835.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440.h | 2 +- hw/ppc/ppc440_uc.c | 7 ++++--- hw/ppc/sam460ex.c | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h index 7c24db8504..ae42bcf0c8 100644 --- a/hw/ppc/ppc440.h +++ b/hw/ppc/ppc440.h @@ -18,6 +18,6 @@ void ppc4xx_cpr_init(CPUPPCState *env); void ppc4xx_sdr_init(CPUPPCState *env); void ppc4xx_ahb_init(CPUPPCState *env); void ppc4xx_dma_init(CPUPPCState *env, int dcr_base); -void ppc460ex_pcie_init(CPUPPCState *env); +void ppc460ex_pcie_init(PowerPCCPU *cpu); #endif /* PPC440_H */ diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 651263926e..8eb985d714 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -17,6 +17,7 @@ #include "hw/qdev-properties.h" #include "hw/pci/pci.h" #include "sysemu/reset.h" +#include "cpu.h" #include "ppc440.h" /*****************************************************************************/ @@ -1108,17 +1109,17 @@ static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env) &dcr_read_pcie, &dcr_write_pcie); } -void ppc460ex_pcie_init(CPUPPCState *env) +void ppc460ex_pcie_init(PowerPCCPU *cpu) { DeviceState *dev; dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env); + ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), &cpu->env); dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), env); + ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), &cpu->env); } diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index cf065aae0e..aaa8d2f4a5 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -422,7 +422,7 @@ static void sam460ex_init(MachineState *machine) usb_create_simple(usb_bus_find(-1), "usb-mouse"); /* PCI bus */ - ppc460ex_pcie_init(env); + ppc460ex_pcie_init(cpu); /* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec00000, qdev_get_gpio_in(uic[1], 0)); -- cgit v1.2.3 From 256f06668a7764a3bab581cd3b548964e3861189 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:46 +0200 Subject: ppc440: Add cpu link property to PCIe controller model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PCIe controller model uses PPC DCRs but cannot be modeled with TYPE_PPC4xx_DCR_DEVICE as it derives from TYPE_PCIE_HOST_BRIDGE. Add a cpu link property to it similar to other DCR devices to allow registering DCRs from the device model. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_uc.c | 114 +++++++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 52 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 8eb985d714..b26c0cee1b 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -779,6 +779,7 @@ struct PPC460EXPCIEState { MemoryRegion iomem; qemu_irq irq[4]; int32_t dcrn_base; + PowerPCCPU *cpu; uint64_t cfg_base; uint32_t cfg_mask; @@ -1001,6 +1002,58 @@ static void ppc460ex_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(s->irq[irq_num], level); } +static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s) +{ + CPUPPCState *env = &s->cpu->env; + + ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s, + &dcr_read_pcie, &dcr_write_pcie); + ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s, + &dcr_read_pcie, &dcr_write_pcie); +} + static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) { PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev); @@ -1008,6 +1061,10 @@ static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) int i, id; char buf[16]; + if (!s->cpu) { + error_setg(errp, "cpu link property must be set"); + return; + } switch (s->dcrn_base) { case DCRN_PCIE0_BASE: id = 0; @@ -1028,10 +1085,13 @@ static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq, pci_swizzle_map_irq_fn, s, &s->iomem, get_system_io(), 0, 4, TYPE_PCIE_BUS); + ppc460ex_pcie_register_dcrs(s); } static Property ppc460ex_pcie_props[] = { DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1), + DEFINE_PROP_LINK("cpu", PPC460EXPCIEState, cpu, TYPE_POWERPC_CPU, + PowerPCCPU *), DEFINE_PROP_END_OF_LIST(), }; @@ -1059,67 +1119,17 @@ static void ppc460ex_pcie_register(void) type_init(ppc460ex_pcie_register) -static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s, CPUPPCState *env) -{ - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s, - &dcr_read_pcie, &dcr_write_pcie); -} - void ppc460ex_pcie_init(PowerPCCPU *cpu) { DeviceState *dev; dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE); + object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), &cpu->env); dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE); + object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - ppc460ex_pcie_register_dcrs(PPC460EX_PCIE_HOST(dev), &cpu->env); } -- cgit v1.2.3 From ca1ae3432f22c33401a0c8cbf4f7cd4cf13e8e6f Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:47 +0200 Subject: ppc440: Add a macro to shorten PCIe controller DCR registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is shorter and more readable to wrap the complex call to ppc_dcr_register() in a macro than to repeat it several times. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <4dec5ef8115791dc67253afdff9a703eb816a2a8.1688586835.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_uc.c | 76 ++++++++++++++++++++---------------------------------- 1 file changed, 28 insertions(+), 48 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index b26c0cee1b..b36dc409d7 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -1002,56 +1002,36 @@ static void ppc460ex_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(s->irq[irq_num], level); } +#define PPC440_PCIE_DCR(s, dcrn) \ + ppc_dcr_register(&(s)->cpu->env, (s)->dcrn_base + (dcrn), (s), \ + &dcr_read_pcie, &dcr_write_pcie) + + static void ppc460ex_pcie_register_dcrs(PPC460EXPCIEState *s) { - CPUPPCState *env = &s->cpu->env; - - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGBAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFGMSK, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGBAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_MSGMSK, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1BAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR1MSKL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2BAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR2MSKL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3BAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_OMR3MSKL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAH, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_REGBAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_REGMSK, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_SPECIAL, s, - &dcr_read_pcie, &dcr_write_pcie); - ppc_dcr_register(env, s->dcrn_base + PEGPL_CFG, s, - &dcr_read_pcie, &dcr_write_pcie); + PPC440_PCIE_DCR(s, PEGPL_CFGBAH); + PPC440_PCIE_DCR(s, PEGPL_CFGBAL); + PPC440_PCIE_DCR(s, PEGPL_CFGMSK); + PPC440_PCIE_DCR(s, PEGPL_MSGBAH); + PPC440_PCIE_DCR(s, PEGPL_MSGBAL); + PPC440_PCIE_DCR(s, PEGPL_MSGMSK); + PPC440_PCIE_DCR(s, PEGPL_OMR1BAH); + PPC440_PCIE_DCR(s, PEGPL_OMR1BAL); + PPC440_PCIE_DCR(s, PEGPL_OMR1MSKH); + PPC440_PCIE_DCR(s, PEGPL_OMR1MSKL); + PPC440_PCIE_DCR(s, PEGPL_OMR2BAH); + PPC440_PCIE_DCR(s, PEGPL_OMR2BAL); + PPC440_PCIE_DCR(s, PEGPL_OMR2MSKH); + PPC440_PCIE_DCR(s, PEGPL_OMR2MSKL); + PPC440_PCIE_DCR(s, PEGPL_OMR3BAH); + PPC440_PCIE_DCR(s, PEGPL_OMR3BAL); + PPC440_PCIE_DCR(s, PEGPL_OMR3MSKH); + PPC440_PCIE_DCR(s, PEGPL_OMR3MSKL); + PPC440_PCIE_DCR(s, PEGPL_REGBAH); + PPC440_PCIE_DCR(s, PEGPL_REGBAL); + PPC440_PCIE_DCR(s, PEGPL_REGMSK); + PPC440_PCIE_DCR(s, PEGPL_SPECIAL); + PPC440_PCIE_DCR(s, PEGPL_CFG); } static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) -- cgit v1.2.3 From 48bb07fbb1d9223448a4c11c6b711db0cf1fdc57 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:48 +0200 Subject: ppc440: Rename parent field of PPC460EXPCIEState to match code style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QOM prefers to call the parent field parent_obj, change PPC460EXPCIEState ro match that convention. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <6995f28215d2a489a661b7d91a1783048829d467.1688586835.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_uc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index b36dc409d7..22c74839ae 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -774,7 +774,7 @@ void ppc4xx_dma_init(CPUPPCState *env, int dcr_base) OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST) struct PPC460EXPCIEState { - PCIExpressHost host; + PCIExpressHost parent_obj; MemoryRegion iomem; qemu_irq irq[4]; -- cgit v1.2.3 From b5d2ad84a14c1305efd9739d98a6adec0bf42e4d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:49 +0200 Subject: ppc440: Rename local variable in dcr_read_pcie() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename local variable storing state struct in dcr_read_pcie() for brevity and consistency with other functions. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <7b6f0033ada74075fc094b1397deb406e1a05741.1688586835.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_uc.c | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 22c74839ae..5724db2702 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -828,78 +828,78 @@ enum { static uint32_t dcr_read_pcie(void *opaque, int dcrn) { - PPC460EXPCIEState *state = opaque; + PPC460EXPCIEState *s = opaque; uint32_t ret = 0; - switch (dcrn - state->dcrn_base) { + switch (dcrn - s->dcrn_base) { case PEGPL_CFGBAH: - ret = state->cfg_base >> 32; + ret = s->cfg_base >> 32; break; case PEGPL_CFGBAL: - ret = state->cfg_base; + ret = s->cfg_base; break; case PEGPL_CFGMSK: - ret = state->cfg_mask; + ret = s->cfg_mask; break; case PEGPL_MSGBAH: - ret = state->msg_base >> 32; + ret = s->msg_base >> 32; break; case PEGPL_MSGBAL: - ret = state->msg_base; + ret = s->msg_base; break; case PEGPL_MSGMSK: - ret = state->msg_mask; + ret = s->msg_mask; break; case PEGPL_OMR1BAH: - ret = state->omr1_base >> 32; + ret = s->omr1_base >> 32; break; case PEGPL_OMR1BAL: - ret = state->omr1_base; + ret = s->omr1_base; break; case PEGPL_OMR1MSKH: - ret = state->omr1_mask >> 32; + ret = s->omr1_mask >> 32; break; case PEGPL_OMR1MSKL: - ret = state->omr1_mask; + ret = s->omr1_mask; break; case PEGPL_OMR2BAH: - ret = state->omr2_base >> 32; + ret = s->omr2_base >> 32; break; case PEGPL_OMR2BAL: - ret = state->omr2_base; + ret = s->omr2_base; break; case PEGPL_OMR2MSKH: - ret = state->omr2_mask >> 32; + ret = s->omr2_mask >> 32; break; case PEGPL_OMR2MSKL: - ret = state->omr3_mask; + ret = s->omr3_mask; break; case PEGPL_OMR3BAH: - ret = state->omr3_base >> 32; + ret = s->omr3_base >> 32; break; case PEGPL_OMR3BAL: - ret = state->omr3_base; + ret = s->omr3_base; break; case PEGPL_OMR3MSKH: - ret = state->omr3_mask >> 32; + ret = s->omr3_mask >> 32; break; case PEGPL_OMR3MSKL: - ret = state->omr3_mask; + ret = s->omr3_mask; break; case PEGPL_REGBAH: - ret = state->reg_base >> 32; + ret = s->reg_base >> 32; break; case PEGPL_REGBAL: - ret = state->reg_base; + ret = s->reg_base; break; case PEGPL_REGMSK: - ret = state->reg_mask; + ret = s->reg_mask; break; case PEGPL_SPECIAL: - ret = state->special; + ret = s->special; break; case PEGPL_CFG: - ret = state->cfg; + ret = s->cfg; break; } -- cgit v1.2.3 From 088b61bc49fab767d73d79d49cb828d866346e6d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:51 +0200 Subject: ppc440: Stop using system io region for PCIe buses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add separate memory regions for the mem and io spaces of the PCIe bus to avoid different buses using the same system io region. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_uc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 5724db2702..663abf3449 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -776,6 +776,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST) struct PPC460EXPCIEState { PCIExpressHost parent_obj; + MemoryRegion busmem; MemoryRegion iomem; qemu_irq irq[4]; int32_t dcrn_base; @@ -1056,15 +1057,17 @@ static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) error_setg(errp, "invalid PCIe DCRN base"); return; } + snprintf(buf, sizeof(buf), "pcie%d-mem", id); + memory_region_init(&s->busmem, OBJECT(s), buf, UINT64_MAX); snprintf(buf, sizeof(buf), "pcie%d-io", id); - memory_region_init(&s->iomem, OBJECT(s), buf, UINT64_MAX); + memory_region_init(&s->iomem, OBJECT(s), buf, 64 * KiB); for (i = 0; i < 4; i++) { sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]); } snprintf(buf, sizeof(buf), "pcie.%d", id); pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq, - pci_swizzle_map_irq_fn, s, &s->iomem, - get_system_io(), 0, 4, TYPE_PCIE_BUS); + pci_swizzle_map_irq_fn, s, &s->busmem, + &s->iomem, 0, 4, TYPE_PCIE_BUS); ppc460ex_pcie_register_dcrs(s); } -- cgit v1.2.3 From 6ef62c5945316c265189e301b5fadf9285850221 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:53 +0200 Subject: ppc440: Add busnum property to PCIe controller model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of guessing controller number from dcrn_base add a property so the device does not need knowledge about where it is used. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_uc.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 663abf3449..b74b2212fa 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -779,6 +779,7 @@ struct PPC460EXPCIEState { MemoryRegion busmem; MemoryRegion iomem; qemu_irq irq[4]; + int32_t num; int32_t dcrn_base; PowerPCCPU *cpu; @@ -1039,32 +1040,25 @@ static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) { PPC460EXPCIEState *s = PPC460EX_PCIE_HOST(dev); PCIHostState *pci = PCI_HOST_BRIDGE(dev); - int i, id; - char buf[16]; + int i; + char buf[20]; if (!s->cpu) { error_setg(errp, "cpu link property must be set"); return; } - switch (s->dcrn_base) { - case DCRN_PCIE0_BASE: - id = 0; - break; - case DCRN_PCIE1_BASE: - id = 1; - break; - default: - error_setg(errp, "invalid PCIe DCRN base"); + if (s->num < 0 || s->dcrn_base < 0) { + error_setg(errp, "busnum and dcrn-base properties must be set"); return; } - snprintf(buf, sizeof(buf), "pcie%d-mem", id); + snprintf(buf, sizeof(buf), "pcie%d-mem", s->num); memory_region_init(&s->busmem, OBJECT(s), buf, UINT64_MAX); - snprintf(buf, sizeof(buf), "pcie%d-io", id); + snprintf(buf, sizeof(buf), "pcie%d-io", s->num); memory_region_init(&s->iomem, OBJECT(s), buf, 64 * KiB); for (i = 0; i < 4; i++) { sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]); } - snprintf(buf, sizeof(buf), "pcie.%d", id); + snprintf(buf, sizeof(buf), "pcie.%d", s->num); pci->bus = pci_register_root_bus(DEVICE(s), buf, ppc460ex_set_irq, pci_swizzle_map_irq_fn, s, &s->busmem, &s->iomem, 0, 4, TYPE_PCIE_BUS); @@ -1072,6 +1066,7 @@ static void ppc460ex_pcie_realize(DeviceState *dev, Error **errp) } static Property ppc460ex_pcie_props[] = { + DEFINE_PROP_INT32("busnum", PPC460EXPCIEState, num, -1), DEFINE_PROP_INT32("dcrn-base", PPC460EXPCIEState, dcrn_base, -1), DEFINE_PROP_LINK("cpu", PPC460EXPCIEState, cpu, TYPE_POWERPC_CPU, PowerPCCPU *), @@ -1107,11 +1102,13 @@ void ppc460ex_pcie_init(PowerPCCPU *cpu) DeviceState *dev; dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); + qdev_prop_set_int32(dev, "busnum", 0); qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE); object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); + qdev_prop_set_int32(dev, "busnum", 1); qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE); object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -- cgit v1.2.3 From 340dc03c798d07fda7fd7f608dc224caa2909849 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:54 +0200 Subject: ppc440: Remove ppc460ex_pcie_init legacy init function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After previous changes we can now remove the legacy init function and move the device creation to board code. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <29aafeea9f1c871c739600a7b093c5456e8a1dc8.1688586835.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440.h | 1 - hw/ppc/ppc440_uc.c | 21 --------------------- hw/ppc/sam460ex.c | 17 ++++++++++++++++- 3 files changed, 16 insertions(+), 23 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440.h b/hw/ppc/ppc440.h index ae42bcf0c8..909373fb38 100644 --- a/hw/ppc/ppc440.h +++ b/hw/ppc/ppc440.h @@ -18,6 +18,5 @@ void ppc4xx_cpr_init(CPUPPCState *env); void ppc4xx_sdr_init(CPUPPCState *env); void ppc4xx_ahb_init(CPUPPCState *env); void ppc4xx_dma_init(CPUPPCState *env, int dcr_base); -void ppc460ex_pcie_init(PowerPCCPU *cpu); #endif /* PPC440_H */ diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index b74b2212fa..4181c843a8 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -770,7 +770,6 @@ void ppc4xx_dma_init(CPUPPCState *env, int dcr_base) */ #include "hw/pci/pcie_host.h" -#define TYPE_PPC460EX_PCIE_HOST "ppc460ex-pcie-host" OBJECT_DECLARE_SIMPLE_TYPE(PPC460EXPCIEState, PPC460EX_PCIE_HOST) struct PPC460EXPCIEState { @@ -799,9 +798,6 @@ struct PPC460EXPCIEState { uint32_t cfg; }; -#define DCRN_PCIE0_BASE 0x100 -#define DCRN_PCIE1_BASE 0x120 - enum { PEGPL_CFGBAH = 0x0, PEGPL_CFGBAL, @@ -1096,20 +1092,3 @@ static void ppc460ex_pcie_register(void) } type_init(ppc460ex_pcie_register) - -void ppc460ex_pcie_init(PowerPCCPU *cpu) -{ - DeviceState *dev; - - dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); - qdev_prop_set_int32(dev, "busnum", 0); - qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE0_BASE); - object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - - dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); - qdev_prop_set_int32(dev, "busnum", 1); - qdev_prop_set_int32(dev, "dcrn-base", DCRN_PCIE1_BASE); - object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); -} diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index aaa8d2f4a5..1bb23bb18b 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -45,6 +45,9 @@ /* dd bs=1 skip=$(($(stat -c '%s' updater/updater-460) - 0x80000)) \ if=updater/updater-460 of=u-boot-sam460-20100605.bin */ +#define PCIE0_DCRN_BASE 0x100 +#define PCIE1_DCRN_BASE 0x120 + /* from Sam460 U-Boot include/configs/Sam460ex.h */ #define FLASH_BASE 0xfff00000 #define FLASH_BASE_H 0x4 @@ -421,8 +424,20 @@ static void sam460ex_init(MachineState *machine) usb_create_simple(usb_bus_find(-1), "usb-kbd"); usb_create_simple(usb_bus_find(-1), "usb-mouse"); + /* PCIe buses */ + dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); + qdev_prop_set_int32(dev, "busnum", 0); + qdev_prop_set_int32(dev, "dcrn-base", PCIE0_DCRN_BASE); + object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + + dev = qdev_new(TYPE_PPC460EX_PCIE_HOST); + qdev_prop_set_int32(dev, "busnum", 1); + qdev_prop_set_int32(dev, "dcrn-base", PCIE1_DCRN_BASE); + object_property_set_link(OBJECT(dev), "cpu", OBJECT(cpu), &error_abort); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + /* PCI bus */ - ppc460ex_pcie_init(cpu); /* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec00000, qdev_get_gpio_in(uic[1], 0)); -- cgit v1.2.3 From 41cd3e649be9f8f12aa2028623af916dd81d3403 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:52 +0200 Subject: ppc/sam460ex: Remove address_space_mem local variable Some places already use get_system_memory() directly so replace the remaining uses and drop the local variable. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/sam460ex.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 1bb23bb18b..d446cfc37b 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -269,7 +269,6 @@ static void main_cpu_reset(void *opaque) static void sam460ex_init(MachineState *machine) { - MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1); DeviceState *uic[4]; @@ -409,7 +408,8 @@ static void sam460ex_init(MachineState *machine) /* FIXME: remove this after fixing l2sram mapping in ppc440_uc.c? */ memory_region_init_ram(l2cache_ram, NULL, "ppc440.l2cache_ram", 256 * KiB, &error_abort); - memory_region_add_subregion(address_space_mem, 0x400000000LL, l2cache_ram); + memory_region_add_subregion(get_system_memory(), 0x400000000LL, + l2cache_ram); /* USB */ sysbus_create_simple(TYPE_PPC4xx_EHCI, 0x4bffd0400, @@ -459,13 +459,13 @@ static void sam460ex_init(MachineState *machine) /* SoC has 4 UARTs * but board has only one wired and two are present in fdt */ if (serial_hd(0) != NULL) { - serial_mm_init(address_space_mem, 0x4ef600300, 0, + serial_mm_init(get_system_memory(), 0x4ef600300, 0, qdev_get_gpio_in(uic[1], 1), PPC_SERIAL_MM_BAUDBASE, serial_hd(0), DEVICE_BIG_ENDIAN); } if (serial_hd(1) != NULL) { - serial_mm_init(address_space_mem, 0x4ef600400, 0, + serial_mm_init(get_system_memory(), 0x4ef600400, 0, qdev_get_gpio_in(uic[0], 1), PPC_SERIAL_MM_BAUDBASE, serial_hd(1), DEVICE_BIG_ENDIAN); -- cgit v1.2.3 From 97784278880b58952400cafcfd1c12fc1c0b5124 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Wed, 5 Jul 2023 22:12:58 +0200 Subject: ppc440_pcix: Don't use iomem for regs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The iomem memory region is better used for the PCI IO space but currently used for registers. Stop using it for that to allow this to be cleaned up in the next patch. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: <3def68f200edd4540393d6b3b03baabe15d649f2.1688586835.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_pcix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index f10f93c533..899558b055 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -64,6 +64,7 @@ struct PPC440PCIXState { MemoryRegion container; MemoryRegion iomem; MemoryRegion busmem; + MemoryRegion regs; }; #define PPC440_REG_BASE 0x80000 @@ -507,11 +508,11 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) h, "pci-conf-idx", 4); memory_region_init_io(&h->data_mem, OBJECT(s), &pci_host_data_le_ops, h, "pci-conf-data", 4); - memory_region_init_io(&s->iomem, OBJECT(s), &pci_reg_ops, s, - "pci.reg", PPC440_REG_SIZE); + memory_region_init_io(&s->regs, OBJECT(s), &pci_reg_ops, s, "pci-reg", + PPC440_REG_SIZE); memory_region_add_subregion(&s->container, PCIC0_CFGADDR, &h->conf_mem); memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem); - memory_region_add_subregion(&s->container, PPC440_REG_BASE, &s->iomem); + memory_region_add_subregion(&s->container, PPC440_REG_BASE, &s->regs); sysbus_init_mmio(sbd, &s->container); } -- cgit v1.2.3 From dd0f356dfe363d51b0cc0e1925db902b97338e18 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 6 Jul 2023 13:16:42 +0200 Subject: ppc440_pcix: Stop using system io region for PCI bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the iomem region to 64K and use it for the PCI io space and map it directly from the board without an intermediate alias that is not really needed. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_pcix.c | 9 ++++++--- hw/ppc/sam460ex.c | 6 +----- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index 899558b055..54286cfef4 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -23,6 +23,7 @@ #include "qemu/error-report.h" #include "qemu/log.h" #include "qemu/module.h" +#include "qemu/units.h" #include "hw/irq.h" #include "hw/ppc/ppc.h" #include "hw/ppc/ppc4xx.h" @@ -491,10 +492,11 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) s = PPC440_PCIX_HOST_BRIDGE(dev); sysbus_init_irq(sbd, &s->irq); - memory_region_init(&s->busmem, OBJECT(dev), "pci bus memory", UINT64_MAX); + memory_region_init(&s->busmem, OBJECT(dev), "pci-mem", UINT64_MAX); + memory_region_init(&s->iomem, OBJECT(dev), "pci-io", 64 * KiB); h->bus = pci_register_root_bus(dev, NULL, ppc440_pcix_set_irq, - ppc440_pcix_map_irq, &s->irq, &s->busmem, - get_system_io(), PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS); + ppc440_pcix_map_irq, &s->irq, &s->busmem, &s->iomem, + PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS); s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge"); @@ -514,6 +516,7 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->container, PCIC0_CFGDATA, &h->data_mem); memory_region_add_subregion(&s->container, PPC440_REG_BASE, &s->regs); sysbus_init_mmio(sbd, &s->container); + sysbus_init_mmio(sbd, &s->iomem); } static void ppc440_pcix_class_init(ObjectClass *klass, void *data) diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index d446cfc37b..7da38bd58e 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -269,7 +269,6 @@ static void main_cpu_reset(void *opaque) static void sam460ex_init(MachineState *machine) { - MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *l2cache_ram = g_new(MemoryRegion, 1); DeviceState *uic[4]; int i; @@ -441,12 +440,9 @@ static void sam460ex_init(MachineState *machine) /* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec00000, qdev_get_gpio_in(uic[1], 0)); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, 0xc08000000); pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); - memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), - 0, 0x10000); - memory_region_add_subregion(get_system_memory(), 0xc08000000, isa); - /* PCI devices */ pci_create_simple(pci_bus, PCI_DEVFN(6, 0), "sm501"); /* SoC has a single SATA port but we don't emulate that yet -- cgit v1.2.3 From e75a951b89382c77cc2bf63db5996cafa54adc3d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 6 Jul 2023 13:16:43 +0200 Subject: ppc4xx_pci: Rename QOM type name define Rename the TYPE_PPC4xx_PCI_HOST_BRIDGE define and its string value to match each other and other similar types and to avoid confusion with "ppc4xx-host-bridge" type defined in same file. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_bamboo.c | 3 +-- hw/ppc/ppc4xx_pci.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index f061b8cf3b..45f409c838 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -205,8 +205,7 @@ static void bamboo_init(MachineState *machine) ppc4xx_sdram_ddr_enable(PPC4xx_SDRAM_DDR(dev)); /* PCI */ - dev = sysbus_create_varargs(TYPE_PPC4xx_PCI_HOST_BRIDGE, - PPC440EP_PCI_CONFIG, + dev = sysbus_create_varargs(TYPE_PPC4xx_PCI_HOST, PPC440EP_PCI_CONFIG, qdev_get_gpio_in(uicdev, pci_irq_nrs[0]), qdev_get_gpio_in(uicdev, pci_irq_nrs[1]), qdev_get_gpio_in(uicdev, pci_irq_nrs[2]), diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c index 1d4a50fa7c..fbdf8266d8 100644 --- a/hw/ppc/ppc4xx_pci.c +++ b/hw/ppc/ppc4xx_pci.c @@ -46,7 +46,7 @@ struct PCITargetMap { uint32_t la; }; -OBJECT_DECLARE_SIMPLE_TYPE(PPC4xxPCIState, PPC4xx_PCI_HOST_BRIDGE) +OBJECT_DECLARE_SIMPLE_TYPE(PPC4xxPCIState, PPC4xx_PCI_HOST) #define PPC4xx_PCI_NR_PMMS 3 #define PPC4xx_PCI_NR_PTMS 2 @@ -321,7 +321,7 @@ static void ppc4xx_pcihost_realize(DeviceState *dev, Error **errp) int i; h = PCI_HOST_BRIDGE(dev); - s = PPC4xx_PCI_HOST_BRIDGE(dev); + s = PPC4xx_PCI_HOST(dev); for (i = 0; i < ARRAY_SIZE(s->irq); i++) { sysbus_init_irq(sbd, &s->irq[i]); @@ -386,7 +386,7 @@ static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data) } static const TypeInfo ppc4xx_pcihost_info = { - .name = TYPE_PPC4xx_PCI_HOST_BRIDGE, + .name = TYPE_PPC4xx_PCI_HOST, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(PPC4xxPCIState), .class_init = ppc4xx_pcihost_class_init, -- cgit v1.2.3 From 2460bdff8ed704e1e922d327d15b535594893144 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 6 Jul 2023 13:16:44 +0200 Subject: ppc4xx_pci: Add define for ppc4xx-host-bridge type name Add a QOM type name define for ppc4xx-host-bridge in the common header and replace direct use of the string name with the constant. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-ID: Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_pcix.c | 3 ++- hw/ppc/ppc4xx_pci.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index 54286cfef4..9321ca0abd 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -498,7 +498,8 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) ppc440_pcix_map_irq, &s->irq, &s->busmem, &s->iomem, PCI_DEVFN(0, 0), 1, TYPE_PCI_BUS); - s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), "ppc4xx-host-bridge"); + s->dev = pci_create_simple(h->bus, PCI_DEVFN(0, 0), + TYPE_PPC4xx_HOST_BRIDGE); memory_region_init(&s->bm, OBJECT(s), "bm-ppc440-pcix", UINT64_MAX); memory_region_add_subregion(&s->bm, 0x0, &s->busmem); diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c index fbdf8266d8..6652119008 100644 --- a/hw/ppc/ppc4xx_pci.c +++ b/hw/ppc/ppc4xx_pci.c @@ -333,7 +333,7 @@ static void ppc4xx_pcihost_realize(DeviceState *dev, Error **errp) TYPE_PCI_BUS); h->bus = b; - pci_create_simple(b, 0, "ppc4xx-host-bridge"); + pci_create_simple(b, 0, TYPE_PPC4xx_HOST_BRIDGE); /* XXX split into 2 memory regions, one for config space, one for regs */ memory_region_init(&s->container, OBJECT(s), "pci-container", PCI_ALL_SIZE); @@ -367,7 +367,7 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data) } static const TypeInfo ppc4xx_host_bridge_info = { - .name = "ppc4xx-host-bridge", + .name = TYPE_PPC4xx_HOST_BRIDGE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = ppc4xx_host_bridge_class_init, -- cgit v1.2.3 From 5efa7545205e8e9617afd8dc3cf0180943f975b7 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 6 Jul 2023 13:16:45 +0200 Subject: ppc440_pcix: Rename QOM type define abd move it to common header Rename TYPE_PPC440_PCIX_HOST_BRIDGE to better match its string value, move it to common header and use it also in sam460ex to replace hard coded type name. Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza Message-ID: <1a1c3fe4b120f345d1005ad7ceca4500783691f7.1688641673.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc440_pcix.c | 9 ++++----- hw/ppc/sam460ex.c | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/ppc/ppc440_pcix.c b/hw/ppc/ppc440_pcix.c index 9321ca0abd..672090de94 100644 --- a/hw/ppc/ppc440_pcix.c +++ b/hw/ppc/ppc440_pcix.c @@ -45,8 +45,7 @@ struct PLBInMap { MemoryRegion mr; }; -#define TYPE_PPC440_PCIX_HOST_BRIDGE "ppc440-pcix-host" -OBJECT_DECLARE_SIMPLE_TYPE(PPC440PCIXState, PPC440_PCIX_HOST_BRIDGE) +OBJECT_DECLARE_SIMPLE_TYPE(PPC440PCIXState, PPC440_PCIX_HOST) #define PPC440_PCIX_NR_POMS 3 #define PPC440_PCIX_NR_PIMS 3 @@ -399,7 +398,7 @@ static const MemoryRegionOps pci_reg_ops = { static void ppc440_pcix_reset(DeviceState *dev) { - struct PPC440PCIXState *s = PPC440_PCIX_HOST_BRIDGE(dev); + struct PPC440PCIXState *s = PPC440_PCIX_HOST(dev); int i; for (i = 0; i < PPC440_PCIX_NR_POMS; i++) { @@ -489,7 +488,7 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) PCIHostState *h; h = PCI_HOST_BRIDGE(dev); - s = PPC440_PCIX_HOST_BRIDGE(dev); + s = PPC440_PCIX_HOST(dev); sysbus_init_irq(sbd, &s->irq); memory_region_init(&s->busmem, OBJECT(dev), "pci-mem", UINT64_MAX); @@ -529,7 +528,7 @@ static void ppc440_pcix_class_init(ObjectClass *klass, void *data) } static const TypeInfo ppc440_pcix_info = { - .name = TYPE_PPC440_PCIX_HOST_BRIDGE, + .name = TYPE_PPC440_PCIX_HOST, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(PPC440PCIXState), .class_init = ppc440_pcix_class_init, diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 7da38bd58e..1e615b8d35 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -438,7 +438,7 @@ static void sam460ex_init(MachineState *machine) /* PCI bus */ /* All PCI irqs are connected to the same UIC pin (cf. UBoot source) */ - dev = sysbus_create_simple("ppc440-pcix-host", 0xc0ec00000, + dev = sysbus_create_simple(TYPE_PPC440_PCIX_HOST, 0xc0ec00000, qdev_get_gpio_in(uic[1], 0)); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, 0xc08000000); pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci.0")); -- cgit v1.2.3 From b0afb574bad3c3a27acd2c3e7a17306a3648b0ac Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 6 Jul 2023 12:15:28 +0930 Subject: ppc/pnv: Log all unimp warnings with similar message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the function name so there's an indication as to where the message is coming from. Change all prints to use the offset instead of the address. Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-ID: <20230706024528.40065-1-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_core.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 8a72171ce0..a59f3f303d 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -85,8 +85,8 @@ static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr, val = 0x24f000000000000ull; break; default: - qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", - addr); + qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__, + offset); } return val; @@ -95,8 +95,10 @@ static uint64_t pnv_core_power8_xscom_read(void *opaque, hwaddr addr, static void pnv_core_power8_xscom_write(void *opaque, hwaddr addr, uint64_t val, unsigned int width) { - qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n", - addr); + uint32_t offset = addr >> 3; + + qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__, + offset); } static const MemoryRegionOps pnv_core_power8_xscom_ops = { @@ -140,8 +142,8 @@ static uint64_t pnv_core_power9_xscom_read(void *opaque, hwaddr addr, val = 0; break; default: - qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", - addr); + qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__, + offset); } return val; @@ -157,8 +159,8 @@ static void pnv_core_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val, case PNV9_XSCOM_EC_PPM_SPECIAL_WKUP_OTR: break; default: - qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n", - addr); + qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__, + offset); } } @@ -189,8 +191,8 @@ static uint64_t pnv_core_power10_xscom_read(void *opaque, hwaddr addr, val = 0; break; default: - qemu_log_mask(LOG_UNIMP, "Warning: reading reg=0x%" HWADDR_PRIx "\n", - addr); + qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__, + offset); } return val; @@ -203,8 +205,8 @@ static void pnv_core_power10_xscom_write(void *opaque, hwaddr addr, switch (offset) { default: - qemu_log_mask(LOG_UNIMP, "Warning: writing to reg=0x%" HWADDR_PRIx "\n", - addr); + qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__, + offset); } } @@ -419,7 +421,7 @@ static uint64_t pnv_quad_power9_xscom_read(void *opaque, hwaddr addr, val = 0; break; default: - qemu_log_mask(LOG_UNIMP, "%s: reading @0x%08x\n", __func__, + qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__, offset); } @@ -436,7 +438,7 @@ static void pnv_quad_power9_xscom_write(void *opaque, hwaddr addr, uint64_t val, case P9X_EX_NCU_SPEC_BAR + 0x400: /* Second EX */ break; default: - qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__, + qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__, offset); } } @@ -463,7 +465,7 @@ static uint64_t pnv_quad_power10_xscom_read(void *opaque, hwaddr addr, switch (offset) { default: - qemu_log_mask(LOG_UNIMP, "%s: reading @0x%08x\n", __func__, + qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__, offset); } @@ -477,7 +479,7 @@ static void pnv_quad_power10_xscom_write(void *opaque, hwaddr addr, switch (offset) { default: - qemu_log_mask(LOG_UNIMP, "%s: writing @0x%08x\n", __func__, + qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__, offset); } } -- cgit v1.2.3 From aa2addf96f2629101ef0aa0c9226d38867c72d76 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Thu, 6 Jul 2023 15:39:22 +1000 Subject: ppc/pnv: Set P10 core xscom region size to match hardware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The P10 core xscom memory regions overlap because the size is wrong. The P10 core+L2 xscom region size is allocated as 0x1000 (with some unused ranges). "EC" is used as a closer match, as "EX" includes L3 which has a disjoint xscom range that would require a different region if it were implemented. Signed-off-by: Nicholas Piggin Reviewed-by: Cédric Le Goater Tested-by: Cédric Le Goater Message-ID: <20230706053923.115003-2-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index a59f3f303d..9e7cf341dc 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -298,9 +298,8 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id); - /* TODO: check PNV_XSCOM_EX_SIZE for p10 */ pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops, - pc, name, PNV_XSCOM_EX_SIZE); + pc, name, pcc->xscom_size); qemu_register_reset(pnv_core_reset, pc); return; @@ -352,6 +351,7 @@ static void pnv_core_power8_class_init(ObjectClass *oc, void *data) PnvCoreClass *pcc = PNV_CORE_CLASS(oc); pcc->xscom_ops = &pnv_core_power8_xscom_ops; + pcc->xscom_size = PNV_XSCOM_EX_SIZE; } static void pnv_core_power9_class_init(ObjectClass *oc, void *data) @@ -359,6 +359,7 @@ static void pnv_core_power9_class_init(ObjectClass *oc, void *data) PnvCoreClass *pcc = PNV_CORE_CLASS(oc); pcc->xscom_ops = &pnv_core_power9_xscom_ops; + pcc->xscom_size = PNV_XSCOM_EX_SIZE; } static void pnv_core_power10_class_init(ObjectClass *oc, void *data) @@ -366,6 +367,7 @@ static void pnv_core_power10_class_init(ObjectClass *oc, void *data) PnvCoreClass *pcc = PNV_CORE_CLASS(oc); pcc->xscom_ops = &pnv_core_power10_xscom_ops; + pcc->xscom_size = PNV10_XSCOM_EC_SIZE; } static void pnv_core_class_init(ObjectClass *oc, void *data) -- cgit v1.2.3 From bdb97596f663e9af9741353417c651f0d581de29 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Fri, 7 Jul 2023 16:42:13 +0930 Subject: ppc/pnv: Add QME region for P10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Quad Management Engine (QME) manages power related settings for its quad. The xscom region is separate from the quad xscoms, therefore a new region is added. The xscoms in a QME select a given core by selecting the forth nibble. Implement dummy reads for the stop state history (SSH) and special wakeup (SPWU) registers. This quietens some sxcom errors when skiboot boots on p10. Power9 does not have a QME. Signed-off-by: Joel Stanley Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley Message-ID: <20230707071213.9924-1-joel@jms.id.au> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/pnv.c | 3 +++ hw/ppc/pnv_core.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 23740f9d07..eb54f93986 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1685,6 +1685,9 @@ static void pnv_chip_power10_quad_realize(Pnv10Chip *chip10, Error **errp) pnv_xscom_add_subregion(chip, PNV10_XSCOM_EQ_BASE(eq->quad_id), &eq->xscom_regs); + + pnv_xscom_add_subregion(chip, PNV10_XSCOM_QME_BASE(eq->quad_id), + &eq->xscom_qme_regs); } } diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 9e7cf341dc..9b39d527de 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -496,7 +496,67 @@ static const MemoryRegionOps pnv_quad_power10_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_quad_realize(DeviceState *dev, Error **errp) +#define P10_QME_SPWU_HYP 0x83c +#define P10_QME_SSH_HYP 0x82c + +static uint64_t pnv_qme_power10_xscom_read(void *opaque, hwaddr addr, + unsigned int width) +{ + uint32_t offset = addr >> 3; + uint64_t val = -1; + + /* + * Forth nibble selects the core within a quad, mask it to process read + * for any core. + */ + switch (offset & ~0xf000) { + case P10_QME_SPWU_HYP: + case P10_QME_SSH_HYP: + return 0; + default: + qemu_log_mask(LOG_UNIMP, "%s: unimp read 0x%08x\n", __func__, + offset); + } + + return val; +} + +static void pnv_qme_power10_xscom_write(void *opaque, hwaddr addr, + uint64_t val, unsigned int width) +{ + uint32_t offset = addr >> 3; + + switch (offset) { + default: + qemu_log_mask(LOG_UNIMP, "%s: unimp write 0x%08x\n", __func__, + offset); + } +} + +static const MemoryRegionOps pnv_qme_power10_xscom_ops = { + .read = pnv_qme_power10_xscom_read, + .write = pnv_qme_power10_xscom_write, + .valid.min_access_size = 8, + .valid.max_access_size = 8, + .impl.min_access_size = 8, + .impl.max_access_size = 8, + .endianness = DEVICE_BIG_ENDIAN, +}; + +static void pnv_quad_power9_realize(DeviceState *dev, Error **errp) +{ + PnvQuad *eq = PNV_QUAD(dev); + PnvQuadClass *pqc = PNV_QUAD_GET_CLASS(eq); + char name[32]; + + snprintf(name, sizeof(name), "xscom-quad.%d", eq->quad_id); + pnv_xscom_region_init(&eq->xscom_regs, OBJECT(dev), + pqc->xscom_ops, + eq, name, + pqc->xscom_size); +} + +static void pnv_quad_power10_realize(DeviceState *dev, Error **errp) { PnvQuad *eq = PNV_QUAD(dev); PnvQuadClass *pqc = PNV_QUAD_GET_CLASS(eq); @@ -507,6 +567,12 @@ static void pnv_quad_realize(DeviceState *dev, Error **errp) pqc->xscom_ops, eq, name, pqc->xscom_size); + + snprintf(name, sizeof(name), "xscom-qme.%d", eq->quad_id); + pnv_xscom_region_init(&eq->xscom_qme_regs, OBJECT(dev), + pqc->xscom_qme_ops, + eq, name, + pqc->xscom_qme_size); } static Property pnv_quad_properties[] = { @@ -517,6 +583,9 @@ static Property pnv_quad_properties[] = { static void pnv_quad_power9_class_init(ObjectClass *oc, void *data) { PnvQuadClass *pqc = PNV_QUAD_CLASS(oc); + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = pnv_quad_power9_realize; pqc->xscom_ops = &pnv_quad_power9_xscom_ops; pqc->xscom_size = PNV9_XSCOM_EQ_SIZE; @@ -525,16 +594,21 @@ static void pnv_quad_power9_class_init(ObjectClass *oc, void *data) static void pnv_quad_power10_class_init(ObjectClass *oc, void *data) { PnvQuadClass *pqc = PNV_QUAD_CLASS(oc); + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = pnv_quad_power10_realize; pqc->xscom_ops = &pnv_quad_power10_xscom_ops; pqc->xscom_size = PNV10_XSCOM_EQ_SIZE; + + pqc->xscom_qme_ops = &pnv_qme_power10_xscom_ops; + pqc->xscom_qme_size = PNV10_XSCOM_QME_SIZE; } static void pnv_quad_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); - dc->realize = pnv_quad_realize; device_class_set_props(dc, pnv_quad_properties); dc->user_creatable = false; } -- cgit v1.2.3