From 9fd0122e7d365e4b634cc252032ea921f2b4a931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 5 Jul 2022 16:58:10 +0200 Subject: [PATCH 01/30] ppc64: Allocate IRQ lines with qdev_init_gpio_in() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This replaces the IRQ array 'irq_inputs' with GPIO lines, the goal being to remove 'irq_inputs' when all CPUs have been converted. Signed-off-by: Cédric Le Goater Acked-by: Mark Cave-Ayland Reviewed-by: Peter Maydell Message-Id: <20220705145814.461723-2-clg@kaod.org> Signed-off-by: Daniel Henrique Barboza --- hw/intc/xics.c | 10 ++++++---- hw/intc/xive.c | 4 ++-- hw/ppc/mac_newworld.c | 8 ++++---- hw/ppc/ppc.c | 15 +++------------ 4 files changed, 15 insertions(+), 22 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 24e67020db..5b0b4d9624 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -301,23 +301,25 @@ void icp_reset(ICPState *icp) static void icp_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); + PowerPCCPU *cpu; CPUPPCState *env; Error *err = NULL; assert(icp->xics); assert(icp->cs); - env = &POWERPC_CPU(icp->cs)->env; + cpu = POWERPC_CPU(icp->cs); + env = &cpu->env; switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_POWER7: - icp->output = env->irq_inputs[POWER7_INPUT_INT]; + icp->output = qdev_get_gpio_in(DEVICE(cpu), POWER7_INPUT_INT); break; case PPC_FLAGS_INPUT_POWER9: /* For SPAPR xics emulation */ - icp->output = env->irq_inputs[POWER9_INPUT_INT]; + icp->output = qdev_get_gpio_in(DEVICE(cpu), POWER9_INPUT_INT); break; case PPC_FLAGS_INPUT_970: - icp->output = env->irq_inputs[PPC970_INPUT_INT]; + icp->output = qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT); break; default: diff --git a/hw/intc/xive.c b/hw/intc/xive.c index ae221fed73..a986b96843 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -695,8 +695,8 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp) env = &cpu->env; switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_POWER9: - tctx->hv_output = env->irq_inputs[POWER9_INPUT_HINT]; - tctx->os_output = env->irq_inputs[POWER9_INPUT_INT]; + tctx->hv_output = qdev_get_gpio_in(DEVICE(cpu), POWER9_INPUT_HINT); + tctx->os_output = qdev_get_gpio_in(DEVICE(cpu), POWER9_INPUT_INT); break; default: diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index c865921bdc..22405dd27a 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -276,16 +276,16 @@ static void ppc_core99_init(MachineState *machine) #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] = - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; + qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] = - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_INT]; + qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] = - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_MCP]; + qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_MCP); /* Not connected ? */ openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] = - ((qemu_irq *)env->irq_inputs)[PPC970_INPUT_HRESET]; + qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_HRESET); break; #endif /* defined(TARGET_PPC64) */ default: diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index fea70df45e..15f2b5f0f0 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -234,10 +234,7 @@ static void ppc970_set_irq(void *opaque, int pin, int level) void ppc970_irq_init(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; - - env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, cpu, - PPC970_INPUT_NB); + qdev_init_gpio_in(DEVICE(cpu), ppc970_set_irq, PPC970_INPUT_NB); } /* POWER7 internal IRQ controller */ @@ -260,10 +257,7 @@ static void power7_set_irq(void *opaque, int pin, int level) void ppcPOWER7_irq_init(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; - - env->irq_inputs = (void **)qemu_allocate_irqs(&power7_set_irq, cpu, - POWER7_INPUT_NB); + qdev_init_gpio_in(DEVICE(cpu), power7_set_irq, POWER7_INPUT_NB); } /* POWER9 internal IRQ controller */ @@ -292,10 +286,7 @@ static void power9_set_irq(void *opaque, int pin, int level) void ppcPOWER9_irq_init(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; - - env->irq_inputs = (void **)qemu_allocate_irqs(&power9_set_irq, cpu, - POWER9_INPUT_NB); + qdev_init_gpio_in(DEVICE(cpu), power9_set_irq, POWER9_INPUT_NB); } #endif /* defined(TARGET_PPC64) */ From 47b60fc6252448c9b8a3cc2296e4b26af57078d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 5 Jul 2022 16:58:11 +0200 Subject: [PATCH 02/30] ppc/40x: Allocate IRQ lines with qdev_init_gpio_in() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Peter Maydell Message-Id: <20220705145814.461723-3-clg@kaod.org> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/ppc.c | 5 +---- hw/ppc/ppc405_uc.c | 4 ++-- hw/ppc/ppc440_bamboo.c | 4 ++-- hw/ppc/sam460ex.c | 4 ++-- hw/ppc/virtex_ml507.c | 10 +++++----- 5 files changed, 12 insertions(+), 15 deletions(-) diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 15f2b5f0f0..8c88d3a480 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -422,10 +422,7 @@ static void ppc40x_set_irq(void *opaque, int pin, int level) void ppc40x_irq_init(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; - - env->irq_inputs = (void **)qemu_allocate_irqs(&ppc40x_set_irq, - cpu, PPC40x_INPUT_NB); + qdev_init_gpio_in(DEVICE(cpu), ppc40x_set_irq, PPC40x_INPUT_NB); } /* PowerPC E500 internal IRQ controller */ diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c index 36c8ba6f3c..d6420c88d3 100644 --- a/hw/ppc/ppc405_uc.c +++ b/hw/ppc/ppc405_uc.c @@ -1470,9 +1470,9 @@ PowerPCCPU *ppc405ep_init(MemoryRegion *address_space_mem, sysbus_realize_and_unref(uicsbd, &error_fatal); sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_INT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT)); sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_CINT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT)); *uicdevp = uicdev; diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index d5973f2484..873f930c77 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -200,9 +200,9 @@ static void bamboo_init(MachineState *machine) sysbus_realize_and_unref(uicsbd, &error_fatal); sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_INT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT)); sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_CINT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT)); /* SDRAM controller */ memset(ram_bases, 0, sizeof(ram_bases)); diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 2f24598f55..7e8da657c2 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -334,9 +334,9 @@ static void sam460ex_init(MachineState *machine) if (i == 0) { sysbus_connect_irq(sbd, PPCUIC_OUTPUT_INT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT)); sysbus_connect_irq(sbd, PPCUIC_OUTPUT_CINT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT)); } else { sysbus_connect_irq(sbd, PPCUIC_OUTPUT_INT, qdev_get_gpio_in(uic[0], input_ints[i])); diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index b67a709ddc..53b126ff48 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -111,9 +111,9 @@ static PowerPCCPU *ppc440_init_xilinx(const char *cpu_type, uint32_t sysclk) sysbus_realize_and_unref(uicsbd, &error_fatal); sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_INT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT)); sysbus_connect_irq(uicsbd, PPCUIC_OUTPUT_CINT, - ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT]); + qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_CINT)); /* This board doesn't wire anything up to the inputs of the UIC. */ return cpu; @@ -213,7 +213,7 @@ static void virtex_init(MachineState *machine) CPUPPCState *env; hwaddr ram_base = 0; DriveInfo *dinfo; - qemu_irq irq[32], *cpu_irq; + qemu_irq irq[32], cpu_irq; int kernel_size; int i; @@ -236,12 +236,12 @@ static void virtex_init(MachineState *machine) dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, 64 * KiB, 1, 0x89, 0x18, 0x0000, 0x0, 1); - cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT]; + cpu_irq = qdev_get_gpio_in(DEVICE(cpu), PPC40x_INPUT_INT); dev = qdev_new("xlnx.xps-intc"); qdev_prop_set_uint32(dev, "kind-of-intr", 0); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); - sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]); + sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(dev, i); } From 0f3e0c6fd39af1c10bf170e0463ece341d73e323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 5 Jul 2022 16:58:12 +0200 Subject: [PATCH 03/30] ppc/6xx: Allocate IRQ lines with qdev_init_gpio_in() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Acked-by: Mark Cave-Ayland Reviewed-by: Peter Maydell Message-Id: <20220705145814.461723-4-clg@kaod.org> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/mac_newworld.c | 8 ++++---- hw/ppc/mac_oldworld.c | 2 +- hw/ppc/pegasos2.c | 2 +- hw/ppc/ppc.c | 5 +---- hw/ppc/prep.c | 2 +- hw/ppc/prep_systemio.c | 2 +- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 22405dd27a..cf7eb72391 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -262,16 +262,16 @@ static void ppc_core99_init(MachineState *machine) switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: openpic_irqs[i].irq[OPENPIC_OUTPUT_INT] = - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; + qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_CINT] = - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; + qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT); openpic_irqs[i].irq[OPENPIC_OUTPUT_MCK] = - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_MCP]; + qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_MCP); /* Not connected ? */ openpic_irqs[i].irq[OPENPIC_OUTPUT_DEBUG] = NULL; /* Check this */ openpic_irqs[i].irq[OPENPIC_OUTPUT_RESET] = - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_HRESET]; + qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_HRESET); break; #if defined(TARGET_PPC64) case PPC_FLAGS_INPUT_970: diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index d62fdf0db3..03732ca7ed 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -271,7 +271,7 @@ static void ppc_heathrow_init(MachineState *machine) case PPC_FLAGS_INPUT_6xx: /* XXX: we register only 1 output pin for heathrow PIC */ qdev_connect_gpio_out(pic_dev, 0, - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]); + qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT)); break; default: error_report("Bus model not supported on OldWorld Mac machine"); diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 9411ca6b16..61f4263953 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -155,7 +155,7 @@ static void pegasos2_init(MachineState *machine) /* Marvell Discovery II system controller */ pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1, - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT])); + qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT))); pci_bus = mv64361_get_pci_bus(pm->mv, 1); /* VIA VT8231 South Bridge (multifunction PCI device) */ diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 8c88d3a480..161e5f9087 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -154,10 +154,7 @@ static void ppc6xx_set_irq(void *opaque, int pin, int level) void ppc6xx_irq_init(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; - - env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, cpu, - PPC6xx_INPUT_NB); + qdev_init_gpio_in(DEVICE(cpu), ppc6xx_set_irq, PPC6xx_INPUT_NB); } #if defined(TARGET_PPC64) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index a1cd4505cc..f08714f2ec 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -275,7 +275,7 @@ static void ibm_40p_init(MachineState *machine) /* PCI -> ISA bridge */ i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378")); qdev_connect_gpio_out(i82378_dev, 0, - cpu->env.irq_inputs[PPC6xx_INPUT_INT]); + qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_INT)); sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(i82378_dev, 15)); isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0")); diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c index 8c9b8dd67b..5a56f155f5 100644 --- a/hw/ppc/prep_systemio.c +++ b/hw/ppc/prep_systemio.c @@ -262,7 +262,7 @@ static void prep_systemio_realize(DeviceState *dev, Error **errp) qemu_set_irq(s->non_contiguous_io_map_irq, s->iomap_type & PORT0850_IOMAP_NONCONTIGUOUS); cpu = POWERPC_CPU(first_cpu); - s->softreset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET]; + s->softreset_irq = qdev_get_gpio_in(DEVICE(cpu), PPC6xx_INPUT_HRESET); isa_register_portio_list(isa, &s->portio, 0x0, ppc_io800_port_list, s, "systemio800"); From 5e66cd0c7802f89e92407ad0a27169d26ffe5b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 5 Jul 2022 16:58:13 +0200 Subject: [PATCH 04/30] ppc/e500: Allocate IRQ lines with qdev_init_gpio_in() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Peter Maydell Message-Id: <20220705145814.461723-5-clg@kaod.org> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/e500.c | 8 ++++---- hw/ppc/ppc.c | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 7f7f5b3452..757cfaa62f 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -861,7 +861,6 @@ void ppce500_init(MachineState *machine) for (i = 0; i < smp_cpus; i++) { PowerPCCPU *cpu; CPUState *cs; - qemu_irq *input; cpu = POWERPC_CPU(object_new(machine->cpu_type)); env = &cpu->env; @@ -885,9 +884,10 @@ void ppce500_init(MachineState *machine) firstenv = env; } - input = (qemu_irq *)env->irq_inputs; - irqs[i].irq[OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; - irqs[i].irq[OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; + irqs[i].irq[OPENPIC_OUTPUT_INT] = + qdev_get_gpio_in(DEVICE(cpu), PPCE500_INPUT_INT); + irqs[i].irq[OPENPIC_OUTPUT_CINT] = + qdev_get_gpio_in(DEVICE(cpu), PPCE500_INPUT_CINT); env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i; env->mpic_iack = pmc->ccsrbar_base + MPC8544_MPIC_REGS_OFFSET + 0xa0; diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 161e5f9087..690f448cb9 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -474,10 +474,7 @@ static void ppce500_set_irq(void *opaque, int pin, int level) void ppce500_irq_init(PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; - - env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq, - cpu, PPCE500_INPUT_NB); + qdev_init_gpio_in(DEVICE(cpu), ppce500_set_irq, PPCE500_INPUT_NB); } /* Enable or Disable the E500 EPR capability */ From 285c471f822a09ceb352e6f73eed42b694173952 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 5 Jul 2022 16:58:14 +0200 Subject: [PATCH 05/30] ppc: Remove unused irq_inputs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Cédric Le Goater Reviewed-by: Peter Maydell Message-Id: <20220705145814.461723-6-clg@kaod.org> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 1 - target/ppc/cpu_init.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 7aaff9dcc5..9b8d001f1c 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1184,7 +1184,6 @@ struct CPUArchState { * by recent Book3s compatible CPUs (POWER7 and newer). */ uint32_t irq_input_state; - void **irq_inputs; target_ulong excp_vectors[POWERPC_EXCP_NB]; /* Exception vectors */ target_ulong excp_prefix; diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 86ad28466a..769031375d 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6678,7 +6678,6 @@ static void init_ppc_proc(PowerPCCPU *cpu) #if !defined(CONFIG_USER_ONLY) int i; - env->irq_inputs = NULL; /* Set all exception vectors to an invalid address */ for (i = 0; i < POWERPC_EXCP_NB; i++) { env->excp_vectors[i] = (target_ulong)(-1ULL); @@ -6808,10 +6807,6 @@ static void init_ppc_proc(PowerPCCPU *cpu) /* Pre-compute some useful values */ env->tlb_per_way = env->nb_tlb / env->nb_ways; } - if (env->irq_inputs == NULL) { - warn_report("no internal IRQ controller registered." - " Attempt QEMU to crash very soon !"); - } #endif if (env->check_pow == NULL) { warn_report("no power management check handler registered." From c4b075318eb1e87de5fc942e6b987694a0e677e1 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Tue, 12 Jul 2022 15:51:14 +0200 Subject: [PATCH 06/30] hw/ppc: pass random seed to fdt If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to initialize early. Set this using the usual guest random number generation function. This is confirmed to successfully initialize the RNG on Linux 5.19-rc6. The rng-seed node is part of the DT spec. Set this on the paravirt platforms, spapr and e500, just as is done on other architectures with paravirt hardware. Cc: Daniel Henrique Barboza Signed-off-by: Jason A. Donenfeld Reviewed-by: Daniel Henrique Barboza Message-Id: <20220712135114.289855-1-Jason@zx2c4.com> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/e500.c | 5 +++++ hw/ppc/spapr.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 757cfaa62f..32495d0123 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -17,6 +17,7 @@ #include "qemu/osdep.h" #include "qemu/datadir.h" #include "qemu/units.h" +#include "qemu/guest-random.h" #include "qapi/error.h" #include "e500.h" #include "e500-ccsr.h" @@ -346,6 +347,7 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, }; const char *dtb_file = machine->dtb; const char *toplevel_compat = machine->dt_compatible; + uint8_t rng_seed[32]; if (dtb_file) { char *filename; @@ -403,6 +405,9 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, if (ret < 0) fprintf(stderr, "couldn't set /chosen/bootargs\n"); + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + qemu_fdt_setprop(fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed)); + if (kvm_enabled()) { /* Read out host's frequencies */ clock_freq = kvmppc_get_clockfreq(); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9a5382d527..3a5112899e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -27,6 +27,7 @@ #include "qemu/osdep.h" #include "qemu/datadir.h" #include "qemu/memalign.h" +#include "qemu/guest-random.h" #include "qapi/error.h" #include "qapi/qapi-events-machine.h" #include "qapi/qapi-events-qdev.h" @@ -1014,6 +1015,7 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset) { MachineState *machine = MACHINE(spapr); SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine); + uint8_t rng_seed[32]; int chosen; _FDT(chosen = fdt_add_subnode(fdt, 0, "chosen")); @@ -1091,6 +1093,9 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset) spapr_dt_ov5_platform_support(spapr, fdt, chosen); } + qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed)); + _FDT(fdt_setprop(fdt, chosen, "rng-seed", rng_seed, sizeof(rng_seed))); + _FDT(spapr_dt_ovec(fdt, chosen, spapr->ov5_cas, "ibm,architecture-vec-5")); } From 1a42c69237a57805b09b50e90878c33100ea2397 Mon Sep 17 00:00:00 2001 From: Murilo Opsfelder Araujo Date: Tue, 12 Jul 2022 18:08:10 -0300 Subject: [PATCH 07/30] target/ppc/kvm: Skip current and parent directories in kvmppc_find_cpu_dt Some systems have /proc/device-tree/cpus/../clock-frequency. However, this is not the expected path for a CPU device tree directory. Signed-off-by: Murilo Opsfelder Araujo Signed-off-by: Fabiano Rosas Reviewed-by: David Gibson Reviewed-by: Daniel Henrique Barboza Message-Id: <20220712210810.35514-1-muriloo@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/kvm.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 6eed466f80..466d0d2f4c 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1877,6 +1877,12 @@ static int kvmppc_find_cpu_dt(char *buf, int buf_len) buf[0] = '\0'; while ((dirp = readdir(dp)) != NULL) { FILE *f; + + /* Don't accidentally read from the current and parent directories */ + if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) { + continue; + } + snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU, dirp->d_name); f = fopen(buf, "r"); From 1315eed69d4810ae297f737b44ee8b63f6589190 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 27 Jun 2022 11:10:59 -0300 Subject: [PATCH 08/30] target/ppc: Fix gen_priv_exception error value in mfspr/mtspr The code in linux-user/ppc/cpu_loop.c expects POWERPC_EXCP_PRIV exception with error POWERPC_EXCP_PRIV_OPC or POWERPC_EXCP_PRIV_REG, while POWERPC_EXCP_INVAL_SPR is expected in POWERPC_EXCP_INVAL exceptions. This mismatch caused an EXCP_DUMP with the message "Unknown privilege violation (03)", as seen in [1]. [1] https://gitlab.com/qemu-project/qemu/-/issues/588 Fixes: 9b2fadda3e01 ("ppc: Rework generation of priv and inval interrupts") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/588 Reviewed-by: Fabiano Rosas Signed-off-by: Matheus Ferst Message-Id: <20220627141104.669152-2-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 1d6daa4608..55f34eb490 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -4789,11 +4789,11 @@ static inline void gen_op_mfspr(DisasContext *ctx) */ if (sprn & 0x10) { if (ctx->pr) { - gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR); + gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); } } else { if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) { - gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR); + gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG); } } } @@ -4976,11 +4976,11 @@ static void gen_mtspr(DisasContext *ctx) */ if (sprn & 0x10) { if (ctx->pr) { - gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR); + gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG); } } else { if (ctx->pr || sprn == 0) { - gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR); + gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG); } } } From efb23674d13f9985510e85f72b1b65a42c367941 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 27 Jun 2022 11:11:00 -0300 Subject: [PATCH 09/30] target/ppc: fix exception error value in slbfee Testing on a POWER9 DD2.3, we observed that the Linux kernel delivers a signal with si_code ILL_PRVOPC (5) when a userspace application tries to use slbfee. To obtain this behavior on linux-user, we should use POWERPC_EXCP_PRIV with POWERPC_EXCP_PRIV_OPC. No functional change is intended for softmmu targets as gen_hvpriv_exception uses the same 'exception' argument (POWERPC_EXCP_HV_EMU) for raise_exception_*, and the powerpc_excp_* methods do not use lower bits of the exception error code when handling POWERPC_EXCP_{INVAL,PRIV}. Reported-by: Laurent Vivier Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20220627141104.669152-3-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 55f34eb490..d7e5670c20 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5386,12 +5386,12 @@ static void gen_slbmfev(DisasContext *ctx) static void gen_slbfee_(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else TCGLabel *l1, *l2; if (unlikely(ctx->pr)) { - gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, From b63fa8b98b2f44669be548d8cd5386e9c990234d Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 27 Jun 2022 11:11:01 -0300 Subject: [PATCH 10/30] target/ppc: remove mfdcrux and mtdcrux The only PowerPC implementations with these insns were the 460 and 460F, which had their definitions removed in [1]. [1] 7ff26aa6c657 ("target/ppc: Remove unused PPC 460 and 460F definitions") Signed-off-by: Matheus Ferst Reviewed-by: Fabiano Rosas Message-Id: <20220627141104.669152-4-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 6 ++---- target/ppc/translate.c | 18 ------------------ 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 9b8d001f1c..a4c893cfad 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2214,8 +2214,6 @@ enum { PPC_DCR = 0x1000000000000000ULL, /* DCR extended accesse */ PPC_DCRX = 0x2000000000000000ULL, - /* user-mode DCR access, implemented in PowerPC 460 */ - PPC_DCRUX = 0x4000000000000000ULL, /* popcntw and popcntd instructions */ PPC_POPCNTWD = 0x8000000000000000ULL, @@ -2239,8 +2237,8 @@ enum { | PPC_405_MAC | PPC_440_SPEC | PPC_BOOKE \ | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \ | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \ - | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \ - | PPC_POPCNTWD | PPC_CILDST) + | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_POPCNTWD \ + | PPC_CILDST) /* extended type values */ diff --git a/target/ppc/translate.c b/target/ppc/translate.c index d7e5670c20..30dd524959 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5907,22 +5907,6 @@ static void gen_mtdcrx(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -/* mfdcrux (PPC 460) : user-mode access to DCR */ -static void gen_mfdcrux(DisasContext *ctx) -{ - gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, - cpu_gpr[rA(ctx->opcode)]); - /* Note: Rc update flag set leads to undefined state of Rc0 */ -} - -/* mtdcrux (PPC 460) : user-mode access to DCR */ -static void gen_mtdcrux(DisasContext *ctx) -{ - gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], - cpu_gpr[rS(ctx->opcode)]); - /* Note: Rc update flag set leads to undefined state of Rc0 */ -} - /* dccci */ static void gen_dccci(DisasContext *ctx) { @@ -6958,8 +6942,6 @@ GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR), GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR), GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX), GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX), -GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX), -GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX), GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON), GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON), GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT), From e89851798597d93554676cfdcbb2f1e0f38cdb68 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 27 Jun 2022 11:11:02 -0300 Subject: [PATCH 11/30] target/ppc: fix exception error code in helper_{load, store}_dcr POWERPC_EXCP_INVAL should only be or-ed with other constants prefixed with POWERPC_EXCP_INVAL_. Also, take the opportunity to move both helpers under #if !defined(CONFIG_USER_ONLY) as the instructions that use them are privileged. No functional change is intended, the lower 4 bits of the error code are ignored by all powerpc_excp_* methods on POWERPC_EXCP_INVAL exceptions. Reported-by: Laurent Vivier Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20220627141104.669152-5-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/timebase_helper.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index ed0641a234..2f112b7de0 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -694,10 +694,10 @@ DEF_HELPER_2(book3s_msgclr, void, env, tl) DEF_HELPER_4(dlmzb, tl, env, tl, tl, i32) #if !defined(CONFIG_USER_ONLY) DEF_HELPER_2(rac, tl, env, tl) -#endif DEF_HELPER_2(load_dcr, tl, env, tl) DEF_HELPER_3(store_dcr, void, env, tl, tl) +#endif DEF_HELPER_2(load_dump_spr, void, env, i32) DEF_HELPER_2(store_dump_spr, void, env, i32) diff --git a/target/ppc/timebase_helper.c b/target/ppc/timebase_helper.c index 86d01d6e4e..b80f56af7e 100644 --- a/target/ppc/timebase_helper.c +++ b/target/ppc/timebase_helper.c @@ -143,7 +143,6 @@ void helper_store_booke_tsr(CPUPPCState *env, target_ulong val) { store_booke_tsr(env, val); } -#endif /*****************************************************************************/ /* Embedded PowerPC specific helpers */ @@ -169,7 +168,7 @@ target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn) (uint32_t)dcrn, (uint32_t)dcrn); raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | - POWERPC_EXCP_PRIV_REG, GETPC()); + POWERPC_EXCP_INVAL_INVAL, GETPC()); } } return val; @@ -192,7 +191,8 @@ void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, target_ulong val) (uint32_t)dcrn, (uint32_t)dcrn); raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | - POWERPC_EXCP_PRIV_REG, GETPC()); + POWERPC_EXCP_INVAL_INVAL, GETPC()); } } } +#endif From c35553b5e727dccfabc074e3658b082d63675dcc Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 27 Jun 2022 11:11:03 -0300 Subject: [PATCH 12/30] target/ppc: fix PMU Group A register read/write exceptions A call to "gen_(hv)priv_exception" should use POWERPC_EXCP_PRIV_* as the 'error' argument instead of POWERPC_EXCP_INVAL_*, and POWERPC_EXCP_FU is an exception type, not an exception error code. To correctly set FSCR[IC], we should raise Facility Unavailable with this exception type and IC value as the error code. Fixes: 565cb1096733 ("target/ppc: add user read/write functions for MMCR0") Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20220627141104.669152-6-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/power8-pmu-regs.c.inc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/target/ppc/power8-pmu-regs.c.inc b/target/ppc/power8-pmu-regs.c.inc index 2bab6cece7..c3cc919ee4 100644 --- a/target/ppc/power8-pmu-regs.c.inc +++ b/target/ppc/power8-pmu-regs.c.inc @@ -22,7 +22,7 @@ static bool spr_groupA_read_allowed(DisasContext *ctx) { if (!ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { - gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); + gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_PMU); return false; } @@ -46,10 +46,10 @@ static bool spr_groupA_write_allowed(DisasContext *ctx) if (ctx->mmcr0_pmcc1) { /* PMCC = 0b01 */ - gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); + gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_PMU); } else { /* PMCC = 0b00 */ - gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR); + gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG); } return false; @@ -214,7 +214,7 @@ void spr_read_PMC56_ureg(DisasContext *ctx, int gprn, int sprn) * Interrupt. */ if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { - gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); + gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_PMU); return; } @@ -249,7 +249,7 @@ void spr_write_PMC56_ureg(DisasContext *ctx, int sprn, int gprn) * Interrupt. */ if (ctx->mmcr0_pmcc0 && ctx->mmcr0_pmcc1) { - gen_hvpriv_exception(ctx, POWERPC_EXCP_FU); + gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_PMU); return; } From 8e1fedf8cef7a11d0cb7d5b23246e1bd5cf02b2a Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 27 Jun 2022 11:11:04 -0300 Subject: [PATCH 13/30] target/ppc: fix exception error code in spr_write_excp_vector The 'error' argument of gen_inval_exception will be or-ed with POWERPC_EXCP_INVAL, so it should always be a constant prefixed with POWERPC_EXCP_INVAL_. No functional change is intended, spr_write_excp_vector is only used by register_BookE_sprs, and powerpc_excp_booke ignores the lower 4 bits of the error code on POWERPC_EXCP_INVAL exceptions. Also, take the opportunity to replace printf with qemu_log_mask. Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20220627141104.669152-7-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 30dd524959..da11472877 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -907,9 +907,9 @@ void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn) } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) { sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38; } else { - printf("Trying to write an unknown exception vector %d %03x\n", - sprn, sprn); - gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + qemu_log_mask(LOG_GUEST_ERROR, "Trying to write an unknown exception" + " vector 0x%03x\n", sprn); + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); return; } From 016b6e1d9c78cd7981b3d9e8f4f3cedd2ba2055a Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 12 Jul 2022 16:37:40 -0300 Subject: [PATCH 14/30] target/ppc: Move tlbie[l] to decode tree Also decode RIC, PRS and R operands. Signed-off-by: Leandro Lupori Reviewed-by: Daniel Henrique Barboza Message-Id: <20220712193741.59134-2-leandro.lupori@eldorado.org.br> [danielhb: mark bit 31 in @X_tlbie pattern as ignored] Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 4 +- target/ppc/insn32.decode | 8 ++ target/ppc/translate.c | 64 +------------- target/ppc/translate/storage-ctrl-impl.c.inc | 87 ++++++++++++++++++++ 4 files changed, 99 insertions(+), 64 deletions(-) create mode 100644 target/ppc/translate/storage-ctrl-impl.c.inc diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 769031375d..4f2355e941 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -6373,7 +6373,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBSYNC | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD | @@ -6591,7 +6591,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | - PPC_MEM_TLBSYNC | + PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD | diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index f7653ef9d5..092e01113f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -856,3 +856,11 @@ VMODSD 000100 ..... ..... ..... 11111001011 @VX VMODUD 000100 ..... ..... ..... 11011001011 @VX VMODSQ 000100 ..... ..... ..... 11100001011 @VX VMODUQ 000100 ..... ..... ..... 11000001011 @VX + +## TLB Management Instructions + +&X_tlbie rb rs ric prs:bool r:bool +@X_tlbie ...... rs:5 - ric:2 prs:1 r:1 rb:5 .......... - &X_tlbie + +TLBIE 011111 ..... - .. . . ..... 0100110010 - @X_tlbie +TLBIEL 011111 ..... - .. . . ..... 0100010010 - @X_tlbie diff --git a/target/ppc/translate.c b/target/ppc/translate.c index da11472877..440ec8a700 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5424,64 +5424,6 @@ static void gen_tlbia(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -/* tlbiel */ -static void gen_tlbiel(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV; -#else - bool psr = (ctx->opcode >> 17) & 0x1; - - if (ctx->pr || (!ctx->hv && !psr && ctx->hr)) { - /* - * tlbiel is privileged except when PSR=0 and HR=1, making it - * hypervisor privileged. - */ - GEN_PRIV; - } - - gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - -/* tlbie */ -static void gen_tlbie(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV; -#else - bool psr = (ctx->opcode >> 17) & 0x1; - TCGv_i32 t1; - - if (ctx->pr) { - /* tlbie is privileged... */ - GEN_PRIV; - } else if (!ctx->hv) { - if (!ctx->gtse || (!psr && ctx->hr)) { - /* - * ... except when GTSE=0 or when PSR=0 and HR=1, making it - * hypervisor privileged. - */ - GEN_PRIV; - } - } - - if (NARROW_MODE(ctx)) { - TCGv t0 = tcg_temp_new(); - tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); - gen_helper_tlbie(cpu_env, t0); - tcg_temp_free(t0); - } else { - gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); - } - t1 = tcg_temp_new_i32(); - tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); - tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH); - tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); - tcg_temp_free_i32(t1); -#endif /* defined(CONFIG_USER_ONLY) */ -} - /* tlbsync */ static void gen_tlbsync(DisasContext *ctx) { @@ -6683,6 +6625,8 @@ static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a) #include "translate/branch-impl.c.inc" +#include "translate/storage-ctrl-impl.c.inc" + /* Handles lfdp */ static void gen_dform39(DisasContext *ctx) { @@ -6921,10 +6865,6 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), * XXX Those instructions will need to be handled differently for * different ISA versions */ -GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE), -GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE), -GEN_HANDLER_E(tlbiel, 0x1F, 0x12, 0x08, 0x00100001, PPC_NONE, PPC2_ISA300), -GEN_HANDLER_E(tlbie, 0x1F, 0x12, 0x09, 0x00100001, PPC_NONE, PPC2_ISA300), GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), #if defined(TARGET_PPC64) GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc new file mode 100644 index 0000000000..7793297dd4 --- /dev/null +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -0,0 +1,87 @@ +/* + * Power ISA decode for Storage Control instructions + * + * Copyright (c) 2022 Instituto de Pesquisas Eldorado (eldorado.org.br) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +/* + * Store Control Instructions + */ + +static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) +{ +#if defined(CONFIG_USER_ONLY) + gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return true; +#else + TCGv_i32 t1; + int rb; + + rb = a->rb; + + if ((ctx->insns_flags2 & PPC2_ISA300) == 0) { + /* + * Before Power ISA 3.0, the corresponding bits of RIC, PRS, and R + * (and RS for tlbiel) were reserved fields and should be ignored. + */ + a->ric = 0; + a->prs = false; + a->r = false; + if (local) { + a->rs = 0; + } + } + + if (ctx->pr) { + /* tlbie[l] is privileged... */ + gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return true; + } else if (!ctx->hv) { + if ((!a->prs && ctx->hr) || (!local && !ctx->gtse)) { + /* + * ... except when PRS=0 and HR=1, or when GTSE=0 for tlbie, + * making it hypervisor privileged. + */ + gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); + return true; + } + } + + if (!local && NARROW_MODE(ctx)) { + TCGv t0 = tcg_temp_new(); + tcg_gen_ext32u_tl(t0, cpu_gpr[rb]); + gen_helper_tlbie(cpu_env, t0); + tcg_temp_free(t0); + } else { + gen_helper_tlbie(cpu_env, cpu_gpr[rb]); + } + + if (local) { + return true; + } + + t1 = tcg_temp_new_i32(); + tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); + tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH); + tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush)); + tcg_temp_free_i32(t1); + + return true; +#endif +} + +TRANS_FLAGS(MEM_TLBIE, TLBIE, do_tlbie, false) +TRANS_FLAGS(MEM_TLBIE, TLBIEL, do_tlbie, true) From e7beaea55bd1efcb554b8e021092a2e79a317b61 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 12 Jul 2022 16:37:41 -0300 Subject: [PATCH 15/30] target/ppc: Implement ISA 3.00 tlbie[l] This initial version supports the invalidation of one or all TLB entries. Flush by PID/LPID, or based in process/partition scope is not supported, because it would make using the generic QEMU TLB implementation hard. In these cases, all entries are flushed. Signed-off-by: Leandro Lupori Reviewed-by: Daniel Henrique Barboza Message-Id: <20220712193741.59134-3-leandro.lupori@eldorado.org.br> [danielhb: moved 'set' declaration to TLBIE_RIC_PWC block] Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 + target/ppc/mmu-book3s-v3.h | 15 ++ target/ppc/mmu_helper.c | 154 +++++++++++++++++++ target/ppc/translate/storage-ctrl-impl.c.inc | 17 ++ 4 files changed, 188 insertions(+) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 2f112b7de0..294ef1396b 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -674,6 +674,8 @@ DEF_HELPER_FLAGS_1(tlbia, TCG_CALL_NO_RWG, void, env) DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl) #if defined(TARGET_PPC64) +DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \ + env, tl, tl, i32) DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(load_slb_esid, tl, env, tl) DEF_HELPER_2(load_slb_vsid, tl, env, tl) diff --git a/target/ppc/mmu-book3s-v3.h b/target/ppc/mmu-book3s-v3.h index d6d5ed8f8e..674377a19e 100644 --- a/target/ppc/mmu-book3s-v3.h +++ b/target/ppc/mmu-book3s-v3.h @@ -50,6 +50,21 @@ struct prtb_entry { #ifdef TARGET_PPC64 +/* + * tlbie[l] helper flags + * + * RIC, PRS, R and local are passed as flags in the last argument. + */ +#define TLBIE_F_RIC_SHIFT 0 +#define TLBIE_F_PRS_SHIFT 2 +#define TLBIE_F_R_SHIFT 3 +#define TLBIE_F_LOCAL_SHIFT 4 + +#define TLBIE_F_RIC_MASK (3 << TLBIE_F_RIC_SHIFT) +#define TLBIE_F_PRS (1 << TLBIE_F_PRS_SHIFT) +#define TLBIE_F_R (1 << TLBIE_F_R_SHIFT) +#define TLBIE_F_LOCAL (1 << TLBIE_F_LOCAL_SHIFT) + static inline bool ppc64_use_proc_tbl(PowerPCCPU *cpu) { return !!(cpu->env.spr[SPR_LPCR] & LPCR_UPRT); diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index 15239dc95b..2a91f3f46a 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -429,6 +429,160 @@ void helper_tlbie(CPUPPCState *env, target_ulong addr) ppc_tlb_invalidate_one(env, addr); } +#if defined(TARGET_PPC64) + +/* Invalidation Selector */ +#define TLBIE_IS_VA 0 +#define TLBIE_IS_PID 1 +#define TLBIE_IS_LPID 2 +#define TLBIE_IS_ALL 3 + +/* Radix Invalidation Control */ +#define TLBIE_RIC_TLB 0 +#define TLBIE_RIC_PWC 1 +#define TLBIE_RIC_ALL 2 +#define TLBIE_RIC_GRP 3 + +/* Radix Actual Page sizes */ +#define TLBIE_R_AP_4K 0 +#define TLBIE_R_AP_64K 5 +#define TLBIE_R_AP_2M 1 +#define TLBIE_R_AP_1G 2 + +/* RB field masks */ +#define TLBIE_RB_EPN_MASK PPC_BITMASK(0, 51) +#define TLBIE_RB_IS_MASK PPC_BITMASK(52, 53) +#define TLBIE_RB_AP_MASK PPC_BITMASK(56, 58) + +void helper_tlbie_isa300(CPUPPCState *env, target_ulong rb, target_ulong rs, + uint32_t flags) +{ + unsigned ric = (flags & TLBIE_F_RIC_MASK) >> TLBIE_F_RIC_SHIFT; + /* + * With the exception of the checks for invalid instruction forms, + * PRS is currently ignored, because we don't know if a given TLB entry + * is process or partition scoped. + */ + bool prs = flags & TLBIE_F_PRS; + bool r = flags & TLBIE_F_R; + bool local = flags & TLBIE_F_LOCAL; + bool effR; + unsigned is = extract64(rb, PPC_BIT_NR(53), 2); + unsigned ap; /* actual page size */ + target_ulong addr, pgoffs_mask; + + qemu_log_mask(CPU_LOG_MMU, + "%s: local=%d addr=" TARGET_FMT_lx " ric=%u prs=%d r=%d is=%u\n", + __func__, local, rb & TARGET_PAGE_MASK, ric, prs, r, is); + + effR = FIELD_EX64(env->msr, MSR, HV) ? r : env->spr[SPR_LPCR] & LPCR_HR; + + /* Partial TLB invalidation is supported for Radix only for now. */ + if (!effR) { + goto inval_all; + } + + /* Check for invalid instruction forms (effR=1). */ + if (unlikely(ric == TLBIE_RIC_GRP || + ((ric == TLBIE_RIC_PWC || ric == TLBIE_RIC_ALL) && + is == TLBIE_IS_VA) || + (!prs && is == TLBIE_IS_PID))) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid instruction form: ric=%u prs=%d r=%d is=%u\n", + __func__, ric, prs, r, is); + goto invalid; + } + + /* We don't cache Page Walks. */ + if (ric == TLBIE_RIC_PWC) { + if (local) { + unsigned set = extract64(rb, PPC_BIT_NR(51), 12); + if (set != 0) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid set: %d\n", + __func__, set); + goto invalid; + } + } + return; + } + + /* + * Invalidation by LPID or PID is not supported, so fallback + * to full TLB flush in these cases. + */ + if (is != TLBIE_IS_VA) { + goto inval_all; + } + + /* + * The results of an attempt to invalidate a translation outside of + * quadrant 0 for Radix Tree translation (effR=1, RIC=0, PRS=1, IS=0, + * and EA 0:1 != 0b00) are boundedly undefined. + */ + if (unlikely(ric == TLBIE_RIC_TLB && prs && is == TLBIE_IS_VA && + (rb & R_EADDR_QUADRANT) != R_EADDR_QUADRANT0)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: attempt to invalidate a translation outside of quadrant 0\n", + __func__); + goto inval_all; + } + + assert(is == TLBIE_IS_VA); + assert(ric == TLBIE_RIC_TLB || ric == TLBIE_RIC_ALL); + + ap = extract64(rb, PPC_BIT_NR(58), 3); + switch (ap) { + case TLBIE_R_AP_4K: + pgoffs_mask = 0xfffull; + break; + + case TLBIE_R_AP_64K: + pgoffs_mask = 0xffffull; + break; + + case TLBIE_R_AP_2M: + pgoffs_mask = 0x1fffffull; + break; + + case TLBIE_R_AP_1G: + pgoffs_mask = 0x3fffffffull; + break; + + default: + /* + * If the value specified in RS 0:31, RS 32:63, RB 54:55, RB 56:58, + * RB 44:51, or RB 56:63, when it is needed to perform the specified + * operation, is not supported by the implementation, the instruction + * is treated as if the instruction form were invalid. + */ + qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid AP: %d\n", __func__, ap); + goto invalid; + } + + addr = rb & TLBIE_RB_EPN_MASK & ~pgoffs_mask; + + if (local) { + tlb_flush_page(env_cpu(env), addr); + } else { + tlb_flush_page_all_cpus(env_cpu(env), addr); + } + return; + +inval_all: + env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; + if (!local) { + env->tlb_need_flush |= TLB_NEED_GLOBAL_FLUSH; + } + return; + +invalid: + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, + POWERPC_EXCP_INVAL | + POWERPC_EXCP_INVAL_INVAL, GETPC()); +} + +#endif + void helper_tlbiva(CPUPPCState *env, target_ulong addr) { /* tlbiva instruction only exists on BookE */ diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index 7793297dd4..467c390888 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -21,6 +21,8 @@ * Store Control Instructions */ +#include "mmu-book3s-v3.h" + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) @@ -65,6 +67,21 @@ static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) tcg_gen_ext32u_tl(t0, cpu_gpr[rb]); gen_helper_tlbie(cpu_env, t0); tcg_temp_free(t0); + +#if defined(TARGET_PPC64) + /* + * ISA 3.1B says that MSR SF must be 1 when this instruction is executed; + * otherwise the results are undefined. + */ + } else if (a->r) { + gen_helper_tlbie_isa300(cpu_env, cpu_gpr[rb], cpu_gpr[a->rs], + tcg_constant_i32(a->ric << TLBIE_F_RIC_SHIFT | + a->prs << TLBIE_F_PRS_SHIFT | + a->r << TLBIE_F_R_SHIFT | + local << TLBIE_F_LOCAL_SHIFT)); + return true; +#endif + } else { gen_helper_tlbie(cpu_env, cpu_gpr[rb]); } From 9f0cf041975f76720681b218f217eb23333c7c1a Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Fri, 1 Jul 2022 10:34:57 -0300 Subject: [PATCH 16/30] target/ppc: receive DisasContext explicitly in GEN_PRIV GEN_PRIV and related CHK_* macros just assumed that variable named "ctx" would be in scope when they are used, and that it would be a pointer to DisasContext. Change these macros to receive the pointer explicitly. Reviewed-by: Leandro Lupori Signed-off-by: Matheus Ferst Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-2-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 299 +++++++++++++++-------------- target/ppc/translate/fp-impl.c.inc | 4 +- 2 files changed, 154 insertions(+), 149 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 440ec8a700..8afc2e4691 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -1267,38 +1267,43 @@ typedef struct opcode_t { const char *oname; } opcode_t; +static void gen_priv_opc(DisasContext *ctx) +{ + gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); +} + /* Helpers for priv. check */ -#define GEN_PRIV \ - do { \ - gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \ +#define GEN_PRIV(CTX) \ + do { \ + gen_priv_opc(CTX); return; \ } while (0) #if defined(CONFIG_USER_ONLY) -#define CHK_HV GEN_PRIV -#define CHK_SV GEN_PRIV -#define CHK_HVRM GEN_PRIV +#define CHK_HV(CTX) GEN_PRIV(CTX) +#define CHK_SV(CTX) GEN_PRIV(CTX) +#define CHK_HVRM(CTX) GEN_PRIV(CTX) #else -#define CHK_HV \ - do { \ - if (unlikely(ctx->pr || !ctx->hv)) { \ - GEN_PRIV; \ - } \ +#define CHK_HV(CTX) \ + do { \ + if (unlikely(ctx->pr || !ctx->hv)) {\ + GEN_PRIV(CTX); \ + } \ } while (0) -#define CHK_SV \ +#define CHK_SV(CTX) \ do { \ if (unlikely(ctx->pr)) { \ - GEN_PRIV; \ + GEN_PRIV(CTX); \ } \ } while (0) -#define CHK_HVRM \ - do { \ - if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \ - GEN_PRIV; \ - } \ +#define CHK_HVRM(CTX) \ + do { \ + if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \ + GEN_PRIV(CTX); \ + } \ } while (0) #endif -#define CHK_NONE +#define CHK_NONE(CTX) /*****************************************************************************/ /* PowerPC instructions table */ @@ -3252,7 +3257,7 @@ GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_UQ)) static void glue(gen_, name##x)(DisasContext *ctx) \ { \ TCGv EA; \ - chk; \ + chk(ctx); \ gen_set_access_type(ctx, ACCESS_INT); \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ @@ -3270,7 +3275,7 @@ static void glue(gen_, name##x)(DisasContext *ctx) \ static void glue(gen_, name##epx)(DisasContext *ctx) \ { \ TCGv EA; \ - CHK_SV; \ + CHK_SV(ctx); \ gen_set_access_type(ctx, ACCESS_INT); \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ @@ -3298,7 +3303,7 @@ GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST) static void glue(gen_, name##x)(DisasContext *ctx) \ { \ TCGv EA; \ - chk; \ + chk(ctx); \ gen_set_access_type(ctx, ACCESS_INT); \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ @@ -3315,7 +3320,7 @@ static void glue(gen_, name##x)(DisasContext *ctx) \ static void glue(gen_, name##epx)(DisasContext *ctx) \ { \ TCGv EA; \ - CHK_SV; \ + CHK_SV(ctx); \ gen_set_access_type(ctx, ACCESS_INT); \ EA = tcg_temp_new(); \ gen_addr_reg_index(ctx, EA); \ @@ -4078,11 +4083,11 @@ static void gen_wait(DisasContext *ctx) static void gen_doze(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv_i32 t; - CHK_HV; + CHK_HV(ctx); t = tcg_const_i32(PPC_PM_DOZE); gen_helper_pminsn(cpu_env, t); tcg_temp_free_i32(t); @@ -4094,11 +4099,11 @@ static void gen_doze(DisasContext *ctx) static void gen_nap(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv_i32 t; - CHK_HV; + CHK_HV(ctx); t = tcg_const_i32(PPC_PM_NAP); gen_helper_pminsn(cpu_env, t); tcg_temp_free_i32(t); @@ -4110,11 +4115,11 @@ static void gen_nap(DisasContext *ctx) static void gen_stop(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv_i32 t; - CHK_HV; + CHK_HV(ctx); t = tcg_const_i32(PPC_PM_STOP); gen_helper_pminsn(cpu_env, t); tcg_temp_free_i32(t); @@ -4126,11 +4131,11 @@ static void gen_stop(DisasContext *ctx) static void gen_sleep(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv_i32 t; - CHK_HV; + CHK_HV(ctx); t = tcg_const_i32(PPC_PM_SLEEP); gen_helper_pminsn(cpu_env, t); tcg_temp_free_i32(t); @@ -4142,11 +4147,11 @@ static void gen_sleep(DisasContext *ctx) static void gen_rvwinkle(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv_i32 t; - CHK_HV; + CHK_HV(ctx); t = tcg_const_i32(PPC_PM_RVWINKLE); gen_helper_pminsn(cpu_env, t); tcg_temp_free_i32(t); @@ -4476,7 +4481,7 @@ static void gen_mcrf(DisasContext *ctx) static void gen_rfi(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else /* * This instruction doesn't exist anymore on 64-bit server @@ -4487,7 +4492,7 @@ static void gen_rfi(DisasContext *ctx) return; } /* Restore CPU state */ - CHK_SV; + CHK_SV(ctx); gen_icount_io_start(ctx); gen_update_cfar(ctx, ctx->cia); gen_helper_rfi(cpu_env); @@ -4499,10 +4504,10 @@ static void gen_rfi(DisasContext *ctx) static void gen_rfid(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else /* Restore CPU state */ - CHK_SV; + CHK_SV(ctx); gen_icount_io_start(ctx); gen_update_cfar(ctx, ctx->cia); gen_helper_rfid(cpu_env); @@ -4514,10 +4519,10 @@ static void gen_rfid(DisasContext *ctx) static void gen_rfscv(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else /* Restore CPU state */ - CHK_SV; + CHK_SV(ctx); gen_icount_io_start(ctx); gen_update_cfar(ctx, ctx->cia); gen_helper_rfscv(cpu_env); @@ -4529,10 +4534,10 @@ static void gen_rfscv(DisasContext *ctx) static void gen_hrfid(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else /* Restore CPU state */ - CHK_HV; + CHK_HV(ctx); gen_helper_hrfid(cpu_env); ctx->base.is_jmp = DISAS_EXIT; #endif @@ -4733,7 +4738,7 @@ static void gen_mfcr(DisasContext *ctx) /* mfmsr */ static void gen_mfmsr(DisasContext *ctx) { - CHK_SV; + CHK_SV(ctx); tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr); } @@ -4847,7 +4852,7 @@ static void gen_mtmsrd(DisasContext *ctx) return; } - CHK_SV; + CHK_SV(ctx); #if !defined(CONFIG_USER_ONLY) TCGv t0, t1; @@ -4890,7 +4895,7 @@ static void gen_mtmsrd(DisasContext *ctx) static void gen_mtmsr(DisasContext *ctx) { - CHK_SV; + CHK_SV(ctx); #if !defined(CONFIG_USER_ONLY) TCGv t0, t1; @@ -5022,7 +5027,7 @@ static void gen_dcbfep(DisasContext *ctx) { /* XXX: specification says this is treated as a load by the MMU */ TCGv t0; - CHK_SV; + CHK_SV(ctx); gen_set_access_type(ctx, ACCESS_CACHE); t0 = tcg_temp_new(); gen_addr_reg_index(ctx, t0); @@ -5034,11 +5039,11 @@ static void gen_dcbfep(DisasContext *ctx) static void gen_dcbi(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv EA, val; - CHK_SV; + CHK_SV(ctx); EA = tcg_temp_new(); gen_set_access_type(ctx, ACCESS_CACHE); gen_addr_reg_index(ctx, EA); @@ -5223,11 +5228,11 @@ static void gen_dcba(DisasContext *ctx) static void gen_mfsr(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_const_tl(SR(ctx->opcode)); gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); tcg_temp_free(t0); @@ -5238,11 +5243,11 @@ static void gen_mfsr(DisasContext *ctx) static void gen_mfsrin(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); @@ -5254,11 +5259,11 @@ static void gen_mfsrin(DisasContext *ctx) static void gen_mtsr(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_const_tl(SR(ctx->opcode)); gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]); tcg_temp_free(t0); @@ -5269,10 +5274,10 @@ static void gen_mtsr(DisasContext *ctx) static void gen_mtsrin(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); @@ -5288,11 +5293,11 @@ static void gen_mtsrin(DisasContext *ctx) static void gen_mfsr_64b(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_const_tl(SR(ctx->opcode)); gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); tcg_temp_free(t0); @@ -5303,11 +5308,11 @@ static void gen_mfsr_64b(DisasContext *ctx) static void gen_mfsrin_64b(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); @@ -5319,11 +5324,11 @@ static void gen_mfsrin_64b(DisasContext *ctx) static void gen_mtsr_64b(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_const_tl(SR(ctx->opcode)); gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]); tcg_temp_free(t0); @@ -5334,11 +5339,11 @@ static void gen_mtsr_64b(DisasContext *ctx) static void gen_mtsrin_64b(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4); gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]); @@ -5350,9 +5355,9 @@ static void gen_mtsrin_64b(DisasContext *ctx) static void gen_slbmte(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); @@ -5362,9 +5367,9 @@ static void gen_slbmte(DisasContext *ctx) static void gen_slbmfee(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env, cpu_gpr[rB(ctx->opcode)]); @@ -5374,9 +5379,9 @@ static void gen_slbmfee(DisasContext *ctx) static void gen_slbmfev(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, cpu_gpr[rB(ctx->opcode)]); @@ -5416,9 +5421,9 @@ static void gen_slbfee_(DisasContext *ctx) static void gen_tlbia(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_HV; + CHK_HV(ctx); gen_helper_tlbia(cpu_env); #endif /* defined(CONFIG_USER_ONLY) */ @@ -5428,13 +5433,13 @@ static void gen_tlbia(DisasContext *ctx) static void gen_tlbsync(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else if (ctx->gtse) { - CHK_SV; /* If gtse is set then tlbsync is supervisor privileged */ + CHK_SV(ctx); /* If gtse is set then tlbsync is supervisor privileged */ } else { - CHK_HV; /* Else hypervisor privileged */ + CHK_HV(ctx); /* Else hypervisor privileged */ } /* BookS does both ptesync and tlbsync make tlbsync a nop for server */ @@ -5449,12 +5454,12 @@ static void gen_tlbsync(DisasContext *ctx) static void gen_slbia(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else uint32_t ih = (ctx->opcode >> 21) & 0x7; TCGv_i32 t0 = tcg_const_i32(ih); - CHK_SV; + CHK_SV(ctx); gen_helper_slbia(cpu_env, t0); tcg_temp_free_i32(t0); @@ -5465,9 +5470,9 @@ static void gen_slbia(DisasContext *ctx) static void gen_slbie(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif /* defined(CONFIG_USER_ONLY) */ @@ -5477,9 +5482,9 @@ static void gen_slbie(DisasContext *ctx) static void gen_slbieg(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_slbieg(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif /* defined(CONFIG_USER_ONLY) */ @@ -5489,9 +5494,9 @@ static void gen_slbieg(DisasContext *ctx) static void gen_slbsync(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_check_tlb_flush(ctx, true); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -5533,9 +5538,9 @@ static void gen_ecowx(DisasContext *ctx) static void gen_tlbld_6xx(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -5544,9 +5549,9 @@ static void gen_tlbld_6xx(DisasContext *ctx) static void gen_tlbli_6xx(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -5564,11 +5569,11 @@ static void gen_mfapidi(DisasContext *ctx) static void gen_tlbiva(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); gen_addr_reg_index(ctx, t0); gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]); @@ -5795,11 +5800,11 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C); static void gen_mfdcr(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv dcrn; - CHK_SV; + CHK_SV(ctx); dcrn = tcg_const_tl(SPR(ctx->opcode)); gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn); tcg_temp_free(dcrn); @@ -5810,11 +5815,11 @@ static void gen_mfdcr(DisasContext *ctx) static void gen_mtdcr(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv dcrn; - CHK_SV; + CHK_SV(ctx); dcrn = tcg_const_tl(SPR(ctx->opcode)); gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]); tcg_temp_free(dcrn); @@ -5826,9 +5831,9 @@ static void gen_mtdcr(DisasContext *ctx) static void gen_mfdcrx(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)]); /* Note: Rc update flag set leads to undefined state of Rc0 */ @@ -5840,9 +5845,9 @@ static void gen_mfdcrx(DisasContext *ctx) static void gen_mtdcrx(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); /* Note: Rc update flag set leads to undefined state of Rc0 */ @@ -5852,7 +5857,7 @@ static void gen_mtdcrx(DisasContext *ctx) /* dccci */ static void gen_dccci(DisasContext *ctx) { - CHK_SV; + CHK_SV(ctx); /* interpreted as no-op */ } @@ -5860,11 +5865,11 @@ static void gen_dccci(DisasContext *ctx) static void gen_dcread(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv EA, val; - CHK_SV; + CHK_SV(ctx); gen_set_access_type(ctx, ACCESS_CACHE); EA = tcg_temp_new(); gen_addr_reg_index(ctx, EA); @@ -5889,14 +5894,14 @@ static void gen_icbt_40x(DisasContext *ctx) /* iccci */ static void gen_iccci(DisasContext *ctx) { - CHK_SV; + CHK_SV(ctx); /* interpreted as no-op */ } /* icread */ static void gen_icread(DisasContext *ctx) { - CHK_SV; + CHK_SV(ctx); /* interpreted as no-op */ } @@ -5904,9 +5909,9 @@ static void gen_icread(DisasContext *ctx) static void gen_rfci_40x(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); /* Restore CPU state */ gen_helper_40x_rfci(cpu_env); ctx->base.is_jmp = DISAS_EXIT; @@ -5916,9 +5921,9 @@ static void gen_rfci_40x(DisasContext *ctx) static void gen_rfci(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); /* Restore CPU state */ gen_helper_rfci(cpu_env); ctx->base.is_jmp = DISAS_EXIT; @@ -5931,9 +5936,9 @@ static void gen_rfci(DisasContext *ctx) static void gen_rfdi(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); /* Restore CPU state */ gen_helper_rfdi(cpu_env); ctx->base.is_jmp = DISAS_EXIT; @@ -5944,9 +5949,9 @@ static void gen_rfdi(DisasContext *ctx) static void gen_rfmci(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); /* Restore CPU state */ gen_helper_rfmci(cpu_env); ctx->base.is_jmp = DISAS_EXIT; @@ -5959,9 +5964,9 @@ static void gen_rfmci(DisasContext *ctx) static void gen_tlbre_40x(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); switch (rB(ctx->opcode)) { case 0: gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env, @@ -5982,11 +5987,11 @@ static void gen_tlbre_40x(DisasContext *ctx) static void gen_tlbsx_40x(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); gen_addr_reg_index(ctx, t0); gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); @@ -6005,9 +6010,9 @@ static void gen_tlbsx_40x(DisasContext *ctx) static void gen_tlbwe_40x(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); switch (rB(ctx->opcode)) { case 0: @@ -6031,9 +6036,9 @@ static void gen_tlbwe_40x(DisasContext *ctx) static void gen_tlbre_440(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); switch (rB(ctx->opcode)) { case 0: @@ -6057,11 +6062,11 @@ static void gen_tlbre_440(DisasContext *ctx) static void gen_tlbsx_440(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); gen_addr_reg_index(ctx, t0); gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0); @@ -6080,9 +6085,9 @@ static void gen_tlbsx_440(DisasContext *ctx) static void gen_tlbwe_440(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); switch (rB(ctx->opcode)) { case 0: case 1: @@ -6107,9 +6112,9 @@ static void gen_tlbwe_440(DisasContext *ctx) static void gen_tlbre_booke206(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_booke206_tlbre(cpu_env); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -6118,11 +6123,11 @@ static void gen_tlbre_booke206(DisasContext *ctx) static void gen_tlbsx_booke206(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); if (rA(ctx->opcode)) { t0 = tcg_temp_new(); tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]); @@ -6140,9 +6145,9 @@ static void gen_tlbsx_booke206(DisasContext *ctx) static void gen_tlbwe_booke206(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_booke206_tlbwe(cpu_env); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -6150,11 +6155,11 @@ static void gen_tlbwe_booke206(DisasContext *ctx) static void gen_tlbivax_booke206(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); gen_addr_reg_index(ctx, t0); gen_helper_booke206_tlbivax(cpu_env, t0); @@ -6165,11 +6170,11 @@ static void gen_tlbivax_booke206(DisasContext *ctx) static void gen_tlbilx_booke206(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); gen_addr_reg_index(ctx, t0); @@ -6197,11 +6202,11 @@ static void gen_tlbilx_booke206(DisasContext *ctx) static void gen_wrtee(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else TCGv t0; - CHK_SV; + CHK_SV(ctx); t0 = tcg_temp_new(); tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE)); tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE)); @@ -6219,9 +6224,9 @@ static void gen_wrtee(DisasContext *ctx) static void gen_wrteei(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); if (ctx->opcode & 0x00008000) { tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); /* Stop translation to have a chance to raise an exception */ @@ -6275,9 +6280,9 @@ static void gen_icbt_440(DisasContext *ctx) static void gen_msgclr(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_HV; + CHK_HV(ctx); if (is_book3s_arch2x(ctx)) { gen_helper_book3s_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]); } else { @@ -6289,9 +6294,9 @@ static void gen_msgclr(DisasContext *ctx) static void gen_msgsnd(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_HV; + CHK_HV(ctx); if (is_book3s_arch2x(ctx)) { gen_helper_book3s_msgsnd(cpu_gpr[rB(ctx->opcode)]); } else { @@ -6304,9 +6309,9 @@ static void gen_msgsnd(DisasContext *ctx) static void gen_msgclrp(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_book3s_msgclrp(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -6314,9 +6319,9 @@ static void gen_msgclrp(DisasContext *ctx) static void gen_msgsndp(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_SV; + CHK_SV(ctx); gen_helper_book3s_msgsndp(cpu_env, cpu_gpr[rB(ctx->opcode)]); #endif /* defined(CONFIG_USER_ONLY) */ } @@ -6325,9 +6330,9 @@ static void gen_msgsndp(DisasContext *ctx) static void gen_msgsync(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) - GEN_PRIV; + GEN_PRIV(ctx); #else - CHK_HV; + CHK_HV(ctx); #endif /* defined(CONFIG_USER_ONLY) */ /* interpreted as no-op */ } @@ -6438,7 +6443,7 @@ static void gen_tcheck(DisasContext *ctx) #define GEN_TM_PRIV_NOOP(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ - gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); \ + gen_priv_opc(ctx); \ } #else @@ -6446,7 +6451,7 @@ static inline void gen_##name(DisasContext *ctx) \ #define GEN_TM_PRIV_NOOP(name) \ static inline void gen_##name(DisasContext *ctx) \ { \ - CHK_SV; \ + CHK_SV(ctx); \ if (unlikely(!ctx->tm_enabled)) { \ gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \ return; \ diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index 319513d001..0e893eafa7 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -901,7 +901,7 @@ static void gen_lfdepx(DisasContext *ctx) { TCGv EA; TCGv_i64 t0; - CHK_SV; + CHK_SV(ctx); if (unlikely(!ctx->fpu_enabled)) { gen_exception(ctx, POWERPC_EXCP_FPU); return; @@ -1058,7 +1058,7 @@ static void gen_stfdepx(DisasContext *ctx) { TCGv EA; TCGv_i64 t0; - CHK_SV; + CHK_SV(ctx); if (unlikely(!ctx->fpu_enabled)) { gen_exception(ctx, POWERPC_EXCP_FPU); return; From fc34e81acd5163ea39eee191ec8846c299ca2662 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Fri, 1 Jul 2022 10:34:58 -0300 Subject: [PATCH 17/30] target/ppc: add macros to check privilege level Equivalent to CHK_SV and CHK_HV, but can be used in decodetree methods. Reviewed-by: Leandro Lupori Signed-off-by: Matheus Ferst Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-3-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/translate.c | 21 +++++++++++++++++++++ target/ppc/translate/fixedpoint-impl.c.inc | 7 ++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 8afc2e4691..e373c39fc8 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6559,6 +6559,27 @@ static int times_16(DisasContext *ctx, int x) } \ } while (0) +#if !defined(CONFIG_USER_ONLY) +#define REQUIRE_SV(CTX) \ + do { \ + if (unlikely((CTX)->pr)) { \ + gen_priv_opc(CTX); \ + return true; \ + } \ + } while (0) + +#define REQUIRE_HV(CTX) \ + do { \ + if (unlikely((CTX)->pr || !(CTX)->hv)) \ + gen_priv_opc(CTX); \ + return true; \ + } \ + } while (0) +#else +#define REQUIRE_SV(CTX) do { gen_priv_opc(CTX); return true; } while (0) +#define REQUIRE_HV(CTX) do { gen_priv_opc(CTX); return true; } while (0) +#endif + /* * Helpers for implementing sets of trans_* functions. * Defer the implementation of NAME to FUNC, with optional extra arguments. diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index cb0097bedb..db14d3bebc 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -79,11 +79,8 @@ static bool do_ldst_quad(DisasContext *ctx, arg_D *a, bool store, bool prefixed) REQUIRE_INSNS_FLAGS(ctx, 64BX); if (!prefixed && !(ctx->insns_flags2 & PPC2_LSQ_ISA207)) { - if (ctx->pr) { - /* lq and stq were privileged prior to V. 2.07 */ - gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); - return true; - } + /* lq and stq were privileged prior to V. 2.07 */ + REQUIRE_SV(ctx); if (ctx->le_mode) { gen_align_no_le(ctx); From 43507e47e14e92e4460fdd29cf9f3798b401589f Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:34:59 -0300 Subject: [PATCH 18/30] target/ppc: Move slbie to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-4-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 7 +++++++ target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 13 ------------- target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 294ef1396b..7c93037257 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -681,7 +681,7 @@ DEF_HELPER_2(load_slb_esid, tl, env, tl) DEF_HELPER_2(load_slb_vsid, tl, env, tl) DEF_HELPER_2(find_slb_vsid, tl, env, tl) DEF_HELPER_FLAGS_2(slbia, TCG_CALL_NO_RWG, void, env, i32) -DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl) +DEF_HELPER_FLAGS_2(SLBIE, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(slbieg, TCG_CALL_NO_RWG, void, env, tl) #endif DEF_HELPER_FLAGS_2(load_sr, TCG_CALL_NO_RWG, tl, env, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 092e01113f..0fe6c33805 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -146,6 +146,9 @@ &X_imm8 xt imm:uint8_t @X_imm8 ...... ..... .. imm:8 .......... . &X_imm8 xt=%x_xt +&X_rb rb +@X_rb ...... ..... ..... rb:5 .......... . &X_rb + &X_uim5 xt uim:uint8_t @X_uim5 ...... ..... ..... uim:5 .......... . &X_uim5 xt=%x_xt @@ -857,6 +860,10 @@ VMODUD 000100 ..... ..... ..... 11011001011 @VX VMODSQ 000100 ..... ..... ..... 11100001011 @VX VMODUQ 000100 ..... ..... ..... 11000001011 @VX +## SLB Management Instructions + +SLBIE 011111 ----- ----- ..... 0110110010 - @X_rb + ## TLB Management Instructions &X_tlbie rb rs ric prs:bool r:bool diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index da9fe99ff8..03f71a82ec 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -197,7 +197,7 @@ static void __helper_slbie(CPUPPCState *env, target_ulong addr, } } -void helper_slbie(CPUPPCState *env, target_ulong addr) +void helper_SLBIE(CPUPPCState *env, target_ulong addr) { __helper_slbie(env, addr, false); } diff --git a/target/ppc/translate.c b/target/ppc/translate.c index e373c39fc8..244eefd965 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5466,18 +5466,6 @@ static void gen_slbia(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -/* slbie */ -static void gen_slbie(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - - gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - /* slbieg */ static void gen_slbieg(DisasContext *ctx) { @@ -6894,7 +6882,6 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), #if defined(TARGET_PPC64) GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI), -GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI), GEN_HANDLER_E(slbieg, 0x1F, 0x12, 0x0E, 0x001F0001, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300), #endif diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index 467c390888..3fa64be067 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -23,6 +23,20 @@ #include "mmu-book3s-v3.h" +static bool trans_SLBIE(DisasContext *ctx, arg_SLBIE *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS(ctx, SLBI); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBIE(cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From a1b05c06255c2136bd4076017c48546035a8cb40 Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:00 -0300 Subject: [PATCH 19/30] target/ppc: Move slbieg to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-5-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 1 + target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 13 ------------- target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 7c93037257..e5e59d1924 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -682,7 +682,7 @@ DEF_HELPER_2(load_slb_vsid, tl, env, tl) DEF_HELPER_2(find_slb_vsid, tl, env, tl) DEF_HELPER_FLAGS_2(slbia, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_FLAGS_2(SLBIE, TCG_CALL_NO_RWG, void, env, tl) -DEF_HELPER_FLAGS_2(slbieg, TCG_CALL_NO_RWG, void, env, tl) +DEF_HELPER_FLAGS_2(SLBIEG, TCG_CALL_NO_RWG, void, env, tl) #endif DEF_HELPER_FLAGS_2(load_sr, TCG_CALL_NO_RWG, tl, env, tl) DEF_HELPER_FLAGS_3(store_sr, TCG_CALL_NO_RWG, void, env, tl, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 0fe6c33805..9df73ce30f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -863,6 +863,7 @@ VMODUQ 000100 ..... ..... ..... 11000001011 @VX ## SLB Management Instructions SLBIE 011111 ----- ----- ..... 0110110010 - @X_rb +SLBIEG 011111 ..... ----- ..... 0111010010 - @X_tb ## TLB Management Instructions diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 03f71a82ec..a842fbd6f6 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -202,7 +202,7 @@ void helper_SLBIE(CPUPPCState *env, target_ulong addr) __helper_slbie(env, addr, false); } -void helper_slbieg(CPUPPCState *env, target_ulong addr) +void helper_SLBIEG(CPUPPCState *env, target_ulong addr) { __helper_slbie(env, addr, true); } diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 244eefd965..591b6dc817 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5466,18 +5466,6 @@ static void gen_slbia(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -/* slbieg */ -static void gen_slbieg(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - - gen_helper_slbieg(cpu_env, cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - /* slbsync */ static void gen_slbsync(DisasContext *ctx) { @@ -6882,7 +6870,6 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), #if defined(TARGET_PPC64) GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI), -GEN_HANDLER_E(slbieg, 0x1F, 0x12, 0x0E, 0x001F0001, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300), #endif GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index 3fa64be067..d699a370f5 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -37,6 +37,20 @@ static bool trans_SLBIE(DisasContext *ctx, arg_SLBIE *a) return true; } +static bool trans_SLBIEG(DisasContext *ctx, arg_SLBIEG *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBIEG(cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From 2bfcb7a3160878ca04f2e49d85854c56974194a5 Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:01 -0300 Subject: [PATCH 20/30] target/ppc: Move slbia to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-6-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 5 +++++ target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 17 ----------------- target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index e5e59d1924..c243d9550a 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -680,7 +680,7 @@ DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(load_slb_esid, tl, env, tl) DEF_HELPER_2(load_slb_vsid, tl, env, tl) DEF_HELPER_2(find_slb_vsid, tl, env, tl) -DEF_HELPER_FLAGS_2(slbia, TCG_CALL_NO_RWG, void, env, i32) +DEF_HELPER_FLAGS_2(SLBIA, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_FLAGS_2(SLBIE, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(SLBIEG, TCG_CALL_NO_RWG, void, env, tl) #endif diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 9df73ce30f..0e214b359c 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -146,6 +146,9 @@ &X_imm8 xt imm:uint8_t @X_imm8 ...... ..... .. imm:8 .......... . &X_imm8 xt=%x_xt +&X_ih ih:uint8_t +@X_ih ...... .. ih:3 ..... ..... .......... . &X_ih + &X_rb rb @X_rb ...... ..... ..... rb:5 .......... . &X_rb @@ -865,6 +868,8 @@ VMODUQ 000100 ..... ..... ..... 11000001011 @VX SLBIE 011111 ----- ----- ..... 0110110010 - @X_rb SLBIEG 011111 ..... ----- ..... 0111010010 - @X_tb +SLBIA 011111 --... ----- ----- 0111110010 - @X_ih + ## TLB Management Instructions &X_tlbie rb rs ric prs:bool r:bool diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index a842fbd6f6..dd2c7e588f 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -101,7 +101,7 @@ void dump_slb(PowerPCCPU *cpu) } #ifdef CONFIG_TCG -void helper_slbia(CPUPPCState *env, uint32_t ih) +void helper_SLBIA(CPUPPCState *env, uint32_t ih) { PowerPCCPU *cpu = env_archcpu(env); int starting_entry; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 591b6dc817..4435865388 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5450,22 +5450,6 @@ static void gen_tlbsync(DisasContext *ctx) } #if defined(TARGET_PPC64) -/* slbia */ -static void gen_slbia(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - uint32_t ih = (ctx->opcode >> 21) & 0x7; - TCGv_i32 t0 = tcg_const_i32(ih); - - CHK_SV(ctx); - - gen_helper_slbia(cpu_env, t0); - tcg_temp_free_i32(t0); -#endif /* defined(CONFIG_USER_ONLY) */ -} - /* slbsync */ static void gen_slbsync(DisasContext *ctx) { @@ -6869,7 +6853,6 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), */ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), #if defined(TARGET_PPC64) -GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI), GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300), #endif GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index d699a370f5..c454ce8c7f 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -51,6 +51,20 @@ static bool trans_SLBIEG(DisasContext *ctx, arg_SLBIEG *a) return true; } +static bool trans_SLBIA(DisasContext *ctx, arg_SLBIA *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS(ctx, SLBI); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBIA(cpu_env, tcg_constant_i32(a->ih)); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From 0b0ba40fd227be94dec2372df6f6e029e496a0e3 Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:02 -0300 Subject: [PATCH 21/30] target/ppc: Move slbmte to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-7-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 2 ++ target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 14 -------------- target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index c243d9550a..98d6c40ac0 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -676,7 +676,7 @@ DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \ env, tl, tl, i32) -DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl) +DEF_HELPER_FLAGS_3(SLBMTE, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(load_slb_esid, tl, env, tl) DEF_HELPER_2(load_slb_vsid, tl, env, tl) DEF_HELPER_2(find_slb_vsid, tl, env, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 0e214b359c..2fc6e9cb27 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -870,6 +870,8 @@ SLBIEG 011111 ..... ----- ..... 0111010010 - @X_tb SLBIA 011111 --... ----- ----- 0111110010 - @X_ih +SLBMTE 011111 ..... ----- ..... 0110010010 - @X_tb + ## TLB Management Instructions &X_tlbie rb rs ric prs:bool r:bool diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index dd2c7e588f..1922960608 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -309,7 +309,7 @@ static int ppc_find_slb_vsid(PowerPCCPU *cpu, target_ulong rb, return 0; } -void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs) +void helper_SLBMTE(CPUPPCState *env, target_ulong rb, target_ulong rs) { PowerPCCPU *cpu = env_archcpu(env); diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 4435865388..169e97a706 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5351,19 +5351,6 @@ static void gen_mtsrin_64b(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -/* slbmte */ -static void gen_slbmte(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - - gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)], - cpu_gpr[rS(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - static void gen_slbmfee(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) @@ -6841,7 +6828,6 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B), -GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index c454ce8c7f..47d672d29a 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -65,6 +65,20 @@ static bool trans_SLBIA(DisasContext *ctx, arg_SLBIA *a) return true; } +static bool trans_SLBMTE(DisasContext *ctx, arg_SLBMTE *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS(ctx, SEGMENT_64B); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBMTE(cpu_env, cpu_gpr[a->rb], cpu_gpr[a->rt]); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From 74a153844ec6ec28162fe2f1301a0efb6ad53205 Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:03 -0300 Subject: [PATCH 22/30] target/ppc: Move slbmfev to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-8-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 2 ++ target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 12 ------------ target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 98d6c40ac0..d1f9dff58f 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -678,7 +678,7 @@ DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \ env, tl, tl, i32) DEF_HELPER_FLAGS_3(SLBMTE, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(load_slb_esid, tl, env, tl) -DEF_HELPER_2(load_slb_vsid, tl, env, tl) +DEF_HELPER_2(SLBMFEV, tl, env, tl) DEF_HELPER_2(find_slb_vsid, tl, env, tl) DEF_HELPER_FLAGS_2(SLBIA, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_FLAGS_2(SLBIE, TCG_CALL_NO_RWG, void, env, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 2fc6e9cb27..0e002999bd 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -872,6 +872,8 @@ SLBIA 011111 --... ----- ----- 0111110010 - @X_ih SLBMTE 011111 ..... ----- ..... 0110010010 - @X_tb +SLBMFEV 011111 ..... ----- ..... 1101010011 - @X_tb + ## TLB Management Instructions &X_tlbie rb rs ric prs:bool r:bool diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 1922960608..7854b91043 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -343,7 +343,7 @@ target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb) return rt; } -target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb) +target_ulong helper_SLBMFEV(CPUPPCState *env, target_ulong rb) { PowerPCCPU *cpu = env_archcpu(env); target_ulong rt = 0; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 169e97a706..e48a306036 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5363,17 +5363,6 @@ static void gen_slbmfee(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -static void gen_slbmfev(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - - gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, - cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} static void gen_slbfee_(DisasContext *ctx) { @@ -6829,7 +6818,6 @@ GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), -GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index 47d672d29a..11f44e9366 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -79,6 +79,20 @@ static bool trans_SLBMTE(DisasContext *ctx, arg_SLBMTE *a) return true; } +static bool trans_SLBMFEV(DisasContext *ctx, arg_SLBMFEV *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS(ctx, SEGMENT_64B); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBMFEV(cpu_gpr[a->rt], cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From 41b60e46b8eafb02b79e724c2b7220eff6d3d42e Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:04 -0300 Subject: [PATCH 23/30] target/ppc: Move slbmfee to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-9-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 1 + target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 13 ------------- target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index d1f9dff58f..0baa2ca0f3 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -677,7 +677,7 @@ DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \ env, tl, tl, i32) DEF_HELPER_FLAGS_3(SLBMTE, TCG_CALL_NO_RWG, void, env, tl, tl) -DEF_HELPER_2(load_slb_esid, tl, env, tl) +DEF_HELPER_2(SLBMFEE, tl, env, tl) DEF_HELPER_2(SLBMFEV, tl, env, tl) DEF_HELPER_2(find_slb_vsid, tl, env, tl) DEF_HELPER_FLAGS_2(SLBIA, TCG_CALL_NO_RWG, void, env, i32) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 0e002999bd..8b431c6f32 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -873,6 +873,7 @@ SLBIA 011111 --... ----- ----- 0111110010 - @X_ih SLBMTE 011111 ..... ----- ..... 0110010010 - @X_tb SLBMFEV 011111 ..... ----- ..... 1101010011 - @X_tb +SLBMFEE 011111 ..... ----- ..... 1110010011 - @X_tb ## TLB Management Instructions diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 7854b91043..5d73d64436 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -319,7 +319,7 @@ void helper_SLBMTE(CPUPPCState *env, target_ulong rb, target_ulong rs) } } -target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb) +target_ulong helper_SLBMFEE(CPUPPCState *env, target_ulong rb) { PowerPCCPU *cpu = env_archcpu(env); target_ulong rt = 0; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index e48a306036..eae60f5370 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5351,18 +5351,6 @@ static void gen_mtsrin_64b(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -static void gen_slbmfee(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - - gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env, - cpu_gpr[rB(ctx->opcode)]); -#endif /* defined(CONFIG_USER_ONLY) */ -} - static void gen_slbfee_(DisasContext *ctx) { @@ -6817,7 +6805,6 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B), -GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B), GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index 11f44e9366..f0854b137f 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -93,6 +93,20 @@ static bool trans_SLBMFEV(DisasContext *ctx, arg_SLBMFEV *a) return true; } +static bool trans_SLBMFEE(DisasContext *ctx, arg_SLBMFEE *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS(ctx, SEGMENT_64B); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBMFEE(cpu_gpr[a->rt], cpu_env, cpu_gpr[a->rb]); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From 26d02c9d426761503afb60df3be9f44fb19cf3d0 Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:05 -0300 Subject: [PATCH 24/30] target/ppc: Move slbfee to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-10-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 2 ++ target/ppc/mmu-hash64.c | 2 +- target/ppc/translate.c | 26 --------------- target/ppc/translate/storage-ctrl-impl.c.inc | 34 ++++++++++++++++++++ 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 0baa2ca0f3..ef2dc30194 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -679,7 +679,7 @@ DEF_HELPER_FLAGS_4(tlbie_isa300, TCG_CALL_NO_WG, void, \ DEF_HELPER_FLAGS_3(SLBMTE, TCG_CALL_NO_RWG, void, env, tl, tl) DEF_HELPER_2(SLBMFEE, tl, env, tl) DEF_HELPER_2(SLBMFEV, tl, env, tl) -DEF_HELPER_2(find_slb_vsid, tl, env, tl) +DEF_HELPER_2(SLBFEE, tl, env, tl) DEF_HELPER_FLAGS_2(SLBIA, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_FLAGS_2(SLBIE, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(SLBIEG, TCG_CALL_NO_RWG, void, env, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 8b431c6f32..5049c98691 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -875,6 +875,8 @@ SLBMTE 011111 ..... ----- ..... 0110010010 - @X_tb SLBMFEV 011111 ..... ----- ..... 1101010011 - @X_tb SLBMFEE 011111 ..... ----- ..... 1110010011 - @X_tb +SLBFEE 011111 ..... ----- ..... 1111010011 1 @X_tb + ## TLB Management Instructions &X_tlbie rb rs ric prs:bool r:bool diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 5d73d64436..7ec7a67a78 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -331,7 +331,7 @@ target_ulong helper_SLBMFEE(CPUPPCState *env, target_ulong rb) return rt; } -target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb) +target_ulong helper_SLBFEE(CPUPPCState *env, target_ulong rb) { PowerPCCPU *cpu = env_archcpu(env); target_ulong rt = 0; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index eae60f5370..d7a785164b 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5351,31 +5351,6 @@ static void gen_mtsrin_64b(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } - -static void gen_slbfee_(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_OPC); -#else - TCGLabel *l1, *l2; - - if (unlikely(ctx->pr)) { - gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_OPC); - return; - } - gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env, - cpu_gpr[rB(ctx->opcode)]); - l1 = gen_new_label(); - l2 = gen_new_label(); - tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1); - tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ); - tcg_gen_br(l2); - gen_set_label(l1); - tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0); - gen_set_label(l2); -#endif -} #endif /* defined(TARGET_PPC64) */ /*** Lookaside buffer management ***/ @@ -6805,7 +6780,6 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001, GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B), GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT_64B), -GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B), #endif GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), /* diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index f0854b137f..d7e2bb185f 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -107,6 +107,40 @@ static bool trans_SLBMFEE(DisasContext *ctx, arg_SLBMFEE *a) return true; } +static bool trans_SLBFEE(DisasContext *ctx, arg_SLBFEE *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS(ctx, SEGMENT_64B); + +#if defined(CONFIG_USER_ONLY) + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); +#else + +#if defined(TARGET_PPC64) + TCGLabel *l1, *l2; + + if (unlikely(ctx->pr)) { + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); + return true; + } + gen_helper_SLBFEE(cpu_gpr[a->rt], cpu_env, + cpu_gpr[a->rb]); + l1 = gen_new_label(); + l2 = gen_new_label(); + tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so); + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[a->rt], -1, l1); + tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ); + tcg_gen_br(l2); + gen_set_label(l1); + tcg_gen_movi_tl(cpu_gpr[a->rt], 0); + gen_set_label(l2); +#else + qemu_build_not_reached(); +#endif +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From acc130cf1d4c4191dd3d60a88ac4e055ea0db3ce Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:06 -0300 Subject: [PATCH 25/30] target/ppc: Move slbsync to decodetree Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-11-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 2 ++ target/ppc/translate.c | 17 ----------------- target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 5049c98691..781051e993 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -877,6 +877,8 @@ SLBMFEE 011111 ..... ----- ..... 1110010011 - @X_tb SLBFEE 011111 ..... ----- ..... 1111010011 1 @X_tb +SLBSYNC 011111 ----- ----- ----- 0101010010 - + ## TLB Management Instructions &X_tlbie rb rs ric prs:bool r:bool diff --git a/target/ppc/translate.c b/target/ppc/translate.c index d7a785164b..5a18ee577f 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -5388,20 +5388,6 @@ static void gen_tlbsync(DisasContext *ctx) #endif /* defined(CONFIG_USER_ONLY) */ } -#if defined(TARGET_PPC64) -/* slbsync */ -static void gen_slbsync(DisasContext *ctx) -{ -#if defined(CONFIG_USER_ONLY) - GEN_PRIV(ctx); -#else - CHK_SV(ctx); - gen_check_tlb_flush(ctx, true); -#endif /* defined(CONFIG_USER_ONLY) */ -} - -#endif /* defined(TARGET_PPC64) */ - /*** External control ***/ /* Optional: */ @@ -6787,9 +6773,6 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA), * different ISA versions */ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC), -#if defined(TARGET_PPC64) -GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300), -#endif GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN), GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN), GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB), diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index d7e2bb185f..5c569a3c75 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -141,6 +141,20 @@ static bool trans_SLBFEE(DisasContext *ctx, arg_SLBFEE *a) return true; } +static bool trans_SLBSYNC(DisasContext *ctx, arg_SLBSYNC *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_check_tlb_flush(ctx, true); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool do_tlbie(DisasContext *ctx, arg_X_tlbie *a, bool local) { #if defined(CONFIG_USER_ONLY) From 491a25535c99b838772ff961a39762333f0e852f Mon Sep 17 00:00:00 2001 From: Lucas Coutinho Date: Fri, 1 Jul 2022 10:35:07 -0300 Subject: [PATCH 26/30] target/ppc: Implement slbiag Reviewed-by: Leandro Lupori Signed-off-by: Lucas Coutinho Message-Id: <20220701133507.740619-12-lucas.coutinho@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 1 + target/ppc/insn32.decode | 4 +++ target/ppc/mmu-hash64.c | 27 ++++++++++++++++++++ target/ppc/translate/storage-ctrl-impl.c.inc | 14 ++++++++++ 4 files changed, 46 insertions(+) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index ef2dc30194..159b352f6e 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -681,6 +681,7 @@ DEF_HELPER_2(SLBMFEE, tl, env, tl) DEF_HELPER_2(SLBMFEV, tl, env, tl) DEF_HELPER_2(SLBFEE, tl, env, tl) DEF_HELPER_FLAGS_2(SLBIA, TCG_CALL_NO_RWG, void, env, i32) +DEF_HELPER_FLAGS_3(SLBIAG, TCG_CALL_NO_RWG, void, env, tl, i32) DEF_HELPER_FLAGS_2(SLBIE, TCG_CALL_NO_RWG, void, env, tl) DEF_HELPER_FLAGS_2(SLBIEG, TCG_CALL_NO_RWG, void, env, tl) #endif diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 781051e993..eb41efc100 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -152,6 +152,9 @@ &X_rb rb @X_rb ...... ..... ..... rb:5 .......... . &X_rb +&X_rs_l rs l:bool +@X_rs_l ...... rs:5 .... l:1 ..... .......... . &X_rs_l + &X_uim5 xt uim:uint8_t @X_uim5 ...... ..... ..... uim:5 .......... . &X_uim5 xt=%x_xt @@ -869,6 +872,7 @@ SLBIE 011111 ----- ----- ..... 0110110010 - @X_rb SLBIEG 011111 ..... ----- ..... 0111010010 - @X_tb SLBIA 011111 --... ----- ----- 0111110010 - @X_ih +SLBIAG 011111 ..... ----. ----- 1101010010 - @X_rs_l SLBMTE 011111 ..... ----- ..... 0110010010 - @X_tb diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index 7ec7a67a78..b9b31fd276 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -173,6 +173,33 @@ void helper_SLBIA(CPUPPCState *env, uint32_t ih) } } +#if defined(TARGET_PPC64) +void helper_SLBIAG(CPUPPCState *env, target_ulong rs, uint32_t l) +{ + PowerPCCPU *cpu = env_archcpu(env); + int n; + + /* + * slbiag must always flush all TLB (which is equivalent to ERAT in ppc + * architecture). Matching on SLB_ESID_V is not good enough, because slbmte + * can overwrite a valid SLB without flushing its lookaside information. + * + * It would be possible to keep the TLB in synch with the SLB by flushing + * when a valid entry is overwritten by slbmte, and therefore slbiag would + * not have to flush unless it evicts a valid SLB entry. However it is + * expected that slbmte is more common than slbiag, and slbiag is usually + * going to evict valid SLB entries, so that tradeoff is unlikely to be a + * good one. + */ + env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH; + + for (n = 0; n < cpu->hash64_opts->slb_size; n++) { + ppc_slb_t *slb = &env->slb[n]; + slb->esid &= ~SLB_ESID_V; + } +} +#endif + static void __helper_slbie(CPUPPCState *env, target_ulong addr, target_ulong global) { diff --git a/target/ppc/translate/storage-ctrl-impl.c.inc b/target/ppc/translate/storage-ctrl-impl.c.inc index 5c569a3c75..6ea1d22ef9 100644 --- a/target/ppc/translate/storage-ctrl-impl.c.inc +++ b/target/ppc/translate/storage-ctrl-impl.c.inc @@ -65,6 +65,20 @@ static bool trans_SLBIA(DisasContext *ctx, arg_SLBIA *a) return true; } +static bool trans_SLBIAG(DisasContext *ctx, arg_SLBIAG *a) +{ + REQUIRE_64BIT(ctx); + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_SV(ctx); + +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64) + gen_helper_SLBIAG(cpu_env, cpu_gpr[a->rs], tcg_constant_i32(a->l)); +#else + qemu_build_not_reached(); +#endif + return true; +} + static bool trans_SLBMTE(DisasContext *ctx, arg_SLBMTE *a) { REQUIRE_64BIT(ctx); From 3778aa970f21b475ca16befcf271078602104fe6 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Thu, 14 Jul 2022 14:23:43 -0300 Subject: [PATCH 27/30] target/ppc: check tb_env != 0 before printing TBU/TBL/DECR When using "-machine none", env->tb_env is not allocated, causing the segmentation fault reported in issue #85 (launchpad bug #811683). To avoid this problem, check if the pointer != NULL before calling the methods to print TBU/TBL/DECR. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/85 Signed-off-by: Matheus Ferst Reviewed-by: Daniel Henrique Barboza Message-Id: <20220714172343.80539-1-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu_init.c | 18 ++++++++---------- target/ppc/monitor.c | 9 +++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 4f2355e941..d1493a660c 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -7471,17 +7471,15 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags) "%08x iidx %d didx %d\n", env->msr, env->spr[SPR_HID0], env->hflags, cpu_mmu_index(env, true), cpu_mmu_index(env, false)); -#if !defined(NO_TIMER_DUMP) - qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64 #if !defined(CONFIG_USER_ONLY) - " DECR " TARGET_FMT_lu -#endif - "\n", - cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env) -#if !defined(CONFIG_USER_ONLY) - , cpu_ppc_load_decr(env) -#endif - ); + if (env->tb_env) { + qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64 + " DECR " TARGET_FMT_lu "\n", cpu_ppc_load_tbu(env), + cpu_ppc_load_tbl(env), cpu_ppc_load_decr(env)); + } +#else + qemu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64 "\n", cpu_ppc_load_tbu(env), + cpu_ppc_load_tbl(env)); #endif for (i = 0; i < 32; i++) { if ((i & (RGPL - 1)) == 0) { diff --git a/target/ppc/monitor.c b/target/ppc/monitor.c index 0b805ef6e9..8250b1304e 100644 --- a/target/ppc/monitor.c +++ b/target/ppc/monitor.c @@ -55,6 +55,9 @@ static target_long monitor_get_decr(Monitor *mon, const struct MonitorDef *md, int val) { CPUArchState *env = mon_get_cpu_env(mon); + if (!env->tb_env) { + return 0; + } return cpu_ppc_load_decr(env); } @@ -62,6 +65,9 @@ static target_long monitor_get_tbu(Monitor *mon, const struct MonitorDef *md, int val) { CPUArchState *env = mon_get_cpu_env(mon); + if (!env->tb_env) { + return 0; + } return cpu_ppc_load_tbu(env); } @@ -69,6 +75,9 @@ static target_long monitor_get_tbl(Monitor *mon, const struct MonitorDef *md, int val) { CPUArchState *env = mon_get_cpu_env(mon); + if (!env->tb_env) { + return 0; + } return cpu_ppc_load_tbl(env); } From 3c2e80ad2fcf004fcf74bf690dc1c952320a5b52 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 28 Jun 2022 10:39:57 -0300 Subject: [PATCH 28/30] ppc: Check partition and process table alignment Check if partition and process tables are properly aligned, in their size, according to PowerISA 3.1B, Book III 6.7.6 programming note. Hardware and KVM also raise an exception in these cases. Signed-off-by: Leandro Lupori Reviewed-by: Fabiano Rosas Message-Id: <20220628133959.15131-2-leandro.lupori@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr.c | 5 +++++ hw/ppc/spapr_hcall.c | 9 +++++++++ target/ppc/mmu-book3s-v3.c | 5 +++++ target/ppc/mmu-radix64.c | 17 +++++++++++++---- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3a5112899e..bc9ba6e6dc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1336,6 +1336,11 @@ static bool spapr_get_pate(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu, patb = spapr->nested_ptcr & PTCR_PATB; pats = spapr->nested_ptcr & PTCR_PATS; + /* Check if partition table is properly aligned */ + if (patb & MAKE_64BIT_MASK(0, pats + 12)) { + return false; + } + /* Calculate number of entries */ pats = 1ull << (pats + 12 - 4); if (pats <= lpid) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index d761a7d0c3..a8d4a6bcf0 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -920,6 +920,7 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu, target_ulong page_size = args[2]; target_ulong table_size = args[3]; target_ulong update_lpcr = 0; + target_ulong table_byte_size; uint64_t cproc; if (flags & ~FLAGS_MASK) { /* Check no reserved bits are set */ @@ -927,6 +928,14 @@ static target_ulong h_register_process_table(PowerPCCPU *cpu, } if (flags & FLAG_MODIFY) { if (flags & FLAG_REGISTER) { + /* Check process table alignment */ + table_byte_size = 1ULL << (table_size + 12); + if (proc_tbl & (table_byte_size - 1)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: process table not properly aligned: proc_tbl 0x" + TARGET_FMT_lx" proc_tbl_size 0x"TARGET_FMT_lx"\n", + __func__, proc_tbl, table_byte_size); + } if (flags & FLAG_RADIX) { /* Register new RADIX process table */ if (proc_tbl & 0xfff || proc_tbl >> 60) { return H_P2; diff --git a/target/ppc/mmu-book3s-v3.c b/target/ppc/mmu-book3s-v3.c index f4985bae78..c8f69b3df9 100644 --- a/target/ppc/mmu-book3s-v3.c +++ b/target/ppc/mmu-book3s-v3.c @@ -28,6 +28,11 @@ bool ppc64_v3_get_pate(PowerPCCPU *cpu, target_ulong lpid, ppc_v3_pate_t *entry) uint64_t patb = cpu->env.spr[SPR_PTCR] & PTCR_PATB; uint64_t pats = cpu->env.spr[SPR_PTCR] & PTCR_PATS; + /* Check if partition table is properly aligned */ + if (patb & MAKE_64BIT_MASK(0, pats + 12)) { + return false; + } + /* Calculate number of entries */ pats = 1ull << (pats + 12 - 4); if (pats <= lpid) { diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 21ac958e48..9a8a2e2875 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -383,7 +383,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; - uint64_t offset, size, prtbe_addr, prtbe0, base_addr, nls, index, pte; + uint64_t offset, size, prtb, prtbe_addr, prtbe0, base_addr, nls, index, pte; int fault_cause = 0, h_page_size, h_prot; hwaddr h_raddr, pte_addr; int ret; @@ -393,9 +393,18 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, __func__, access_str(access_type), eaddr, mmu_idx, pid); + prtb = (pate.dw1 & PATE1_R_PRTB); + size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); + if (prtb & (size - 1)) { + /* Process Table not properly aligned */ + if (guest_visible) { + ppc_radix64_raise_si(cpu, access_type, eaddr, DSISR_R_BADCONFIG); + } + return 1; + } + /* Index Process Table by PID to Find Corresponding Process Table Entry */ offset = pid * sizeof(struct prtb_entry); - size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); if (offset >= size) { /* offset exceeds size of the process table */ if (guest_visible) { @@ -403,7 +412,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, } return 1; } - prtbe_addr = (pate.dw1 & PATE1_R_PRTB) + offset; + prtbe_addr = prtb + offset; if (vhyp_flat_addressing(cpu)) { prtbe0 = ldq_phys(cs->as, prtbe_addr); @@ -568,7 +577,7 @@ static bool ppc_radix64_xlate_impl(PowerPCCPU *cpu, vaddr eaddr, return false; } - /* Get Process Table */ + /* Get Partition Table */ if (cpu->vhyp) { PPCVirtualHypervisorClass *vhc; vhc = PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); From 47e83d9107887c867bad8900ed39e83b79110b66 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 28 Jun 2022 10:39:58 -0300 Subject: [PATCH 29/30] target/ppc: Improve Radix xlate level validation Check if the number and size of Radix levels are valid on POWER9/POWER10 CPUs, according to the supported Radix Tree Configurations described in their User Manuals. Signed-off-by: Leandro Lupori Reviewed-by: Fabiano Rosas Message-Id: <20220628133959.15131-3-leandro.lupori@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/mmu-radix64.c | 49 +++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 9a8a2e2875..705bff76be 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -236,17 +236,37 @@ static void ppc_radix64_set_rc(PowerPCCPU *cpu, MMUAccessType access_type, } } +static bool ppc_radix64_is_valid_level(int level, int psize, uint64_t nls) +{ + /* + * Check if this is a valid level, according to POWER9 and POWER10 + * Processor User's Manuals, sections 4.10.4.1 and 5.10.6.1, respectively: + * Supported Radix Tree Configurations and Resulting Page Sizes. + * + * Note: these checks are specific to POWER9 and POWER10 CPUs. Any future + * CPUs that supports a different Radix MMU configuration will need their + * own implementation. + */ + switch (level) { + case 0: /* Root Page Dir */ + return psize == 52 && nls == 13; + case 1: + case 2: + return nls == 9; + case 3: + return nls == 9 || nls == 5; + default: + qemu_log_mask(LOG_GUEST_ERROR, "invalid radix level: %d\n", level); + return false; + } +} + static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr, uint64_t *pte_addr, uint64_t *nls, int *psize, uint64_t *pte, int *fault_cause) { uint64_t index, pde; - if (*nls < 5) { /* Directory maps less than 2**5 entries */ - *fault_cause |= DSISR_R_BADCONFIG; - return 1; - } - /* Read page entry from guest address space */ pde = ldq_phys(as, *pte_addr); if (!(pde & R_PTE_VALID)) { /* Invalid Entry */ @@ -270,12 +290,8 @@ static int ppc_radix64_walk_tree(AddressSpace *as, vaddr eaddr, hwaddr *raddr, int *psize, uint64_t *pte, int *fault_cause, hwaddr *pte_addr) { - uint64_t index, pde, rpn , mask; - - if (nls < 5) { /* Directory maps less than 2**5 entries */ - *fault_cause |= DSISR_R_BADCONFIG; - return 1; - } + uint64_t index, pde, rpn, mask; + int level = 0; index = eaddr >> (*psize - nls); /* Shift */ index &= ((1UL << nls) - 1); /* Mask */ @@ -283,6 +299,11 @@ static int ppc_radix64_walk_tree(AddressSpace *as, vaddr eaddr, do { int ret; + if (!ppc_radix64_is_valid_level(level++, *psize, nls)) { + *fault_cause |= DSISR_R_BADCONFIG; + return 1; + } + ret = ppc_radix64_next_level(as, eaddr, pte_addr, &nls, psize, &pde, fault_cause); if (ret) { @@ -456,6 +477,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, } } else { uint64_t rpn, mask; + int level = 0; index = (eaddr & R_EADDR_MASK) >> (*g_page_size - nls); /* Shift */ index &= ((1UL << nls) - 1); /* Mask */ @@ -475,6 +497,11 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, return ret; } + if (!ppc_radix64_is_valid_level(level++, *g_page_size, nls)) { + fault_cause |= DSISR_R_BADCONFIG; + return 1; + } + ret = ppc_radix64_next_level(cs->as, eaddr & R_EADDR_MASK, &h_raddr, &nls, g_page_size, &pte, &fault_cause); if (ret) { From d2066bc50d690a6605307eaf0e72a9cf51e6fc25 Mon Sep 17 00:00:00 2001 From: Leandro Lupori Date: Tue, 28 Jun 2022 10:39:59 -0300 Subject: [PATCH 30/30] target/ppc: Check page dir/table base alignment According to PowerISA 3.1B, Book III 6.7.6 programming note, the page directory base addresses are expected to be aligned to their size. Real hardware seems to rely on that and will access the wrong address if they are misaligned. This results in a translation failure even if the page tables seem to be properly populated. Signed-off-by: Leandro Lupori Reviewed-by: Daniel Henrique Barboza Message-Id: <20220628133959.15131-4-leandro.lupori@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/mmu-radix64.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 705bff76be..00f2e9fa2e 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -265,7 +265,7 @@ static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr, uint64_t *pte_addr, uint64_t *nls, int *psize, uint64_t *pte, int *fault_cause) { - uint64_t index, pde; + uint64_t index, mask, nlb, pde; /* Read page entry from guest address space */ pde = ldq_phys(as, *pte_addr); @@ -280,7 +280,17 @@ static int ppc_radix64_next_level(AddressSpace *as, vaddr eaddr, *nls = pde & R_PDE_NLS; index = eaddr >> (*psize - *nls); /* Shift */ index &= ((1UL << *nls) - 1); /* Mask */ - *pte_addr = (pde & R_PDE_NLB) + (index * sizeof(pde)); + nlb = pde & R_PDE_NLB; + mask = MAKE_64BIT_MASK(0, *nls + 3); + + if (nlb & mask) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: misaligned page dir/table base: 0x"TARGET_FMT_lx + " page dir size: 0x"TARGET_FMT_lx"\n", + __func__, nlb, mask + 1); + nlb &= ~mask; + } + *pte_addr = nlb + index * sizeof(pde); } return 0; } @@ -294,8 +304,18 @@ static int ppc_radix64_walk_tree(AddressSpace *as, vaddr eaddr, int level = 0; index = eaddr >> (*psize - nls); /* Shift */ - index &= ((1UL << nls) - 1); /* Mask */ - *pte_addr = base_addr + (index * sizeof(pde)); + index &= ((1UL << nls) - 1); /* Mask */ + mask = MAKE_64BIT_MASK(0, nls + 3); + + if (base_addr & mask) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: misaligned page dir base: 0x"TARGET_FMT_lx + " page dir size: 0x"TARGET_FMT_lx"\n", + __func__, base_addr, mask + 1); + base_addr &= ~mask; + } + *pte_addr = base_addr + index * sizeof(pde); + do { int ret;