From e7a65ba694d84592d190644d8d0ae4ea9137c35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 30 Dec 2022 15:35:24 +0100 Subject: [PATCH 01/46] hw/mips/malta: Split FPGA LEDs/ASCII display updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to refresh the ASCII bar when a LED is toggled (and vice versa). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230104133935.4639-3-philmd@linaro.org> --- hw/mips/malta.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index c0a2e0ab04..e9424150aa 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -106,11 +106,10 @@ static struct _loaderparams { } loaderparams; /* Malta FPGA */ -static void malta_fpga_update_display(void *opaque) +static void malta_fpga_update_display_leds(MaltaFPGAState *s) { char leds_text[9]; int i; - MaltaFPGAState *s = opaque; for (i = 7 ; i >= 0 ; i--) { if (s->leds & (1 << i)) { @@ -123,6 +122,10 @@ static void malta_fpga_update_display(void *opaque) qemu_chr_fe_printf(&s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text); +} + +static void malta_fpga_update_display_ascii(MaltaFPGAState *s) +{ qemu_chr_fe_printf(&s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text); } @@ -457,13 +460,13 @@ static void malta_fpga_write(void *opaque, hwaddr addr, /* LEDBAR Register */ case 0x00408: s->leds = val & 0xff; - malta_fpga_update_display(s); + malta_fpga_update_display_leds(s); break; /* ASCIIWORD Register */ case 0x00410: snprintf(s->display_text, 9, "%08X", (uint32_t)val); - malta_fpga_update_display(s); + malta_fpga_update_display_ascii(s); break; /* ASCIIPOS0 to ASCIIPOS7 Registers */ @@ -476,7 +479,7 @@ static void malta_fpga_write(void *opaque, hwaddr addr, case 0x00448: case 0x00450: s->display_text[(saddr - 0x00418) >> 3] = (char) val; - malta_fpga_update_display(s); + malta_fpga_update_display_ascii(s); break; /* SOFTRES Register */ From 9f81e43f10496bc225a9bbed3d56a26b9f759fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 30 Dec 2022 15:35:24 +0100 Subject: [PATCH 02/46] hw/mips/malta: Trace FPGA LEDs/ASCII display updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The FPGA LEDs/ASCII display is mostly used by the bootloader to show very low-level debug info. QEMU connects its output to a character device backend, which is not very practical to correlate with ASM instruction executed, interrupts or MMIO accesses. Also, the display discard the previous states. To ease bootloader debugging experience, add a pair of trace events. Such events can be analyzed over time or diff-ed between different runs. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230104133935.4639-4-philmd@linaro.org> --- hw/mips/malta.c | 3 +++ hw/mips/trace-events | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index e9424150aa..44d88a24a7 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -58,6 +58,7 @@ #include "semihosting/semihost.h" #include "hw/mips/cps.h" #include "hw/qdev-clock.h" +#include "trace.h" #define ENVP_PADDR 0x2000 #define ENVP_VADDR cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR) @@ -120,12 +121,14 @@ static void malta_fpga_update_display_leds(MaltaFPGAState *s) } leds_text[8] = '\0'; + trace_malta_fpga_leds(leds_text); qemu_chr_fe_printf(&s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text); } static void malta_fpga_update_display_ascii(MaltaFPGAState *s) { + trace_malta_fpga_display(s->display_text); qemu_chr_fe_printf(&s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text); } diff --git a/hw/mips/trace-events b/hw/mips/trace-events index 13ee731a48..b5b882c6c2 100644 --- a/hw/mips/trace-events +++ b/hw/mips/trace-events @@ -4,3 +4,7 @@ gt64120_write(uint64_t addr, uint64_t value) "gt64120 write 0x%03"PRIx64" value: gt64120_read_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 read %s size:%u value:0x%08" PRIx64 gt64120_write_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 write %s size:%u value:0x%08" PRIx64 gt64120_isd_remap(uint64_t from_length, uint64_t from_addr, uint64_t to_length, uint64_t to_addr) "ISD: 0x%08" PRIx64 "@0x%08" PRIx64 " -> 0x%08" PRIx64 "@0x%08" PRIx64 + +# malta.c +malta_fpga_leds(const char *text) "LEDs %s" +malta_fpga_display(const char *text) "ASCII '%s'" From 65423e6efeac1ee1057870361337c572c941140c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 4 Jan 2023 09:35:22 +0100 Subject: [PATCH 03/46] hw/mips/gt64xxx_pci: Accumulate address space changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Single registers access in ISD can produce multiple changes in the address spaces. To reduce computational effort, accumulate these as a single memory transaction. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230104133935.4639-5-philmd@linaro.org> --- hw/mips/gt64xxx_pci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 164866cf3e..65416c7b27 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -282,6 +282,8 @@ static void gt64120_isd_mapping(GT64120State *s) hwaddr start = ((hwaddr)s->regs[GT_ISD] << 21) & 0xFFFE00000ull; hwaddr length = 0x1000; + memory_region_transaction_begin(); + if (s->ISD_length) { memory_region_del_subregion(get_system_memory(), &s->ISD_mem); } @@ -292,10 +294,14 @@ static void gt64120_isd_mapping(GT64120State *s) s->ISD_start = start; s->ISD_length = length; memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem); + + memory_region_transaction_commit(); } static void gt64120_pci_mapping(GT64120State *s) { + memory_region_transaction_begin(); + /* Update PCI0IO mapping */ if ((s->regs[GT_PCI0IOLD] & 0x7f) <= s->regs[GT_PCI0IOHD]) { /* Unmap old IO address */ @@ -354,6 +360,8 @@ static void gt64120_pci_mapping(GT64120State *s) &s->PCI0M1_mem); } } + + memory_region_transaction_commit(); } static int gt64120_post_load(void *opaque, int version_id) From 145e2198d749ec09a405f1607a9932499b76f1eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 4 Jan 2023 10:03:14 +0100 Subject: [PATCH 04/46] hw/mips/gt64xxx_pci: Endian-swap using PCI_HOST_BRIDGE MemoryRegionOps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GT64120's PCI endianness swapping works on little-endian hosts, but doesn't on big-endian ones. Instead of complicating how CFGADDR/CFGDATA registers deal with endianness, use the existing MemoryRegionOps from hw/pci/pci_host.c. Doing so also reduce the access to internal PCI_HOST_BRIDGE fields. Map the PCI_HOST_BRIDGE MemoryRegionOps into the corresponding CFGADDR/CFGDATA regions in the ISD MMIO and remove the unused code in the current ISD read/write handlers. Update the mapping when PCI0_CMD register is accessed (in case the endianness is changed). This allows using the GT64120 on a big-endian host (and boot the MIPS Malta machine in little-endian). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230104133935.4639-6-philmd@linaro.org> --- hw/mips/gt64xxx_pci.c | 70 ++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 20 deletions(-) diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 65416c7b27..81232514c5 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -298,6 +298,50 @@ static void gt64120_isd_mapping(GT64120State *s) memory_region_transaction_commit(); } +static void gt64120_update_pci_cfgdata_mapping(GT64120State *s) +{ + /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */ + static const MemoryRegionOps *pci_host_conf_ops[] = { + &pci_host_conf_be_ops, &pci_host_conf_le_ops + }; + static const MemoryRegionOps *pci_host_data_ops[] = { + &pci_host_data_be_ops, &pci_host_data_le_ops + }; + PCIHostState *phb = PCI_HOST_BRIDGE(s); + + memory_region_transaction_begin(); + + /* + * The setting of the MByteSwap bit and MWordSwap bit in the PCI Internal + * Command Register determines how data transactions from the CPU to/from + * PCI are handled along with the setting of the Endianess bit in the CPU + * Configuration Register. See: + * - Table 16: 32-bit PCI Transaction Endianess + * - Table 158: PCI_0 Command, Offset: 0xc00 + */ + if (memory_region_is_mapped(&phb->conf_mem)) { + memory_region_del_subregion(&s->ISD_mem, &phb->conf_mem); + object_unparent(OBJECT(&phb->conf_mem)); + } + memory_region_init_io(&phb->conf_mem, OBJECT(phb), + pci_host_conf_ops[s->regs[GT_PCI0_CMD] & 1], + s, "pci-conf-idx", 4); + memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2, + &phb->conf_mem, 1); + + if (memory_region_is_mapped(&phb->data_mem)) { + memory_region_del_subregion(&s->ISD_mem, &phb->data_mem); + object_unparent(OBJECT(&phb->data_mem)); + } + memory_region_init_io(&phb->data_mem, OBJECT(phb), + pci_host_data_ops[s->regs[GT_PCI0_CMD] & 1], + s, "pci-conf-data", 4); + memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGDATA << 2, + &phb->data_mem, 1); + + memory_region_transaction_commit(); +} + static void gt64120_pci_mapping(GT64120State *s) { memory_region_transaction_begin(); @@ -389,7 +433,6 @@ static void gt64120_writel(void *opaque, hwaddr addr, uint64_t val, unsigned size) { GT64120State *s = opaque; - PCIHostState *phb = PCI_HOST_BRIDGE(s); uint32_t saddr = addr >> 2; trace_gt64120_write(addr, val); @@ -592,6 +635,7 @@ static void gt64120_writel(void *opaque, hwaddr addr, case GT_PCI0_CMD: case GT_PCI1_CMD: s->regs[saddr] = val & 0x0401fc0f; + gt64120_update_pci_cfgdata_mapping(s); break; case GT_PCI0_TOR: case GT_PCI0_BS_SCS10: @@ -632,15 +676,9 @@ static void gt64120_writel(void *opaque, hwaddr addr, saddr << 2, size, size << 1, val); break; case GT_PCI0_CFGADDR: - phb->config_reg = val & 0x80fffffc; - break; case GT_PCI0_CFGDATA: - if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) { - val = bswap32(val); - } - if (phb->config_reg & (1u << 31)) { - pci_data_write(phb->bus, phb->config_reg, val, 4); - } + /* Mapped via in gt64120_pci_mapping() */ + g_assert_not_reached(); break; /* Interrupts */ @@ -698,7 +736,6 @@ static uint64_t gt64120_readl(void *opaque, hwaddr addr, unsigned size) { GT64120State *s = opaque; - PCIHostState *phb = PCI_HOST_BRIDGE(s); uint32_t val; uint32_t saddr = addr >> 2; @@ -883,17 +920,9 @@ static uint64_t gt64120_readl(void *opaque, /* PCI Internal */ case GT_PCI0_CFGADDR: - val = phb->config_reg; - break; case GT_PCI0_CFGDATA: - if (!(phb->config_reg & (1 << 31))) { - val = 0xffffffff; - } else { - val = pci_data_read(phb->bus, phb->config_reg, 4); - } - if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) { - val = bswap32(val); - } + /* Mapped via in gt64120_pci_mapping() */ + g_assert_not_reached(); break; case GT_PCI0_CMD: @@ -1153,6 +1182,7 @@ static void gt64120_reset(DeviceState *dev) gt64120_isd_mapping(s); gt64120_pci_mapping(s); + gt64120_update_pci_cfgdata_mapping(s); } static void gt64120_realize(DeviceState *dev, Error **errp) From 7c032bfbe838c24dcbdc8f9c452553b24f20daad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 10 Mar 2019 02:25:07 +0100 Subject: [PATCH 05/46] hw/mips/Kconfig: Introduce CONFIG_GT64120 to select gt64xxx_pci.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Bernhard Beschow Message-Id: <20221209151533.69516-2-philmd@linaro.org> Reviewed-by: Richard Henderson --- hw/mips/Kconfig | 6 ++++++ hw/mips/meson.build | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index 725525358d..d6bbbe7069 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -1,5 +1,6 @@ config MALTA bool + select GT64120 select ISA_SUPERIO config MIPSSIM @@ -59,3 +60,8 @@ config MIPS_BOSTON config FW_CFG_MIPS bool + +config GT64120 + bool + select PCI + select I8259 diff --git a/hw/mips/meson.build b/hw/mips/meson.build index dd0101ad4d..6ccd385df0 100644 --- a/hw/mips/meson.build +++ b/hw/mips/meson.build @@ -2,7 +2,8 @@ mips_ss = ss.source_set() mips_ss.add(files('bootloader.c', 'mips_int.c')) mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c')) mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 'loongson3_virt.c')) -mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c')) +mips_ss.add(when: 'CONFIG_MALTA', if_true: files('malta.c')) +mips_ss.add(when: 'CONFIG_GT64120', if_true: files('gt64xxx_pci.c')) mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c')) if 'CONFIG_TCG' in config_all From 37e506b69a6791bede30677f05081296f3b77f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 2 Mar 2021 23:42:56 +0100 Subject: [PATCH 06/46] hw/mips/gt64xxx_pci: Let the GT64120 manage the lower 512MiB hole MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the comment in the Malta board, the [0x0000.0000-0x2000.0000] range is decoded by the GT64120, so move the "empty_slot" there. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221209151533.69516-3-philmd@linaro.org> Reviewed-by: Richard Henderson --- configs/devices/mips-softmmu/common.mak | 1 - hw/mips/Kconfig | 1 + hw/mips/gt64xxx_pci.c | 8 ++++++++ hw/mips/malta.c | 7 ------- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak index 88aff94625..a125e74f24 100644 --- a/configs/devices/mips-softmmu/common.mak +++ b/configs/devices/mips-softmmu/common.mak @@ -24,7 +24,6 @@ CONFIG_IDE_ISA=y CONFIG_PFLASH_CFI01=y CONFIG_I8259=y CONFIG_MC146818RTC=y -CONFIG_EMPTY_SLOT=y CONFIG_MIPS_CPS=y CONFIG_MIPS_ITU=y CONFIG_MALTA=y diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index d6bbbe7069..8f7bce38fb 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -64,4 +64,5 @@ config FW_CFG_MIPS config GT64120 bool select PCI + select EMPTY_SLOT select I8259 diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 81232514c5..7ba052a2e0 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -28,6 +28,7 @@ #include "qemu/log.h" #include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" +#include "hw/misc/empty_slot.h" #include "migration/vmstate.h" #include "hw/intc/i8259.h" #include "hw/irq.h" @@ -1200,6 +1201,13 @@ static void gt64120_realize(DeviceState *dev, Error **errp) PCI_DEVFN(18, 0), TYPE_PCI_BUS); pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci"); + + /* + * The whole address space decoded by the GT-64120A doesn't generate + * exception when accessing invalid memory. Create an empty slot to + * emulate this feature. + */ + empty_slot_init("GT64120", 0, 0x20000000); } static void gt64120_pci_realize(PCIDevice *d, Error **errp) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 44d88a24a7..c8fc420e4f 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -53,7 +53,6 @@ #include "sysemu/runstate.h" #include "qapi/error.h" #include "qemu/error-report.h" -#include "hw/misc/empty_slot.h" #include "sysemu/kvm.h" #include "semihosting/semihost.h" #include "hw/mips/cps.h" @@ -1399,12 +1398,6 @@ void mips_malta_init(MachineState *machine) /* Northbridge */ dev = sysbus_create_simple("gt64120", -1, NULL); pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci")); - /* - * The whole address space decoded by the GT-64120A doesn't generate - * exception when accessing invalid memory. Create an empty slot to - * emulate this feature. - */ - empty_slot_init("GT64120", 0, 0x20000000); /* Southbridge */ piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true, From 81ad24762d4295bbe1e2216b21d1e90b81d351a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 02:00:42 +0200 Subject: [PATCH 07/46] hw/mips/gt64xxx_pci: Manage endian bits with the RegisterFields API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221220113436.14299-4-philmd@linaro.org> Reviewed-by: Richard Henderson --- hw/mips/gt64xxx_pci.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 7ba052a2e0..85bdf5279c 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -26,6 +26,7 @@ #include "qapi/error.h" #include "qemu/units.h" #include "qemu/log.h" +#include "hw/registerfields.h" #include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" #include "hw/misc/empty_slot.h" @@ -41,6 +42,9 @@ #define GT_CPU (0x000 >> 2) #define GT_MULTI (0x120 >> 2) +REG32(GT_CPU, 0x000) +FIELD(GT_CPU, Endianness, 12, 1) + /* CPU Address Decode */ #define GT_SCS10LD (0x008 >> 2) #define GT_SCS10HD (0x010 >> 2) @@ -210,6 +214,17 @@ #define GT_PCI0_CFGADDR (0xcf8 >> 2) #define GT_PCI0_CFGDATA (0xcfc >> 2) +REG32(GT_PCI0_CMD, 0xc00) +FIELD(GT_PCI0_CMD, MByteSwap, 0, 1) +FIELD(GT_PCI0_CMD, SByteSwap, 16, 1) +#define R_GT_PCI0_CMD_ByteSwap_MASK \ + (R_GT_PCI0_CMD_MByteSwap_MASK | R_GT_PCI0_CMD_SByteSwap_MASK) +REG32(GT_PCI1_CMD, 0xc80) +FIELD(GT_PCI1_CMD, MByteSwap, 0, 1) +FIELD(GT_PCI1_CMD, SByteSwap, 16, 1) +#define R_GT_PCI1_CMD_ByteSwap_MASK \ + (R_GT_PCI1_CMD_MByteSwap_MASK | R_GT_PCI1_CMD_SByteSwap_MASK) + /* Interrupts */ #define GT_INTRCAUSE (0xc18 >> 2) #define GT_INTRMASK (0xc1c >> 2) @@ -1020,15 +1035,16 @@ static const MemoryRegionOps isd_mem_ops = { static void gt64120_reset(DeviceState *dev) { GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev); +#if TARGET_BIG_ENDIAN + bool cpu_little_endian = false; +#else + bool cpu_little_endian = true; +#endif /* FIXME: Malta specific hw assumptions ahead */ /* CPU Configuration */ -#if TARGET_BIG_ENDIAN - s->regs[GT_CPU] = 0x00000000; -#else - s->regs[GT_CPU] = 0x00001000; -#endif + s->regs[GT_CPU] = cpu_little_endian ? R_GT_CPU_Endianness_MASK : 0; s->regs[GT_MULTI] = 0x00000003; /* CPU Address decode */ @@ -1135,11 +1151,7 @@ static void gt64120_reset(DeviceState *dev) s->regs[GT_TC_CONTROL] = 0x00000000; /* PCI Internal */ -#if TARGET_BIG_ENDIAN - s->regs[GT_PCI0_CMD] = 0x00000000; -#else - s->regs[GT_PCI0_CMD] = 0x00010001; -#endif + s->regs[GT_PCI0_CMD] = cpu_little_endian ? R_GT_PCI0_CMD_ByteSwap_MASK : 0; s->regs[GT_PCI0_TOR] = 0x0000070f; s->regs[GT_PCI0_BS_SCS10] = 0x00fff000; s->regs[GT_PCI0_BS_SCS32] = 0x00fff000; @@ -1156,11 +1168,7 @@ static void gt64120_reset(DeviceState *dev) s->regs[GT_PCI0_SSCS10_BAR] = 0x00000000; s->regs[GT_PCI0_SSCS32_BAR] = 0x01000000; s->regs[GT_PCI0_SCS3BT_BAR] = 0x1f000000; -#if TARGET_BIG_ENDIAN - s->regs[GT_PCI1_CMD] = 0x00000000; -#else - s->regs[GT_PCI1_CMD] = 0x00010001; -#endif + s->regs[GT_PCI1_CMD] = cpu_little_endian ? R_GT_PCI1_CMD_ByteSwap_MASK : 0; s->regs[GT_PCI1_TOR] = 0x0000070f; s->regs[GT_PCI1_BS_SCS10] = 0x00fff000; s->regs[GT_PCI1_BS_SCS32] = 0x00fff000; From a699b915ded075b6253bebf50ec5dc2040d23612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 24 Jun 2019 17:06:24 +0200 Subject: [PATCH 08/46] hw/mips/gt64xxx_pci: Add a 'cpu-little-endian' qdev property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This device does not have to be TARGET-dependent. Add a 'cpu_big_endian' property which sets the byte-swapping options if required. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221220113436.14299-5-philmd@linaro.org> Reviewed-by: Richard Henderson --- hw/mips/gt64xxx_pci.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 85bdf5279c..79c15a5e3a 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -26,6 +26,7 @@ #include "qapi/error.h" #include "qemu/units.h" #include "qemu/log.h" +#include "hw/qdev-properties.h" #include "hw/registerfields.h" #include "hw/pci/pci_device.h" #include "hw/pci/pci_host.h" @@ -256,6 +257,9 @@ struct GT64120State { PCI_MAPPING_ENTRY(ISD); MemoryRegion pci0_mem; AddressSpace pci0_mem_as; + + /* properties */ + bool cpu_little_endian; }; /* Adjust range to avoid touching space which isn't mappable via PCI */ @@ -1035,16 +1039,11 @@ static const MemoryRegionOps isd_mem_ops = { static void gt64120_reset(DeviceState *dev) { GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev); -#if TARGET_BIG_ENDIAN - bool cpu_little_endian = false; -#else - bool cpu_little_endian = true; -#endif /* FIXME: Malta specific hw assumptions ahead */ /* CPU Configuration */ - s->regs[GT_CPU] = cpu_little_endian ? R_GT_CPU_Endianness_MASK : 0; + s->regs[GT_CPU] = s->cpu_little_endian ? R_GT_CPU_Endianness_MASK : 0; s->regs[GT_MULTI] = 0x00000003; /* CPU Address decode */ @@ -1151,7 +1150,7 @@ static void gt64120_reset(DeviceState *dev) s->regs[GT_TC_CONTROL] = 0x00000000; /* PCI Internal */ - s->regs[GT_PCI0_CMD] = cpu_little_endian ? R_GT_PCI0_CMD_ByteSwap_MASK : 0; + s->regs[GT_PCI0_CMD] = s->cpu_little_endian ? R_GT_PCI0_CMD_ByteSwap_MASK : 0; s->regs[GT_PCI0_TOR] = 0x0000070f; s->regs[GT_PCI0_BS_SCS10] = 0x00fff000; s->regs[GT_PCI0_BS_SCS32] = 0x00fff000; @@ -1168,7 +1167,7 @@ static void gt64120_reset(DeviceState *dev) s->regs[GT_PCI0_SSCS10_BAR] = 0x00000000; s->regs[GT_PCI0_SSCS32_BAR] = 0x01000000; s->regs[GT_PCI0_SCS3BT_BAR] = 0x1f000000; - s->regs[GT_PCI1_CMD] = cpu_little_endian ? R_GT_PCI1_CMD_ByteSwap_MASK : 0; + s->regs[GT_PCI1_CMD] = s->cpu_little_endian ? R_GT_PCI1_CMD_ByteSwap_MASK : 0; s->regs[GT_PCI1_TOR] = 0x0000070f; s->regs[GT_PCI1_BS_SCS10] = 0x00fff000; s->regs[GT_PCI1_BS_SCS32] = 0x00fff000; @@ -1262,11 +1261,18 @@ static const TypeInfo gt64120_pci_info = { }, }; +static Property gt64120_properties[] = { + DEFINE_PROP_BOOL("cpu-little-endian", GT64120State, + cpu_little_endian, !TARGET_BIG_ENDIAN), + DEFINE_PROP_END_OF_LIST(), +}; + static void gt64120_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + device_class_set_props(dc, gt64120_properties); dc->realize = gt64120_realize; dc->reset = gt64120_reset; dc->vmsd = &vmstate_gt64120; From fae45dd53dcf4029e30b0915efcc62dfd56bdee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 01:54:06 +0200 Subject: [PATCH 09/46] hw/mips/malta: Explicit GT64120 endianness upon device creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Propagate the controller endianess from the machine, setting the "cpu-little-endian" property. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221209151533.69516-6-philmd@linaro.org> Reviewed-by: Richard Henderson --- hw/mips/malta.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index c8fc420e4f..f959bce673 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -1396,7 +1396,9 @@ void mips_malta_init(MachineState *machine) stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420); /* Northbridge */ - dev = sysbus_create_simple("gt64120", -1, NULL); + dev = qdev_new("gt64120"); + qdev_prop_set_bit(dev, "cpu-little-endian", !be); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci")); /* Southbridge */ From 90f7d0b4940be29259f6977d2df2ca09495680e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 21 May 2021 15:41:49 +0200 Subject: [PATCH 10/46] hw/mips/meson: Make gt64xxx_pci.c endian-agnostic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The single machine using this device explicitly sets its endianness. We don't need to set a default. This allow us to remove the target specificity from the build system. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221209151533.69516-7-philmd@linaro.org> Reviewed-by: Richard Henderson --- hw/mips/gt64xxx_pci.c | 2 +- hw/mips/meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 79c15a5e3a..f226d03420 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -1263,7 +1263,7 @@ static const TypeInfo gt64120_pci_info = { static Property gt64120_properties[] = { DEFINE_PROP_BOOL("cpu-little-endian", GT64120State, - cpu_little_endian, !TARGET_BIG_ENDIAN), + cpu_little_endian, false), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/mips/meson.build b/hw/mips/meson.build index 6ccd385df0..152103f15f 100644 --- a/hw/mips/meson.build +++ b/hw/mips/meson.build @@ -3,7 +3,7 @@ mips_ss.add(files('bootloader.c', 'mips_int.c')) mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c')) mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 'loongson3_virt.c')) mips_ss.add(when: 'CONFIG_MALTA', if_true: files('malta.c')) -mips_ss.add(when: 'CONFIG_GT64120', if_true: files('gt64xxx_pci.c')) +softmmu_ss.add(when: 'CONFIG_GT64120', if_true: files('gt64xxx_pci.c')) mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c')) if 'CONFIG_TCG' in config_all From a7db759ef70fdc6ec7e79c603d3daf7c87113bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 13 Jan 2023 09:20:12 +0100 Subject: [PATCH 11/46] hw/mips/gt64xxx_pci: Move it to hw/pci-host/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GT-64120 is a north-bridge, and it is not MIPS specific. Move it with the other north-bridge devices. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221209151533.69516-8-philmd@linaro.org> Reviewed-by: Richard Henderson --- MAINTAINERS | 2 +- hw/mips/Kconfig | 6 ------ hw/mips/meson.build | 1 - hw/mips/trace-events | 7 ------- hw/pci-host/Kconfig | 6 ++++++ hw/{mips/gt64xxx_pci.c => pci-host/gt64120.c} | 0 hw/pci-host/meson.build | 1 + hw/pci-host/trace-events | 7 +++++++ 8 files changed, 15 insertions(+), 15 deletions(-) rename hw/{mips/gt64xxx_pci.c => pci-host/gt64120.c} (100%) diff --git a/MAINTAINERS b/MAINTAINERS index 5606e5dbd2..a670fbc926 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1241,7 +1241,7 @@ S: Odd Fixes F: hw/isa/piix4.c F: hw/acpi/piix4.c F: hw/mips/malta.c -F: hw/mips/gt64xxx_pci.c +F: hw/pci-host/gt64120.c F: include/hw/southbridge/piix.h F: tests/avocado/linux_ssh_mips_malta.py F: tests/avocado/machine_mips_malta.py diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index 8f7bce38fb..7a55143f8a 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -60,9 +60,3 @@ config MIPS_BOSTON config FW_CFG_MIPS bool - -config GT64120 - bool - select PCI - select EMPTY_SLOT - select I8259 diff --git a/hw/mips/meson.build b/hw/mips/meson.build index 152103f15f..900613fc08 100644 --- a/hw/mips/meson.build +++ b/hw/mips/meson.build @@ -3,7 +3,6 @@ mips_ss.add(files('bootloader.c', 'mips_int.c')) mips_ss.add(when: 'CONFIG_FW_CFG_MIPS', if_true: files('fw_cfg.c')) mips_ss.add(when: 'CONFIG_LOONGSON3V', if_true: files('loongson3_bootp.c', 'loongson3_virt.c')) mips_ss.add(when: 'CONFIG_MALTA', if_true: files('malta.c')) -softmmu_ss.add(when: 'CONFIG_GT64120', if_true: files('gt64xxx_pci.c')) mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c')) if 'CONFIG_TCG' in config_all diff --git a/hw/mips/trace-events b/hw/mips/trace-events index b5b882c6c2..4a4e5fe1a1 100644 --- a/hw/mips/trace-events +++ b/hw/mips/trace-events @@ -1,10 +1,3 @@ -# gt64xxx_pci.c -gt64120_read(uint64_t addr, uint64_t value) "gt64120 read 0x%03"PRIx64" value:0x%08" PRIx64 -gt64120_write(uint64_t addr, uint64_t value) "gt64120 write 0x%03"PRIx64" value:0x%08" PRIx64 -gt64120_read_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 read %s size:%u value:0x%08" PRIx64 -gt64120_write_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 write %s size:%u value:0x%08" PRIx64 -gt64120_isd_remap(uint64_t from_length, uint64_t from_addr, uint64_t to_length, uint64_t to_addr) "ISD: 0x%08" PRIx64 "@0x%08" PRIx64 " -> 0x%08" PRIx64 "@0x%08" PRIx64 - # malta.c malta_fpga_leds(const char *text) "LEDs %s" malta_fpga_display(const char *text) "ASCII '%s'" diff --git a/hw/pci-host/Kconfig b/hw/pci-host/Kconfig index 38fd2ee8f3..a07070eddf 100644 --- a/hw/pci-host/Kconfig +++ b/hw/pci-host/Kconfig @@ -81,3 +81,9 @@ config MV64361 config DINO bool select PCI + +config GT64120 + bool + select PCI + select EMPTY_SLOT + select I8259 diff --git a/hw/mips/gt64xxx_pci.c b/hw/pci-host/gt64120.c similarity index 100% rename from hw/mips/gt64xxx_pci.c rename to hw/pci-host/gt64120.c diff --git a/hw/pci-host/meson.build b/hw/pci-host/meson.build index e832babc9d..9a813d552e 100644 --- a/hw/pci-host/meson.build +++ b/hw/pci-host/meson.build @@ -1,6 +1,7 @@ pci_ss = ss.source_set() pci_ss.add(when: 'CONFIG_PAM', if_true: files('pam.c')) pci_ss.add(when: 'CONFIG_PCI_BONITO', if_true: files('bonito.c')) +pci_ss.add(when: 'CONFIG_GT64120', if_true: files('gt64120.c')) pci_ss.add(when: 'CONFIG_PCI_EXPRESS_DESIGNWARE', if_true: files('designware.c')) pci_ss.add(when: 'CONFIG_PCI_EXPRESS_GENERIC_BRIDGE', if_true: files('gpex.c')) pci_ss.add(when: ['CONFIG_PCI_EXPRESS_GENERIC_BRIDGE', 'CONFIG_ACPI'], if_true: files('gpex-acpi.c')) diff --git a/hw/pci-host/trace-events b/hw/pci-host/trace-events index 437e66ff50..9d216bb89f 100644 --- a/hw/pci-host/trace-events +++ b/hw/pci-host/trace-events @@ -6,6 +6,13 @@ bonito_spciconf_small_access(uint64_t addr, unsigned size) "PCI config address i # grackle.c grackle_set_irq(int irq_num, int level) "set_irq num %d level %d" +# gt64120.c +gt64120_read(uint64_t addr, uint64_t value) "gt64120 read 0x%03"PRIx64" value:0x%08" PRIx64 +gt64120_write(uint64_t addr, uint64_t value) "gt64120 write 0x%03"PRIx64" value:0x%08" PRIx64 +gt64120_read_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 read %s size:%u value:0x%08" PRIx64 +gt64120_write_intreg(const char *regname, unsigned size, uint64_t value) "gt64120 write %s size:%u value:0x%08" PRIx64 +gt64120_isd_remap(uint64_t from_length, uint64_t from_addr, uint64_t to_length, uint64_t to_addr) "ISD: 0x%08" PRIx64 "@0x%08" PRIx64 " -> 0x%08" PRIx64 "@0x%08" PRIx64 + # mv64361.c mv64361_region_map(const char *name, uint64_t poffs, uint64_t size, uint64_t moffs) "Mapping %s 0x%"PRIx64"+0x%"PRIx64" @ 0x%"PRIx64 mv64361_region_enable(const char *op, int num) "Should %s region %d" From 14c2b18414ee88a175b4855361dfbdaa836e0491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 30 Dec 2022 21:53:42 +0100 Subject: [PATCH 12/46] tests/avocado: Add tests booting YAMON ROM on MIPS Malta machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add quick tests booting YAMON: $ avocado --show=app,console run -t machine:malta tests/avocado/machine_mips_malta.py (1/2) tests/avocado/machine_mips_malta.py:MaltaMachine.test_mipsel_malta_yamon: console: YAMON ROM Monitor, Revision 02.22. console: Copyright (c) 1999-2007 MIPS Technologies, Inc. - All Rights Reserved. console: For a list of available commands, type 'help'. console: Compilation time = May 24 2013 12:16:34 (pburton) console: Board type/revision = 0x02 (Malta) / 0x00 console: Core board type/revision = 0x01 (CoreLV) / 0x00 console: System controller/revision = Galileo / GT_64120A-B-0 console: FPGA revision = 0x0000 console: MAC address = ff.ff.ff.ff.ff.ff console: Board S/N = 0123456789 console: PCI bus frequency = 33.33 MHz console: Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00 console: Processor ID/revision = 0x93 (MIPS 24Kf) / 0x00 console: Endianness = Little console: CPU/Bus frequency = 333 MHz / 419 MHz console: Coherency = None console: Flash memory size = 4 MByte console: SDRAM size = 128 MByte console: First free SDRAM address = 0x800c32f0 console: WARNING: Environment variable flash area is invalid! console: HINT : Perform "erase -e" console: YAMON> PASS (1.88 s) (2/2) tests/avocado/machine_mips_malta.py:MaltaMachine.test_mips64el_malta_yamon: ... console: System controller/revision = Galileo / GT_64120A-B-0 console: Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00 console: Processor ID/revision = 0x82 (MIPS 20Kc) / 0xa0 ... console: YAMON> PASS (1.89 s) RESULTS : PASS 2 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0 JOB TIME : 4.57 s YAMON does some endian-swapped acceses on the ISD<->PCI CFG/DATA registers. These tests are useful to debug cross-endianness issues, in particular on big-endian host. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230104133935.4639-7-philmd@linaro.org> --- tests/avocado/machine_mips_malta.py | 47 ++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/tests/avocado/machine_mips_malta.py b/tests/avocado/machine_mips_malta.py index f1895d59f3..92233451c5 100644 --- a/tests/avocado/machine_mips_malta.py +++ b/tests/avocado/machine_mips_malta.py @@ -11,11 +11,13 @@ import os import gzip import logging -from avocado import skipUnless -from avocado_qemu import QemuSystemTest -from avocado_qemu import wait_for_console_pattern -from avocado.utils import archive from avocado import skipIf +from avocado import skipUnless +from avocado.utils import archive +from avocado_qemu import QemuSystemTest +from avocado_qemu import exec_command_and_wait_for_pattern +from avocado_qemu import interrupt_interactive_console_until_pattern +from avocado_qemu import wait_for_console_pattern NUMPY_AVAILABLE = True @@ -118,3 +120,40 @@ class MaltaMachineFramebuffer(QemuSystemTest): :avocado: tags=mips:smp """ self.do_test_i6400_framebuffer_logo(8) + +class MaltaMachine(QemuSystemTest): + + def do_test_yamon(self): + rom_url = ('http://www.imgtec.com/tools/mips-tools/downloads/' + 'yamon/yamon-bin-02.22.zip') + rom_hash = '8da7ecddbc5312704b8b324341ee238189bde480' + zip_path = self.fetch_asset(rom_url, asset_hash=rom_hash) + + archive.extract(zip_path, self.workdir) + yamon_path = os.path.join(self.workdir, 'yamon-02.22.bin') + + self.vm.set_console() + self.vm.add_args('-bios', yamon_path) + self.vm.launch() + + prompt = 'YAMON>' + pattern = 'YAMON ROM Monitor' + interrupt_interactive_console_until_pattern(self, pattern, prompt) + wait_for_console_pattern(self, prompt) + self.vm.shutdown() + + def test_mipsel_malta_yamon(self): + """ + :avocado: tags=arch:mipsel + :avocado: tags=machine:malta + :avocado: tags=endian:little + """ + self.do_test_yamon() + + def test_mips64el_malta_yamon(self): + """ + :avocado: tags=arch:mips64el + :avocado: tags=machine:malta + :avocado: tags=endian:little + """ + self.do_test_yamon() From cd5066f8618bc6c80ec9088923c58f4a42ab0e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 2 Nov 2022 16:24:39 +0100 Subject: [PATCH 13/46] hw/mips/bootloader: Handle buffers as opaque arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is irrelevant to the API what the buffers to fill are made of. In particular, some MIPS ISA have 16-bit wide instructions. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-2-philmd@linaro.org> --- hw/mips/bootloader.c | 55 +++++++++++++++++++++--------------- hw/mips/boston.c | 2 +- hw/mips/fuloong2e.c | 2 +- hw/mips/malta.c | 19 +++++++------ include/hw/mips/bootloader.h | 10 +++---- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index f5f42f2bf2..21ffd4d772 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -55,16 +55,20 @@ static bool bootcpu_supports_isa(uint64_t isa_mask) } /* Base types */ -static void bl_gen_nop(uint32_t **p) +static void bl_gen_nop(void **ptr) { - stl_p(*p, 0); - *p = *p + 1; + uint32_t *p = *ptr; + + stl_p(p, 0); + p++; + *ptr = p; } -static void bl_gen_r_type(uint32_t **p, uint8_t opcode, +static void bl_gen_r_type(void **ptr, uint8_t opcode, bl_reg rs, bl_reg rt, bl_reg rd, uint8_t shift, uint8_t funct) { + uint32_t *p = *ptr; uint32_t insn = 0; insn = deposit32(insn, 26, 6, opcode); @@ -74,13 +78,16 @@ static void bl_gen_r_type(uint32_t **p, uint8_t opcode, insn = deposit32(insn, 6, 5, shift); insn = deposit32(insn, 0, 6, funct); - stl_p(*p, insn); - *p = *p + 1; + stl_p(p, insn); + p++; + + *ptr = p; } -static void bl_gen_i_type(uint32_t **p, uint8_t opcode, +static void bl_gen_i_type(void **ptr, uint8_t opcode, bl_reg rs, bl_reg rt, uint16_t imm) { + uint32_t *p = *ptr; uint32_t insn = 0; insn = deposit32(insn, 26, 6, opcode); @@ -88,12 +95,14 @@ static void bl_gen_i_type(uint32_t **p, uint8_t opcode, insn = deposit32(insn, 16, 5, rt); insn = deposit32(insn, 0, 16, imm); - stl_p(*p, insn); - *p = *p + 1; + stl_p(p, insn); + p++; + + *ptr = p; } /* Single instructions */ -static void bl_gen_dsll(uint32_t **p, bl_reg rd, bl_reg rt, uint8_t sa) +static void bl_gen_dsll(void **p, bl_reg rd, bl_reg rt, uint8_t sa) { if (bootcpu_supports_isa(ISA_MIPS3)) { bl_gen_r_type(p, 0, 0, rt, rd, sa, 0x38); @@ -102,28 +111,28 @@ static void bl_gen_dsll(uint32_t **p, bl_reg rd, bl_reg rt, uint8_t sa) } } -static void bl_gen_jalr(uint32_t **p, bl_reg rs) +static void bl_gen_jalr(void **p, bl_reg rs) { bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09); } -static void bl_gen_lui(uint32_t **p, bl_reg rt, uint16_t imm) +static void bl_gen_lui(void **p, bl_reg rt, uint16_t imm) { /* R6: It's a alias of AUI with RS = 0 */ bl_gen_i_type(p, 0x0f, 0, rt, imm); } -static void bl_gen_ori(uint32_t **p, bl_reg rt, bl_reg rs, uint16_t imm) +static void bl_gen_ori(void **p, bl_reg rt, bl_reg rs, uint16_t imm) { bl_gen_i_type(p, 0x0d, rs, rt, imm); } -static void bl_gen_sw(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset) +static void bl_gen_sw(void **p, bl_reg rt, uint8_t base, uint16_t offset) { bl_gen_i_type(p, 0x2b, base, rt, offset); } -static void bl_gen_sd(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset) +static void bl_gen_sd(void **p, bl_reg rt, uint8_t base, uint16_t offset) { if (bootcpu_supports_isa(ISA_MIPS3)) { bl_gen_i_type(p, 0x3f, base, rt, offset); @@ -133,13 +142,13 @@ static void bl_gen_sd(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset) } /* Pseudo instructions */ -static void bl_gen_li(uint32_t **p, bl_reg rt, uint32_t imm) +static void bl_gen_li(void **p, bl_reg rt, uint32_t imm) { bl_gen_lui(p, rt, extract32(imm, 16, 16)); bl_gen_ori(p, rt, rt, extract32(imm, 0, 16)); } -static void bl_gen_dli(uint32_t **p, bl_reg rt, uint64_t imm) +static void bl_gen_dli(void **p, bl_reg rt, uint64_t imm) { bl_gen_li(p, rt, extract64(imm, 32, 32)); bl_gen_dsll(p, rt, rt, 16); @@ -148,7 +157,7 @@ static void bl_gen_dli(uint32_t **p, bl_reg rt, uint64_t imm) bl_gen_ori(p, rt, rt, extract64(imm, 0, 16)); } -static void bl_gen_load_ulong(uint32_t **p, bl_reg rt, target_ulong imm) +static void bl_gen_load_ulong(void **p, bl_reg rt, target_ulong imm) { if (bootcpu_supports_isa(ISA_MIPS3)) { bl_gen_dli(p, rt, imm); /* 64bit */ @@ -158,14 +167,14 @@ static void bl_gen_load_ulong(uint32_t **p, bl_reg rt, target_ulong imm) } /* Helpers */ -void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr) +void bl_gen_jump_to(void **p, target_ulong jump_addr) { bl_gen_load_ulong(p, BL_REG_T9, jump_addr); bl_gen_jalr(p, BL_REG_T9); bl_gen_nop(p); /* delay slot */ } -void bl_gen_jump_kernel(uint32_t **p, +void bl_gen_jump_kernel(void **p, bool set_sp, target_ulong sp, bool set_a0, target_ulong a0, bool set_a1, target_ulong a1, @@ -192,7 +201,7 @@ void bl_gen_jump_kernel(uint32_t **p, bl_gen_jump_to(p, kernel_addr); } -void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val) +void bl_gen_write_ulong(void **p, target_ulong addr, target_ulong val) { bl_gen_load_ulong(p, BL_REG_K0, val); bl_gen_load_ulong(p, BL_REG_K1, addr); @@ -203,14 +212,14 @@ void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val) } } -void bl_gen_write_u32(uint32_t **p, target_ulong addr, uint32_t val) +void bl_gen_write_u32(void **p, target_ulong addr, uint32_t val) { bl_gen_li(p, BL_REG_K0, val); bl_gen_load_ulong(p, BL_REG_K1, addr); bl_gen_sw(p, BL_REG_K0, BL_REG_K1, 0x0); } -void bl_gen_write_u64(uint32_t **p, target_ulong addr, uint64_t val) +void bl_gen_write_u64(void **p, target_ulong addr, uint64_t val) { bl_gen_dli(p, BL_REG_K0, val); bl_gen_load_ulong(p, BL_REG_K1, addr); diff --git a/hw/mips/boston.c b/hw/mips/boston.c index edda87e23c..b6dd9fb200 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -323,7 +323,7 @@ static void boston_register_types(void) } type_init(boston_register_types) -static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr) +static void gen_firmware(void *p, hwaddr kernel_entry, hwaddr fdt_addr) { uint64_t regaddr; diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c index 34befa5dd5..cfc8ca6ae4 100644 --- a/hw/mips/fuloong2e.c +++ b/hw/mips/fuloong2e.c @@ -179,7 +179,7 @@ static void write_bootloader(CPUMIPSState *env, uint8_t *base, /* Second part of the bootloader */ p = (uint32_t *)(base + 0x040); - bl_gen_jump_kernel(&p, + bl_gen_jump_kernel((void **)&p, true, ENVP_VADDR - 64, true, 2, true, ENVP_VADDR, true, ENVP_VADDR + 8, diff --git a/hw/mips/malta.c b/hw/mips/malta.c index f959bce673..b5b62e7245 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -844,6 +844,7 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, uint64_t kernel_entry) { uint32_t *p; + void *v; /* Small bootloader */ p = (uint32_t *)base; @@ -886,38 +887,39 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, #else #define cpu_to_gt32 cpu_to_be32 #endif + v = p; /* move GT64120 registers from 0x14000000 to 0x1be00000 */ - bl_gen_write_u32(&p, /* GT_ISD */ + bl_gen_write_u32(&v, /* GT_ISD */ cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), cpu_to_gt32(0x1be00000 << 3)); /* setup MEM-to-PCI0 mapping */ /* setup PCI0 io window to 0x18000000-0x181fffff */ - bl_gen_write_u32(&p, /* GT_PCI0IOLD */ + bl_gen_write_u32(&v, /* GT_PCI0IOLD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), cpu_to_gt32(0x18000000 << 3)); - bl_gen_write_u32(&p, /* GT_PCI0IOHD */ + bl_gen_write_u32(&v, /* GT_PCI0IOHD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), cpu_to_gt32(0x08000000 << 3)); /* setup PCI0 mem windows */ - bl_gen_write_u32(&p, /* GT_PCI0M0LD */ + bl_gen_write_u32(&v, /* GT_PCI0M0LD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), cpu_to_gt32(0x10000000 << 3)); - bl_gen_write_u32(&p, /* GT_PCI0M0HD */ + bl_gen_write_u32(&v, /* GT_PCI0M0HD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), cpu_to_gt32(0x07e00000 << 3)); - bl_gen_write_u32(&p, /* GT_PCI0M1LD */ + bl_gen_write_u32(&v, /* GT_PCI0M1LD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), cpu_to_gt32(0x18200000 << 3)); - bl_gen_write_u32(&p, /* GT_PCI0M1HD */ + bl_gen_write_u32(&v, /* GT_PCI0M1HD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), cpu_to_gt32(0x0bc00000 << 3)); #undef cpu_to_gt32 - bl_gen_jump_kernel(&p, + bl_gen_jump_kernel(&v, true, ENVP_VADDR - 64, /* * If semihosting is used, arguments have already been @@ -928,6 +930,7 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, true, ENVP_VADDR + 8, true, loaderparams.ram_low_size, kernel_entry); + p = v; /* YAMON subroutines */ p = (uint32_t *) (base + 0x800); diff --git a/include/hw/mips/bootloader.h b/include/hw/mips/bootloader.h index fffb0b7da8..c32f6c2835 100644 --- a/include/hw/mips/bootloader.h +++ b/include/hw/mips/bootloader.h @@ -11,16 +11,16 @@ #include "exec/cpu-defs.h" -void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr); -void bl_gen_jump_kernel(uint32_t **p, +void bl_gen_jump_to(void **ptr, target_ulong jump_addr); +void bl_gen_jump_kernel(void **ptr, bool set_sp, target_ulong sp, bool set_a0, target_ulong a0, bool set_a1, target_ulong a1, bool set_a2, target_ulong a2, bool set_a3, target_ulong a3, target_ulong kernel_addr); -void bl_gen_write_ulong(uint32_t **p, target_ulong addr, target_ulong val); -void bl_gen_write_u32(uint32_t **p, target_ulong addr, uint32_t val); -void bl_gen_write_u64(uint32_t **p, target_ulong addr, uint64_t val); +void bl_gen_write_ulong(void **ptr, target_ulong addr, target_ulong val); +void bl_gen_write_u32(void **ptr, target_ulong addr, uint32_t val); +void bl_gen_write_u64(void **ptr, target_ulong addr, uint64_t val); #endif From cf386ca8ab20ecad5efa535f3d48750df740da39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 2 Nov 2022 16:25:46 +0100 Subject: [PATCH 14/46] hw/mips/bootloader: Implement nanoMIPS NOP opcode generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20221211204533.85359-3-philmd@linaro.org> --- hw/mips/bootloader.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index 21ffd4d772..0035f37335 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -54,14 +54,30 @@ static bool bootcpu_supports_isa(uint64_t isa_mask) return cpu_supports_isa(&MIPS_CPU(first_cpu)->env, isa_mask); } +static void st_nm32_p(void **ptr, uint32_t insn) +{ + uint16_t *p = *ptr; + + stw_p(p, insn >> 16); + p++; + stw_p(p, insn >> 0); + p++; + + *ptr = p; +} + /* Base types */ static void bl_gen_nop(void **ptr) { - uint32_t *p = *ptr; + if (bootcpu_supports_isa(ISA_NANOMIPS32)) { + st_nm32_p(ptr, 0x8000c000); + } else { + uint32_t *p = *ptr; - stl_p(p, 0); - p++; - *ptr = p; + stl_p(p, 0); + p++; + *ptr = p; + } } static void bl_gen_r_type(void **ptr, uint8_t opcode, From 73be38cbe34df90be4ab9618e62859fa074015ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 18:33:52 +0100 Subject: [PATCH 15/46] hw/mips/bootloader: Implement nanoMIPS SW opcode generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-4-philmd@linaro.org> --- hw/mips/bootloader.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index 0035f37335..3e1e73360f 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -143,9 +143,27 @@ static void bl_gen_ori(void **p, bl_reg rt, bl_reg rs, uint16_t imm) bl_gen_i_type(p, 0x0d, rs, rt, imm); } +static void bl_gen_sw_nm(void **ptr, bl_reg rt, uint8_t rs, uint16_t ofs12) +{ + uint32_t insn = 0; + + assert(extract32(ofs12, 0, 12) == ofs12); + insn = deposit32(insn, 26, 6, 0b100001); + insn = deposit32(insn, 21, 5, rt); + insn = deposit32(insn, 16, 5, rs); + insn = deposit32(insn, 12, 4, 0b1001); + insn = deposit32(insn, 0, 12, ofs12); + + st_nm32_p(ptr, insn); +} + static void bl_gen_sw(void **p, bl_reg rt, uint8_t base, uint16_t offset) { - bl_gen_i_type(p, 0x2b, base, rt, offset); + if (bootcpu_supports_isa(ISA_NANOMIPS32)) { + bl_gen_sw_nm(p, rt, base, offset); + } else { + bl_gen_i_type(p, 0x2b, base, rt, offset); + } } static void bl_gen_sd(void **p, bl_reg rt, uint8_t base, uint16_t offset) From 5d380e4ca898e7f0ebd436e255a7da4869b15a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 18:34:09 +0100 Subject: [PATCH 16/46] hw/mips/bootloader: Implement nanoMIPS LI (LUI+ORI) opcode generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-5-philmd@linaro.org> --- hw/mips/bootloader.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index 3e1e73360f..9fc926d83f 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -132,12 +132,39 @@ static void bl_gen_jalr(void **p, bl_reg rs) bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09); } +static void bl_gen_lui_nm(void **ptr, bl_reg rt, uint32_t imm20) +{ + uint32_t insn = 0; + + assert(extract32(imm20, 0, 20) == imm20); + insn = deposit32(insn, 26, 6, 0b111000); + insn = deposit32(insn, 21, 5, rt); + insn = deposit32(insn, 12, 9, extract32(imm20, 0, 9)); + insn = deposit32(insn, 2, 10, extract32(imm20, 9, 10)); + insn = deposit32(insn, 0, 1, sextract32(imm20, 19, 1)); + + st_nm32_p(ptr, insn); +} + static void bl_gen_lui(void **p, bl_reg rt, uint16_t imm) { /* R6: It's a alias of AUI with RS = 0 */ bl_gen_i_type(p, 0x0f, 0, rt, imm); } +static void bl_gen_ori_nm(void **ptr, bl_reg rt, bl_reg rs, uint16_t imm12) +{ + uint32_t insn = 0; + + assert(extract32(imm12, 0, 12) == imm12); + insn = deposit32(insn, 26, 6, 0b100000); + insn = deposit32(insn, 21, 5, rt); + insn = deposit32(insn, 16, 5, rs); + insn = deposit32(insn, 0, 12, imm12); + + st_nm32_p(ptr, insn); +} + static void bl_gen_ori(void **p, bl_reg rt, bl_reg rs, uint16_t imm) { bl_gen_i_type(p, 0x0d, rs, rt, imm); @@ -178,8 +205,13 @@ static void bl_gen_sd(void **p, bl_reg rt, uint8_t base, uint16_t offset) /* Pseudo instructions */ static void bl_gen_li(void **p, bl_reg rt, uint32_t imm) { - bl_gen_lui(p, rt, extract32(imm, 16, 16)); - bl_gen_ori(p, rt, rt, extract32(imm, 0, 16)); + if (bootcpu_supports_isa(ISA_NANOMIPS32)) { + bl_gen_lui_nm(p, rt, extract32(imm, 12, 20)); + bl_gen_ori_nm(p, rt, rt, extract32(imm, 0, 12)); + } else { + bl_gen_lui(p, rt, extract32(imm, 16, 16)); + bl_gen_ori(p, rt, rt, extract32(imm, 0, 16)); + } } static void bl_gen_dli(void **p, bl_reg rt, uint64_t imm) From 9356a2d2be024480aa7f65a598f8c8283f04faa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 19:55:41 +0100 Subject: [PATCH 17/46] hw/mips/bootloader: Implement nanoMIPS JALRc opcode generator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-6-philmd@linaro.org> --- hw/mips/bootloader.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c index 9fc926d83f..1dd6ef2096 100644 --- a/hw/mips/bootloader.c +++ b/hw/mips/bootloader.c @@ -129,7 +129,17 @@ static void bl_gen_dsll(void **p, bl_reg rd, bl_reg rt, uint8_t sa) static void bl_gen_jalr(void **p, bl_reg rs) { - bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09); + if (bootcpu_supports_isa(ISA_NANOMIPS32)) { + uint32_t insn = 0; + + insn = deposit32(insn, 26, 6, 0b010010); /* JALRC */ + insn = deposit32(insn, 21, 5, BL_REG_RA); + insn = deposit32(insn, 16, 5, rs); + + st_nm32_p(p, insn); + } else { + bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x09); + } } static void bl_gen_lui_nm(void **ptr, bl_reg rt, uint32_t imm20) From 391a2bdae99cb09e2cf88337898cb53385bddcc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 18:42:23 +0100 Subject: [PATCH 18/46] hw/mips/malta: Use bootloader generator API for nanoMIPS CPUs (1/5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similarly to how commit 0c8427baf0 ("hw/mips/malta: Use bootloader helper to set BAR registers") converted write_bootloader(), convert the equivalent write_bootloader_nanomips(), allowing us to modify the bootloader code more easily in the future. Part 1/5: Convert PCI0 MEM1 BAR setup Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-7-philmd@linaro.org> --- hw/mips/malta.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index b5b62e7245..a496053a9a 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -620,6 +620,7 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, uint64_t kernel_entry) { uint16_t *p; + void *v; /* Small bootloader */ p = (uint16_t *)base; @@ -693,13 +694,13 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, * * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff * - set up PCI0 MEM0 at 0x10000000, size 0x8000000 - * - set up PCI0 MEM1 at 0x18200000, size 0xbe00000 * */ stw_p(p++, 0xe040); stw_p(p++, 0x0681); /* lui t1, %hi(0xb4000000) */ #if TARGET_BIG_ENDIAN +#define cpu_to_gt32 cpu_to_le32 stw_p(p++, 0xe020); stw_p(p++, 0x0be1); /* lui t0, %hi(0xdf000000) */ @@ -742,14 +743,8 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0xe020); stw_p(p++, 0x0821); /* lui t0, %hi(0xc1000000) */ - /* 0x80 corresponds to GT_PCI0M1LD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9080); - /* sw t0, 0x80(t1) */ - - stw_p(p++, 0xe020); stw_p(p++, 0x0bc0); - /* lui t0, %hi(0x5e000000) */ - #else +#define cpu_to_gt32 cpu_to_be32 stw_p(p++, 0x0020); stw_p(p++, 0x00df); /* addiu[32] t0, $0, 0xdf */ @@ -792,19 +787,20 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0x0020); stw_p(p++, 0x00c1); /* addiu[32] t0, $0, 0xc1 */ - - /* 0x80 corresponds to GT_PCI0M1LD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9080); - /* sw t0, 0x80(t1) */ - - stw_p(p++, 0x0020); stw_p(p++, 0x005e); - /* addiu[32] t0, $0, 0x5e */ - #endif + v = p; - /* 0x88 corresponds to GT_PCI0M1HD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9088); - /* sw t0, 0x88(t1) */ + /* setup PCI0 mem windows */ + bl_gen_write_u32(&v, /* GT_PCI0M1LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), + cpu_to_gt32(0x18200000 << 3)); + bl_gen_write_u32(&v, /* GT_PCI0M1HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), + cpu_to_gt32(0x0bc00000 << 3)); + + p = v; + +#undef cpu_to_gt32 stw_p(p++, 0xe320 | NM_HI1(kernel_entry)); From 262502a681e3e7efc54feb93a660a768c68e3395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 18:49:13 +0100 Subject: [PATCH 19/46] hw/mips/malta: Use bootloader generator API for nanoMIPS CPUs (2/5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part 2/5: Convert PCI0 MEM0 BAR setup Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-8-philmd@linaro.org> --- hw/mips/malta.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index a496053a9a..7d0fc5d0c8 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -693,7 +693,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, * Load BAR registers as done by YAMON: * * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff - * - set up PCI0 MEM0 at 0x10000000, size 0x8000000 * */ stw_p(p++, 0xe040); stw_p(p++, 0x0681); @@ -729,20 +728,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0xe020); stw_p(p++, 0x0001); /* lui t0, %hi(0x80000000) */ - /* 0x58 corresponds to GT_PCI0M0LD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9058); - /* sw t0, 0x58(t1) */ - - stw_p(p++, 0xe020); stw_p(p++, 0x07e0); - /* lui t0, %hi(0x3f000000) */ - - /* 0x60 corresponds to GT_PCI0M0HD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9060); - /* sw t0, 0x60(t1) */ - - stw_p(p++, 0xe020); stw_p(p++, 0x0821); - /* lui t0, %hi(0xc1000000) */ - #else #define cpu_to_gt32 cpu_to_be32 @@ -773,24 +758,16 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0x0020); stw_p(p++, 0x0080); /* addiu[32] t0, $0, 0x80 */ - - /* 0x58 corresponds to GT_PCI0M0LD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9058); - /* sw t0, 0x58(t1) */ - - stw_p(p++, 0x0020); stw_p(p++, 0x003f); - /* addiu[32] t0, $0, 0x3f */ - - /* 0x60 corresponds to GT_PCI0M0HD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9060); - /* sw t0, 0x60(t1) */ - - stw_p(p++, 0x0020); stw_p(p++, 0x00c1); - /* addiu[32] t0, $0, 0xc1 */ #endif v = p; /* setup PCI0 mem windows */ + bl_gen_write_u32(&v, /* GT_PCI0M0LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), + cpu_to_gt32(0x10000000 << 3)); + bl_gen_write_u32(&v, /* GT_PCI0M0HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), + cpu_to_gt32(0x07e00000 << 3)); bl_gen_write_u32(&v, /* GT_PCI0M1LD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), cpu_to_gt32(0x18200000 << 3)); From 02e0bec464ff3086446d4ad938e301bd85e57d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 18:54:49 +0100 Subject: [PATCH 20/46] hw/mips/malta: Use bootloader generator API for nanoMIPS CPUs (3/5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part 3/5: Convert PCI0 I/O BAR setup Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-9-philmd@linaro.org> --- hw/mips/malta.c | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 7d0fc5d0c8..f0ed32167f 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -691,9 +691,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, /* * Load BAR registers as done by YAMON: - * - * - set up PCI0 I/O BARs from 0x18000000 to 0x181fffff - * */ stw_p(p++, 0xe040); stw_p(p++, 0x0681); /* lui t1, %hi(0xb4000000) */ @@ -713,21 +710,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0xe020); stw_p(p++, 0x0801); /* lui t0, %hi(0xc0000000) */ - - /* 0x48 corresponds to GT_PCI0IOLD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9048); - /* sw t0, 0x48(t1) */ - - stw_p(p++, 0xe020); stw_p(p++, 0x0800); - /* lui t0, %hi(0x40000000) */ - - /* 0x50 corresponds to GT_PCI0IOHD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9050); - /* sw t0, 0x50(t1) */ - - stw_p(p++, 0xe020); stw_p(p++, 0x0001); - /* lui t0, %hi(0x80000000) */ - #else #define cpu_to_gt32 cpu_to_be32 @@ -744,23 +726,17 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0x0020); stw_p(p++, 0x00c0); /* addiu[32] t0, $0, 0xc0 */ - - /* 0x48 corresponds to GT_PCI0IOLD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9048); - /* sw t0, 0x48(t1) */ - - stw_p(p++, 0x0020); stw_p(p++, 0x0040); - /* addiu[32] t0, $0, 0x40 */ - - /* 0x50 corresponds to GT_PCI0IOHD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9050); - /* sw t0, 0x50(t1) */ - - stw_p(p++, 0x0020); stw_p(p++, 0x0080); - /* addiu[32] t0, $0, 0x80 */ #endif v = p; + /* setup PCI0 io window to 0x18000000-0x181fffff */ + bl_gen_write_u32(&v, /* GT_PCI0IOLD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), + cpu_to_gt32(0x18000000 << 3)); + bl_gen_write_u32(&v, /* GT_PCI0IOHD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), + cpu_to_gt32(0x08000000 << 3)); + /* setup PCI0 mem windows */ bl_gen_write_u32(&v, /* GT_PCI0M0LD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), From 3265f41fc7d988276c672e4bdc46ae60713f141c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 18:47:21 +0100 Subject: [PATCH 21/46] hw/mips/malta: Use bootloader generator API for nanoMIPS CPUs (4/5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part 4/5: Convert GT64120 ISD base address setup Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-10-philmd@linaro.org> --- hw/mips/malta.c | 40 +++++++--------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index f0ed32167f..e618513e35 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -689,46 +689,20 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size)); /* ori a3,a3,%lo(loaderparams.ram_low_size) */ - /* - * Load BAR registers as done by YAMON: - */ - stw_p(p++, 0xe040); stw_p(p++, 0x0681); - /* lui t1, %hi(0xb4000000) */ - #if TARGET_BIG_ENDIAN #define cpu_to_gt32 cpu_to_le32 - - stw_p(p++, 0xe020); stw_p(p++, 0x0be1); - /* lui t0, %hi(0xdf000000) */ - - /* 0x68 corresponds to GT_ISD (from hw/mips/gt64xxx_pci.c) */ - stw_p(p++, 0x8422); stw_p(p++, 0x9068); - /* sw t0, 0x68(t1) */ - - stw_p(p++, 0xe040); stw_p(p++, 0x077d); - /* lui t1, %hi(0xbbe00000) */ - - stw_p(p++, 0xe020); stw_p(p++, 0x0801); - /* lui t0, %hi(0xc0000000) */ #else #define cpu_to_gt32 cpu_to_be32 - - stw_p(p++, 0x0020); stw_p(p++, 0x00df); - /* addiu[32] t0, $0, 0xdf */ - - /* 0x68 corresponds to GT_ISD */ - stw_p(p++, 0x8422); stw_p(p++, 0x9068); - /* sw t0, 0x68(t1) */ - - /* Use kseg2 remapped address 0x1be00000 */ - stw_p(p++, 0xe040); stw_p(p++, 0x077d); - /* lui t1, %hi(0xbbe00000) */ - - stw_p(p++, 0x0020); stw_p(p++, 0x00c0); - /* addiu[32] t0, $0, 0xc0 */ #endif v = p; + /* setup MEM-to-PCI0 mapping as done by YAMON */ + + /* move GT64120 registers from 0x14000000 to 0x1be00000 */ + bl_gen_write_u32(&v, /* GT_ISD */ + cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), + cpu_to_gt32(0x1be00000 << 3)); + /* setup PCI0 io window to 0x18000000-0x181fffff */ bl_gen_write_u32(&v, /* GT_PCI0IOLD */ cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), From 9f911a25277aceaad14dc1ce4ac330ad5b057d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 19:08:50 +0100 Subject: [PATCH 22/46] hw/mips/malta: Use bootloader generator API for nanoMIPS CPUs (5/5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part 5/5: Convert jumping to kernel Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-11-philmd@linaro.org> --- hw/mips/malta.c | 68 ++++++++----------------------------------------- 1 file changed, 11 insertions(+), 57 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index e618513e35..b66dad0510 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -625,11 +625,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, /* Small bootloader */ p = (uint16_t *)base; -#define NM_HI1(VAL) (((VAL) >> 16) & 0x1f) -#define NM_HI2(VAL) \ - (((VAL) & 0xf000) | (((VAL) >> 19) & 0xffc) | (((VAL) >> 31) & 0x1)) -#define NM_LO(VAL) ((VAL) & 0xfff) - stw_p(p++, 0x2800); stw_p(p++, 0x001c); /* bc to_here */ stw_p(p++, 0x8000); stw_p(p++, 0xc000); @@ -648,46 +643,6 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, /* nop */ /* to_here: */ - if (semihosting_get_argc()) { - /* Preserve a0 content as arguments have been passed */ - stw_p(p++, 0x8000); stw_p(p++, 0xc000); - /* nop */ - } else { - stw_p(p++, 0x0080); stw_p(p++, 0x0002); - /* li a0,2 */ - } - - stw_p(p++, 0xe3a0 | NM_HI1(ENVP_VADDR - 64)); - - stw_p(p++, NM_HI2(ENVP_VADDR - 64)); - /* lui sp,%hi(ENVP_VADDR - 64) */ - - stw_p(p++, 0x83bd); stw_p(p++, NM_LO(ENVP_VADDR - 64)); - /* ori sp,sp,%lo(ENVP_VADDR - 64) */ - - stw_p(p++, 0xe0a0 | NM_HI1(ENVP_VADDR)); - - stw_p(p++, NM_HI2(ENVP_VADDR)); - /* lui a1,%hi(ENVP_VADDR) */ - - stw_p(p++, 0x80a5); stw_p(p++, NM_LO(ENVP_VADDR)); - /* ori a1,a1,%lo(ENVP_VADDR) */ - - stw_p(p++, 0xe0c0 | NM_HI1(ENVP_VADDR + 8)); - - stw_p(p++, NM_HI2(ENVP_VADDR + 8)); - /* lui a2,%hi(ENVP_VADDR + 8) */ - - stw_p(p++, 0x80c6); stw_p(p++, NM_LO(ENVP_VADDR + 8)); - /* ori a2,a2,%lo(ENVP_VADDR + 8) */ - - stw_p(p++, 0xe0e0 | NM_HI1(loaderparams.ram_low_size)); - - stw_p(p++, NM_HI2(loaderparams.ram_low_size)); - /* lui a3,%hi(loaderparams.ram_low_size) */ - - stw_p(p++, 0x80e7); stw_p(p++, NM_LO(loaderparams.ram_low_size)); - /* ori a3,a3,%lo(loaderparams.ram_low_size) */ #if TARGET_BIG_ENDIAN #define cpu_to_gt32 cpu_to_le32 @@ -725,20 +680,19 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), cpu_to_gt32(0x0bc00000 << 3)); - p = v; - #undef cpu_to_gt32 - stw_p(p++, 0xe320 | NM_HI1(kernel_entry)); - - stw_p(p++, NM_HI2(kernel_entry)); - /* lui t9,%hi(kernel_entry) */ - - stw_p(p++, 0x8339); stw_p(p++, NM_LO(kernel_entry)); - /* ori t9,t9,%lo(kernel_entry) */ - - stw_p(p++, 0x4bf9); stw_p(p++, 0x0000); - /* jalrc t8 */ + bl_gen_jump_kernel(&v, + true, ENVP_VADDR - 64, + /* + * If semihosting is used, arguments have already been + * passed, so we preserve $a0. + */ + !semihosting_get_argc(), 2, + true, ENVP_VADDR, + true, ENVP_VADDR + 8, + true, loaderparams.ram_low_size, + kernel_entry); } /* From 0e45355c5cf0f4ec88b5484c3bf2574bdc9c4e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 11 Dec 2022 21:25:48 +0100 Subject: [PATCH 23/46] hw/mips/malta: Merge common BL code as bl_setup_gt64120_jump_kernel() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge common code shared between write_bootloader() and write_bootloader_nanomips() into bl_setup_gt64120_jump_kernel(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221211204533.85359-12-philmd@linaro.org> --- hw/mips/malta.c | 155 +++++++++++++++++------------------------------- 1 file changed, 56 insertions(+), 99 deletions(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index b66dad0510..34c24110cd 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -616,11 +616,64 @@ static void network_init(PCIBus *pci_bus) } } +static void bl_setup_gt64120_jump_kernel(void **p, uint64_t run_addr, + uint64_t kernel_entry) +{ + /* Bus endianess is always reversed */ +#if TARGET_BIG_ENDIAN +#define cpu_to_gt32 cpu_to_le32 +#else +#define cpu_to_gt32 cpu_to_be32 +#endif + + /* setup MEM-to-PCI0 mapping as done by YAMON */ + + /* move GT64120 registers from 0x14000000 to 0x1be00000 */ + bl_gen_write_u32(p, /* GT_ISD */ + cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), + cpu_to_gt32(0x1be00000 << 3)); + + /* setup PCI0 io window to 0x18000000-0x181fffff */ + bl_gen_write_u32(p, /* GT_PCI0IOLD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), + cpu_to_gt32(0x18000000 << 3)); + bl_gen_write_u32(p, /* GT_PCI0IOHD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), + cpu_to_gt32(0x08000000 << 3)); + + /* setup PCI0 mem windows */ + bl_gen_write_u32(p, /* GT_PCI0M0LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), + cpu_to_gt32(0x10000000 << 3)); + bl_gen_write_u32(p, /* GT_PCI0M0HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), + cpu_to_gt32(0x07e00000 << 3)); + bl_gen_write_u32(p, /* GT_PCI0M1LD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), + cpu_to_gt32(0x18200000 << 3)); + bl_gen_write_u32(p, /* GT_PCI0M1HD */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), + cpu_to_gt32(0x0bc00000 << 3)); + +#undef cpu_to_gt32 + + bl_gen_jump_kernel(p, + true, ENVP_VADDR - 64, + /* + * If semihosting is used, arguments have already + * been passed, so we preserve $a0. + */ + !semihosting_get_argc(), 2, + true, ENVP_VADDR, + true, ENVP_VADDR + 8, + true, loaderparams.ram_low_size, + kernel_entry); +} + static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, uint64_t kernel_entry) { uint16_t *p; - void *v; /* Small bootloader */ p = (uint16_t *)base; @@ -644,55 +697,7 @@ static void write_bootloader_nanomips(uint8_t *base, uint64_t run_addr, /* to_here: */ -#if TARGET_BIG_ENDIAN -#define cpu_to_gt32 cpu_to_le32 -#else -#define cpu_to_gt32 cpu_to_be32 -#endif - v = p; - - /* setup MEM-to-PCI0 mapping as done by YAMON */ - - /* move GT64120 registers from 0x14000000 to 0x1be00000 */ - bl_gen_write_u32(&v, /* GT_ISD */ - cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), - cpu_to_gt32(0x1be00000 << 3)); - - /* setup PCI0 io window to 0x18000000-0x181fffff */ - bl_gen_write_u32(&v, /* GT_PCI0IOLD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), - cpu_to_gt32(0x18000000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0IOHD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), - cpu_to_gt32(0x08000000 << 3)); - - /* setup PCI0 mem windows */ - bl_gen_write_u32(&v, /* GT_PCI0M0LD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), - cpu_to_gt32(0x10000000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0M0HD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), - cpu_to_gt32(0x07e00000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0M1LD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), - cpu_to_gt32(0x18200000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0M1HD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), - cpu_to_gt32(0x0bc00000 << 3)); - -#undef cpu_to_gt32 - - bl_gen_jump_kernel(&v, - true, ENVP_VADDR - 64, - /* - * If semihosting is used, arguments have already been - * passed, so we preserve $a0. - */ - !semihosting_get_argc(), 2, - true, ENVP_VADDR, - true, ENVP_VADDR + 8, - true, loaderparams.ram_low_size, - kernel_entry); + bl_setup_gt64120_jump_kernel((void **)&p, run_addr, kernel_entry); } /* @@ -758,55 +763,8 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, * */ - /* Bus endianess is always reversed */ -#if TARGET_BIG_ENDIAN -#define cpu_to_gt32 cpu_to_le32 -#else -#define cpu_to_gt32 cpu_to_be32 -#endif v = p; - - /* move GT64120 registers from 0x14000000 to 0x1be00000 */ - bl_gen_write_u32(&v, /* GT_ISD */ - cpu_mips_phys_to_kseg1(NULL, 0x14000000 + 0x68), - cpu_to_gt32(0x1be00000 << 3)); - - /* setup MEM-to-PCI0 mapping */ - /* setup PCI0 io window to 0x18000000-0x181fffff */ - bl_gen_write_u32(&v, /* GT_PCI0IOLD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x48), - cpu_to_gt32(0x18000000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0IOHD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x50), - cpu_to_gt32(0x08000000 << 3)); - /* setup PCI0 mem windows */ - bl_gen_write_u32(&v, /* GT_PCI0M0LD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x58), - cpu_to_gt32(0x10000000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0M0HD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x60), - cpu_to_gt32(0x07e00000 << 3)); - - bl_gen_write_u32(&v, /* GT_PCI0M1LD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x80), - cpu_to_gt32(0x18200000 << 3)); - bl_gen_write_u32(&v, /* GT_PCI0M1HD */ - cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0x88), - cpu_to_gt32(0x0bc00000 << 3)); - -#undef cpu_to_gt32 - - bl_gen_jump_kernel(&v, - true, ENVP_VADDR - 64, - /* - * If semihosting is used, arguments have already been - * passed, so we preserve $a0. - */ - !semihosting_get_argc(), 2, - true, ENVP_VADDR, - true, ENVP_VADDR + 8, - true, loaderparams.ram_low_size, - kernel_entry); + bl_setup_gt64120_jump_kernel(&v, run_addr, kernel_entry); p = v; /* YAMON subroutines */ @@ -851,7 +809,6 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr, stl_p(p++, 0x00000000); /* nop */ stl_p(p++, 0x03e00009); /* jalr ra */ stl_p(p++, 0xa1040000); /* sb a0,0(t0) */ - } static void G_GNUC_PRINTF(3, 4) prom_set(uint32_t *prom_buf, int index, From 6dd92ce6c541d331f384b808173b7c97c09c8684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 01:53:53 +0200 Subject: [PATCH 24/46] hw/mips/malta: Introduce PIIX4_PCI_DEVFN definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PIIX4 PCI-ISA bridge function is always located at 10:0. Since we want to re-use its address, add the PIIX4_PCI_DEVFN definition. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Bernhard Beschow Reviewed-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Message-Id: <20221027204720.33611-2-philmd@linaro.org> --- hw/mips/malta.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 34c24110cd..9fc3280407 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -71,6 +71,8 @@ #define FLASH_SIZE 0x400000 +#define PIIX4_PCI_DEVFN PCI_DEVFN(10, 0) + typedef struct { MemoryRegion iomem; MemoryRegion iomem_lo; /* 0 - 0x900 */ @@ -1239,7 +1241,7 @@ void mips_malta_init(MachineState *machine) pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci")); /* Southbridge */ - piix4 = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(10, 0), true, + piix4 = pci_create_simple_multifunction(pci_bus, PIIX4_PCI_DEVFN, true, TYPE_PIIX4_PCI_DEVICE); isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix4), "isa.0")); From 1953dfa80e0fc44a8ccfc97b4ada941e9383bba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 01:54:46 +0200 Subject: [PATCH 25/46] hw/mips/malta: Set PIIX4 IRQ routes in embedded bootloader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux kernel expects the northbridge & southbridge chipsets configured by the BIOS firmware. We emulate that by writing a tiny bootloader code in write_bootloader(). Upon introduction in commit 5c2b87e34d ("PIIX4 support"), the PIIX4 configuration space included values specific to the Malta board. Set the Malta-specific IRQ routing values in the embedded bootloader, so the next commit can remove the Malta specific bits from the PIIX4 PCI-ISA bridge and make it generic (matching the real hardware). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Message-Id: <20221027204720.33611-3-philmd@linaro.org> --- hw/mips/malta.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 9fc3280407..ae76b4db70 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -621,6 +621,10 @@ static void network_init(PCIBus *pci_bus) static void bl_setup_gt64120_jump_kernel(void **p, uint64_t run_addr, uint64_t kernel_entry) { + static const char pci_pins_cfg[PCI_NUM_PINS] = { + 10, 10, 11, 11 /* PIIX IRQRC[A:D] */ + }; + /* Bus endianess is always reversed */ #if TARGET_BIG_ENDIAN #define cpu_to_gt32 cpu_to_le32 @@ -659,6 +663,20 @@ static void bl_setup_gt64120_jump_kernel(void **p, uint64_t run_addr, #undef cpu_to_gt32 + /* + * The PIIX ISA bridge is on PCI bus 0 dev 10 func 0. + * Load the PIIX IRQC[A:D] routing config address, then + * write routing configuration to the config data register. + */ + bl_gen_write_u32(p, /* GT_PCI0_CFGADDR */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0xcf8), + tswap32((1 << 31) /* ConfigEn */ + | PCI_BUILD_BDF(0, PIIX4_PCI_DEVFN) << 8 + | PIIX_PIRQCA)); + bl_gen_write_u32(p, /* GT_PCI0_CFGDATA */ + cpu_mips_phys_to_kseg1(NULL, 0x1be00000 + 0xcfc), + tswap32(ldl_be_p(pci_pins_cfg))); + bl_gen_jump_kernel(p, true, ENVP_VADDR - 64, /* From c12b1e67d50c01f6ba78abcdaaa533abaf71b664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 26 Oct 2022 21:06:36 +0200 Subject: [PATCH 26/46] hw/isa/piix4: Correct IRQRC[A:D] reset values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IRQRC[A:D] registers reset value is 0x80. We were forcing the MIPS Malta machine routing to be able to boot a Linux kernel without any bootloader. We now have these registers initialized in the Malta machine write_bootloader(), so we can use the correct reset values. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Bernhard Beschow Reviewed-by: Michael S. Tsirkin Message-Id: <20221027204720.33611-4-philmd@linaro.org> --- hw/isa/piix4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 8fc1db6dc9..0d23e11a39 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -116,10 +116,10 @@ static void piix4_isa_reset(DeviceState *dev) pci_conf[0x4c] = 0x4d; pci_conf[0x4e] = 0x03; pci_conf[0x4f] = 0x00; - pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10 - pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10 - pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11 - pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11 + pci_conf[0x60] = 0x80; + pci_conf[0x61] = 0x80; + pci_conf[0x62] = 0x80; + pci_conf[0x63] = 0x80; pci_conf[0x69] = 0x02; pci_conf[0x70] = 0x80; pci_conf[0x76] = 0x0c; From a844873512400fae6bed9e87694dc96ff2f15f39 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sun, 18 Dec 2022 01:06:45 +0100 Subject: [PATCH 27/46] mips: Remove support for trap and emulate KVM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This support was limited to the Malta board, drop it. I do not have a machine that can run VZ KVM, so I am assuming that it works for -M malta as well. Signed-off-by: Paolo Bonzini Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221221091718.71844-1-philmd@linaro.org> --- docs/about/deprecated.rst | 9 ------- docs/about/removed-features.rst | 9 +++++++ hw/mips/malta.c | 46 +++++---------------------------- target/mips/cpu.c | 7 +---- target/mips/cpu.h | 3 --- target/mips/internal.h | 3 --- target/mips/kvm.c | 11 +------- target/mips/sysemu/addr.c | 17 ------------ target/mips/sysemu/physaddr.c | 13 ---------- 9 files changed, 18 insertions(+), 100 deletions(-) diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 68d29642d7..9f1bbc495d 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -171,15 +171,6 @@ accepted incorrect commands will return an error. Users should make sure that all arguments passed to ``device_add`` are consistent with the documented property types. -System accelerators -------------------- - -MIPS ``Trap-and-Emul`` KVM support (since 6.0) -'''''''''''''''''''''''''''''''''''''''''''''' - -The MIPS ``Trap-and-Emul`` KVM host and guest support has been removed -from Linux upstream kernel, declare it deprecated. - Host Architectures ------------------ diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst index c918cabd1a..6c3aa5097f 100644 --- a/docs/about/removed-features.rst +++ b/docs/about/removed-features.rst @@ -652,6 +652,15 @@ Userspace local APIC with KVM (x86, removed 8.0) a local APIC. The ``split`` setting is supported, as is using ``-M kernel-irqchip=off`` when the CPU does not have a local APIC. +System accelerators +------------------- + +MIPS "Trap-and-Emulate" KVM support (removed in 8.0) +'''''''''''''''''''''''''''''''''''''''''''''''''''' + +The MIPS "Trap-and-Emulate" KVM host and guest support was removed +from Linux in 2021, and is not supported anymore by QEMU either. + System emulator machines ------------------------ diff --git a/hw/mips/malta.c b/hw/mips/malta.c index ae76b4db70..8bf2e2ff5f 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -57,6 +57,7 @@ #include "semihosting/semihost.h" #include "hw/mips/cps.h" #include "hw/qdev-clock.h" +#include "target/mips/internal.h" #include "trace.h" #define ENVP_PADDR 0x2000 @@ -875,7 +876,6 @@ static uint64_t load_kernel(void) uint32_t *prom_buf; long prom_size; int prom_index = 0; - uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr); uint8_t rng_seed[32]; char rng_seed_hex[sizeof(rng_seed) * 2 + 1]; size_t rng_seed_prom_offset; @@ -899,19 +899,10 @@ static uint64_t load_kernel(void) } /* Check where the kernel has been linked */ - if (kernel_entry & 0x80000000ll) { - if (kvm_enabled()) { - error_report("KVM guest kernels must be linked in useg. " - "Did you forget to enable CONFIG_KVM_GUEST?"); - exit(1); - } - - xlate_to_kseg0 = cpu_mips_phys_to_kseg0; - } else { - /* if kernel entry is in useg it is probably a KVM T&E kernel */ - mips_um_ksegs_enable(); - - xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0; + if (kernel_entry <= USEG_LIMIT) { + error_report("Trap-and-Emul kernels (Linux CONFIG_KVM_GUEST)" + " are not supported"); + exit(1); } /* load initrd */ @@ -952,7 +943,7 @@ static uint64_t load_kernel(void) if (initrd_size > 0) { prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%" PRId64 " %s", - xlate_to_kseg0(NULL, initrd_offset), + cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size, loaderparams.kernel_cmdline); } else { prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline); @@ -1019,11 +1010,6 @@ static void main_cpu_reset(void *opaque) } malta_mips_config(cpu); - - if (kvm_enabled()) { - /* Start running from the bootloader we wrote to end of RAM */ - env->active_tc.PC = 0x40000000 + loaderparams.ram_low_size; - } } static void create_cpu_without_cps(MachineState *ms, MaltaState *s, @@ -1157,13 +1143,7 @@ void mips_malta_init(MachineState *machine) fl_idx++; if (kernel_filename) { ram_low_size = MIN(ram_size, 256 * MiB); - /* For KVM we reserve 1MB of RAM for running bootloader */ - if (kvm_enabled()) { - ram_low_size -= 0x100000; - bootloader_run_addr = cpu_mips_kvm_um_phys_to_kseg0(NULL, ram_low_size); - } else { - bootloader_run_addr = cpu_mips_phys_to_kseg0(NULL, RESET_ADDRESS); - } + bootloader_run_addr = cpu_mips_phys_to_kseg0(NULL, RESET_ADDRESS); /* Write a small bootloader to the flash location. */ loaderparams.ram_size = ram_size; @@ -1180,20 +1160,8 @@ void mips_malta_init(MachineState *machine) write_bootloader_nanomips(memory_region_get_ram_ptr(bios), bootloader_run_addr, kernel_entry); } - if (kvm_enabled()) { - /* Write the bootloader code @ the end of RAM, 1MB reserved */ - write_bootloader(memory_region_get_ram_ptr(ram_low_preio) + - ram_low_size, - bootloader_run_addr, kernel_entry); - } } else { target_long bios_size = FLASH_SIZE; - /* The flash region isn't executable from a KVM guest */ - if (kvm_enabled()) { - error_report("KVM enabled but no -kernel argument was specified. " - "Booting from flash is not supported with KVM."); - exit(1); - } /* Load firmware from flash. */ if (!dinfo) { /* Load a BIOS image. */ diff --git a/target/mips/cpu.c b/target/mips/cpu.c index c614b04607..052e54bda3 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -292,12 +292,7 @@ static void mips_cpu_reset_hold(Object *obj) env->tlb->tlb_in_use = env->tlb->nb_tlb; env->CP0_Wired = 0; env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId; - env->CP0_EBase = (cs->cpu_index & 0x3FF); - if (mips_um_ksegs_enabled()) { - env->CP0_EBase |= 0x40000000; - } else { - env->CP0_EBase |= (int32_t)0x80000000; - } + env->CP0_EBase = KSEG0_BASE | (cs->cpu_index & 0x3FF); if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) { env->CP0_CMGCRBase = 0x1fbf8000 >> 4; } diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 0a085643a3..caf2b06911 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1296,11 +1296,8 @@ void cpu_set_exception_base(int vp_index, target_ulong address); uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr); uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr); -uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr); uint64_t cpu_mips_kseg1_to_phys(void *opaque, uint64_t addr); uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t addr); -bool mips_um_ksegs_enabled(void); -void mips_um_ksegs_enable(void); #if !defined(CONFIG_USER_ONLY) diff --git a/target/mips/internal.h b/target/mips/internal.h index 57b312689a..4b0031d10d 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -99,9 +99,6 @@ int mips_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #define KSEG2_BASE ((target_ulong)(int32_t)0xC0000000UL) #define KSEG3_BASE ((target_ulong)(int32_t)0xE0000000UL) -#define KVM_KSEG0_BASE ((target_ulong)(int32_t)0x40000000UL) -#define KVM_KSEG2_BASE ((target_ulong)(int32_t)0x60000000UL) - #if !defined(CONFIG_USER_ONLY) enum { diff --git a/target/mips/kvm.c b/target/mips/kvm.c index bcb8e06b2c..c14e8f550f 100644 --- a/target/mips/kvm.c +++ b/target/mips/kvm.c @@ -1268,25 +1268,16 @@ int kvm_arch_msi_data_to_gsi(uint32_t data) int mips_kvm_type(MachineState *machine, const char *vm_type) { -#if defined(KVM_CAP_MIPS_VZ) || defined(KVM_CAP_MIPS_TE) +#if defined(KVM_CAP_MIPS_VZ) int r; KVMState *s = KVM_STATE(machine->accelerator); -#endif -#if defined(KVM_CAP_MIPS_VZ) r = kvm_check_extension(s, KVM_CAP_MIPS_VZ); if (r > 0) { return KVM_VM_MIPS_VZ; } #endif -#if defined(KVM_CAP_MIPS_TE) - r = kvm_check_extension(s, KVM_CAP_MIPS_TE); - if (r > 0) { - return KVM_VM_MIPS_TE; - } -#endif - return -1; } diff --git a/target/mips/sysemu/addr.c b/target/mips/sysemu/addr.c index 86f1c129c9..4f025be44a 100644 --- a/target/mips/sysemu/addr.c +++ b/target/mips/sysemu/addr.c @@ -23,8 +23,6 @@ #include "qemu/osdep.h" #include "cpu.h" -static int mips_um_ksegs; - uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr) { return addr & 0x1fffffffll; @@ -35,11 +33,6 @@ uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr) return addr | ~0x7fffffffll; } -uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr) -{ - return addr | 0x40000000ll; -} - uint64_t cpu_mips_kseg1_to_phys(void *opaque, uint64_t addr) { return addr & 0x1fffffffll; @@ -49,13 +42,3 @@ uint64_t cpu_mips_phys_to_kseg1(void *opaque, uint64_t addr) { return (addr & 0x1fffffffll) | 0xffffffffa0000000ll; } - -bool mips_um_ksegs_enabled(void) -{ - return mips_um_ksegs; -} - -void mips_um_ksegs_enable(void) -{ - mips_um_ksegs = 1; -} diff --git a/target/mips/sysemu/physaddr.c b/target/mips/sysemu/physaddr.c index 1918633aa1..2970df8a09 100644 --- a/target/mips/sysemu/physaddr.c +++ b/target/mips/sysemu/physaddr.c @@ -130,19 +130,6 @@ int get_physical_address(CPUMIPSState *env, hwaddr *physical, /* effective address (modified for KVM T&E kernel segments) */ target_ulong address = real_address; - if (mips_um_ksegs_enabled()) { - /* KVM T&E adds guest kernel segments in useg */ - if (real_address >= KVM_KSEG0_BASE) { - if (real_address < KVM_KSEG2_BASE) { - /* kseg0 */ - address += KSEG0_BASE - KVM_KSEG0_BASE; - } else if (real_address <= USEG_LIMIT) { - /* kseg2/3 */ - address += KSEG2_BASE - KVM_KSEG2_BASE; - } - } - } - if (address <= USEG_LIMIT) { /* useg */ uint16_t segctl; From f9950374300cb4d8d898bbfc694a0639e9aafdc3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 10 Jan 2023 09:49:42 +0100 Subject: [PATCH 28/46] mips: Always include nanomips disassembler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the nanomips disassembler is not C++ code anymore, it need not depend on link_language == cpp. Always include it and remove the CONFIG_NANOMIPS_DIS symbol. Cc: Philippe Mathieu-Daudé Signed-off-by: Paolo Bonzini Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Daniel P. Berrangé Message-Id: <20230110084942.299460-1-pbonzini@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- disas/meson.build | 3 +-- include/exec/poison.h | 1 - meson.build | 5 ----- target/mips/cpu.c | 2 -- 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/disas/meson.build b/disas/meson.build index 1977f5cd92..c865bdd882 100644 --- a/disas/meson.build +++ b/disas/meson.build @@ -4,8 +4,7 @@ common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c')) common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c')) common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c')) common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c')) -common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c')) -common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.c')) +common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c')) common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c')) common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c')) common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c')) diff --git a/include/exec/poison.h b/include/exec/poison.h index f0959bc84e..140daa4a85 100644 --- a/include/exec/poison.h +++ b/include/exec/poison.h @@ -74,7 +74,6 @@ #pragma GCC poison CONFIG_M68K_DIS #pragma GCC poison CONFIG_MICROBLAZE_DIS #pragma GCC poison CONFIG_MIPS_DIS -#pragma GCC poison CONFIG_NANOMIPS_DIS #pragma GCC poison CONFIG_NIOS2_DIS #pragma GCC poison CONFIG_PPC_DIS #pragma GCC poison CONFIG_RISCV_DIS diff --git a/meson.build b/meson.build index 175517eafd..5d68a8fd23 100644 --- a/meson.build +++ b/meson.build @@ -2490,11 +2490,6 @@ disassemblers = { 'xtensa' : ['CONFIG_XTENSA_DIS'], 'loongarch' : ['CONFIG_LOONGARCH_DIS'], } -if link_language == 'cpp' - disassemblers += { - 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'], - } -endif have_ivshmem = config_host_data.get('CONFIG_EVENTFD') host_kconfig = \ diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 052e54bda3..f995e88776 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -434,9 +434,7 @@ static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info) info->print_insn = print_insn_little_mips; #endif } else { -#if defined(CONFIG_NANOMIPS_DIS) info->print_insn = print_insn_nanomips; -#endif } } From 1bdad09bf3326b89add221ef092e57ed81f6e347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Wed, 4 Jan 2023 12:13:00 +0100 Subject: [PATCH 29/46] hw/pci/pci_host: Trace config accesses on unexisting functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we only emit trace events for existing PCI functions. In order to ease debugging PCI enumeration process, also emit for unexisting functions: $ qemu-system-foo -trace pci_cfg_\* ... pci_cfg_read empty 00:0a.4 @0x0 -> 0xffffffff pci_cfg_read empty 00:0a.5 @0x0 -> 0xffffffff pci_cfg_read empty 00:0a.6 @0x0 -> 0xffffffff pci_cfg_read empty 00:0a.7 @0x0 -> 0xffffffff pci_cfg_read pcnet 00:0b.0 @0x0 -> 0x20001022 pci_cfg_read empty 00:0c.0 @0x0 -> 0xffffffff pci_cfg_read empty 00:0d.0 @0x0 -> 0xffffffff pci_cfg_read empty 00:0e.0 @0x0 -> 0xffffffff pci_cfg_read empty 00:0f.0 @0x0 -> 0xffffffff pci_cfg_read empty 00:10.0 @0x0 -> 0xffffffff pci_cfg_read empty 00:11.0 @0x0 -> 0xffffffff pci_cfg_read cirrus-vga 00:12.0 @0x0 -> 0xb81013 Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230104133935.4639-2-philmd@linaro.org> --- hw/pci/pci_host.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c index eaf217ff55..ead1d3e61c 100644 --- a/hw/pci/pci_host.c +++ b/hw/pci/pci_host.c @@ -118,6 +118,9 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, unsigned len) uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1); if (!pci_dev) { + trace_pci_cfg_write("empty", extract32(addr, 16, 8), + extract32(addr, 11, 5), extract32(addr, 8, 3), + config_addr, val); return; } @@ -131,6 +134,9 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, unsigned len) uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1); if (!pci_dev) { + trace_pci_cfg_read("empty", extract32(addr, 16, 8), + extract32(addr, 11, 5), extract32(addr, 8, 3), + config_addr, ~0x0); return ~0x0; } From f021f4e9d269746bc89dadf0cac117154733e4be Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 9 Jan 2023 18:23:17 +0100 Subject: [PATCH 30/46] hw/pci/pci: Factor out pci_bus_map_irqs() from pci_bus_irqs() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_bus_irqs() coupled together the assignment of pci_set_irq_fn and pci_map_irq_fn to a PCI bus. This coupling gets in the way when the pci_map_irq_fn is board-specific while the pci_set_irq_fn is device- specific. For example, both of QEMU's PIIX south bridge models have different pci_map_irq_fn implementations which are board-specific rather than device-specific. These implementations should therefore reside in board code. The pci_set_irq_fn's, however, should stay in the device models because they access memory internal to the model. Factoring out pci_bus_map_irqs() from pci_bus_irqs() allows the assignments to be decoupled, resolving the problem described above. Note also how pci_vpb_realize() which gets touched in this commit assigns different pci_map_irq_fn's depending on the board. Signed-off-by: Bernhard Beschow Reviewed-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230109172347.1830-5-shentey@gmail.com> [PMD: Factor out in vfu_object_set_bus_irq()] Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc_q35.c | 4 ++-- hw/isa/piix3.c | 8 ++++---- hw/isa/piix4.c | 3 ++- hw/pci-host/raven.c | 3 ++- hw/pci-host/versatile.c | 3 ++- hw/pci/pci.c | 12 +++++++++--- hw/remote/machine.c | 3 ++- hw/remote/vfio-user-obj.c | 4 ++-- include/hw/pci/pci.h | 3 ++- 9 files changed, 27 insertions(+), 16 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 67ceb04bcc..65ea226211 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -268,8 +268,8 @@ static void pc_q35_init(MachineState *machine) for (i = 0; i < GSI_NUM_PINS; i++) { qdev_connect_gpio_out_named(lpc_dev, ICH9_GPIO_GSI, i, x86ms->gsi[i]); } - pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc, - ICH9_LPC_NB_PIRQS); + pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc, ICH9_LPC_NB_PIRQS); + pci_bus_map_irqs(host_bus, ich9_lpc_map_irq); pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq); isa_bus = ich9_lpc->isa_bus; diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index eabad7ba58..666e794f77 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -384,8 +384,8 @@ static void piix3_realize(PCIDevice *dev, Error **errp) return; } - pci_bus_irqs(pci_bus, piix3_set_irq, pci_slot_get_pirq, - piix3, PIIX_NUM_PIRQS); + pci_bus_irqs(pci_bus, piix3_set_irq, piix3, PIIX_NUM_PIRQS); + pci_bus_map_irqs(pci_bus, pci_slot_get_pirq); pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); } @@ -420,8 +420,8 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp) * connected to the IOAPIC directly. * These additional routes can be discovered through ACPI. */ - pci_bus_irqs(pci_bus, xen_piix3_set_irq, xen_pci_slot_get_pirq, - piix3, XEN_PIIX_NUM_PIRQS); + pci_bus_irqs(pci_bus, xen_piix3_set_irq, piix3, XEN_PIIX_NUM_PIRQS); + pci_bus_map_irqs(pci_bus, xen_pci_slot_get_pirq); } static void piix3_xen_class_init(ObjectClass *klass, void *data) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 0d23e11a39..9c79c9677b 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -271,7 +271,8 @@ static void piix4_realize(PCIDevice *dev, Error **errp) } qdev_connect_gpio_out(DEVICE(&s->pm), 0, s->isa[9]); - pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS); + pci_bus_irqs(pci_bus, piix4_set_irq, s, PIIX_NUM_PIRQS); + pci_bus_map_irqs(pci_bus, pci_slot_get_pirq); } static void piix4_init(Object *obj) diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c index 2c96ddf8fe..5b00b4e462 100644 --- a/hw/pci-host/raven.c +++ b/hw/pci-host/raven.c @@ -258,7 +258,8 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp) qdev_init_gpio_in(d, raven_change_gpio, 1); - pci_bus_irqs(&s->pci_bus, raven_set_irq, raven_map_irq, s, PCI_NUM_PINS); + pci_bus_irqs(&s->pci_bus, raven_set_irq, s, PCI_NUM_PINS); + pci_bus_map_irqs(&s->pci_bus, raven_map_irq); memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, s, "pci-conf-idx", 4); diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index 0d50ea4cc0..60d4e7cd92 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -422,7 +422,8 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp) mapfn = pci_vpb_map_irq; } - pci_bus_irqs(&s->pci_bus, pci_vpb_set_irq, mapfn, s->irq, 4); + pci_bus_irqs(&s->pci_bus, pci_vpb_set_irq, s->irq, 4); + pci_bus_map_irqs(&s->pci_bus, mapfn); /* Our memory regions are: * 0 : our control registers diff --git a/hw/pci/pci.c b/hw/pci/pci.c index c2fb88f9a3..39a7bb32aa 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -280,6 +280,7 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) PCIBus *bus; for (;;) { bus = pci_get_bus(pci_dev); + assert(bus->map_irq); irq_num = bus->map_irq(pci_dev, irq_num); if (bus->set_irq) break; @@ -518,16 +519,20 @@ void pci_root_bus_cleanup(PCIBus *bus) qbus_unrealize(BUS(bus)); } -void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, +void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, void *irq_opaque, int nirq) { bus->set_irq = set_irq; - bus->map_irq = map_irq; bus->irq_opaque = irq_opaque; bus->nirq = nirq; bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0])); } +void pci_bus_map_irqs(PCIBus *bus, pci_map_irq_fn map_irq) +{ + bus->map_irq = map_irq; +} + void pci_bus_irqs_cleanup(PCIBus *bus) { bus->set_irq = NULL; @@ -549,7 +554,8 @@ PCIBus *pci_register_root_bus(DeviceState *parent, const char *name, bus = pci_root_bus_new(parent, name, address_space_mem, address_space_io, devfn_min, typename); - pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq); + pci_bus_irqs(bus, set_irq, irq_opaque, nirq); + pci_bus_map_irqs(bus, map_irq); return bus; } diff --git a/hw/remote/machine.c b/hw/remote/machine.c index 75d550daae..519f855ec1 100644 --- a/hw/remote/machine.c +++ b/hw/remote/machine.c @@ -63,8 +63,9 @@ static void remote_machine_init(MachineState *machine) } else { remote_iohub_init(&s->iohub); - pci_bus_irqs(pci_host->bus, remote_iohub_set_irq, remote_iohub_map_irq, + pci_bus_irqs(pci_host->bus, remote_iohub_set_irq, &s->iohub, REMOTE_IOHUB_NB_PIRQS); + pci_bus_map_irqs(pci_host->bus, remote_iohub_map_irq); } qbus_set_hotplug_handler(BUS(pci_host->bus), OBJECT(s)); diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index fe1fdfb5f7..88ffafc73e 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -665,8 +665,8 @@ void vfu_object_set_bus_irq(PCIBus *pci_bus) int bus_num = pci_bus_num(pci_bus); int max_bdf = PCI_BUILD_BDF(bus_num, PCI_DEVFN_MAX - 1); - pci_bus_irqs(pci_bus, vfu_object_set_irq, vfu_object_map_irq, pci_bus, - max_bdf); + pci_bus_irqs(pci_bus, vfu_object_set_irq, pci_bus, max_bdf); + pci_bus_map_irqs(pci_bus, vfu_object_map_irq); } static int vfu_object_device_reset(vfu_ctx_t *vfu_ctx, vfu_reset_type_t type) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 7048a373d1..85ee458cd2 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -282,8 +282,9 @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name, MemoryRegion *address_space_io, uint8_t devfn_min, const char *typename); void pci_root_bus_cleanup(PCIBus *bus); -void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, +void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, void *irq_opaque, int nirq); +void pci_bus_map_irqs(PCIBus *bus, pci_map_irq_fn map_irq); void pci_bus_irqs_cleanup(PCIBus *bus); int pci_bus_get_irq_level(PCIBus *bus, int irq_num); /* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */ From 738c2eb47f2fb150a337b6bfb151f4339d0bb8b3 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 9 Jan 2023 18:23:18 +0100 Subject: [PATCH 31/46] hw/isa/piix3: Decouple INTx-to-LNKx routing which is board-specific MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_map_irq_fn's in general seem to be board-specific. So move PIIX3's pci_slot_get_pirq() to board code to not have PIIX3 make assuptions about its board. Signed-off-by: Bernhard Beschow Reviewed-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230109172347.1830-6-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc_piix.c | 15 +++++++++++++++ hw/isa/piix3.c | 13 ------------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index b48047f50c..bb3b10557f 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -47,6 +47,7 @@ #include "hw/sysbus.h" #include "hw/i2c/smbus_eeprom.h" #include "hw/xen/xen-x86.h" +#include "hw/xen/xen.h" #include "exec/memory.h" #include "hw/acpi/acpi.h" #include "hw/acpi/piix4.h" @@ -73,6 +74,17 @@ static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; #endif +/* + * Return the global irq number corresponding to a given device irq + * pin. We could also use the bus number to have a more precise mapping. + */ +static int pc_pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx) +{ + int slot_addend; + slot_addend = PCI_SLOT(pci_dev->devfn) - 1; + return (pci_intx + slot_addend) & 3; +} + /* PC hardware initialisation */ static void pc_init1(MachineState *machine, const char *host_type, const char *pci_type) @@ -216,6 +228,9 @@ static void pc_init1(MachineState *machine, x86ms->below_4g_mem_size, x86ms->above_4g_mem_size, pci_memory, ram_memory); + pci_bus_map_irqs(pci_bus, + xen_enabled() ? xen_pci_slot_get_pirq + : pc_pci_slot_get_pirq); pcms->bus = pci_bus; pci_dev = pci_create_simple_multifunction(pci_bus, -1, true, type); diff --git a/hw/isa/piix3.c b/hw/isa/piix3.c index 666e794f77..283b971ec4 100644 --- a/hw/isa/piix3.c +++ b/hw/isa/piix3.c @@ -79,17 +79,6 @@ static void piix3_set_irq(void *opaque, int pirq, int level) piix3_set_irq_level(piix3, pirq, level); } -/* - * Return the global irq number corresponding to a given device irq - * pin. We could also use the bus number to have a more precise mapping. - */ -static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx) -{ - int slot_addend; - slot_addend = PCI_SLOT(pci_dev->devfn) - 1; - return (pci_intx + slot_addend) & 3; -} - static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin) { PIIX3State *piix3 = opaque; @@ -385,7 +374,6 @@ static void piix3_realize(PCIDevice *dev, Error **errp) } pci_bus_irqs(pci_bus, piix3_set_irq, piix3, PIIX_NUM_PIRQS); - pci_bus_map_irqs(pci_bus, pci_slot_get_pirq); pci_bus_set_route_irq_fn(pci_bus, piix3_route_intx_pin_to_irq); } @@ -421,7 +409,6 @@ static void piix3_xen_realize(PCIDevice *dev, Error **errp) * These additional routes can be discovered through ACPI. */ pci_bus_irqs(pci_bus, xen_piix3_set_irq, piix3, XEN_PIIX_NUM_PIRQS); - pci_bus_map_irqs(pci_bus, xen_pci_slot_get_pirq); } static void piix3_xen_class_init(ObjectClass *klass, void *data) From 3c73d590e7b20c58061cc7a67ecc6e3f5bf39192 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 9 Jan 2023 18:23:19 +0100 Subject: [PATCH 32/46] hw/isa/piix4: Decouple INTx-to-LNKx routing which is board-specific MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pci_map_irq_fn's in general seem to be board-specific, and PIIX4's pci_slot_get_pirq() in particular seems very Malta-specific. So move the latter to malta.c to 1/ keep the board logic in one place and 2/ avoid PIIX4 to make assumptions about its board. Signed-off-by: Bernhard Beschow Reviewed-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230109172347.1830-7-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/isa/piix4.c | 26 -------------------------- hw/mips/malta.c | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 9c79c9677b..6e9434129d 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -79,31 +79,6 @@ static void piix4_set_irq(void *opaque, int irq_num, int level) } } -static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) -{ - int slot; - - slot = PCI_SLOT(pci_dev->devfn); - - switch (slot) { - /* PIIX4 USB */ - case 10: - return 3; - /* AMD 79C973 Ethernet */ - case 11: - return 1; - /* Crystal 4281 Sound */ - case 12: - return 2; - /* PCI slot 1 to 4 */ - case 18 ... 21: - return ((slot - 18) + irq_num) & 0x03; - /* Unknown device, don't do any translation */ - default: - return irq_num; - } -} - static void piix4_isa_reset(DeviceState *dev) { PIIX4State *d = PIIX4_PCI_DEVICE(dev); @@ -272,7 +247,6 @@ static void piix4_realize(PCIDevice *dev, Error **errp) qdev_connect_gpio_out(DEVICE(&s->pm), 0, s->isa[9]); pci_bus_irqs(pci_bus, piix4_set_irq, s, PIIX_NUM_PIRQS); - pci_bus_map_irqs(pci_bus, pci_slot_get_pirq); } static void piix4_init(Object *obj) diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 8bf2e2ff5f..ec172b111a 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -39,6 +39,7 @@ #include "hw/mips/bootloader.h" #include "hw/mips/cpudevs.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" #include "qemu/log.h" #include "hw/mips/bios.h" #include "hw/ide/pci.h" @@ -993,6 +994,31 @@ static void malta_mips_config(MIPSCPU *cpu) } } +static int malta_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num) +{ + int slot; + + slot = PCI_SLOT(pci_dev->devfn); + + switch (slot) { + /* PIIX4 USB */ + case 10: + return 3; + /* AMD 79C973 Ethernet */ + case 11: + return 1; + /* Crystal 4281 Sound */ + case 12: + return 2; + /* PCI slot 1 to 4 */ + case 18 ... 21: + return ((slot - 18) + irq_num) & 0x03; + /* Unknown device, don't do any translation */ + default: + return irq_num; + } +} + static void main_cpu_reset(void *opaque) { MIPSCPU *cpu = opaque; @@ -1225,6 +1251,7 @@ void mips_malta_init(MachineState *machine) qdev_prop_set_bit(dev, "cpu-little-endian", !be); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci")); + pci_bus_map_irqs(pci_bus, malta_pci_slot_get_pirq); /* Southbridge */ piix4 = pci_create_simple_multifunction(pci_bus, PIIX4_PCI_DEVFN, true, From c451e07798e3640bed992cb43d8d867ef0ae1f4a Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 9 Jan 2023 18:23:20 +0100 Subject: [PATCH 33/46] hw/mips/Kconfig: Track Malta's PIIX dependencies via Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tracking dependencies via Kconfig seems much cleaner. Note that PIIX4 already depends on ACPI_PIIX4. Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Message-Id: <20230109172347.1830-8-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- configs/devices/mips-softmmu/common.mak | 2 -- hw/mips/Kconfig | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/configs/devices/mips-softmmu/common.mak b/configs/devices/mips-softmmu/common.mak index a125e74f24..7da99327a7 100644 --- a/configs/devices/mips-softmmu/common.mak +++ b/configs/devices/mips-softmmu/common.mak @@ -17,9 +17,7 @@ CONFIG_I8254=y CONFIG_PCSPK=y CONFIG_PCKBD=y CONFIG_FDC=y -CONFIG_ACPI_PIIX4=y CONFIG_I8257=y -CONFIG_PIIX4=y CONFIG_IDE_ISA=y CONFIG_PFLASH_CFI01=y CONFIG_I8259=y diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index 7a55143f8a..da3a37e215 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -2,6 +2,7 @@ config MALTA bool select GT64120 select ISA_SUPERIO + select PIIX4 config MIPSSIM bool From f0712099a29aba335fd1dbf4b19811ad0f57d095 Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 9 Jan 2023 18:23:21 +0100 Subject: [PATCH 34/46] hw/usb/hcd-uhci: Introduce TYPE_ defines for device models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested-by: Mark Cave-Ayland Signed-off-by: Bernhard Beschow Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Message-Id: <20221204190553.3274-7-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/pc_piix.c | 3 ++- hw/i386/pc_q35.c | 13 +++++++------ hw/isa/piix4.c | 2 +- hw/usb/hcd-uhci.c | 16 ++++++++-------- hw/usb/hcd-uhci.h | 4 ++++ 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index bb3b10557f..df64dd8dcc 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -51,6 +51,7 @@ #include "exec/memory.h" #include "hw/acpi/acpi.h" #include "hw/acpi/piix4.h" +#include "hw/usb/hcd-uhci.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/xen.h" @@ -305,7 +306,7 @@ static void pc_init1(MachineState *machine, #endif if (pcmc->pci_enabled && machine_usb(machine)) { - pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci"); + pci_create_simple(pci_bus, piix3_devfn + 2, TYPE_PIIX3_USB_UHCI); } if (pcmc->pci_enabled && x86_machine_is_acpi_enabled(X86_MACHINE(pcms))) { diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 65ea226211..83c57c6eb1 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -48,6 +48,7 @@ #include "hw/ide/pci.h" #include "hw/ide/ahci.h" #include "hw/usb.h" +#include "hw/usb/hcd-uhci.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/numa.h" @@ -65,15 +66,15 @@ struct ehci_companions { }; static const struct ehci_companions ich9_1d[] = { - { .name = "ich9-usb-uhci1", .func = 0, .port = 0 }, - { .name = "ich9-usb-uhci2", .func = 1, .port = 2 }, - { .name = "ich9-usb-uhci3", .func = 2, .port = 4 }, + { .name = TYPE_ICH9_USB_UHCI(1), .func = 0, .port = 0 }, + { .name = TYPE_ICH9_USB_UHCI(2), .func = 1, .port = 2 }, + { .name = TYPE_ICH9_USB_UHCI(3), .func = 2, .port = 4 }, }; static const struct ehci_companions ich9_1a[] = { - { .name = "ich9-usb-uhci4", .func = 0, .port = 0 }, - { .name = "ich9-usb-uhci5", .func = 1, .port = 2 }, - { .name = "ich9-usb-uhci6", .func = 2, .port = 4 }, + { .name = TYPE_ICH9_USB_UHCI(4), .func = 0, .port = 0 }, + { .name = TYPE_ICH9_USB_UHCI(5), .func = 1, .port = 2 }, + { .name = TYPE_ICH9_USB_UHCI(6), .func = 2, .port = 4 }, }; static int ehci_create_ich9_with_companions(PCIBus *bus, int slot) diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 6e9434129d..de60ceef73 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -255,7 +255,7 @@ static void piix4_init(Object *obj) object_initialize_child(obj, "rtc", &s->rtc, TYPE_MC146818_RTC); object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE); - object_initialize_child(obj, "uhci", &s->uhci, "piix4-usb-uhci"); + object_initialize_child(obj, "uhci", &s->uhci, TYPE_PIIX4_USB_UHCI); object_initialize_child(obj, "pm", &s->pm, TYPE_PIIX4_PM); qdev_prop_set_uint32(DEVICE(&s->pm), "smb_io_base", 0x1100); diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index d1b5657d72..30ae0104bb 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -1292,56 +1292,56 @@ void uhci_data_class_init(ObjectClass *klass, void *data) static UHCIInfo uhci_info[] = { { - .name = "piix3-usb-uhci", + .name = TYPE_PIIX3_USB_UHCI, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82371SB_2, .revision = 0x01, .irq_pin = 3, .unplug = true, },{ - .name = "piix4-usb-uhci", + .name = TYPE_PIIX4_USB_UHCI, .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82371AB_2, .revision = 0x01, .irq_pin = 3, .unplug = true, },{ - .name = "ich9-usb-uhci1", /* 00:1d.0 */ + .name = TYPE_ICH9_USB_UHCI(1), /* 00:1d.0 */ .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI1, .revision = 0x03, .irq_pin = 0, .unplug = false, },{ - .name = "ich9-usb-uhci2", /* 00:1d.1 */ + .name = TYPE_ICH9_USB_UHCI(2), /* 00:1d.1 */ .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI2, .revision = 0x03, .irq_pin = 1, .unplug = false, },{ - .name = "ich9-usb-uhci3", /* 00:1d.2 */ + .name = TYPE_ICH9_USB_UHCI(3), /* 00:1d.2 */ .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI3, .revision = 0x03, .irq_pin = 2, .unplug = false, },{ - .name = "ich9-usb-uhci4", /* 00:1a.0 */ + .name = TYPE_ICH9_USB_UHCI(4), /* 00:1a.0 */ .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI4, .revision = 0x03, .irq_pin = 0, .unplug = false, },{ - .name = "ich9-usb-uhci5", /* 00:1a.1 */ + .name = TYPE_ICH9_USB_UHCI(5), /* 00:1a.1 */ .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI5, .revision = 0x03, .irq_pin = 1, .unplug = false, },{ - .name = "ich9-usb-uhci6", /* 00:1a.2 */ + .name = TYPE_ICH9_USB_UHCI(6), /* 00:1a.2 */ .vendor_id = PCI_VENDOR_ID_INTEL, .device_id = PCI_DEVICE_ID_INTEL_82801I_UHCI6, .revision = 0x03, diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h index 5843af504a..e0fdb98ef1 100644 --- a/hw/usb/hcd-uhci.h +++ b/hw/usb/hcd-uhci.h @@ -91,4 +91,8 @@ typedef struct UHCIInfo { void uhci_data_class_init(ObjectClass *klass, void *data); void usb_uhci_common_realize(PCIDevice *dev, Error **errp); +#define TYPE_PIIX3_USB_UHCI "piix3-usb-uhci" +#define TYPE_PIIX4_USB_UHCI "piix4-usb-uhci" +#define TYPE_ICH9_USB_UHCI(fn) "ich9-usb-uhci" #fn + #endif From 2aaf0ec7ff239523ce2c8d913b120202c219af3e Mon Sep 17 00:00:00 2001 From: Bernhard Beschow Date: Mon, 9 Jan 2023 18:23:22 +0100 Subject: [PATCH 35/46] hw/intc/i8259: Make using the isa_pic singleton more type-safe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This even spares some casts in hot code paths along the way. Signed-off-by: Bernhard Beschow Reviewed-by: Michael S. Tsirkin Reviewed-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20230109172347.1830-10-shentey@gmail.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/intc/i8259.c | 11 ++++------- include/hw/intc/i8259.h | 6 +++--- include/qemu/typedefs.h | 1 + 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index cc4e21ffec..0261f087b2 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -55,7 +55,7 @@ struct PICClass { #ifdef DEBUG_IRQ_LATENCY static int64_t irq_time[16]; #endif -DeviceState *isa_pic; +PICCommonState *isa_pic; static PICCommonState *slave_pic; /* return the highest priority found in mask (highest = smallest @@ -173,9 +173,8 @@ static void pic_intack(PICCommonState *s, int irq) pic_update_irq(s); } -int pic_read_irq(DeviceState *d) +int pic_read_irq(PICCommonState *s) { - PICCommonState *s = PIC_COMMON(d); int irq, intno; irq = pic_get_irq(s); @@ -354,10 +353,8 @@ static uint64_t pic_ioport_read(void *opaque, hwaddr addr, return ret; } -int pic_get_output(DeviceState *d) +int pic_get_output(PICCommonState *s) { - PICCommonState *s = PIC_COMMON(d); - return (pic_get_irq(s) >= 0); } @@ -426,7 +423,7 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq) irq_set[i] = qdev_get_gpio_in(dev, i); } - isa_pic = dev; + isa_pic = PIC_COMMON(dev); isadev = i8259_init_chip(TYPE_I8259, bus, false); dev = DEVICE(isadev); diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h index e2b1e8c59a..a0e34dd990 100644 --- a/include/hw/intc/i8259.h +++ b/include/hw/intc/i8259.h @@ -3,10 +3,10 @@ /* i8259.c */ -extern DeviceState *isa_pic; +extern PICCommonState *isa_pic; qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq); qemu_irq *kvm_i8259_init(ISABus *bus); -int pic_get_output(DeviceState *d); -int pic_read_irq(DeviceState *d); +int pic_get_output(PICCommonState *s); +int pic_read_irq(PICCommonState *s); #endif diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 073abab998..fba04875c2 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -99,6 +99,7 @@ typedef struct PCIExpressDevice PCIExpressDevice; typedef struct PCIExpressHost PCIExpressHost; typedef struct PCIHostDeviceAddress PCIHostDeviceAddress; typedef struct PCIHostState PCIHostState; +typedef struct PICCommonState PICCommonState; typedef struct PostcopyDiscardState PostcopyDiscardState; typedef struct Property Property; typedef struct PropertyInfo PropertyInfo; From 2b85e0cda4b066010efda63a2d2359872ba07a04 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 10 Jan 2023 10:53:48 +0100 Subject: [PATCH 36/46] hw/intc: Extract the IRQ counting functions into a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These IRQ counting functions will soon be required in binaries that do not include the APIC code, too, so let's extract them into a separate file that can be linked independently of the APIC code. While we're at it, change the apic_* prefix into kvm_* since the functions are used from the i8259 PIC (i.e. not the APIC), too. Reviewed-by: Bernhard Beschow Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: <20230110095351.611724-2-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/i386/kvm/i8259.c | 4 +-- hw/i386/kvm/ioapic.c | 4 +-- hw/intc/apic.c | 3 +- hw/intc/apic_common.c | 30 ++------------------ hw/intc/kvm_irqcount.c | 49 +++++++++++++++++++++++++++++++++ hw/intc/meson.build | 6 ++++ hw/intc/trace-events | 9 +++--- hw/rtc/mc146818rtc.c | 6 ++-- include/hw/i386/apic.h | 2 -- include/hw/i386/apic_internal.h | 1 - include/hw/intc/kvm_irqcount.h | 10 +++++++ 11 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 hw/intc/kvm_irqcount.c create mode 100644 include/hw/intc/kvm_irqcount.h diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c index d61bae4dc3..3ca0e1ff03 100644 --- a/hw/i386/kvm/i8259.c +++ b/hw/i386/kvm/i8259.c @@ -14,7 +14,7 @@ #include "hw/isa/i8259_internal.h" #include "hw/intc/i8259.h" #include "qemu/module.h" -#include "hw/i386/apic_internal.h" +#include "hw/intc/kvm_irqcount.h" #include "hw/irq.h" #include "sysemu/kvm.h" #include "qom/object.h" @@ -117,7 +117,7 @@ static void kvm_pic_set_irq(void *opaque, int irq, int level) pic_stat_update_irq(irq, level); delivered = kvm_set_irq(kvm_state, irq, level); - apic_report_irq_delivered(delivered); + kvm_report_irq_delivered(delivered); } static void kvm_pic_realize(DeviceState *dev, Error **errp) diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index ee7c8ef68b..272e26b4a2 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -15,7 +15,7 @@ #include "hw/i386/x86.h" #include "hw/qdev-properties.h" #include "hw/i386/ioapic_internal.h" -#include "hw/i386/apic_internal.h" +#include "hw/intc/kvm_irqcount.h" #include "sysemu/kvm.h" /* PC Utility function */ @@ -116,7 +116,7 @@ static void kvm_ioapic_set_irq(void *opaque, int irq, int level) ioapic_stat_update_irq(common, irq, level); delivered = kvm_set_irq(kvm_state, s->kvm_gsi_base + irq, level); - apic_report_irq_delivered(delivered); + kvm_report_irq_delivered(delivered); } static void kvm_ioapic_realize(DeviceState *dev, Error **errp) diff --git a/hw/intc/apic.c b/hw/intc/apic.c index 3df11c34d6..2d3e55f4e2 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -22,6 +22,7 @@ #include "hw/i386/apic.h" #include "hw/i386/ioapic.h" #include "hw/intc/i8259.h" +#include "hw/intc/kvm_irqcount.h" #include "hw/pci/msi.h" #include "qemu/host-utils.h" #include "sysemu/kvm.h" @@ -399,7 +400,7 @@ void apic_poll_irq(DeviceState *dev) static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode) { - apic_report_irq_delivered(!apic_get_bit(s->irr, vector_num)); + kvm_report_irq_delivered(!apic_get_bit(s->irr, vector_num)); apic_set_bit(s->irr, vector_num); if (trigger_mode) diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 2a20982066..4a34f03047 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -25,6 +25,7 @@ #include "qapi/visitor.h" #include "hw/i386/apic.h" #include "hw/i386/apic_internal.h" +#include "hw/intc/kvm_irqcount.h" #include "trace.h" #include "hw/boards.h" #include "sysemu/hax.h" @@ -33,7 +34,6 @@ #include "hw/sysbus.h" #include "migration/vmstate.h" -static int apic_irq_delivered; bool apic_report_tpr_access; void cpu_set_apic_base(DeviceState *dev, uint64_t val) @@ -122,32 +122,6 @@ void apic_handle_tpr_access_report(DeviceState *dev, target_ulong ip, vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access); } -void apic_report_irq_delivered(int delivered) -{ - apic_irq_delivered += delivered; - - trace_apic_report_irq_delivered(apic_irq_delivered); -} - -void apic_reset_irq_delivered(void) -{ - /* Copy this into a local variable to encourage gcc to emit a plain - * register for a sys/sdt.h marker. For details on this workaround, see: - * https://sourceware.org/bugzilla/show_bug.cgi?id=13296 - */ - volatile int a_i_d = apic_irq_delivered; - trace_apic_reset_irq_delivered(a_i_d); - - apic_irq_delivered = 0; -} - -int apic_get_irq_delivered(void) -{ - trace_apic_get_irq_delivered(apic_irq_delivered); - - return apic_irq_delivered; -} - void apic_deliver_nmi(DeviceState *dev) { APICCommonState *s = APIC_COMMON(dev); @@ -272,7 +246,7 @@ static void apic_reset_common(DeviceState *dev) s->apicbase = APIC_DEFAULT_ADDRESS | bsp | MSR_IA32_APICBASE_ENABLE; s->id = s->initial_apic_id; - apic_reset_irq_delivered(); + kvm_reset_irq_delivered(); s->vapic_paddr = 0; info->vapic_base_update(s); diff --git a/hw/intc/kvm_irqcount.c b/hw/intc/kvm_irqcount.c new file mode 100644 index 0000000000..2ef8a83a7a --- /dev/null +++ b/hw/intc/kvm_irqcount.c @@ -0,0 +1,49 @@ +/* + * KVM PIC functions for counting the delivered IRQs. + * + * 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 + */ + +#include "qemu/osdep.h" +#include "hw/intc/kvm_irqcount.h" +#include "trace.h" + +static int kvm_irq_delivered; + +void kvm_report_irq_delivered(int delivered) +{ + kvm_irq_delivered += delivered; + + trace_kvm_report_irq_delivered(kvm_irq_delivered); +} + +void kvm_reset_irq_delivered(void) +{ + /* + * Copy this into a local variable to encourage gcc to emit a plain + * register for a sys/sdt.h marker. For details on this workaround, see: + * https://sourceware.org/bugzilla/show_bug.cgi?id=13296 + */ + volatile int k_i_d = kvm_irq_delivered; + trace_kvm_reset_irq_delivered(k_i_d); + + kvm_irq_delivered = 0; +} + +int kvm_get_irq_delivered(void) +{ + trace_kvm_get_irq_delivered(kvm_irq_delivered); + + return kvm_irq_delivered; +} diff --git a/hw/intc/meson.build b/hw/intc/meson.build index bcbf22ff51..cd9f1ee888 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -25,6 +25,12 @@ softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_intc.c')) softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-ipi.c')) softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-intc.c')) +if config_all_devices.has_key('CONFIG_APIC') or \ + config_all_devices.has_key('CONFIG_I8259') or \ + config_all_devices.has_key('CONFIG_MC146818RTC') + softmmu_ss.add(files('kvm_irqcount.c')) +endif + specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c')) specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c')) specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c')) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 6fbc2045e6..50cadfb996 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -10,10 +10,6 @@ pic_ioport_read(bool master, uint64_t addr, int val) "master %d addr 0x%"PRIx64" # apic_common.c cpu_set_apic_base(uint64_t val) "0x%016"PRIx64 cpu_get_apic_base(uint64_t val) "0x%016"PRIx64 -# coalescing -apic_report_irq_delivered(int apic_irq_delivered) "coalescing %d" -apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d" -apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d" # apic.c apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d" @@ -30,6 +26,11 @@ ioapic_mem_read(uint8_t addr, uint8_t regsel, uint8_t size, uint32_t val) "ioapi ioapic_mem_write(uint8_t addr, uint8_t regsel, uint8_t size, uint32_t val) "ioapic mem write addr 0x%"PRIx8" regsel: 0x%"PRIx8" size 0x%"PRIx8" val 0x%"PRIx32 ioapic_set_irq(int vector, int level) "vector: %d level: %d" +# kvm_irqcount.c +kvm_report_irq_delivered(int irq_delivered) "coalescing %d" +kvm_reset_irq_delivered(int irq_delivered) "old coalescing %d" +kvm_get_irq_delivered(int irq_delivered) "returning coalescing %d" + # slavio_intctl.c slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = 0x%x" slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = 0x%x" diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c index 1ebb412479..947d68c257 100644 --- a/hw/rtc/mc146818rtc.c +++ b/hw/rtc/mc146818rtc.c @@ -27,6 +27,7 @@ #include "qemu/module.h" #include "qemu/bcd.h" #include "hw/acpi/acpi_aml_interface.h" +#include "hw/intc/kvm_irqcount.h" #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" @@ -46,7 +47,6 @@ #ifdef TARGET_I386 #include "qapi/qapi-commands-misc-target.h" -#include "hw/i386/apic.h" #endif //#define DEBUG_CMOS @@ -124,9 +124,9 @@ void qmp_rtc_reset_reinjection(Error **errp) static bool rtc_policy_slew_deliver_irq(RTCState *s) { - apic_reset_irq_delivered(); + kvm_reset_irq_delivered(); qemu_irq_raise(s->irq); - return apic_get_irq_delivered(); + return kvm_get_irq_delivered(); } static void rtc_coalesced_timer(void *opaque) diff --git a/include/hw/i386/apic.h b/include/hw/i386/apic.h index da1d2fe155..bdc15a7a73 100644 --- a/include/hw/i386/apic.h +++ b/include/hw/i386/apic.h @@ -9,8 +9,6 @@ int apic_accept_pic_intr(DeviceState *s); void apic_deliver_pic_intr(DeviceState *s, int level); void apic_deliver_nmi(DeviceState *d); int apic_get_interrupt(DeviceState *s); -void apic_reset_irq_delivered(void); -int apic_get_irq_delivered(void); void cpu_set_apic_base(DeviceState *s, uint64_t val); uint64_t cpu_get_apic_base(DeviceState *s); void cpu_set_apic_tpr(DeviceState *s, uint8_t val); diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index 968b6648b3..5f2ba24bfc 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -199,7 +199,6 @@ typedef struct VAPICState { extern bool apic_report_tpr_access; -void apic_report_irq_delivered(int delivered); bool apic_next_timer(APICCommonState *s, int64_t current_time); void apic_enable_tpr_access_reporting(DeviceState *d, bool enable); void apic_enable_vapic(DeviceState *d, hwaddr paddr); diff --git a/include/hw/intc/kvm_irqcount.h b/include/hw/intc/kvm_irqcount.h new file mode 100644 index 0000000000..0ed5999e49 --- /dev/null +++ b/include/hw/intc/kvm_irqcount.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#ifndef KVM_IRQCOUNT_H +#define KVM_IRQCOUNT_H + +void kvm_report_irq_delivered(int delivered); +void kvm_reset_irq_delivered(void); +int kvm_get_irq_delivered(void); + +#endif From aae167211fb326784b323b87a0e4c0fa832940b3 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 10 Jan 2023 10:53:49 +0100 Subject: [PATCH 37/46] hw/core/qdev-properties-system: Allow the 'slew' policy only on x86 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'slew' tick policy is currently enforced to be only available on x86 via some "#ifdef TARGET_I386" statements in mc146818rtc.c. We want to get rid of those #ifdefs, so we need a different way of checking whether the policy is allowed or not. Using the setter function in hw/core/qdev-properties-system.c seems to be a good place, so let's add a check here. Suggested-by: Mark Cave-Ayland Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Reviewed-by: Bernhard Beschow Message-Id: <20230110095351.611724-3-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/core/qdev-properties-system.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 54a09fa9ac..d42493f630 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -33,6 +33,7 @@ #include "net/net.h" #include "hw/pci/pci.h" #include "hw/pci/pcie.h" +#include "hw/i386/x86.h" #include "util/block-helpers.h" static bool check_prop_still_unset(Object *obj, const char *name, @@ -558,13 +559,38 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) /* --- lost tick policy --- */ +static void qdev_propinfo_set_losttickpolicy(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + Property *prop = opaque; + int *ptr = object_field_prop_ptr(obj, prop); + int value; + + if (!visit_type_enum(v, name, &value, prop->info->enum_table, errp)) { + return; + } + + if (value == LOST_TICK_POLICY_SLEW) { + MachineState *ms = MACHINE(qdev_get_machine()); + + if (!object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) { + error_setg(errp, + "the 'slew' policy is only available for x86 machines"); + return; + } + } + + *ptr = value; +} + QEMU_BUILD_BUG_ON(sizeof(LostTickPolicy) != sizeof(int)); const PropertyInfo qdev_prop_losttickpolicy = { .name = "LostTickPolicy", .enum_table = &LostTickPolicy_lookup, .get = qdev_propinfo_get_enum, - .set = qdev_propinfo_set_enum, + .set = qdev_propinfo_set_losttickpolicy, .set_default_value = qdev_propinfo_set_default_value_enum, }; From e896d849331eb853cf3b7df6a24be279ae9a421d Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 10 Jan 2023 10:53:50 +0100 Subject: [PATCH 38/46] hw/rtc/mc146818rtc: Make the mc146818 RTC device target independent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only reason for this code being target dependent was the IRQ-counting related code in rtc_policy_slew_deliver_irq(). Since these functions have been moved into a new, separate file (kvm_irqcount.c) which is now always compiled and linked if necessary, we can get rid of the #ifdef TARGET_I386 switches in mc146818rtc.c and declare it in the softmmu_ss instead of specific_ss, so that the code only gets compiled once for all targets. Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Mark Cave-Ayland Message-Id: <20230110095351.611724-4-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/rtc/mc146818rtc.c | 14 -------------- hw/rtc/meson.build | 3 +-- include/hw/rtc/mc146818rtc.h | 1 + 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c index 947d68c257..bc1192b7ae 100644 --- a/hw/rtc/mc146818rtc.c +++ b/hw/rtc/mc146818rtc.c @@ -45,10 +45,6 @@ #include "qapi/visitor.h" #include "hw/rtc/mc146818rtc_regs.h" -#ifdef TARGET_I386 -#include "qapi/qapi-commands-misc-target.h" -#endif - //#define DEBUG_CMOS //#define DEBUG_COALESCED @@ -112,7 +108,6 @@ static void rtc_coalesced_timer_update(RTCState *s) static QLIST_HEAD(, RTCState) rtc_devices = QLIST_HEAD_INITIALIZER(rtc_devices); -#ifdef TARGET_I386 void qmp_rtc_reset_reinjection(Error **errp) { RTCState *s; @@ -145,13 +140,6 @@ static void rtc_coalesced_timer(void *opaque) rtc_coalesced_timer_update(s); } -#else -static bool rtc_policy_slew_deliver_irq(RTCState *s) -{ - assert(0); - return false; -} -#endif static uint32_t rtc_periodic_clock_ticks(RTCState *s) { @@ -922,12 +910,10 @@ static void rtc_realizefn(DeviceState *dev, Error **errp) rtc_set_date_from_host(isadev); switch (s->lost_tick_policy) { -#ifdef TARGET_I386 case LOST_TICK_POLICY_SLEW: s->coalesced_timer = timer_new_ns(rtc_clock, rtc_coalesced_timer, s); break; -#endif case LOST_TICK_POLICY_DISCARD: break; default: diff --git a/hw/rtc/meson.build b/hw/rtc/meson.build index dc33973384..34a4d316fa 100644 --- a/hw/rtc/meson.build +++ b/hw/rtc/meson.build @@ -13,5 +13,4 @@ softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_rtc.c')) softmmu_ss.add(when: 'CONFIG_GOLDFISH_RTC', if_true: files('goldfish_rtc.c')) softmmu_ss.add(when: 'CONFIG_LS7A_RTC', if_true: files('ls7a_rtc.c')) softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-rtc.c')) - -specific_ss.add(when: 'CONFIG_MC146818RTC', if_true: files('mc146818rtc.c')) +softmmu_ss.add(when: 'CONFIG_MC146818RTC', if_true: files('mc146818rtc.c')) diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h index 1db0fcee92..45bcd6f040 100644 --- a/include/hw/rtc/mc146818rtc.h +++ b/include/hw/rtc/mc146818rtc.h @@ -55,5 +55,6 @@ ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq); void rtc_set_memory(ISADevice *dev, int addr, int val); int rtc_get_memory(ISADevice *dev, int addr); +void qmp_rtc_reset_reinjection(Error **errp); #endif /* HW_RTC_MC146818RTC_H */ From e8dc34196b2a81b21469f6d95afc390ef645e63b Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 10 Jan 2023 10:53:51 +0100 Subject: [PATCH 39/46] softmmu/rtc: Emit warning when using driftfix=slew on systems without mc146818 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'slew' lost tick policy is only available on systems with a mc146818 RTC. On other systems, "-rtc driftfix=slew" is currently silently ignored. Let's emit at least a warning in this case to make the users aware that there is something wrong in their command line settings. Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth Reviewed-by: Mark Cave-Ayland Message-Id: <20230110095351.611724-5-thuth@redhat.com> Signed-off-by: Philippe Mathieu-Daudé --- softmmu/rtc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/softmmu/rtc.c b/softmmu/rtc.c index 7e2956f81e..f7114bed7d 100644 --- a/softmmu/rtc.c +++ b/softmmu/rtc.c @@ -33,6 +33,7 @@ #include "sysemu/replay.h" #include "sysemu/sysemu.h" #include "sysemu/rtc.h" +#include "hw/rtc/mc146818rtc.h" static enum { RTC_BASE_UTC, @@ -177,10 +178,13 @@ void configure_rtc(QemuOpts *opts) value = qemu_opt_get(opts, "driftfix"); if (value) { if (!strcmp(value, "slew")) { - object_register_sugar_prop("mc146818rtc", + object_register_sugar_prop(TYPE_MC146818_RTC, "lost_tick_policy", "slew", false); + if (!object_class_by_name(TYPE_MC146818_RTC)) { + warn_report("driftfix 'slew' is not available with this machine"); + } } else if (!strcmp(value, "none")) { /* discard is default */ } else { From 4dd5cb5d847ed887dd0a00c602b08bade6f6ffa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 26 Sep 2019 15:42:11 +0200 Subject: [PATCH 40/46] hw/pci-host/bonito: Convert to 3-phase reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the TYPE_PCI_BONITO class to use 3-phase reset. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230105130710.49264-2-philmd@linaro.org> --- hw/pci-host/bonito.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index f04f3ad668..450eb29ec0 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -47,7 +47,6 @@ #include "hw/mips/mips.h" #include "hw/pci/pci_host.h" #include "migration/vmstate.h" -#include "sysemu/reset.h" #include "sysemu/runstate.h" #include "hw/misc/unimp.h" #include "hw/registerfields.h" @@ -593,9 +592,9 @@ static int pci_bonito_map_irq(PCIDevice *pci_dev, int irq_num) } } -static void bonito_reset(void *opaque) +static void bonito_reset_hold(Object *obj) { - PCIBonitoState *s = opaque; + PCIBonitoState *s = PCI_BONITO(obj); uint32_t val = 0; /* set the default value of north bridge registers */ @@ -739,8 +738,6 @@ static void bonito_realize(PCIDevice *dev, Error **errp) pci_set_byte(dev->config + PCI_MIN_GNT, 0x3c); pci_set_byte(dev->config + PCI_MAX_LAT, 0x00); - - qemu_register_reset(bonito_reset, s); } PCIBus *bonito_init(qemu_irq *pic) @@ -770,7 +767,9 @@ static void bonito_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); + rc->phases.hold = bonito_reset_hold; k->realize = bonito_realize; k->vendor_id = 0xdf53; k->device_id = 0x00d5; From f9ab9c6e2b6091f1be519852eb2552a96e800a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 5 Jan 2023 11:47:04 +0100 Subject: [PATCH 41/46] hw/pci-host/bonito: Use 'bonito_host' for PCI host bridge code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make it easier to differentiate between the Host Bridge object and its PCI function #0, rename bonito_pcihost* as bonito_host*. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230105130710.49264-3-philmd@linaro.org> --- hw/pci-host/bonito.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 450eb29ec0..5c0928ffe6 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -627,7 +627,7 @@ static const VMStateDescription vmstate_bonito = { } }; -static void bonito_pcihost_realize(DeviceState *dev, Error **errp) +static void bonito_host_realize(DeviceState *dev, Error **errp) { PCIHostState *phb = PCI_HOST_BRIDGE(dev); BonitoState *bs = BONITO_PCI_HOST_BRIDGE(dev); @@ -795,23 +795,23 @@ static const TypeInfo bonito_info = { }, }; -static void bonito_pcihost_class_init(ObjectClass *klass, void *data) +static void bonito_host_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->realize = bonito_pcihost_realize; + dc->realize = bonito_host_realize; } -static const TypeInfo bonito_pcihost_info = { +static const TypeInfo bonito_host_info = { .name = TYPE_BONITO_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(BonitoState), - .class_init = bonito_pcihost_class_init, + .class_init = bonito_host_class_init, }; static void bonito_register_types(void) { - type_register_static(&bonito_pcihost_info); + type_register_static(&bonito_host_info); type_register_static(&bonito_info); } From eb66dac46da958c0ba20a2803344b20c8f79c48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 5 Jan 2023 11:48:34 +0100 Subject: [PATCH 42/46] hw/pci-host/bonito: Use 'bonito_pci' for PCI function #0 code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make it easier to differentiate between the Host Bridge object and its PCI function #0, rename bonito* as bonito_pci*. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230105130710.49264-4-philmd@linaro.org> --- hw/pci-host/bonito.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 5c0928ffe6..9c26aa2ad9 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -653,7 +653,7 @@ static void bonito_host_realize(DeviceState *dev, Error **errp) create_unimplemented_device("pci.io", BONITO_PCIIO_BASE, 1 * MiB); } -static void bonito_realize(PCIDevice *dev, Error **errp) +static void bonito_pci_realize(PCIDevice *dev, Error **errp) { PCIBonitoState *s = PCI_BONITO(dev); SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost); @@ -763,14 +763,14 @@ PCIBus *bonito_init(qemu_irq *pic) return phb->bus; } -static void bonito_class_init(ObjectClass *klass, void *data) +static void bonito_pci_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); rc->phases.hold = bonito_reset_hold; - k->realize = bonito_realize; + k->realize = bonito_pci_realize; k->vendor_id = 0xdf53; k->device_id = 0x00d5; k->revision = 0x01; @@ -784,11 +784,11 @@ static void bonito_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } -static const TypeInfo bonito_info = { +static const TypeInfo bonito_pci_info = { .name = TYPE_PCI_BONITO, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIBonitoState), - .class_init = bonito_class_init, + .class_init = bonito_pci_class_init, .interfaces = (InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, @@ -812,7 +812,7 @@ static const TypeInfo bonito_host_info = { static void bonito_register_types(void) { type_register_static(&bonito_host_info); - type_register_static(&bonito_info); + type_register_static(&bonito_pci_info); } type_init(bonito_register_types) From aad07969bb3bd7771678143119e53b86829f8746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 5 Jan 2023 13:48:08 +0100 Subject: [PATCH 43/46] hw/pci-host/bonito: Declare TYPE_BONITO_PCI_HOST_BRIDGE in header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare the TYPE_BONITO_PCI_HOST_BRIDGE QOM type in a header to be able to access it from board code. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20230105130710.49264-8-philmd@linaro.org> --- MAINTAINERS | 1 + hw/pci-host/bonito.c | 4 +--- include/hw/pci-host/bonito.h | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 include/hw/pci-host/bonito.h diff --git a/MAINTAINERS b/MAINTAINERS index a670fbc926..f7f5e9e439 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1262,6 +1262,7 @@ F: hw/isa/vt82c686.c F: hw/pci-host/bonito.c F: hw/usb/vt82c686-uhci-pci.c F: include/hw/isa/vt82c686.h +F: include/hw/pci-host/bonito.h F: tests/avocado/machine_mips_fuloong2e.py Loongson-3 virtual platforms diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 9c26aa2ad9..ac1eebf9de 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -45,6 +45,7 @@ #include "hw/pci/pci_device.h" #include "hw/irq.h" #include "hw/mips/mips.h" +#include "hw/pci-host/bonito.h" #include "hw/pci/pci_host.h" #include "migration/vmstate.h" #include "sysemu/runstate.h" @@ -238,9 +239,6 @@ struct BonitoState { MemoryRegion pci_mem; }; -#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost" -OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, BONITO_PCI_HOST_BRIDGE) - #define TYPE_PCI_BONITO "Bonito" OBJECT_DECLARE_SIMPLE_TYPE(PCIBonitoState, PCI_BONITO) diff --git a/include/hw/pci-host/bonito.h b/include/hw/pci-host/bonito.h new file mode 100644 index 0000000000..b8ecf7870a --- /dev/null +++ b/include/hw/pci-host/bonito.h @@ -0,0 +1,18 @@ +/* + * QEMU Bonito64 north bridge support + * + * Copyright (c) 2008 yajin (yajin@vm-kernel.org) + * Copyright (c) 2010 Huacai Chen (zltjiangshi@gmail.com) + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_PCI_HOST_BONITO_H +#define HW_PCI_HOST_BONITO_H + +#include "qom/object.h" + +#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost" +OBJECT_DECLARE_SIMPLE_TYPE(BonitoState, BONITO_PCI_HOST_BRIDGE) + +#endif From 026334610f40fe8c0abac9565eddee1d6cc99de7 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Wed, 11 Jan 2023 14:21:33 -0300 Subject: [PATCH 44/46] hw/mips/boston: Rename MachineState 'mc' pointer to 'ms' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the QEMU convention of naming MachineState pointers as 'ms' by renaming the instance in create_fdt() where we're calling it 'mc'. Cc: Paul Burton Cc: Aleksandar Rikalo Suggested-by: Philippe Mathieu-Daudé Signed-off-by: Daniel Henrique Barboza Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Bin Meng Message-Id: <20230111172133.334735-1-dbarboza@ventanamicro.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/boston.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/mips/boston.c b/hw/mips/boston.c index b6dd9fb200..a9d87f3437 100644 --- a/hw/mips/boston.c +++ b/hw/mips/boston.c @@ -515,7 +515,7 @@ static const void *create_fdt(BostonState *s, { void *fdt; int cpu; - MachineState *mc = s->mach; + MachineState *ms = s->mach; uint32_t platreg_ph, gic_ph, clk_ph; char *name, *gic_name, *platreg_name, *stdout_name; static const char * const syscon_compat[2] = { @@ -542,7 +542,7 @@ static const void *create_fdt(BostonState *s, qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); - for (cpu = 0; cpu < mc->smp.cpus; cpu++) { + for (cpu = 0; cpu < ms->smp.cpus; cpu++) { name = g_strdup_printf("/cpus/cpu@%d", cpu); qemu_fdt_add_subnode(fdt, name); qemu_fdt_setprop_string(fdt, name, "compatible", "img,mips"); From 6ba97c48a64d059ddfa5400330dfaf5982f5f2c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 19 Dec 2022 12:14:46 +0100 Subject: [PATCH 45/46] target/mips: Restrict 'qapi-commands-machine.h' to system emulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit a0e61807a3 ("qapi: Remove QMP events and commands from user-mode builds") we don't generate the "qapi-commands-machine.h" header in a user-emulation-only build. Extract the QMP functions from cpu.c (which is always compiled) to the new 'sysemu/mips-qmp-cmds.c' unit (which is only compiled when system emulation is selected). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221219211034.70491-4-philmd@linaro.org> --- target/mips/cpu.c | 29 ---------------------- target/mips/sysemu/meson.build | 1 + target/mips/sysemu/mips-qmp-cmds.c | 39 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 29 deletions(-) create mode 100644 target/mips/sysemu/mips-qmp-cmds.c diff --git a/target/mips/cpu.c b/target/mips/cpu.c index f995e88776..05caf54999 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -32,7 +32,6 @@ #include "hw/qdev-properties.h" #include "hw/qdev-clock.h" #include "semihosting/semihost.h" -#include "qapi/qapi-commands-machine-target.h" #include "fpu_helper.h" const char regnames[32][3] = { @@ -624,34 +623,6 @@ static void mips_cpu_register_types(void) type_init(mips_cpu_register_types) -static void mips_cpu_add_definition(gpointer data, gpointer user_data) -{ - ObjectClass *oc = data; - CpuDefinitionInfoList **cpu_list = user_data; - CpuDefinitionInfo *info; - const char *typename; - - typename = object_class_get_name(oc); - info = g_malloc0(sizeof(*info)); - info->name = g_strndup(typename, - strlen(typename) - strlen("-" TYPE_MIPS_CPU)); - info->q_typename = g_strdup(typename); - - QAPI_LIST_PREPEND(*cpu_list, info); -} - -CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) -{ - CpuDefinitionInfoList *cpu_list = NULL; - GSList *list; - - list = object_class_get_list(TYPE_MIPS_CPU, false); - g_slist_foreach(list, mips_cpu_add_definition, &cpu_list); - g_slist_free(list); - - return cpu_list; -} - /* Could be used by generic CPU object */ MIPSCPU *mips_cpu_create_with_clock(const char *cpu_type, Clock *cpu_refclk) { diff --git a/target/mips/sysemu/meson.build b/target/mips/sysemu/meson.build index cefc227582..261492de5b 100644 --- a/target/mips/sysemu/meson.build +++ b/target/mips/sysemu/meson.build @@ -3,5 +3,6 @@ mips_softmmu_ss.add(files( 'cp0.c', 'cp0_timer.c', 'machine.c', + 'mips-qmp-cmds.c', 'physaddr.c', )) diff --git a/target/mips/sysemu/mips-qmp-cmds.c b/target/mips/sysemu/mips-qmp-cmds.c new file mode 100644 index 0000000000..6db4626412 --- /dev/null +++ b/target/mips/sysemu/mips-qmp-cmds.c @@ -0,0 +1,39 @@ +/* + * QEMU MIPS CPU (monitor definitions) + * + * SPDX-FileCopyrightText: 2012 SUSE LINUX Products GmbH + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/qapi-commands-machine-target.h" +#include "cpu.h" + +static void mips_cpu_add_definition(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + CpuDefinitionInfoList **cpu_list = user_data; + CpuDefinitionInfo *info; + const char *typename; + + typename = object_class_get_name(oc); + info = g_malloc0(sizeof(*info)); + info->name = g_strndup(typename, + strlen(typename) - strlen("-" TYPE_MIPS_CPU)); + info->q_typename = g_strdup(typename); + + QAPI_LIST_PREPEND(*cpu_list, info); +} + +CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) +{ + CpuDefinitionInfoList *cpu_list = NULL; + GSList *list; + + list = object_class_get_list(TYPE_MIPS_CPU, false); + g_slist_foreach(list, mips_cpu_add_definition, &cpu_list); + g_slist_free(list); + + return cpu_list; +} From 4828656f65324249273ad2f2db80844ba90eeb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Fri, 16 Dec 2022 09:42:09 +0100 Subject: [PATCH 46/46] scripts/git.orderfile: Display MAINTAINERS changes first MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we get custom to see MAINTAINERS changes first, we might catch missing MAINTAINERS updates easier. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-Id: <20221216225505.26052-1-philmd@linaro.org> --- scripts/git.orderfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/git.orderfile b/scripts/git.orderfile index b32203b710..8edac0380b 100644 --- a/scripts/git.orderfile +++ b/scripts/git.orderfile @@ -9,6 +9,8 @@ # git config diff.orderFile scripts/git.orderfile # +MAINTAINERS + # Documentation docs/* *.rst