From 2e93a90f4f0ea0503c1a850b2ea04e5eb8063e8c Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Thu, 17 Nov 2022 12:32:18 -0300 Subject: [PATCH 01/14] MAINTAINERS: downgrade PPC KVM/TCG CPUs and pSeries to 'Odd Fixes' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The maintainer is no longer being paid to maintain these components. All maintainership work is being done in his personal time since the middle of the 7.2 development cycle. Change the status of PPC KVM CPUs, PPC TCG CPUs and the pSeries machine to 'Odd Fixes', reflecting that the maintainer no longer has exclusive time to dedicate to them. It'll also (hopefully) keep expectations under check when/if these components are used in a customer product. Cc: Cédric Le Goater Cc: David Gibson Cc: Greg Kurz Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz Reviewed-by: David Gibson Message-Id: <20221117153218.182835-1-danielhb413@gmail.com> Signed-off-by: Daniel Henrique Barboza --- MAINTAINERS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 716d5a24ad..9a8c40a1c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -276,7 +276,7 @@ R: Cédric Le Goater R: David Gibson R: Greg Kurz L: qemu-ppc@nongnu.org -S: Maintained +S: Odd Fixes F: target/ppc/ F: hw/ppc/ppc.c F: hw/ppc/ppc_booke.c @@ -402,7 +402,7 @@ M: Daniel Henrique Barboza R: Cédric Le Goater R: David Gibson R: Greg Kurz -S: Maintained +S: Odd Fixes F: target/ppc/kvm.c S390 KVM CPUs @@ -1382,7 +1382,7 @@ R: Cédric Le Goater R: David Gibson R: Greg Kurz L: qemu-ppc@nongnu.org -S: Maintained +S: Odd Fixes F: hw/*/spapr* F: include/hw/*/spapr* F: hw/*/xics* From c0a55a0c9da2ffd7836530f9b30171eef3da03b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Nov 2022 23:29:33 +0100 Subject: [PATCH 02/14] hw/sd/sdhci: Support big endian SD host controller interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some SDHCI IP can be synthetized in various endianness: https://github.com/u-boot/u-boot/blob/v2021.04/doc/README.fsl-esdhc - CONFIG_SYS_FSL_ESDHC_BE ESDHC IP is in big-endian mode. Accessing ESDHC registers can be determined by ESDHC IP's endian mode or processor's endian mode. Our current implementation is little-endian. In order to support big endianness: - Rename current MemoryRegionOps as sdhci_mmio_le_ops ('le') - Add an 'endianness' property to SDHCIState (default little endian) - Set the 'io_ops' field in realize() after checking the property - Add the sdhci_mmio_be_ops (big-endian) MemoryRegionOps. Signed-off-by: Philippe Mathieu-Daudé Tested-by: Bernhard Beschow Reviewed-by: Bernhard Beschow Message-Id: <20221101222934.52444-3-philmd@linaro.org> Signed-off-by: Daniel Henrique Barboza --- hw/sd/sdhci-internal.h | 1 + hw/sd/sdhci.c | 32 +++++++++++++++++++++++++++++--- include/hw/sd/sdhci.h | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h index 964570f8e8..5f3765f12d 100644 --- a/hw/sd/sdhci-internal.h +++ b/hw/sd/sdhci-internal.h @@ -308,6 +308,7 @@ extern const VMStateDescription sdhci_vmstate; #define SDHC_CAPAB_REG_DEFAULT 0x057834b4 #define DEFINE_SDHCI_COMMON_PROPERTIES(_state) \ + DEFINE_PROP_UINT8("endianness", _state, endianness, DEVICE_LITTLE_ENDIAN), \ DEFINE_PROP_UINT8("sd-spec-version", _state, sd_spec_version, 2), \ DEFINE_PROP_UINT8("uhs", _state, uhs_mode, UHS_NOT_SUPPORTED), \ DEFINE_PROP_UINT8("vendor", _state, vendor, SDHCI_VENDOR_NONE), \ diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 306070c872..6811f0f1a8 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1329,7 +1329,7 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) value >> shift, value >> shift); } -static const MemoryRegionOps sdhci_mmio_ops = { +static const MemoryRegionOps sdhci_mmio_le_ops = { .read = sdhci_read, .write = sdhci_write, .valid = { @@ -1340,6 +1340,21 @@ static const MemoryRegionOps sdhci_mmio_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static const MemoryRegionOps sdhci_mmio_be_ops = { + .read = sdhci_read, + .write = sdhci_write, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + .unaligned = false + }, + .endianness = DEVICE_BIG_ENDIAN, +}; + static void sdhci_init_readonly_registers(SDHCIState *s, Error **errp) { ERRP_GUARD(); @@ -1367,8 +1382,6 @@ void sdhci_initfn(SDHCIState *s) s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s); s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s); - - s->io_ops = &sdhci_mmio_ops; } void sdhci_uninitfn(SDHCIState *s) @@ -1384,10 +1397,23 @@ void sdhci_common_realize(SDHCIState *s, Error **errp) { ERRP_GUARD(); + switch (s->endianness) { + case DEVICE_LITTLE_ENDIAN: + s->io_ops = &sdhci_mmio_le_ops; + break; + case DEVICE_BIG_ENDIAN: + s->io_ops = &sdhci_mmio_be_ops; + break; + default: + error_setg(errp, "Incorrect endianness"); + return; + } + sdhci_init_readonly_registers(s, errp); if (*errp) { return; } + s->buf_maxsz = sdhci_get_fifolen(s); s->fifo_buffer = g_malloc0(s->buf_maxsz); diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h index 01a64c5442..a989fca3b2 100644 --- a/include/hw/sd/sdhci.h +++ b/include/hw/sd/sdhci.h @@ -96,6 +96,7 @@ struct SDHCIState { /* Configurable properties */ bool pending_insert_quirk; /* Quirk for Raspberry Pi card insert int */ uint32_t quirks; + uint8_t endianness; uint8_t sd_spec_version; uint8_t uhs_mode; uint8_t vendor; /* For vendor specific functionality */ From 3f288c4b2fb01d12734cdf62414509f779668407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 1 Nov 2022 23:29:34 +0100 Subject: [PATCH 03/14] hw/ppc/e500: Add Freescale eSDHC to e500plat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds missing functionality to e500plat machine which increases the chance of given "real" firmware images to access SD cards. Signed-off-by: Bernhard Beschow Message-Id: <20221018210146.193159-8-shentey@gmail.com> [PMD: Simplify using create_unimplemented_device("esdhc")] Signed-off-by: Philippe Mathieu-Daudé Tested-by: Bernhard Beschow Reviewed-by: Bernhard Beschow Message-Id: <20221101222934.52444-4-philmd@linaro.org> Signed-off-by: Daniel Henrique Barboza --- docs/system/ppc/ppce500.rst | 13 ++++++++++ hw/ppc/Kconfig | 2 ++ hw/ppc/e500.c | 48 ++++++++++++++++++++++++++++++++++++- hw/ppc/e500.h | 1 + hw/ppc/e500plat.c | 1 + 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/system/ppc/ppce500.rst b/docs/system/ppc/ppce500.rst index fa40e57d18..c9fe0915dc 100644 --- a/docs/system/ppc/ppce500.rst +++ b/docs/system/ppc/ppce500.rst @@ -19,6 +19,7 @@ The ``ppce500`` machine supports the following devices: * Power-off functionality via one GPIO pin * 1 Freescale MPC8xxx PCI host controller * VirtIO devices via PCI bus +* 1 Freescale Enhanced Secure Digital Host controller (eSDHC) * 1 Freescale Enhanced Triple Speed Ethernet controller (eTSEC) Hardware configuration information @@ -180,3 +181,15 @@ as follows: -kernel vmlinux \ -drive if=pflash,file=/path/to/rootfs.ext2,format=raw \ -append "rootwait root=/dev/mtdblock0" + +Alternatively, the root file system can also reside on an emulated SD card +whose size must again be a power of two: + +.. code-block:: bash + + $ qemu-system-ppc64 -M ppce500 -cpu e500mc -smp 4 -m 2G \ + -display none -serial stdio \ + -kernel vmlinux \ + -device sd-card,drive=mydrive \ + -drive id=mydrive,if=none,file=/path/to/rootfs.ext2,format=raw \ + -append "rootwait root=/dev/mmcblk0" diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index b8d2522f45..72a311edcb 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -128,10 +128,12 @@ config E500 select PFLASH_CFI01 select PLATFORM_BUS select PPCE500_PCI + select SDHCI select SERIAL select MPC_I2C select FDT_PPC select DS1338 + select UNIMP config E500PLAT bool diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 2fe496677c..2bef2f01cb 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -48,6 +48,8 @@ #include "hw/net/fsl_etsec/etsec.h" #include "hw/i2c/i2c.h" #include "hw/irq.h" +#include "hw/sd/sdhci.h" +#include "hw/misc/unimp.h" #define EPAPR_MAGIC (0x45504150) #define DTC_LOAD_PAD 0x1800000 @@ -66,11 +68,14 @@ #define MPC8544_SERIAL1_REGS_OFFSET 0x4600ULL #define MPC8544_PCI_REGS_OFFSET 0x8000ULL #define MPC8544_PCI_REGS_SIZE 0x1000ULL +#define MPC85XX_ESDHC_REGS_OFFSET 0x2e000ULL +#define MPC85XX_ESDHC_REGS_SIZE 0x1000ULL #define MPC8544_UTIL_OFFSET 0xe0000ULL #define MPC8XXX_GPIO_OFFSET 0x000FF000ULL #define MPC8544_I2C_REGS_OFFSET 0x3000ULL #define MPC8XXX_GPIO_IRQ 47 #define MPC8544_I2C_IRQ 43 +#define MPC85XX_ESDHC_IRQ 72 #define RTC_REGS_OFFSET 0x68 #define PLATFORM_CLK_FREQ_HZ (400 * 1000 * 1000) @@ -203,6 +208,22 @@ static void dt_i2c_create(void *fdt, const char *soc, const char *mpic, g_free(i2c); } +static void dt_sdhc_create(void *fdt, const char *parent, const char *mpic) +{ + hwaddr mmio = MPC85XX_ESDHC_REGS_OFFSET; + hwaddr size = MPC85XX_ESDHC_REGS_SIZE; + int irq = MPC85XX_ESDHC_IRQ; + g_autofree char *name = NULL; + + name = g_strdup_printf("%s/sdhc@%" PRIx64, parent, mmio); + qemu_fdt_add_subnode(fdt, name); + qemu_fdt_setprop(fdt, name, "sdhci,auto-cmd12", NULL, 0); + qemu_fdt_setprop_phandle(fdt, name, "interrupt-parent", mpic); + qemu_fdt_setprop_cells(fdt, name, "bus-width", 4); + qemu_fdt_setprop_cells(fdt, name, "interrupts", irq, 0x2); + qemu_fdt_setprop_cells(fdt, name, "reg", mmio, size); + qemu_fdt_setprop_string(fdt, name, "compatible", "fsl,esdhc"); +} typedef struct PlatformDevtreeData { void *fdt; @@ -553,6 +574,10 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, dt_rtc_create(fdt, "i2c", "rtc"); + /* sdhc */ + if (pmc->has_esdhc) { + dt_sdhc_create(fdt, soc, mpic); + } gutil = g_strdup_printf("%s/global-utilities@%llx", soc, MPC8544_UTIL_OFFSET); @@ -982,7 +1007,8 @@ void ppce500_init(MachineState *machine) 0, qdev_get_gpio_in(mpicdev, 42), 399193, serial_hd(1), DEVICE_BIG_ENDIAN); } - /* I2C */ + + /* I2C */ dev = qdev_new("mpc-i2c"); s = SYS_BUS_DEVICE(dev); sysbus_realize_and_unref(s, &error_fatal); @@ -992,6 +1018,26 @@ void ppce500_init(MachineState *machine) i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); i2c_slave_create_simple(i2c, "ds1338", RTC_REGS_OFFSET); + /* eSDHC */ + if (pmc->has_esdhc) { + create_unimplemented_device("esdhc", + pmc->ccsrbar_base + MPC85XX_ESDHC_REGS_OFFSET, + MPC85XX_ESDHC_REGS_SIZE); + + /* + * Compatible with: + * - SD Host Controller Specification Version 2.0 Part A2 + * (See MPC8569E Reference Manual) + */ + dev = qdev_new(TYPE_SYSBUS_SDHCI); + qdev_prop_set_uint8(dev, "sd-spec-version", 2); + qdev_prop_set_uint8(dev, "endianness", DEVICE_BIG_ENDIAN); + s = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(s, &error_fatal); + sysbus_connect_irq(s, 0, qdev_get_gpio_in(mpicdev, MPC85XX_ESDHC_IRQ)); + memory_region_add_subregion(ccsr_addr_space, MPC85XX_ESDHC_REGS_OFFSET, + sysbus_mmio_get_region(s, 0)); + } /* General Utility device */ dev = qdev_new("mpc8544-guts"); diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h index 68f754ce50..8c09ef92e4 100644 --- a/hw/ppc/e500.h +++ b/hw/ppc/e500.h @@ -27,6 +27,7 @@ struct PPCE500MachineClass { int mpic_version; bool has_mpc8xxx_gpio; + bool has_esdhc; hwaddr platform_bus_base; hwaddr platform_bus_size; int platform_bus_first_irq; diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c index 5bb1c603da..44bf874b0f 100644 --- a/hw/ppc/e500plat.c +++ b/hw/ppc/e500plat.c @@ -86,6 +86,7 @@ static void e500plat_machine_class_init(ObjectClass *oc, void *data) pmc->fixup_devtree = e500plat_fixup_devtree; pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_42; pmc->has_mpc8xxx_gpio = true; + pmc->has_esdhc = true; pmc->platform_bus_base = 0xf00000000ULL; pmc->platform_bus_size = 128 * MiB; pmc->platform_bus_first_irq = 5; From 308fd18142159ceccca6ef7a80fd794722928aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 13 Dec 2022 13:35:47 +0100 Subject: [PATCH 04/14] target/ppc/kvm: Add missing "cpu.h" and "exec/hwaddr.h" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kvm_ppc.h is missing various declarations from "cpu.h": target/ppc/kvm_ppc.h:128:40: error: unknown type name 'CPUPPCState'; did you mean 'CPUState'? static inline int kvmppc_get_hypercall(CPUPPCState *env, ^~~~~~~~~~~ CPUState include/qemu/typedefs.h:45:25: note: 'CPUState' declared here typedef struct CPUState CPUState; ^ target/ppc/kvm_ppc.h:134:40: error: unknown type name 'PowerPCCPU' static inline int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) ^ target/ppc/kvm_ppc.h:285:38: error: unknown type name 'hwaddr' hwaddr ptex, int n) ^ target/ppc/kvm_ppc.h:220:15: error: unknown type name 'target_ulong' static inline target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, ^ target/ppc/kvm_ppc.h:286:38: error: unknown type name 'ppc_hash_pte64_t' static inline void kvmppc_read_hptes(ppc_hash_pte64_t *hptes, ^ Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Message-Id: <20221213123550.39302-2-philmd@linaro.org> Signed-off-by: Daniel Henrique Barboza --- target/ppc/kvm_ppc.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index ee9325bf9a..5fd9753953 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -9,6 +9,9 @@ #ifndef KVM_PPC_H #define KVM_PPC_H +#include "exec/hwaddr.h" +#include "cpu.h" + #define TYPE_HOST_POWERPC_CPU POWERPC_CPU_TYPE_NAME("host") #ifdef CONFIG_KVM From 31b55f5bdadc74e980e76a932aace79444ab4e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 13 Dec 2022 13:35:48 +0100 Subject: [PATCH 05/14] hw/ppc/vof: Do not include the full "cpu.h" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "vof.h" doesn't need the full "cpu.h" to get the target_ulong definition, including "exec/cpu-defs.h" is enough. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Message-Id: <20221213123550.39302-3-philmd@linaro.org> Signed-off-by: Daniel Henrique Barboza --- include/hw/ppc/vof.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/ppc/vof.h b/include/hw/ppc/vof.h index f8c0effcaf..d3f293da8b 100644 --- a/include/hw/ppc/vof.h +++ b/include/hw/ppc/vof.h @@ -9,7 +9,7 @@ #include "qom/object.h" #include "exec/address-spaces.h" #include "exec/memory.h" -#include "cpu.h" +#include "exec/cpu-defs.h" typedef struct Vof { uint64_t top_addr; /* copied from rma_size */ From 46d80a56a151e229670ddfc5c996c8d68efac920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 13 Dec 2022 13:35:49 +0100 Subject: [PATCH 06/14] hw/ppc/spapr: Reduce "vof.h" inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently objects including "hw/ppc/spapr.h" are forced to be target specific due to the inclusion of "vof.h" in "spapr.h". "spapr.h" only uses a Vof pointer, so doesn't require the structure declaration. The only place where Vof structure is accessed is in spapr.c, so include "vof.h" there, and forward declare the structure in "spapr.h". Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Daniel Henrique Barboza Message-Id: <20221213123550.39302-4-philmd@linaro.org> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr.c | 1 + include/hw/ppc/spapr.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index dc850032ae..59641adaec 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -62,6 +62,7 @@ #include "hw/ppc/fdt.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" +#include "hw/ppc/vof.h" #include "hw/qdev-properties.h" #include "hw/pci-host/spapr.h" #include "hw/pci/msi.h" diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 04a95669ab..5c8aabd444 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -12,7 +12,6 @@ #include "hw/ppc/spapr_xive.h" /* For SpaprXive */ #include "hw/ppc/xics.h" /* For ICSState */ #include "hw/ppc/spapr_tpm_proxy.h" -#include "hw/ppc/vof.h" struct SpaprVioBus; struct SpaprPhbState; @@ -22,6 +21,8 @@ typedef struct SpaprEventLogEntry SpaprEventLogEntry; typedef struct SpaprEventSource SpaprEventSource; typedef struct SpaprPendingHpt SpaprPendingHpt; +typedef struct Vof Vof; + #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL #define SPAPR_ENTRY_POINT 0x100 From e4cadfbe3c8cb22696d05bd6311515c6830ee43f Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 16 Dec 2022 15:57:04 +0100 Subject: [PATCH 07/14] target/ppc/mmu_common: Log which effective address had no TLB entry found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's not leave developers in the dark where this log message comes from. Signed-off-by: Bernhard Beschow Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221216145709.271940-2-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/mmu_common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c index 89107a6af2..49067c05e6 100644 --- a/target/ppc/mmu_common.c +++ b/target/ppc/mmu_common.c @@ -811,7 +811,8 @@ static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb, } } - qemu_log_mask(CPU_LOG_MMU, "%s: TLB entry not found\n", __func__); + qemu_log_mask(CPU_LOG_MMU, "%s: No TLB entry found for effective address " + "0x" TARGET_FMT_lx "\n", __func__, address); return -1; found_tlb: From 2479abef09bbb27549eee67eeb1ace457531a7ed Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 16 Dec 2022 15:57:05 +0100 Subject: [PATCH 08/14] target/ppc/mmu_common: Fix table layout of "info tlb" HMP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting with the URWX columns the columns didn't line up. Before: QEMU 7.2.50 monitor - type 'help' for more information (qemu) info tlb TLB0: Effective Physical Size TID TS SRWX URWX WIMGE U0123 0x0000000000a80000 0x000000000105d000 4K 117 0 SR--UR-- --M-- U---- 0x0000000000100000 0x000000000114e000 4K 117 0 SR--UR-- --M-- U---- (qemu) After: QEMU 7.2.50 monitor - type 'help' for more information (qemu) info tlb TLB0: Effective Physical Size TID TS SRWX URWX WIMGE U0123 0x00000000b7a00000 0x000000000fcf5000 4K 18 0 SR-- UR-- --M-- U---- 0x0000000000800000 0x000000000fd73000 4K 18 0 SR-- UR-X --M-- U---- TLB1: Effective Physical Size TID TS SRWX URWX WIMGE U0123 0x00000000c0000000 0x0000000000000000 16M 0 0 SR-X U--- --M-- U---- 0x00000000c1000000 0x0000000001000000 16M 0 0 SRW- U--- --M-- U---- (qemu) Signed-off-by: Bernhard Beschow Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221216145709.271940-3-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/mmu_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c index 49067c05e6..8901f4d134 100644 --- a/target/ppc/mmu_common.c +++ b/target/ppc/mmu_common.c @@ -980,7 +980,7 @@ static void mmubooke206_dump_one_tlb(CPUPPCState *env, int tlbn, int offset, pa = entry->mas7_3 & ~(size - 1); qemu_printf("0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c" - "U%c%c%c %c%c%c%c%c U%c%c%c%c\n", + " U%c%c%c %c%c%c%c%c U%c%c%c%c\n", (uint64_t)ea, (uint64_t)pa, book3e_tsize_to_str[tsize], (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT, From 712622385b6fd0c8cc6a5ff2dad8da7cbfdb0dd3 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 16 Dec 2022 15:57:06 +0100 Subject: [PATCH 09/14] hw/ppc/virtex_ml507: Prefer local over global variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Beschow Reviewed-by: Edgar E. Iglesias Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221216145709.271940-4-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/virtex_ml507.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 13cace229b..f2f81bd425 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -157,7 +157,7 @@ static int xilinx_load_device_tree(MachineState *machine, int r; const char *dtb_filename; - dtb_filename = current_machine->dtb; + dtb_filename = machine->dtb; if (dtb_filename) { fdt = load_device_tree(dtb_filename, &fdt_size); if (!fdt) { From 1a3e6528acbaeb37707f80f4a002cfa4c645e926 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 16 Dec 2022 15:57:07 +0100 Subject: [PATCH 10/14] hw/ppc/e500: Prefer local variable over qdev_get_machine() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernhard Beschow Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20221216145709.271940-5-shentey@gmail.com> [danielhb: remove linebreak in object_property_add_child()] Signed-off-by: Daniel Henrique Barboza --- hw/ppc/e500.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 2bef2f01cb..87439c9592 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -984,8 +984,7 @@ void ppce500_init(MachineState *machine) memory_region_add_subregion(address_space_mem, 0, machine->ram); dev = qdev_new("e500-ccsr"); - object_property_add_child(qdev_get_machine(), "e500-ccsr", - OBJECT(dev)); + object_property_add_child(OBJECT(machine), "e500-ccsr", OBJECT(dev)); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); ccsr = CCSR(dev); ccsr_addr_space = &ccsr->ccsr_space; @@ -1048,7 +1047,7 @@ void ppce500_init(MachineState *machine) /* PCI */ dev = qdev_new("e500-pcihost"); - object_property_add_child(qdev_get_machine(), "pci-host", OBJECT(dev)); + object_property_add_child(OBJECT(machine), "pci-host", OBJECT(dev)); qdev_prop_set_uint32(dev, "first_slot", pmc->pci_first_slot); qdev_prop_set_uint32(dev, "first_pin_irq", pci_irq_nrs[0]); s = SYS_BUS_DEVICE(dev); From a80fc80eda494634b2fa111f56c65980848642ca Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 16 Dec 2022 15:57:08 +0100 Subject: [PATCH 11/14] hw/ppc/e500: Resolve variable shadowing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assign to the outer variable instead which even saves some code. Signed-off-by: Bernhard Beschow Reviewed-by: Cédric Le Goater Message-Id: <20221216145709.271940-6-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/e500.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 87439c9592..da7bdb948a 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -908,7 +908,7 @@ void ppce500_init(MachineState *machine) bool kernel_as_payload; hwaddr bios_entry = 0; target_long payload_size; - struct boot_info *boot_info; + struct boot_info *boot_info = NULL; int dt_size; int i; unsigned int smp_cpus = machine->smp.cpus; @@ -963,7 +963,6 @@ void ppce500_init(MachineState *machine) /* Register reset handler */ if (!i) { /* Primary CPU */ - struct boot_info *boot_info; boot_info = g_new0(struct boot_info, 1); qemu_register_reset(ppce500_cpu_reset, cpu); env->load_info = boot_info; @@ -1262,7 +1261,6 @@ void ppce500_init(MachineState *machine) } assert(dt_size < DTB_MAX_SIZE); - boot_info = env->load_info; boot_info->entry = bios_entry; boot_info->dt_base = dt_base; boot_info->dt_size = dt_size; From 320c5ad8fffe8ce7562fcc34975398bb4bb50666 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Fri, 16 Dec 2022 15:57:09 +0100 Subject: [PATCH 12/14] hw/ppc/e500: Move comment to more appropriate place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The TLB entries are set up in mmubooke_create_initial_mapping(), not in booke206_page_size_to_tlb(). Signed-off-by: Bernhard Beschow Reviewed-by: Cédric Le Goater Message-Id: <20221216145709.271940-7-shentey@gmail.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/e500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index da7bdb948a..9fa1f8e6cf 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -717,7 +717,6 @@ static int ppce500_prep_device_tree(PPCE500MachineState *machine, kernel_base, kernel_size, true); } -/* Create -kernel TLB entries for BookE. */ hwaddr booke206_page_size_to_tlb(uint64_t size) { return 63 - clz64(size / KiB); @@ -748,6 +747,7 @@ static uint64_t mmubooke_initial_mapsize(CPUPPCState *env) return (1ULL << 10 << tsize); } +/* Create -kernel TLB entries for BookE. */ static void mmubooke_create_initial_mapping(CPUPPCState *env) { ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0); From 395b5d5b455ac3f6ebf9534454b7187a1d6118a4 Mon Sep 17 00:00:00 2001 From: Nicholas Miehlbradt Date: Tue, 20 Dec 2022 04:23:29 +0000 Subject: [PATCH 13/14] target/ppc: Implement the DEXCR and HDEXCR Define the DEXCR and HDEXCR as special purpose registers. Each register occupies two SPR indicies, one which can be read in an unprivileged state and one which can be modified in the appropriate priviliged state, however both indicies refer to the same underlying value. Note that the ISA uses the abbreviation UDEXCR in two different contexts: the userspace DEXCR, the SPR index which can be read from userspace (implemented in this patch), and the ultravisor DEXCR, the equivalent register for the ultravisor state (not implemented). Signed-off-by: Nicholas Miehlbradt Reviewed-by: Daniel Henrique Barboza Message-Id: <20221220042330.2387944-2-nicholas@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 19 +++++++++++++++++++ target/ppc/cpu_init.c | 25 +++++++++++++++++++++++++ target/ppc/spr_common.h | 1 + target/ppc/translate.c | 19 +++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 81d4263a07..3923f174f8 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1068,6 +1068,21 @@ struct ppc_radix_page_info { uint32_t entries[PPC_PAGE_SIZES_MAX_SZ]; }; +/*****************************************************************************/ +/* Dynamic Execution Control Register */ + +#define DEXCR_ASPECT(name, num) \ +FIELD(DEXCR, PNH_##name, PPC_BIT_NR(num), 1) \ +FIELD(DEXCR, PRO_##name, PPC_BIT_NR(num + 32), 1) \ +FIELD(HDEXCR, HNU_##name, PPC_BIT_NR(num), 1) \ +FIELD(HDEXCR, ENF_##name, PPC_BIT_NR(num + 32), 1) \ + +DEXCR_ASPECT(SBHE, 0) +DEXCR_ASPECT(IBRTPD, 1) +DEXCR_ASPECT(SRAPD, 4) +DEXCR_ASPECT(NPHIE, 5) +DEXCR_ASPECT(PHIE, 6) + /*****************************************************************************/ /* The whole PowerPC CPU context */ @@ -1674,9 +1689,11 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_BOOKE_GIVOR13 (0x1BC) #define SPR_BOOKE_GIVOR14 (0x1BD) #define SPR_TIR (0x1BE) +#define SPR_UHDEXCR (0x1C7) #define SPR_PTCR (0x1D0) #define SPR_HASHKEYR (0x1D4) #define SPR_HASHPKEYR (0x1D5) +#define SPR_HDEXCR (0x1D7) #define SPR_BOOKE_SPEFSCR (0x200) #define SPR_Exxx_BBEAR (0x201) #define SPR_Exxx_BBTAR (0x202) @@ -1865,8 +1882,10 @@ void ppc_compat_add_property(Object *obj, const char *name, #define SPR_RCPU_L2U_RA2 (0x32A) #define SPR_MPC_MD_DBRAM1 (0x32A) #define SPR_RCPU_L2U_RA3 (0x32B) +#define SPR_UDEXCR (0x32C) #define SPR_TAR (0x32F) #define SPR_ASDR (0x330) +#define SPR_DEXCR (0x33C) #define SPR_IC (0x350) #define SPR_VTB (0x351) #define SPR_MMCRC (0x353) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 95d25856a0..abee71d407 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5727,6 +5727,30 @@ static void register_power10_hash_sprs(CPUPPCState *env) hashpkeyr_initial_value); } +static void register_power10_dexcr_sprs(CPUPPCState *env) +{ + spr_register(env, SPR_DEXCR, "DEXCR", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0); + + spr_register(env, SPR_UDEXCR, "DEXCR", + &spr_read_dexcr_ureg, SPR_NOACCESS, + &spr_read_dexcr_ureg, SPR_NOACCESS, + 0); + + spr_register_hv(env, SPR_HDEXCR, "HDEXCR", + SPR_NOACCESS, SPR_NOACCESS, + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + 0); + + spr_register(env, SPR_UHDEXCR, "HDEXCR", + &spr_read_dexcr_ureg, SPR_NOACCESS, + &spr_read_dexcr_ureg, SPR_NOACCESS, + 0); +} + /* * Initialize PMU counter overflow timers for Power8 and * newer Power chips when using TCG. @@ -6402,6 +6426,7 @@ static void init_proc_POWER10(CPUPPCState *env) register_power8_rpr_sprs(env); register_power9_mmu_sprs(env); register_power10_hash_sprs(env); + register_power10_dexcr_sprs(env); /* FIXME: Filter fields properly based on privilege level */ spr_register_kvm_hv(env, SPR_PSSCR, "PSSCR", NULL, NULL, NULL, NULL, diff --git a/target/ppc/spr_common.h b/target/ppc/spr_common.h index b5a5bc6895..8437eb0340 100644 --- a/target/ppc/spr_common.h +++ b/target/ppc/spr_common.h @@ -195,6 +195,7 @@ void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn); void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn); void spr_write_hmer(DisasContext *ctx, int sprn, int gprn); void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn); +void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn); #endif void register_low_BATs(CPUPPCState *env); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 19c1d17cb0..edb3daa9b5 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -1249,6 +1249,25 @@ void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn) gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB); spr_write_prev_upper32(ctx, sprn, gprn); } + +void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn) +{ + TCGv t0 = tcg_temp_new(); + + /* + * Access to the (H)DEXCR in problem state is done using separated + * SPR indexes which are 16 below the SPR indexes which have full + * access to the (H)DEXCR in privileged state. Problem state can + * only read bits 32:63, bits 0:31 return 0. + * + * See section 9.3.1-9.3.2 of PowerISA v3.1B + */ + + gen_load_spr(t0, sprn + 16); + tcg_gen_ext32u_tl(cpu_gpr[gprn], t0); + + tcg_temp_free(t0); +} #endif #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ From 4091fabfeb54f02762bdecba7344353c56533873 Mon Sep 17 00:00:00 2001 From: Nicholas Miehlbradt Date: Tue, 20 Dec 2022 04:23:30 +0000 Subject: [PATCH 14/14] target/ppc: Check DEXCR on hash{st, chk} instructions Adds checks to the hashst and hashchk instructions to only execute if enabled by the relevant aspect in the DEXCR and HDEXCR. This behaviour is guarded behind TARGET_PPC64 since Power10 is currently the only implementation which has the DEXCR. Reviewed-by: Daniel Henrique Barboza Signed-off-by: Nicholas Miehlbradt Message-Id: <20221220042330.2387944-3-nicholas@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/excp_helper.c | 58 +++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 94adcb766b..add4d54ae7 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2902,29 +2902,57 @@ static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key) return stage1_h ^ stage1_l; } +static void do_hash(CPUPPCState *env, target_ulong ea, target_ulong ra, + target_ulong rb, uint64_t key, bool store) +{ + uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; + + if (store) { + cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); + } else { + loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); + if (loaded_hash != calculated_hash) { + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_TRAP, GETPC()); + } + } +} + #include "qemu/guest-random.h" -#define HELPER_HASH(op, key, store) \ +#ifdef TARGET_PPC64 +#define HELPER_HASH(op, key, store, dexcr_aspect) \ void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ target_ulong rb) \ { \ - uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; \ - \ - if (store) { \ - cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); \ - } else { \ - loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); \ - if (loaded_hash != calculated_hash) { \ - raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, \ - POWERPC_EXCP_TRAP, GETPC()); \ - } \ + if (env->msr & R_MSR_PR_MASK) { \ + if (!(env->spr[SPR_DEXCR] & R_DEXCR_PRO_##dexcr_aspect##_MASK || \ + env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ + return; \ + } else if (!(env->msr & R_MSR_HV_MASK)) { \ + if (!(env->spr[SPR_DEXCR] & R_DEXCR_PNH_##dexcr_aspect##_MASK || \ + env->spr[SPR_HDEXCR] & R_HDEXCR_ENF_##dexcr_aspect##_MASK)) \ + return; \ + } else if (!(env->msr & R_MSR_S_MASK)) { \ + if (!(env->spr[SPR_HDEXCR] & R_HDEXCR_HNU_##dexcr_aspect##_MASK)) \ + return; \ } \ + \ + do_hash(env, ea, ra, rb, key, store); \ } +#else +#define HELPER_HASH(op, key, store, dexcr_aspect) \ +void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ + target_ulong rb) \ +{ \ + do_hash(env, ea, ra, rb, key, store); \ +} +#endif /* TARGET_PPC64 */ -HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true) -HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false) -HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true) -HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false) +HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true, NPHIE) +HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false, NPHIE) +HELPER_HASH(HASHSTP, env->spr[SPR_HASHPKEYR], true, PHIE) +HELPER_HASH(HASHCHKP, env->spr[SPR_HASHPKEYR], false, PHIE) #endif /* CONFIG_TCG */ #if !defined(CONFIG_USER_ONLY)