diff options
34 files changed, 378 insertions, 181 deletions
@@ -42,7 +42,8 @@ Justin Terry (VM) <juterry@microsoft.com> Justin Terry (VM) via Qemu-devel <qemu Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <aleksandar.markovic@mips.com> Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <aleksandar.markovic@imgtec.com> Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> <amarkovic@wavecomp.com> -Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> <arikalo@wavecomp.com> +Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <arikalo@wavecomp.com> +Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> <aleksandar.rikalo@rt-rk.com> Anthony Liguori <anthony@codemonkey.ws> Anthony Liguori <aliguori@us.ibm.com> James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com> Leif Lindholm <leif@nuviainc.com> <leif.lindholm@linaro.org> diff --git a/MAINTAINERS b/MAINTAINERS index 3690f313c3..a209b5d8ce 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -213,7 +213,7 @@ F: disas/microblaze.c MIPS TCG CPUs M: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> R: Aurelien Jarno <aurelien@aurel32.net> -R: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> +R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Maintained F: target/mips/ F: default-configs/*mips* @@ -1048,9 +1048,9 @@ MIPS Machines ------------- Jazz M: Hervé Poussineau <hpoussin@reactos.org> -R: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> +R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Maintained -F: hw/mips/mips_jazz.c +F: hw/mips/jazz.c F: hw/display/jazz_led.c F: hw/dma/rc4030.c @@ -1061,7 +1061,7 @@ R: Aurelien Jarno <aurelien@aurel32.net> S: Maintained F: hw/isa/piix4.c F: hw/acpi/piix4.c -F: hw/mips/mips_malta.c +F: hw/mips/malta.c F: hw/mips/gt64xxx_pci.c F: include/hw/southbridge/piix.h F: tests/acceptance/linux_ssh_mips_malta.py @@ -1069,30 +1069,32 @@ F: tests/acceptance/machine_mips_malta.py Mipssim M: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> -R: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> +R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Odd Fixes -F: hw/mips/mips_mipssim.c +F: hw/mips/mipssim.c F: hw/net/mipsnet.c R4000 M: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> R: Aurelien Jarno <aurelien@aurel32.net> -R: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> +R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Obsolete -F: hw/mips/mips_r4k.c +F: hw/mips/r4k.c -Fulong 2E +Fuloong 2E +M: Huacai Chen <chenhc@lemote.com> M: Philippe Mathieu-Daudé <f4bug@amsat.org> M: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> +R: Jiaxun Yang <jiaxun.yang@flygoat.com> S: Odd Fixes -F: hw/mips/mips_fulong2e.c +F: hw/mips/fuloong2e.c F: hw/isa/vt82c686.c F: hw/pci-host/bonito.c F: include/hw/isa/vt82c686.h Boston M: Paul Burton <pburton@wavecomp.com> -R: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> +R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Maintained F: hw/core/loader-fit.c F: hw/mips/boston.c @@ -2606,7 +2608,7 @@ F: disas/i386.c MIPS TCG target M: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com> R: Aurelien Jarno <aurelien@aurel32.net> -R: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com> +R: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com> S: Maintained F: tcg/mips/ diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index 8b0c9b1e15..9f8a3ef156 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -2,7 +2,7 @@ include mips-softmmu-common.mak CONFIG_IDE_VIA=y -CONFIG_FULONG=y +CONFIG_FULOONG=y CONFIG_ATI_VGA=y CONFIG_RTL8139_PCI=y CONFIG_JAZZ=y diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst index 3142fac386..f0061f94aa 100644 --- a/docs/system/deprecated.rst +++ b/docs/system/deprecated.rst @@ -368,6 +368,11 @@ mips ``r4k`` platform (since 5.0) This machine type is very old and unmaintained. Users should use the ``malta`` machine type instead. +mips ``fulong2e`` machine (since 5.1) +''''''''''''''''''''''''''''''''''''' + +This machine has been renamed ``fuloong2e``. + ``pc-1.0``, ``pc-1.1``, ``pc-1.2`` and ``pc-1.3`` (since 5.0) ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' diff --git a/docs/system/target-mips.rst b/docs/system/target-mips.rst index 2736fd0509..cd2a931edf 100644 --- a/docs/system/target-mips.rst +++ b/docs/system/target-mips.rst @@ -74,7 +74,7 @@ The MIPS Magnum R4000 emulation supports: - G364 framebuffer -The Fulong 2E emulation supports: +The Fuloong 2E emulation supports: - Loongson 2E CPU diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index d9b51fce8d..fac4e56b7d 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -503,7 +503,7 @@ static void via_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_via; /* * Reason: part of VIA VT82C686 southbridge, needs to be wired up, - * e.g. by mips_fulong2e_init() + * e.g. by mips_fuloong2e_init() */ dc->user_creatable = false; } diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index 2c2adbc42a..67d39c56a4 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -41,8 +41,9 @@ config JAZZ select DS1225Y select JAZZ_LED -config FULONG +config FULOONG bool + select PCI_BONITO config MIPS_CPS bool diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs index 525809af07..739e2b7b40 100644 --- a/hw/mips/Makefile.objs +++ b/hw/mips/Makefile.objs @@ -1,8 +1,8 @@ obj-y += addr.o mips_int.o -obj-$(CONFIG_R4K) += mips_r4k.o -obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o -obj-$(CONFIG_MIPSSIM) += mips_mipssim.o -obj-$(CONFIG_JAZZ) += mips_jazz.o -obj-$(CONFIG_FULONG) += mips_fulong2e.o +obj-$(CONFIG_R4K) += r4k.o +obj-$(CONFIG_MALTA) += gt64xxx_pci.o malta.o +obj-$(CONFIG_MIPSSIM) += mipssim.o +obj-$(CONFIG_JAZZ) += jazz.o +obj-$(CONFIG_FULOONG) += fuloong2e.o obj-$(CONFIG_MIPS_CPS) += cps.o obj-$(CONFIG_MIPS_BOSTON) += boston.o diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/fuloong2e.c index 05b9efa516..f583c44b79 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/fuloong2e.c @@ -1,5 +1,5 @@ /* - * QEMU fulong 2e mini pc support + * QEMU fuloong 2e mini pc support * * Copyright (c) 2008 yajin (yajin@vm-kernel.org) * Copyright (c) 2009 chenming (chenming@rdc.faw.com.cn) @@ -11,8 +11,8 @@ */ /* - * Fulong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz) - * http://www.linux-mips.org/wiki/Fulong + * Fuloong 2e mini pc is based on ICT/ST Loongson 2e CPU (MIPS III like, 800MHz) + * https://www.linux-mips.org/wiki/Fuloong_2E * * Loongson 2e user manual: * http://www.loongsondeveloper.com/doc/Loongson2EUserGuide.pdf @@ -45,13 +45,13 @@ #include "sysemu/reset.h" #include "qemu/error-report.h" -#define DEBUG_FULONG2E_INIT +#define DEBUG_FULOONG2E_INIT #define ENVP_ADDR 0x80002000l #define ENVP_NB_ENTRIES 16 #define ENVP_ENTRY_SIZE 256 -/* fulong 2e has a 512k flash: Winbond W39L040AP70Z */ +/* Fuloong 2e has a 512k flash: Winbond W39L040AP70Z */ #define BIOS_SIZE (512 * KiB) #define MAX_IDE_BUS 2 @@ -68,12 +68,12 @@ * 2, use "Bonito2edev" to replace "dir_corresponding_to_your_target_hardware" * in the "Compile Guide". */ -#define FULONG_BIOSNAME "pmon_fulong2e.bin" +#define FULOONG_BIOSNAME "pmon_2e.bin" -/* PCI SLOT in fulong 2e */ -#define FULONG2E_VIA_SLOT 5 -#define FULONG2E_ATI_SLOT 6 -#define FULONG2E_RTL8139_SLOT 7 +/* PCI SLOT in Fuloong 2e */ +#define FULOONG2E_VIA_SLOT 5 +#define FULOONG2E_ATI_SLOT 6 +#define FULOONG2E_RTL8139_SLOT 7 static struct _loaderparams { int ram_size; @@ -278,7 +278,7 @@ static void network_init(PCIBus *pci_bus) const char *default_devaddr = NULL; if (i == 0 && (!nd->model || strcmp(nd->model, "rtl8139") == 0)) { - /* The fulong board has a RTL8139 card using PCI SLOT 7 */ + /* The Fuloong board has a RTL8139 card using PCI SLOT 7 */ default_devaddr = "07"; } @@ -286,7 +286,7 @@ static void network_init(PCIBus *pci_bus) } } -static void mips_fulong2e_init(MachineState *machine) +static void mips_fuloong2e_init(MachineState *machine) { const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; @@ -315,12 +315,11 @@ static void mips_fulong2e_init(MachineState *machine) error_report("Invalid RAM size, should be 256MB"); exit(EXIT_FAILURE); } + memory_region_add_subregion(address_space_mem, 0, machine->ram); - /* allocate RAM */ - memory_region_init_rom(bios, NULL, "fulong2e.bios", BIOS_SIZE, + /* Boot ROM */ + memory_region_init_rom(bios, NULL, "fuloong2e.bios", BIOS_SIZE, &error_fatal); - - memory_region_add_subregion(address_space_mem, 0, machine->ram); memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios); /* @@ -337,7 +336,7 @@ static void mips_fulong2e_init(MachineState *machine) write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { if (bios_name == NULL) { - bios_name = FULONG_BIOSNAME; + bios_name = FULOONG_BIOSNAME; } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { @@ -363,7 +362,7 @@ static void mips_fulong2e_init(MachineState *machine) pci_bus = bonito_init((qemu_irq *)&(env->irq[2])); /* South bridge -> IP5 */ - vt82c686b_southbridge_init(pci_bus, FULONG2E_VIA_SLOT, env->irq[5], + vt82c686b_southbridge_init(pci_bus, FULOONG2E_VIA_SLOT, env->irq[5], &smbus, &isa_bus); /* GPU */ @@ -384,14 +383,15 @@ static void mips_fulong2e_init(MachineState *machine) network_init(pci_bus); } -static void mips_fulong2e_machine_init(MachineClass *mc) +static void mips_fuloong2e_machine_init(MachineClass *mc) { - mc->desc = "Fulong 2e mini pc"; - mc->init = mips_fulong2e_init; + mc->desc = "Fuloong 2e mini pc"; + mc->alias = "fulong2e"; /* Incorrect name used up to QEMU 4.2 */ + mc->init = mips_fuloong2e_init; mc->block_default_type = IF_IDE; mc->default_cpu_type = MIPS_CPU_TYPE_NAME("Loongson-2E"); mc->default_ram_size = 256 * MiB; - mc->default_ram_id = "fulong2e.ram"; + mc->default_ram_id = "fuloong2e.ram"; } -DEFINE_MACHINE("fulong2e", mips_fulong2e_machine_init) +DEFINE_MACHINE("fuloong2e", mips_fuloong2e_machine_init) diff --git a/hw/mips/mips_jazz.c b/hw/mips/jazz.c index afea52b41b..afea52b41b 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/jazz.c diff --git a/hw/mips/mips_malta.c b/hw/mips/malta.c index 17bf41616b..636c95d1fe 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/malta.c @@ -427,10 +427,9 @@ static uint64_t malta_fpga_read(void *opaque, hwaddr addr, break; default: -#if 0 - printf("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n", - addr); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "malta_fpga_read: Bad register addr 0x%"HWADDR_PRIX"\n", + addr); break; } return val; @@ -515,10 +514,9 @@ static void malta_fpga_write(void *opaque, hwaddr addr, break; default: -#if 0 - printf("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n", - addr); -#endif + qemu_log_mask(LOG_GUEST_ERROR, + "malta_fpga_write: Bad register addr 0x%"HWADDR_PRIX"\n", + addr); break; } } diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c index 796730b11d..4a1bf846da 100644 --- a/hw/mips/mips_int.c +++ b/hw/mips/mips_int.c @@ -47,17 +47,12 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level) if (level) { env->CP0_Cause |= 1 << (irq + CP0Ca_IP); - - if (kvm_enabled() && irq == 2) { - kvm_mips_set_interrupt(cpu, irq, level); - } - } else { env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP)); + } - if (kvm_enabled() && irq == 2) { - kvm_mips_set_interrupt(cpu, irq, level); - } + if (kvm_enabled() && irq == 2) { + kvm_mips_set_interrupt(cpu, irq, level); } if (env->CP0_Cause & CP0Ca_IP_mask) { diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mipssim.c index d220318939..d220318939 100644 --- a/hw/mips/mips_mipssim.c +++ b/hw/mips/mipssim.c diff --git a/hw/mips/mips_r4k.c b/hw/mips/r4k.c index 3487013a4a..3487013a4a 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/r4k.c diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c index ff5db03e6b..beec1c4e4d 100644 --- a/hw/nvram/mac_nvram.c +++ b/hw/nvram/mac_nvram.c @@ -30,18 +30,9 @@ #include "migration/vmstate.h" #include "qemu/cutils.h" #include "qemu/module.h" +#include "trace.h" #include <zlib.h> -/* debug NVR */ -//#define DEBUG_NVR - -#ifdef DEBUG_NVR -#define NVR_DPRINTF(fmt, ...) \ - do { printf("NVR: " fmt , ## __VA_ARGS__); } while (0) -#else -#define NVR_DPRINTF(fmt, ...) -#endif - #define DEF_SYSTEM_SIZE 0xc10 /* macio style NVRAM device */ @@ -51,9 +42,8 @@ static void macio_nvram_writeb(void *opaque, hwaddr addr, MacIONVRAMState *s = opaque; addr = (addr >> s->it_shift) & (s->size - 1); + trace_macio_nvram_write(addr, value); s->data[addr] = value; - NVR_DPRINTF("writeb addr %04" HWADDR_PRIx " val %" PRIx64 "\n", - addr, value); } static uint64_t macio_nvram_readb(void *opaque, hwaddr addr, @@ -64,8 +54,7 @@ static uint64_t macio_nvram_readb(void *opaque, hwaddr addr, addr = (addr >> s->it_shift) & (s->size - 1); value = s->data[addr]; - NVR_DPRINTF("readb addr %04" HWADDR_PRIx " val %" PRIx32 "\n", - addr, value); + trace_macio_nvram_read(addr, value); return value; } diff --git a/hw/nvram/trace-events b/hw/nvram/trace-events index 0dea9260ce..e023193295 100644 --- a/hw/nvram/trace-events +++ b/hw/nvram/trace-events @@ -13,3 +13,7 @@ fw_cfg_add_string(uint16_t key_value, const char *key_name, const char *value) " fw_cfg_add_i16(uint16_t key_value, const char *key_name, uint16_t value) "key 0x%04" PRIx16 " '%s', value 0x%" PRIx16 fw_cfg_add_i32(uint16_t key_value, const char *key_name, uint32_t value) "key 0x%04" PRIx16 " '%s', value 0x%" PRIx32 fw_cfg_add_i64(uint16_t key_value, const char *key_name, uint64_t value) "key 0x%04" PRIx16 " '%s', value 0x%" PRIx64 + +# mac_nvram.c +macio_nvram_read(uint32_t addr, uint8_t val) "read addr=0x%04"PRIx32" val=0x%02x" +macio_nvram_write(uint32_t addr, uint8_t val) "write addr=0x%04"PRIx32" val=0x%02x" diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c index 3ae2f788a4..952bc71122 100644 --- a/hw/pci-bridge/dec.c +++ b/hw/pci-bridge/dec.c @@ -32,16 +32,6 @@ #include "hw/pci/pci_bridge.h" #include "hw/pci/pci_bus.h" -/* debug DEC */ -//#define DEBUG_DEC - -#ifdef DEBUG_DEC -#define DEC_DPRINTF(fmt, ...) \ - do { printf("DEC: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DEC_DPRINTF(fmt, ...) -#endif - #define DEC_21154(obj) OBJECT_CHECK(DECState, (obj), TYPE_DEC_21154) typedef struct DECState { diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig index 9642c77e98..036a61877a 100644 --- a/hw/pci-host/Kconfig +++ b/hw/pci-host/Kconfig @@ -55,3 +55,8 @@ config PCI_EXPRESS_DESIGNWARE bool select PCI_EXPRESS select MSI_NONBROKEN + +config PCI_BONITO + select PCI + select UNIMP + bool diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs index 8c87e8494d..e422e0aca0 100644 --- a/hw/pci-host/Makefile.objs +++ b/hw/pci-host/Makefile.objs @@ -12,7 +12,7 @@ common-obj-$(CONFIG_PPCE500_PCI) += ppce500.o common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o common-obj-$(CONFIG_PCI_SABRE) += sabre.o -common-obj-$(CONFIG_FULONG) += bonito.o +common-obj-$(CONFIG_PCI_BONITO) += bonito.o common-obj-$(CONFIG_PCI_I440FX) += i440fx.o common-obj-$(CONFIG_XEN_IGD_PASSTHROUGH) += xen_igd_pt.o common-obj-$(CONFIG_PCI_EXPRESS_Q35) += q35.o diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index f212796044..f9697dcc43 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -11,7 +11,7 @@ */ /* - * fulong 2e mini pc has a bonito north bridge. + * fuloong 2e mini pc has a bonito north bridge. */ /* @@ -39,6 +39,7 @@ */ #include "qemu/osdep.h" +#include "qemu/units.h" #include "qemu/error-report.h" #include "hw/pci/pci.h" #include "hw/irq.h" @@ -48,6 +49,8 @@ #include "sysemu/reset.h" #include "sysemu/runstate.h" #include "exec/address-spaces.h" +#include "hw/misc/unimp.h" +#include "hw/registerfields.h" /* #define DEBUG_BONITO */ @@ -81,7 +84,7 @@ #define BONITO_PCILO1_BASE 0x14000000 #define BONITO_PCILO2_BASE 0x18000000 #define BONITO_PCIHI_BASE 0x20000000 -#define BONITO_PCIHI_SIZE 0x20000000 +#define BONITO_PCIHI_SIZE 0x60000000 #define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE - 1) #define BONITO_PCIIO_BASE 0x1fd00000 #define BONITO_PCIIO_BASE_VA 0xbfd00000 @@ -110,8 +113,19 @@ /* Power on register */ #define BONITO_BONPONCFG (0x00 >> 2) /* 0x100 */ + +/* PCI configuration register */ #define BONITO_BONGENCFG_OFFSET 0x4 #define BONITO_BONGENCFG (BONITO_BONGENCFG_OFFSET >> 2) /*0x104 */ +REG32(BONGENCFG, 0x104) +FIELD(BONGENCFG, DEBUGMODE, 0, 1) +FIELD(BONGENCFG, SNOOP, 1, 1) +FIELD(BONGENCFG, CPUSELFRESET, 2, 1) +FIELD(BONGENCFG, BYTESWAP, 6, 1) +FIELD(BONGENCFG, UNCACHED, 7, 1) +FIELD(BONGENCFG, PREFETCH, 8, 1) +FIELD(BONGENCFG, WRITEBEHIND, 9, 1) +FIELD(BONGENCFG, PCIQUEUE, 12, 1) /* 2. IO & IDE configuration */ #define BONITO_IODEVCFG (0x08 >> 2) /* 0x108 */ @@ -239,7 +253,7 @@ static void bonito_writel(void *opaque, hwaddr addr, saddr = addr >> 2; - DPRINTF("bonito_writel "TARGET_FMT_plx" val %x saddr %x\n", + DPRINTF("bonito_writel "TARGET_FMT_plx" val %lx saddr %x\n", addr, val, saddr); switch (saddr) { case BONITO_BONPONCFG: @@ -327,7 +341,7 @@ static void bonito_pciconf_writel(void *opaque, hwaddr addr, PCIBonitoState *s = opaque; PCIDevice *d = PCI_DEVICE(s); - DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %x\n", addr, val); + DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %lx\n", addr, val); d->config_write(d, addr, val, 4); } @@ -474,7 +488,7 @@ static void bonito_spciconf_write(void *opaque, hwaddr addr, uint64_t val, uint32_t pciaddr; uint16_t status; - DPRINTF("bonito_spciconf_write "TARGET_FMT_plx" size %d val %x\n", + DPRINTF("bonito_spciconf_write "TARGET_FMT_plx" size %d val %lx\n", addr, size, val); pciaddr = bonito_sbridge_pciaddr(s, addr); @@ -559,11 +573,11 @@ static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num) slot = (pci_dev->devfn >> 3); switch (slot) { - case 5: /* FULONG2E_VIA_SLOT, SouthBridge, IDE, USB, ACPI, AC97, MC97 */ + case 5: /* FULOONG2E_VIA_SLOT, SouthBridge, IDE, USB, ACPI, AC97, MC97 */ return irq_num % 4 + BONITO_IRQ_BASE; - case 6: /* FULONG2E_ATI_SLOT, VGA */ + case 6: /* FULOONG2E_ATI_SLOT, VGA */ return 4 + BONITO_IRQ_BASE; - case 7: /* FULONG2E_RTL_SLOT, RTL8139 */ + case 7: /* FULOONG2E_RTL_SLOT, RTL8139 */ return 5 + BONITO_IRQ_BASE; case 8 ... 12: /* PCI slot 1 to 4 */ return (slot - 8 + irq_num) + 6 + BONITO_IRQ_BASE; @@ -575,11 +589,18 @@ static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num) static void bonito_reset(void *opaque) { PCIBonitoState *s = opaque; + uint32_t val = 0; /* set the default value of north bridge registers */ s->regs[BONITO_BONPONCFG] = 0xc40; - s->regs[BONITO_BONGENCFG] = 0x1384; + val = FIELD_DP32(val, BONGENCFG, PCIQUEUE, 1); + val = FIELD_DP32(val, BONGENCFG, WRITEBEHIND, 1); + val = FIELD_DP32(val, BONGENCFG, PREFETCH, 1); + val = FIELD_DP32(val, BONGENCFG, UNCACHED, 1); + val = FIELD_DP32(val, BONGENCFG, CPUSELFRESET, 1); + s->regs[BONITO_BONGENCFG] = val; + s->regs[BONITO_IODEVCFG] = 0x2bff8010; s->regs[BONITO_SDCFG] = 0x255e0091; @@ -604,14 +625,26 @@ static void bonito_pcihost_realize(DeviceState *dev, Error **errp) { PCIHostState *phb = PCI_HOST_BRIDGE(dev); BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev); + MemoryRegion *pcimem_lo_alias = g_new(MemoryRegion, 3); - memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", BONITO_PCILO_SIZE); + memory_region_init(&bs->pci_mem, OBJECT(dev), "pci.mem", BONITO_PCIHI_SIZE); phb->bus = pci_register_root_bus(dev, "pci", pci_bonito_set_irq, pci_bonito_map_irq, dev, &bs->pci_mem, get_system_io(), 0x28, 32, TYPE_PCI_BUS); - memory_region_add_subregion(get_system_memory(), BONITO_PCILO_BASE, - &bs->pci_mem); + + for (size_t i = 0; i < 3; i++) { + char *name = g_strdup_printf("pci.lomem%zu", i); + + memory_region_init_alias(&pcimem_lo_alias[i], NULL, name, + &bs->pci_mem, i * 64 * MiB, 64 * MiB); + memory_region_add_subregion(get_system_memory(), + BONITO_PCILO_BASE + i * 64 * MiB, + &pcimem_lo_alias[i]); + g_free(name); + } + + create_unimplemented_device("pci.io", BONITO_PCIIO_BASE, 1 * MiB); } static void bonito_realize(PCIDevice *dev, Error **errp) @@ -619,6 +652,8 @@ static void bonito_realize(PCIDevice *dev, Error **errp) PCIBonitoState *s = PCI_BONITO(dev); SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost); PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); + BonitoState *bs = BONITO_PCI_HOST_BRIDGE(s->pcihost); + MemoryRegion *pcimem_alias = g_new(MemoryRegion, 1); /* * Bonito North Bridge, built on FPGA, @@ -644,15 +679,20 @@ static void bonito_realize(PCIDevice *dev, Error **errp) sysbus_init_mmio(sysbus, &phb->data_mem); sysbus_mmio_map(sysbus, 2, BONITO_SPCICONFIG_BASE); + create_unimplemented_device("bonito", BONITO_REG_BASE, BONITO_REG_SIZE); + memory_region_init_io(&s->iomem_ldma, OBJECT(s), &bonito_ldma_ops, s, "ldma", 0x100); sysbus_init_mmio(sysbus, &s->iomem_ldma); - sysbus_mmio_map(sysbus, 3, 0xbfe00200); + sysbus_mmio_map(sysbus, 3, 0x1fe00200); + /* PCI copier */ memory_region_init_io(&s->iomem_cop, OBJECT(s), &bonito_cop_ops, s, "cop", 0x100); sysbus_init_mmio(sysbus, &s->iomem_cop); - sysbus_mmio_map(sysbus, 4, 0xbfe00300); + sysbus_mmio_map(sysbus, 4, 0x1fe00300); + + create_unimplemented_device("ROMCS", BONITO_FLASH_BASE, 60 * MiB); /* Map PCI IO Space 0x1fd0 0000 - 0x1fd1 0000 */ memory_region_init_alias(&s->bonito_pciio, OBJECT(s), "isa_mmio", @@ -661,10 +701,25 @@ static void bonito_realize(PCIDevice *dev, Error **errp) sysbus_mmio_map(sysbus, 5, BONITO_PCIIO_BASE); /* add pci local io mapping */ - memory_region_init_alias(&s->bonito_localio, OBJECT(s), "isa_mmio", - get_system_io(), 0, BONITO_DEV_SIZE); + + memory_region_init_alias(&s->bonito_localio, OBJECT(s), "IOCS[0]", + get_system_io(), 0, 256 * KiB); sysbus_init_mmio(sysbus, &s->bonito_localio); sysbus_mmio_map(sysbus, 6, BONITO_DEV_BASE); + create_unimplemented_device("IOCS[1]", BONITO_DEV_BASE + 1 * 256 * KiB, + 256 * KiB); + create_unimplemented_device("IOCS[2]", BONITO_DEV_BASE + 2 * 256 * KiB, + 256 * KiB); + create_unimplemented_device("IOCS[3]", BONITO_DEV_BASE + 3 * 256 * KiB, + 256 * KiB); + + memory_region_init_alias(pcimem_alias, NULL, "pci.mem.alias", + &bs->pci_mem, 0, BONITO_PCIHI_SIZE); + memory_region_add_subregion(get_system_memory(), + BONITO_PCIHI_BASE, pcimem_alias); + create_unimplemented_device("PCI_2", + (hwaddr)BONITO_PCIHI_BASE + BONITO_PCIHI_SIZE, + 2 * GiB); /* set the default value of north bridge pci config */ pci_set_word(dev->config + PCI_COMMAND, 0x0000); diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index da637822f9..806a5d9a8d 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1984,12 +1984,26 @@ static void pnv_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg) cpu_synchronize_state(cs); ppc_cpu_do_system_reset(cs); - /* - * SRR1[42:45] is set to 0100 which the ISA defines as implementation - * dependent. POWER processors use this for xscom triggered interrupts, - * which come from the BMC or NMI IPIs. - */ - env->spr[SPR_SRR1] |= PPC_BIT(43); + if (env->spr[SPR_SRR1] & SRR1_WAKESTATE) { + /* + * Power-save wakeups, as indicated by non-zero SRR1[46:47] put the + * wakeup reason in SRR1[42:45], system reset is indicated with 0b0100 + * (PPC_BIT(43)). + */ + if (!(env->spr[SPR_SRR1] & SRR1_WAKERESET)) { + warn_report("ppc_cpu_do_system_reset does not set system reset wakeup reason"); + env->spr[SPR_SRR1] |= SRR1_WAKERESET; + } + } else { + /* + * For non-powersave system resets, SRR1[42:45] are defined to be + * implementation-dependent. The POWER9 User Manual specifies that + * an external (SCOM driven, which may come from a BMC nmi command or + * another CPU requesting a NMI IPI) system reset exception should be + * 0b0010 (PPC_BIT(44)). + */ + env->spr[SPR_SRR1] |= SRR1_WAKESCOM; + } } static void pnv_nmi(NMIState *n, int cpu_index, Error **errp) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9b358fcc60..3b1a5ed865 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -445,7 +445,8 @@ static int spapr_dt_dynamic_memory_v2(SpaprMachineState *spapr, void *fdt, g_assert(drc); elem = spapr_get_drconf_cell(size / lmb_size, addr, spapr_drc_index(drc), node, - SPAPR_LMB_FLAGS_ASSIGNED); + (SPAPR_LMB_FLAGS_ASSIGNED | + SPAPR_LMB_FLAGS_HOTREMOVABLE)); QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry); nr_entries++; cur_addr = addr + size; diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index e1f76c74f3..9c8c1b14cf 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -407,6 +407,7 @@ static const TypeInfo spapr_cpu_core_type_infos[] = { DEFINE_SPAPR_CPU_CORE_TYPE("power8nvl_v1.0"), DEFINE_SPAPR_CPU_CORE_TYPE("power9_v1.0"), DEFINE_SPAPR_CPU_CORE_TYPE("power9_v2.0"), + DEFINE_SPAPR_CPU_CORE_TYPE("power10_v1.0"), #ifdef CONFIG_KVM DEFINE_SPAPR_CPU_CORE_TYPE("host"), #endif diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c index 3bd05fed12..f2155ddb1d 100644 --- a/hw/vfio/pci-quirks.c +++ b/hw/vfio/pci-quirks.c @@ -1620,7 +1620,7 @@ int vfio_pci_nvidia_v100_ram_init(VFIOPCIDevice *vdev, Error **errp) } cap = (void *) hdr; - p = mmap(NULL, nv2reg->size, PROT_READ | PROT_WRITE | PROT_EXEC, + p = mmap(NULL, nv2reg->size, PROT_READ | PROT_WRITE, MAP_SHARED, vdev->vbasedev.fd, nv2reg->offset); if (p == MAP_FAILED) { ret = -errno; @@ -1680,7 +1680,7 @@ int vfio_pci_nvlink2_init(VFIOPCIDevice *vdev, Error **errp) /* Some NVLink bridges may not have assigned ATSD */ if (atsdreg->size) { - p = mmap(NULL, atsdreg->size, PROT_READ | PROT_WRITE | PROT_EXEC, + p = mmap(NULL, atsdreg->size, PROT_READ | PROT_WRITE, MAP_SHARED, vdev->vbasedev.fd, atsdreg->offset); if (p == MAP_FAILED) { ret = -errno; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index d2533e7264..c421410e3f 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -886,6 +886,7 @@ int spapr_rtc_import_offset(SpaprRtcState *rtc, int64_t legacy_offset); #define SPAPR_LMB_FLAGS_ASSIGNED 0x00000008 #define SPAPR_LMB_FLAGS_DRC_INVALID 0x00000020 #define SPAPR_LMB_FLAGS_RESERVED 0x00000080 +#define SPAPR_LMB_FLAGS_HOTREMOVABLE 0x00000100 void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg); diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c index 5b27f8603e..df71e15a25 100644 --- a/linux-user/ppc/cpu_loop.c +++ b/linux-user/ppc/cpu_loop.c @@ -267,6 +267,7 @@ void cpu_loop(CPUPPCState *env) queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; case POWERPC_EXCP_SYSCALL: /* System call exception */ + case POWERPC_EXCP_SYSCALL_VECTORED: cpu_abort(cs, "Syscall exception while in user mode. " "Aborting\n"); break; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 7db7882f52..1988b436cb 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -127,8 +127,9 @@ enum { POWERPC_EXCP_SDOOR_HV = 100, /* ISA 3.00 additions */ POWERPC_EXCP_HVIRT = 101, + POWERPC_EXCP_SYSCALL_VECTORED = 102, /* scv exception */ /* EOL */ - POWERPC_EXCP_NB = 102, + POWERPC_EXCP_NB = 103, /* QEMU exceptions: used internally during code translation */ POWERPC_EXCP_STOP = 0x200, /* stop translation */ POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */ @@ -475,9 +476,31 @@ typedef struct ppc_v3_pate_t { #define SRR1_PROTFAULT DSISR_PROTFAULT #define SRR1_IAMR DSISR_AMR +/* SRR1[42:45] wakeup fields for System Reset Interrupt */ + +#define SRR1_WAKEMASK 0x003c0000 /* reason for wakeup */ + +#define SRR1_WAKEHMI 0x00280000 /* Hypervisor maintenance */ +#define SRR1_WAKEHVI 0x00240000 /* Hypervisor Virt. Interrupt (P9) */ +#define SRR1_WAKEEE 0x00200000 /* External interrupt */ +#define SRR1_WAKEDEC 0x00180000 /* Decrementer interrupt */ +#define SRR1_WAKEDBELL 0x00140000 /* Privileged doorbell */ +#define SRR1_WAKERESET 0x00100000 /* System reset */ +#define SRR1_WAKEHDBELL 0x000c0000 /* Hypervisor doorbell */ +#define SRR1_WAKESCOM 0x00080000 /* SCOM not in power-saving mode */ + +/* SRR1[46:47] power-saving exit mode */ + +#define SRR1_WAKESTATE 0x00030000 /* Powersave exit mask */ + +#define SRR1_WS_HVLOSS 0x00030000 /* HV resources not maintained */ +#define SRR1_WS_GPRLOSS 0x00020000 /* GPRs not maintained */ +#define SRR1_WS_NOLOSS 0x00010000 /* All resources maintained */ + /* Facility Status and Control (FSCR) bits */ #define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */ #define FSCR_TAR (63 - 55) /* Target Address Register */ +#define FSCR_SCV (63 - 51) /* System call vectored */ /* Interrupt cause mask and position in FSCR. HFSCR has the same format */ #define FSCR_IC_MASK (0xFFULL) #define FSCR_IC_POS (63 - 7) @@ -487,6 +510,7 @@ typedef struct ppc_v3_pate_t { #define FSCR_IC_TM 5 #define FSCR_IC_EBB 7 #define FSCR_IC_TAR 8 +#define FSCR_IC_SCV 12 /* Exception state register bits definition */ #define ESR_PIL PPC_BIT(36) /* Illegal Instruction */ @@ -554,6 +578,8 @@ enum { POWERPC_FLAG_VSX = 0x00080000, /* Has Transaction Memory (ISA 2.07) */ POWERPC_FLAG_TM = 0x00100000, + /* Has SCV (ISA 3.00) */ + POWERPC_FLAG_SCV = 0x00200000, }; /*****************************************************************************/ diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index f052979664..a988ba15f4 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -67,19 +67,31 @@ static inline void dump_syscall(CPUPPCState *env) ppc_dump_gpr(env, 8), env->nip); } +static inline void dump_syscall_vectored(CPUPPCState *env) +{ + qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 + " r3=%016" PRIx64 " r4=%016" PRIx64 " r5=%016" PRIx64 + " r6=%016" PRIx64 " r7=%016" PRIx64 " r8=%016" PRIx64 + " nip=" TARGET_FMT_lx "\n", + ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3), + ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5), + ppc_dump_gpr(env, 6), ppc_dump_gpr(env, 7), + ppc_dump_gpr(env, 8), env->nip); +} + static inline void dump_hcall(CPUPPCState *env) { qemu_log_mask(CPU_LOG_INT, "hypercall r3=%016" PRIx64 - " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 - " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 - " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 + " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64 + " r7=%016" PRIx64 " r8=%016" PRIx64 " r9=%016" PRIx64 + " r10=%016" PRIx64 " r11=%016" PRIx64 " r12=%016" PRIx64 " nip=" TARGET_FMT_lx "\n", ppc_dump_gpr(env, 3), ppc_dump_gpr(env, 4), - ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), - ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), - ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), - ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), - env->nip); + ppc_dump_gpr(env, 5), ppc_dump_gpr(env, 6), + ppc_dump_gpr(env, 7), ppc_dump_gpr(env, 8), + ppc_dump_gpr(env, 9), ppc_dump_gpr(env, 10), + ppc_dump_gpr(env, 11), ppc_dump_gpr(env, 12), + env->nip); } static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, @@ -89,7 +101,7 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, env->resume_as_sreset = false; /* Pretend to be returning from doze always as we don't lose state */ - *msr |= (0x1ull << (63 - 47)); + *msr |= SRR1_WS_NOLOSS; /* Machine checks are sent normally */ if (excp == POWERPC_EXCP_MCHECK) { @@ -97,25 +109,25 @@ static int powerpc_reset_wakeup(CPUState *cs, CPUPPCState *env, int excp, } switch (excp) { case POWERPC_EXCP_RESET: - *msr |= 0x4ull << (63 - 45); + *msr |= SRR1_WAKERESET; break; case POWERPC_EXCP_EXTERNAL: - *msr |= 0x8ull << (63 - 45); + *msr |= SRR1_WAKEEE; break; case POWERPC_EXCP_DECR: - *msr |= 0x6ull << (63 - 45); + *msr |= SRR1_WAKEDEC; break; case POWERPC_EXCP_SDOOR: - *msr |= 0x5ull << (63 - 45); + *msr |= SRR1_WAKEDBELL; break; case POWERPC_EXCP_SDOOR_HV: - *msr |= 0x3ull << (63 - 45); + *msr |= SRR1_WAKEHDBELL; break; case POWERPC_EXCP_HV_MAINT: - *msr |= 0xaull << (63 - 45); + *msr |= SRR1_WAKEHMI; break; case POWERPC_EXCP_HVIRT: - *msr |= 0x9ull << (63 - 45); + *msr |= SRR1_WAKEHVI; break; default: cpu_abort(cs, "Unsupported exception %d in Power Save mode\n", @@ -185,7 +197,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; target_ulong msr, new_msr, vector; - int srr0, srr1, asrr0, asrr1, lev, ail; + int srr0, srr1, asrr0, asrr1, lev = -1, ail; bool lpes0; qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx @@ -421,6 +433,13 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) new_msr |= (target_ulong)MSR_HVB; } break; + case POWERPC_EXCP_SYSCALL_VECTORED: /* scv exception */ + lev = env->error_code; + dump_syscall_vectored(env); + env->nip += 4; + new_msr |= env->msr & ((target_ulong)1 << MSR_EE); + new_msr |= env->msr & ((target_ulong)1 << MSR_RI); + break; case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */ case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */ case POWERPC_EXCP_DECR: /* Decrementer exception */ @@ -724,12 +743,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) break; } - /* Save PC */ - env->spr[srr0] = env->nip; - - /* Save MSR */ - env->spr[srr1] = msr; - /* Sanity check */ if (!(env->msr_mask & MSR_HVB)) { if (new_msr & MSR_HVB) { @@ -742,14 +755,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } } - /* If any alternate SRR register are defined, duplicate saved values */ - if (asrr0 != -1) { - env->spr[asrr0] = env->spr[srr0]; - } - if (asrr1 != -1) { - env->spr[asrr1] = env->spr[srr1]; - } - /* * Sort out endianness of interrupt, this differs depending on the * CPU, the HV mode, etc... @@ -784,14 +789,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } #endif - /* Jump to handler */ - vector = env->excp_vectors[excp]; - if (vector == (target_ulong)-1ULL) { - cpu_abort(cs, "Raised an exception without defined vector %d\n", - excp); - } - vector |= env->excp_prefix; - /* * AIL only works if there is no HV transition and we are running * with translations enabled @@ -800,10 +797,21 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) { ail = 0; } - /* Handle AIL */ - if (ail) { - new_msr |= (1 << MSR_IR) | (1 << MSR_DR); - vector |= ppc_excp_vector_offset(cs, ail); + + vector = env->excp_vectors[excp]; + if (vector == (target_ulong)-1ULL) { + cpu_abort(cs, "Raised an exception without defined vector %d\n", + excp); + } + + vector |= env->excp_prefix; + + /* If any alternate SRR register are defined, duplicate saved values */ + if (asrr0 != -1) { + env->spr[asrr0] = env->nip; + } + if (asrr1 != -1) { + env->spr[asrr1] = msr; } #if defined(TARGET_PPC64) @@ -823,6 +831,37 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) } #endif + if (excp != POWERPC_EXCP_SYSCALL_VECTORED) { + /* Save PC */ + env->spr[srr0] = env->nip; + + /* Save MSR */ + env->spr[srr1] = msr; + + /* Handle AIL */ + if (ail) { + new_msr |= (1 << MSR_IR) | (1 << MSR_DR); + vector |= ppc_excp_vector_offset(cs, ail); + } + +#if defined(TARGET_PPC64) + } else { + /* scv AIL is a little different */ + if (ail) { + new_msr |= (1 << MSR_IR) | (1 << MSR_DR); + } + if (ail == AIL_C000_0000_0000_4000) { + vector |= 0xc000000000003000ull; + } else { + vector |= 0x0000000000017000ull; + } + vector += lev * 0x20; + + env->lr = env->nip; + env->ctr = msr; +#endif + } + powerpc_set_excp_state(cpu, vector, new_msr); } @@ -1160,6 +1199,11 @@ void helper_rfid(CPUPPCState *env) do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]); } +void helper_rfscv(CPUPPCState *env) +{ + do_rfi(env, env->lr, env->ctr); +} + void helper_hrfid(CPUPPCState *env) { do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]); diff --git a/target/ppc/helper.h b/target/ppc/helper.h index a95c010391..2dfa1c6942 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -15,6 +15,7 @@ DEF_HELPER_1(rfmci, void, env) #if defined(TARGET_PPC64) DEF_HELPER_2(pminsn, void, env, i32) DEF_HELPER_1(rfid, void, env) +DEF_HELPER_1(rfscv, void, env) DEF_HELPER_1(hrfid, void, env) DEF_HELPER_2(store_lpcr, void, env, tl) DEF_HELPER_2(store_pcr, void, env, tl) diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c index 1404e53dec..c60bf31357 100644 --- a/target/ppc/mmu-radix64.c +++ b/target/ppc/mmu-radix64.c @@ -28,7 +28,8 @@ #include "mmu-radix64.h" #include "mmu-book3s-v3.h" -static bool ppc_radix64_get_fully_qualified_addr(CPUPPCState *env, vaddr eaddr, +static bool ppc_radix64_get_fully_qualified_addr(const CPUPPCState *env, + vaddr eaddr, uint64_t *lpid, uint64_t *pid) { if (msr_hv) { /* MSR[HV] -> Hypervisor/bare metal */ @@ -49,6 +50,8 @@ static bool ppc_radix64_get_fully_qualified_addr(CPUPPCState *env, vaddr eaddr, *lpid = 0; *pid = 0; break; + default: + g_assert_not_reached(); } } else { /* !MSR[HV] -> Guest */ switch (eaddr & R_EADDR_QUADRANT) { @@ -63,6 +66,8 @@ static bool ppc_radix64_get_fully_qualified_addr(CPUPPCState *env, vaddr eaddr, *lpid = env->spr[SPR_LPIDR]; *pid = 0; /* pid set to 0 -> addresses guest operating system */ break; + default: + g_assert_not_reached(); } } @@ -269,7 +274,7 @@ static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu, int rwx, ppc_v3_pate_t pate, hwaddr *h_raddr, int *h_prot, int *h_page_size, bool pde_addr, - bool cause_excp) + bool guest_visible) { int fault_cause = 0; hwaddr pte_addr; @@ -281,16 +286,18 @@ static int ppc_radix64_partition_scoped_xlate(PowerPCCPU *cpu, int rwx, pate.dw0 & PRTBE_R_RPDS, h_raddr, h_page_size, &pte, &fault_cause, &pte_addr) || ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, h_prot, true)) { - if (pde_addr) /* address being translated was that of a guest pde */ + if (pde_addr) { /* address being translated was that of a guest pde */ fault_cause |= DSISR_PRTABLE_FAULT; - if (cause_excp) { + } + if (guest_visible) { ppc_radix64_raise_hsi(cpu, rwx, eaddr, g_raddr, fault_cause); } return 1; } - /* Update Reference and Change Bits */ - ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, h_prot); + if (guest_visible) { + ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, h_prot); + } return 0; } @@ -299,7 +306,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, vaddr eaddr, uint64_t pid, ppc_v3_pate_t pate, hwaddr *g_raddr, int *g_prot, int *g_page_size, - bool cause_excp) + bool guest_visible) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -313,7 +320,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, size = 1ULL << ((pate.dw1 & PATE1_R_PRTS) + 12); if (offset >= size) { /* offset exceeds size of the process table */ - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE); } return 1; @@ -333,7 +340,8 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, */ ret = ppc_radix64_partition_scoped_xlate(cpu, 0, eaddr, prtbe_addr, pate, &h_raddr, &h_prot, - &h_page_size, 1, 1); + &h_page_size, true, + guest_visible); if (ret) { return ret; } @@ -353,7 +361,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, &fault_cause, &pte_addr); if (ret) { /* No valid PTE */ - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause); } return ret; @@ -372,7 +380,8 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, do { ret = ppc_radix64_partition_scoped_xlate(cpu, 0, eaddr, pte_addr, pate, &h_raddr, &h_prot, - &h_page_size, 1, 1); + &h_page_size, true, + guest_visible); if (ret) { return ret; } @@ -381,7 +390,7 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, &nls, g_page_size, &pte, &fault_cause); if (ret) { /* No valid pte */ - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause); } return ret; @@ -398,13 +407,15 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, if (ppc_radix64_check_prot(cpu, rwx, pte, &fault_cause, g_prot, false)) { /* Access denied due to protection */ - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_si(cpu, rwx, eaddr, fault_cause); } return 1; } - ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, g_prot); + if (guest_visible) { + ppc_radix64_set_rc(cpu, rwx, pte, pte_addr, g_prot); + } return 0; } @@ -429,17 +440,17 @@ static int ppc_radix64_process_scoped_xlate(PowerPCCPU *cpu, int rwx, static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, bool relocation, hwaddr *raddr, int *psizep, int *protp, - bool cause_excp) + bool guest_visible) { CPUPPCState *env = &cpu->env; - uint64_t lpid = 0, pid = 0; + uint64_t lpid, pid; ppc_v3_pate_t pate; int psize, prot; hwaddr g_raddr; /* Virtual Mode Access - get the fully qualified address */ if (!ppc_radix64_get_fully_qualified_addr(&cpu->env, eaddr, &lpid, &pid)) { - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_segi(cpu, rwx, eaddr); } return 1; @@ -452,13 +463,13 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, vhc->get_pate(cpu->vhyp, &pate); } else { if (!ppc64_v3_get_pate(cpu, lpid, &pate)) { - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_NOPTE); } return 1; } if (!validate_pate(cpu, lpid, &pate)) { - if (cause_excp) { + if (guest_visible) { ppc_radix64_raise_si(cpu, rwx, eaddr, DSISR_R_BADCONFIG); } return 1; @@ -479,7 +490,7 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, if (relocation) { int ret = ppc_radix64_process_scoped_xlate(cpu, rwx, eaddr, pid, pate, &g_raddr, &prot, - &psize, cause_excp); + &psize, guest_visible); if (ret) { return ret; } @@ -502,7 +513,7 @@ static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, ret = ppc_radix64_partition_scoped_xlate(cpu, rwx, eaddr, g_raddr, pate, raddr, &prot, &psize, - 0, cause_excp); + false, guest_visible); if (ret) { return ret; } diff --git a/target/ppc/mmu-radix64.h b/target/ppc/mmu-radix64.h index 96228546aa..f28c5794d0 100644 --- a/target/ppc/mmu-radix64.h +++ b/target/ppc/mmu-radix64.h @@ -55,9 +55,9 @@ static inline int ppc_radix64_get_prot_eaa(uint64_t pte) (pte & R_PTE_EAA_X ? PAGE_EXEC : 0); } -static inline int ppc_radix64_get_prot_amr(PowerPCCPU *cpu) +static inline int ppc_radix64_get_prot_amr(const PowerPCCPU *cpu) { - CPUPPCState *env = &cpu->env; + const CPUPPCState *env = &cpu->env; int amr = env->spr[SPR_AMR] >> 62; /* We only care about key0 AMR63:62 */ int iamr = env->spr[SPR_IAMR] >> 62; /* We only care about key0 IAMR63:62 */ diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 338529879f..4ce3d664b5 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -173,6 +173,7 @@ struct DisasContext { bool vsx_enabled; bool spe_enabled; bool tm_enabled; + bool scv_enabled; bool gtse; ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ int singlestep_enabled; @@ -4030,6 +4031,24 @@ static void gen_rfid(DisasContext *ctx) #endif } +#if !defined(CONFIG_USER_ONLY) +static void gen_rfscv(DisasContext *ctx) +{ +#if defined(CONFIG_USER_ONLY) + GEN_PRIV; +#else + /* Restore CPU state */ + CHK_SV; + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { + gen_io_start(); + } + gen_update_cfar(ctx, ctx->base.pc_next - 4); + gen_helper_rfscv(cpu_env); + gen_sync_exception(ctx); +#endif +} +#endif + static void gen_hrfid(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) @@ -4048,6 +4067,7 @@ static void gen_hrfid(DisasContext *ctx) #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER #else #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL +#define POWERPC_SYSCALL_VECTORED POWERPC_EXCP_SYSCALL_VECTORED #endif static void gen_sc(DisasContext *ctx) { @@ -4057,6 +4077,23 @@ static void gen_sc(DisasContext *ctx) gen_exception_err(ctx, POWERPC_SYSCALL, lev); } +#if defined(TARGET_PPC64) +#if !defined(CONFIG_USER_ONLY) +static void gen_scv(DisasContext *ctx) +{ + uint32_t lev; + + if (unlikely(!ctx->scv_enabled)) { + gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_SCV); + return; + } + + lev = (ctx->opcode >> 5) & 0x7F; + gen_exception_err(ctx, POWERPC_SYSCALL_VECTORED, lev); +} +#endif +#endif + /*** Trap ***/ /* Check for unconditional traps (always or never) */ @@ -7049,6 +7086,12 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER), GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW), #if defined(TARGET_PPC64) GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B), +#if !defined(CONFIG_USER_ONLY) +/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */ +GEN_HANDLER_E(scv, 0x11, 0x10, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300), +GEN_HANDLER_E(scv, 0x11, 0x00, 0xFF, 0x03FFF01E, PPC_NONE, PPC2_ISA300), +GEN_HANDLER_E(rfscv, 0x13, 0x12, 0x02, 0x03FF8001, PPC_NONE, PPC2_ISA300), +#endif GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), @@ -7056,7 +7099,9 @@ GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206), GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H), #endif -GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW), +/* Top bit of opc2 corresponds with low bit of LEV, so use two handlers */ +GEN_HANDLER(sc, 0x11, 0x11, 0xFF, 0x03FFF01D, PPC_FLOW), +GEN_HANDLER(sc, 0x11, 0x01, 0xFF, 0x03FFF01D, PPC_FLOW), GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW), GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW), #if defined(TARGET_PPC64) @@ -7835,6 +7880,12 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) } else { ctx->vsx_enabled = false; } + if ((env->flags & POWERPC_FLAG_SCV) + && (env->spr[SPR_FSCR] & (1ull << FSCR_SCV))) { + ctx->scv_enabled = true; + } else { + ctx->scv_enabled = false; + } #if defined(TARGET_PPC64) if ((env->flags & POWERPC_FLAG_TM) && msr_tm) { ctx->tm_enabled = !!msr_tm; diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index d8adc1bd49..38cb773ab4 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -3382,6 +3382,7 @@ static void init_excp_POWER9(CPUPPCState *env) #if !defined(CONFIG_USER_ONLY) env->excp_vectors[POWERPC_EXCP_HVIRT] = 0x00000EA0; + env->excp_vectors[POWERPC_EXCP_SYSCALL_VECTORED] = 0x00000000; #endif } @@ -9030,7 +9031,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | - POWERPC_FLAG_VSX | POWERPC_FLAG_TM; + POWERPC_FLAG_VSX | POWERPC_FLAG_TM | POWERPC_FLAG_SCV; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; diff --git a/tests/qtest/endianness-test.c b/tests/qtest/endianness-test.c index 2798802c63..cc088ac01a 100644 --- a/tests/qtest/endianness-test.c +++ b/tests/qtest/endianness-test.c @@ -33,7 +33,7 @@ static const TestCase test_cases[] = { { "mips64", "pica61", 0x90000000, .bswap = true }, { "mips64", "mips", 0x14000000, .bswap = true }, { "mips64", "malta", 0x10000000, .bswap = true }, - { "mips64el", "fulong2e", 0x1fd00000 }, + { "mips64el", "fuloong2e", 0x1fd00000 }, { "ppc", "g3beige", 0xfe000000, .bswap = true, .superio = "i82378" }, { "ppc", "40p", 0x80000000, .bswap = true }, { "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" }, |