aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-09-03 05:49:44 +0200
committerRichard Henderson <richard.henderson@linaro.org>2025-09-03 05:49:44 +0200
commita10631b0cf04ce7daf26648840df3f15bc36724e (patch)
tree72846208ab54e2f18510c72011e683fd3de9e66d /hw
parent8415b0619f65bff12f10c774659df92d3f61daca (diff)
parente502e614f4c3e5ee7b12cf1c926d9581262fd626 (diff)
downloadqemu-a10631b0cf04ce7daf26648840df3f15bc36724e.zip
qemu-a10631b0cf04ce7daf26648840df3f15bc36724e.tar.gz
qemu-a10631b0cf04ce7daf26648840df3f15bc36724e.tar.bz2
Merge tag 'hw-misc-20250902' of https://github.com/philmd/qemu into staging
Misc HW patches - Compile various system files once - Remove SDCard spec v1.10 - Remove mipssim machine and mipsnet device model - Prevent crash in e1000e when legacy interrupt fires after enabling MSI-X - Introduce qemu_init_irq_child() - Remove various memory leaks reported by ASan - Few Coverity fixes - Use 74Kf CPU to run MIPS16e binaries and M14Kc for microMIPS ones # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmi3FDYACgkQ4+MsLN6t # wN7fwA//WqegI1RTs65uHGV2M0vcYtGYTrucLyJtE9lJubb3wVjzdZpNcVVwKFRi # lXNjnOfmA7lIsC2CMRaiFO/hIk40yN2BLoEupSrLXjiygtiwlhG8OX0mU/6o06/k # Q41rEAu0wLVdJDpyUZWnVi1WvjMzaal3RvENRMr5CsrFw/Yk6Z7HKBDMEMuJjOWL # qBTAf8o8pnfliiyeS+OE4r5iIFUHzCtGlQtJH1GZ+zFgR2LNe6UUbofmUnzIFU0j # KuepdXemmd29nEz7wk8a7sjbJmoN9vLdJtsM+zcwNOsxmFC9+1ap/8BAGzRmhrWp # l5zJmL2YbvdHExKLC3qlnhGsKutK+9K4VAB6jLZu0MHfUQBYCGgFgYFcLdlGlRzg # OGgCvx5M7vZekTEHQu3zT29iUOAKAkD7dYlGIPqSUGuPGDZgPOqIMMc1HJAblXB1 # xNATGo2T2D3M01/ugwPAMF2IhLmKa9oAQDKnsW+bG6WJ4rjhqQpbmvxn51JB8q/x # a7xuUJa8BqX24NMo5d6JqPZPQhor0P0J0ws6oKutLf381FQ9JAnVEVmbQqPSijHY # BW3by77G2e97hfK0MwqUi43yuRHmNsh3flCdgCt7Zx6lsqmnMJuuhuOL4jQx6JRR # hPWDFiR+mns12AL3J56A0Y92enoLTawMzrA5M/06my9HLjXuu5M= # =WRLz # -----END PGP SIGNATURE----- # gpg: Signature made Tue 02 Sep 2025 05:58:46 PM CEST # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'hw-misc-20250902' of https://github.com/philmd/qemu: (38 commits) hw/i386/pc_piix.c: remove unnecessary if() from pc_init1() hw/arm/boot: Correctly free the MemoryDeviceInfoList docs/about/removed-features: Clarify 'device_add' is removed hw/mips/malta: Include 'system/system.h' hw/mips/loongson3_virt: Include 'system/system.h' hw/isa/superio: Include 'system/system.h' hw/arm/virt: Include 'system/system.h' crypto/hmac: Allow to build hmac over multiple qcrypto_gnutls_hmac_bytes[v] calls hw/sd/sdcard: Refactor sd_bootpart_offset hw/sd/sdcard: Add validation for boot-partition-size hw/net: Remove mipsnet device model hw/mips: Remove mipssim machine hw/display/xlnx_dp: Don't leak dpcd and edid objects hw/misc/xlnx-versal-cframe-reg: Free FIFO, g_tree on deinit hw/char/max78000_uart: Destroy FIFO on deinit hw/gpio/pca9554: Avoid leak in pca9554_set_pin() hw/ide/ich.c: Use qemu_init_irq_child() to avoid memory leak hw/char/serial-pci-multi: Use qemu_init_irq_child() to avoid leak hw/irq: New qemu_init_irq_child() function hw/ppc: Fix build error with CONFIG_POWERNV disabled ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/boot.c2
-rw-r--r--hw/arm/virt.c1
-rw-r--r--hw/char/max78000_uart.c7
-rw-r--r--hw/char/serial-pci-multi.c3
-rw-r--r--hw/core/irq.c8
-rw-r--r--hw/display/xlnx_dp.c10
-rw-r--r--hw/gpio/pca9554.c2
-rw-r--r--hw/i386/pc_piix.c6
-rw-r--r--hw/ide/ich.c3
-rw-r--r--hw/intc/meson.build6
-rw-r--r--hw/isa/isa-superio.c1
-rw-r--r--hw/meson.build45
-rw-r--r--hw/mips/Kconfig7
-rw-r--r--hw/mips/loongson3_virt.c1
-rw-r--r--hw/mips/malta.c1
-rw-r--r--hw/mips/meson.build1
-rw-r--r--hw/mips/mipssim.c249
-rw-r--r--hw/misc/xlnx-versal-cframe-reg.c9
-rw-r--r--hw/net/Kconfig3
-rw-r--r--hw/net/e1000e_core.c5
-rw-r--r--hw/net/meson.build1
-rw-r--r--hw/net/mipsnet.c297
-rw-r--r--hw/net/trace-events7
-rw-r--r--hw/pci/pci.c15
-rw-r--r--hw/ppc/pnv.c86
-rw-r--r--hw/scsi/mptsas.c6
-rw-r--r--hw/sd/sd.c37
-rw-r--r--hw/sd/sdmmc-internal.h3
28 files changed, 188 insertions, 634 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1e57c4a..d084030 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -549,7 +549,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
unsigned int i;
hwaddr mem_base, mem_len;
char **node_path;
- g_autofree MemoryDeviceInfoList *md_list = NULL;
+ g_autoptr(MemoryDeviceInfoList) md_list = NULL;
Error *err = NULL;
if (binfo->dtb_filename) {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 1e63f40..e5c4142 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -50,6 +50,7 @@
#include "system/kvm.h"
#include "system/hvf.h"
#include "system/qtest.h"
+#include "system/system.h"
#include "hw/loader.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
diff --git a/hw/char/max78000_uart.c b/hw/char/max78000_uart.c
index 19506d5..c76c0e7 100644
--- a/hw/char/max78000_uart.c
+++ b/hw/char/max78000_uart.c
@@ -247,6 +247,12 @@ static void max78000_uart_init(Object *obj)
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
}
+static void max78000_uart_finalize(Object *obj)
+{
+ Max78000UartState *s = MAX78000_UART(obj);
+ fifo8_destroy(&s->rx_fifo);
+}
+
static void max78000_uart_realize(DeviceState *dev, Error **errp)
{
Max78000UartState *s = MAX78000_UART(dev);
@@ -274,6 +280,7 @@ static const TypeInfo max78000_uart_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Max78000UartState),
.instance_init = max78000_uart_init,
+ .instance_finalize = max78000_uart_finalize,
.class_init = max78000_uart_class_init,
};
diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c
index 13df272..34f30fb 100644
--- a/hw/char/serial-pci-multi.c
+++ b/hw/char/serial-pci-multi.c
@@ -180,7 +180,8 @@ static void multi_serial_init(Object *o)
size_t i, nports = multi_serial_get_port_count(PCI_DEVICE_GET_CLASS(dev));
for (i = 0; i < nports; i++) {
- qemu_init_irq(&pms->irqs[i], multi_serial_irq_mux, pms, i);
+ qemu_init_irq_child(o, "irq[*]", &pms->irqs[i],
+ multi_serial_irq_mux, pms, i);
object_initialize_child(o, "serial[*]", &pms->state[i], TYPE_SERIAL);
}
}
diff --git a/hw/core/irq.c b/hw/core/irq.c
index 6dd8d47..0c768f7 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -49,6 +49,14 @@ void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
init_irq_fields(irq, handler, opaque, n);
}
+void qemu_init_irq_child(Object *parent, const char *propname,
+ IRQState *irq, qemu_irq_handler handler,
+ void *opaque, int n)
+{
+ object_initialize_child(parent, propname, irq, TYPE_IRQ);
+ init_irq_fields(irq, handler, opaque, n);
+}
+
void qemu_init_irqs(IRQState irq[], size_t count,
qemu_irq_handler handler, void *opaque)
{
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 7c980ee..ef73e18 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -1267,14 +1267,18 @@ static void xlnx_dp_init(Object *obj)
s->aux_bus = aux_bus_init(DEVICE(obj), "aux");
/*
- * Initialize DPCD and EDID..
+ * Initialize DPCD and EDID. Once we have added the objects as
+ * child properties of this device, we can drop the reference we
+ * hold to them, leaving the child-property as the only reference.
*/
s->dpcd = DPCD(qdev_new("dpcd"));
object_property_add_child(OBJECT(s), "dpcd", OBJECT(s->dpcd));
+ object_unref(s->dpcd);
s->edid = I2CDDC(qdev_new("i2c-ddc"));
i2c_slave_set_address(I2C_SLAVE(s->edid), 0x50);
object_property_add_child(OBJECT(s), "edid", OBJECT(s->edid));
+ object_unref(s->edid);
fifo8_create(&s->rx_fifo, 16);
fifo8_create(&s->tx_fifo, 16);
@@ -1311,8 +1315,8 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp)
qdev_realize(DEVICE(s->dpcd), BUS(s->aux_bus), &error_fatal);
aux_map_slave(AUX_SLAVE(s->dpcd), 0x0000);
- qdev_realize_and_unref(DEVICE(s->edid), BUS(aux_get_i2c_bus(s->aux_bus)),
- &error_fatal);
+ qdev_realize(DEVICE(s->edid), BUS(aux_get_i2c_bus(s->aux_bus)),
+ &error_fatal);
s->console = graphic_console_init(dev, 0, &xlnx_dp_gfx_ops, s);
surface = qemu_console_surface(s->console);
diff --git a/hw/gpio/pca9554.c b/hw/gpio/pca9554.c
index de3f883..eac0d23 100644
--- a/hw/gpio/pca9554.c
+++ b/hw/gpio/pca9554.c
@@ -174,7 +174,7 @@ static void pca9554_set_pin(Object *obj, Visitor *v, const char *name,
PCA9554State *s = PCA9554(obj);
int pin, rc, val;
uint8_t state, mask;
- char *state_str;
+ g_autofree char *state_str = NULL;
if (!visit_type_str(v, name, &state_str, errp)) {
return;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7e78b6d..caf8bab 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -106,7 +106,7 @@ static void pc_init1(MachineState *machine, const char *pci_type)
X86MachineState *x86ms = X86_MACHINE(machine);
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *system_io = get_system_io();
- Object *phb = NULL;
+ Object *phb;
ISABus *isa_bus;
Object *piix4_pm = NULL;
qemu_irq smi_irq;
@@ -284,9 +284,7 @@ static void pc_init1(MachineState *machine, const char *pci_type)
pc_i8259_create(isa_bus, gsi_state->i8259_irq);
}
- if (phb) {
- ioapic_init_gsi(gsi_state, phb);
- }
+ ioapic_init_gsi(gsi_state, phb);
if (tcg_enabled()) {
x86_register_ferr_irq(x86ms->gsi[13]);
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 4cade0d..b00987f 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -114,7 +114,8 @@ static void pci_ich9_ahci_init(Object *obj)
{
AHCIPCIState *d = ICH9_AHCI(obj);
- qemu_init_irq(&d->irq, pci_ich9_ahci_update_irq, d, 0);
+ qemu_init_irq_child(obj, "update-irq", &d->irq,
+ pci_ich9_ahci_update_irq, d, 0);
ahci_init(&d->ahci, DEVICE(obj));
d->ahci.irq = &d->irq;
}
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 3137521..3efb276 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -38,11 +38,11 @@ if config_all_devices.has_key('CONFIG_APIC') or \
endif
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'))
-specific_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files('arm_gicv3_cpuif.c'))
+arm_common_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
+arm_common_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files('arm_gicv3_cpuif.c'))
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
-specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
+arm_common_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c'))
specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
diff --git a/hw/isa/isa-superio.c b/hw/isa/isa-superio.c
index 2853485..941b0f9 100644
--- a/hw/isa/isa-superio.c
+++ b/hw/isa/isa-superio.c
@@ -15,6 +15,7 @@
#include "qemu/module.h"
#include "qapi/error.h"
#include "system/blockdev.h"
+#include "system/system.h"
#include "chardev/char.h"
#include "hw/char/parallel.h"
#include "hw/block/fdc.h"
diff --git a/hw/meson.build b/hw/meson.build
index 791ce21..1022bdb 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -1,3 +1,26 @@
+# Enter target code first to reuse variables associated
+subdir('alpha')
+subdir('arm')
+subdir('avr')
+subdir('hppa')
+subdir('xenpv') # i386 uses it
+subdir('i386')
+subdir('loongarch')
+subdir('m68k')
+subdir('microblaze')
+subdir('mips')
+subdir('openrisc')
+subdir('ppc')
+subdir('remote')
+subdir('riscv')
+subdir('rx')
+subdir('s390x')
+subdir('sh4')
+subdir('sparc')
+subdir('sparc64')
+subdir('tricore')
+subdir('xtensa')
+
subdir('9pfs')
subdir('acpi')
subdir('adc')
@@ -44,26 +67,4 @@ subdir('virtio')
subdir('vmapple')
subdir('watchdog')
subdir('xen')
-subdir('xenpv')
subdir('fsi')
-
-subdir('alpha')
-subdir('arm')
-subdir('avr')
-subdir('hppa')
-subdir('i386')
-subdir('loongarch')
-subdir('m68k')
-subdir('microblaze')
-subdir('mips')
-subdir('openrisc')
-subdir('ppc')
-subdir('remote')
-subdir('riscv')
-subdir('rx')
-subdir('s390x')
-subdir('sh4')
-subdir('sparc')
-subdir('sparc64')
-subdir('tricore')
-subdir('xtensa')
diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig
index f84fffc..b59cb2f 100644
--- a/hw/mips/Kconfig
+++ b/hw/mips/Kconfig
@@ -13,13 +13,6 @@ config MALTA
select SERIAL_MM
select SMBUS_EEPROM
-config MIPSSIM
- bool
- default y
- depends on MIPS
- select SERIAL_MM
- select MIPSNET
-
config JAZZ
bool
default y
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index de6fbcc..672083d 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -49,6 +49,7 @@
#include "system/qtest.h"
#include "system/reset.h"
#include "system/runstate.h"
+#include "system/system.h"
#include "qemu/error-report.h"
#define PM_CNTL_MODE 0x10
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index cbdbb21..344dc8c 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -52,6 +52,7 @@
#include "system/qtest.h"
#include "system/reset.h"
#include "system/runstate.h"
+#include "system/system.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "system/kvm.h"
diff --git a/hw/mips/meson.build b/hw/mips/meson.build
index 31dbd2b..390f0fd 100644
--- a/hw/mips/meson.build
+++ b/hw/mips/meson.build
@@ -8,7 +8,6 @@ mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
if 'CONFIG_TCG' in config_all_accel
mips_ss.add(when: 'CONFIG_JAZZ', if_true: files('jazz.c'))
-mips_ss.add(when: 'CONFIG_MIPSSIM', if_true: files('mipssim.c'))
mips_ss.add(when: 'CONFIG_FULOONG', if_true: files('fuloong2e.c'))
mips_ss.add(when: 'CONFIG_MIPS_BOSTON', if_true: files('boston.c'))
endif
diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c
deleted file mode 100644
index e843307..0000000
--- a/hw/mips/mipssim.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * QEMU/mipssim emulation
- *
- * Emulates a very simple machine model similar to the one used by the
- * proprietary MIPS emulator.
- *
- * Copyright (c) 2007 Thiemo Seufer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/datadir.h"
-#include "system/address-spaces.h"
-#include "hw/clock.h"
-#include "hw/mips/mips.h"
-#include "hw/char/serial-mm.h"
-#include "net/net.h"
-#include "system/system.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "elf.h"
-#include "hw/sysbus.h"
-#include "hw/qdev-properties.h"
-#include "qemu/error-report.h"
-#include "system/qtest.h"
-#include "system/reset.h"
-#include "cpu.h"
-
-#define BIOS_SIZE (4 * MiB)
-
-static struct _loaderparams {
- int ram_size;
- const char *kernel_filename;
- const char *kernel_cmdline;
- const char *initrd_filename;
-} loaderparams;
-
-typedef struct ResetData {
- MIPSCPU *cpu;
- uint64_t vector;
-} ResetData;
-
-static uint64_t load_kernel(void)
-{
- uint64_t entry, kernel_high, initrd_size;
- long kernel_size;
- ram_addr_t initrd_offset;
-
- kernel_size = load_elf(loaderparams.kernel_filename, NULL,
- cpu_mips_kseg0_to_phys, NULL,
- &entry, NULL,
- &kernel_high, NULL,
- TARGET_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB,
- EM_MIPS, 1, 0);
- if (kernel_size < 0) {
- error_report("could not load kernel '%s': %s",
- loaderparams.kernel_filename,
- load_elf_strerror(kernel_size));
- exit(1);
- }
-
- /* load initrd */
- initrd_size = 0;
- initrd_offset = 0;
- if (loaderparams.initrd_filename) {
- initrd_size = get_image_size(loaderparams.initrd_filename);
- if (initrd_size > 0) {
- initrd_offset = ROUND_UP(kernel_high, INITRD_PAGE_SIZE);
- if (initrd_offset + initrd_size > loaderparams.ram_size) {
- error_report("memory too small for initial ram disk '%s'",
- loaderparams.initrd_filename);
- exit(1);
- }
- initrd_size = load_image_targphys(loaderparams.initrd_filename,
- initrd_offset, loaderparams.ram_size - initrd_offset);
- }
- if (initrd_size == (target_ulong) -1) {
- error_report("could not load initial ram disk '%s'",
- loaderparams.initrd_filename);
- exit(1);
- }
- }
- return entry;
-}
-
-static void main_cpu_reset(void *opaque)
-{
- ResetData *s = (ResetData *)opaque;
- CPUMIPSState *env = &s->cpu->env;
-
- cpu_reset(CPU(s->cpu));
- env->active_tc.PC = s->vector & ~(target_ulong)1;
- if (s->vector & 1) {
- env->hflags |= MIPS_HFLAG_M16;
- }
-}
-
-static void mipsnet_init(int base, qemu_irq irq)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qemu_create_nic_device("mipsnet", true, NULL);
- if (!dev) {
- return;
- }
-
- s = SYS_BUS_DEVICE(dev);
- sysbus_realize_and_unref(s, &error_fatal);
- sysbus_connect_irq(s, 0, irq);
- memory_region_add_subregion(get_system_io(),
- base,
- sysbus_mmio_get_region(s, 0));
-}
-
-static void
-mips_mipssim_init(MachineState *machine)
-{
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- const char *bios_name = TARGET_BIG_ENDIAN ? "mips_bios.bin"
- : "mipsel_bios.bin";
- char *filename;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *isa = g_new(MemoryRegion, 1);
- MemoryRegion *bios = g_new(MemoryRegion, 1);
- Clock *cpuclk;
- MIPSCPU *cpu;
- CPUMIPSState *env;
- ResetData *reset_info;
- int bios_size;
-
- cpuclk = clock_new(OBJECT(machine), "cpu-refclk");
-#ifdef TARGET_MIPS64
- clock_set_hz(cpuclk, 6000000); /* 6 MHz */
-#else
- clock_set_hz(cpuclk, 12000000); /* 12 MHz */
-#endif
-
- /* Init CPUs. */
- cpu = mips_cpu_create_with_clock(machine->cpu_type, cpuclk,
- TARGET_BIG_ENDIAN);
- env = &cpu->env;
-
- reset_info = g_new0(ResetData, 1);
- reset_info->cpu = cpu;
- reset_info->vector = env->active_tc.PC;
- qemu_register_reset(main_cpu_reset, reset_info);
-
- /* Allocate RAM. */
- memory_region_init_rom(bios, NULL, "mips_mipssim.bios", BIOS_SIZE,
- &error_fatal);
-
- memory_region_add_subregion(address_space_mem, 0, machine->ram);
-
- /* Map the BIOS / boot exception handler. */
- memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios);
- /* Load a BIOS / boot exception handler image. */
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,
- machine->firmware ?: bios_name);
- if (filename) {
- bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE);
- g_free(filename);
- } else {
- bios_size = -1;
- }
- if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
- machine->firmware && !qtest_enabled()) {
- /* Bail out if we have neither a kernel image nor boot vector code. */
- error_report("Could not load MIPS bios '%s'", machine->firmware);
- exit(1);
- } else {
- /* We have a boot vector start address. */
- env->active_tc.PC = (target_long)(int32_t)0xbfc00000;
- }
-
- if (kernel_filename) {
- loaderparams.ram_size = machine->ram_size;
- loaderparams.kernel_filename = kernel_filename;
- loaderparams.kernel_cmdline = kernel_cmdline;
- loaderparams.initrd_filename = initrd_filename;
- reset_info->vector = load_kernel();
- }
-
- /* Init CPU internal devices. */
- cpu_mips_irq_init_cpu(cpu);
- cpu_mips_clock_init(cpu);
-
- /*
- * Register 64 KB of ISA IO space at 0x1fd00000. But without interrupts
- * (except for the hardcoded serial port interrupt) -device cannot work,
- * so do not expose the ISA bus to the user.
- */
- memory_region_init_alias(isa, NULL, "isa_mmio",
- get_system_io(), 0, 0x00010000);
- memory_region_add_subregion(get_system_memory(), 0x1fd00000, isa);
-
- /*
- * A single 16450 sits at offset 0x3f8. It is attached to
- * MIPS CPU INT2, which is interrupt 4.
- */
- if (serial_hd(0)) {
- DeviceState *dev = qdev_new(TYPE_SERIAL_MM);
-
- qdev_prop_set_chr(dev, "chardev", serial_hd(0));
- qdev_prop_set_uint8(dev, "regshift", 0);
- qdev_prop_set_uint8(dev, "endianness", DEVICE_LITTLE_ENDIAN);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, env->irq[4]);
- memory_region_add_subregion(get_system_io(), 0x3f8,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
- }
-
- /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */
- mipsnet_init(0x4200, env->irq[2]);
-}
-
-static void mips_mipssim_machine_init(MachineClass *mc)
-{
- mc->desc = "MIPS MIPSsim platform";
- mc->init = mips_mipssim_init;
-#ifdef TARGET_MIPS64
- mc->default_cpu_type = MIPS_CPU_TYPE_NAME("5Kf");
-#else
- mc->default_cpu_type = MIPS_CPU_TYPE_NAME("24Kf");
-#endif
- mc->default_ram_id = "mips_mipssim.ram";
-}
-
-DEFINE_MACHINE("mipssim", mips_mipssim_machine_init)
diff --git a/hw/misc/xlnx-versal-cframe-reg.c b/hw/misc/xlnx-versal-cframe-reg.c
index 1ce083e..95e167b 100644
--- a/hw/misc/xlnx-versal-cframe-reg.c
+++ b/hw/misc/xlnx-versal-cframe-reg.c
@@ -693,6 +693,14 @@ static void cframe_reg_init(Object *obj)
fifo32_create(&s->new_f_data, FRAME_NUM_WORDS);
}
+static void cframe_reg_finalize(Object *obj)
+{
+ XlnxVersalCFrameReg *s = XLNX_VERSAL_CFRAME_REG(obj);
+
+ fifo32_destroy(&s->new_f_data);
+ g_tree_destroy(s->cframes);
+}
+
static const VMStateDescription vmstate_cframe = {
.name = "cframe",
.version_id = 1,
@@ -833,6 +841,7 @@ static const TypeInfo cframe_reg_info = {
.instance_size = sizeof(XlnxVersalCFrameReg),
.class_init = cframe_reg_class_init,
.instance_init = cframe_reg_init,
+ .instance_finalize = cframe_reg_finalize,
.interfaces = (const InterfaceInfo[]) {
{ TYPE_XLNX_CFI_IF },
{ }
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 7f80218..2b513d6 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -82,9 +82,6 @@ config OPENCORES_ETH
config XGMAC
bool
-config MIPSNET
- bool
-
config ALLWINNER_EMAC
bool
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 2413858..06657bb 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -341,11 +341,6 @@ e1000e_intmgr_collect_delayed_causes(E1000ECore *core)
{
uint32_t res;
- if (msix_enabled(core->owner)) {
- assert(core->delayed_causes == 0);
- return 0;
- }
-
res = core->delayed_causes;
core->delayed_causes = 0;
diff --git a/hw/net/meson.build b/hw/net/meson.build
index e6759e2..913eaed 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -23,7 +23,6 @@ system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
-system_ss.add(when: 'CONFIG_MIPSNET', if_true: files('mipsnet.c'))
system_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('xilinx_axienet.c'))
system_ss.add(when: 'CONFIG_ALLWINNER_EMAC', if_true: files('allwinner_emac.c'))
system_ss.add(when: 'CONFIG_ALLWINNER_SUN8I_EMAC', if_true: files('allwinner-sun8i-emac.c'))
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
deleted file mode 100644
index 583aa1c..0000000
--- a/hw/net/mipsnet.c
+++ /dev/null
@@ -1,297 +0,0 @@
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "net/net.h"
-#include "qemu/module.h"
-#include "trace.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "qom/object.h"
-
-/* MIPSnet register offsets */
-
-#define MIPSNET_DEV_ID 0x00
-#define MIPSNET_BUSY 0x08
-#define MIPSNET_RX_DATA_COUNT 0x0c
-#define MIPSNET_TX_DATA_COUNT 0x10
-#define MIPSNET_INT_CTL 0x14
-# define MIPSNET_INTCTL_TXDONE 0x00000001
-# define MIPSNET_INTCTL_RXDONE 0x00000002
-# define MIPSNET_INTCTL_TESTBIT 0x80000000
-#define MIPSNET_INTERRUPT_INFO 0x18
-#define MIPSNET_RX_DATA_BUFFER 0x1c
-#define MIPSNET_TX_DATA_BUFFER 0x20
-
-#define MAX_ETH_FRAME_SIZE 1514
-
-#define TYPE_MIPS_NET "mipsnet"
-OBJECT_DECLARE_SIMPLE_TYPE(MIPSnetState, MIPS_NET)
-
-struct MIPSnetState {
- SysBusDevice parent_obj;
-
- uint32_t busy;
- uint32_t rx_count;
- uint32_t rx_read;
- uint32_t tx_count;
- uint32_t tx_written;
- uint32_t intctl;
- uint8_t rx_buffer[MAX_ETH_FRAME_SIZE];
- uint8_t tx_buffer[MAX_ETH_FRAME_SIZE];
- MemoryRegion io;
- qemu_irq irq;
- NICState *nic;
- NICConf conf;
-};
-
-static void mipsnet_reset(MIPSnetState *s)
-{
- s->busy = 1;
- s->rx_count = 0;
- s->rx_read = 0;
- s->tx_count = 0;
- s->tx_written = 0;
- s->intctl = 0;
- memset(s->rx_buffer, 0, MAX_ETH_FRAME_SIZE);
- memset(s->tx_buffer, 0, MAX_ETH_FRAME_SIZE);
-}
-
-static void mipsnet_update_irq(MIPSnetState *s)
-{
- int isr = !!s->intctl;
- trace_mipsnet_irq(isr, s->intctl);
- qemu_set_irq(s->irq, isr);
-}
-
-static int mipsnet_buffer_full(MIPSnetState *s)
-{
- if (s->rx_count >= MAX_ETH_FRAME_SIZE) {
- return 1;
- }
- return 0;
-}
-
-static int mipsnet_can_receive(NetClientState *nc)
-{
- MIPSnetState *s = qemu_get_nic_opaque(nc);
-
- if (s->busy) {
- return 0;
- }
- return !mipsnet_buffer_full(s);
-}
-
-static ssize_t mipsnet_receive(NetClientState *nc,
- const uint8_t *buf, size_t size)
-{
- MIPSnetState *s = qemu_get_nic_opaque(nc);
-
- trace_mipsnet_receive(size);
- if (!mipsnet_can_receive(nc)) {
- return 0;
- }
-
- if (size >= sizeof(s->rx_buffer)) {
- return 0;
- }
- s->busy = 1;
-
- /* Just accept everything. */
-
- /* Write packet data. */
- memcpy(s->rx_buffer, buf, size);
-
- s->rx_count = size;
- s->rx_read = 0;
-
- /* Now we can signal we have received something. */
- s->intctl |= MIPSNET_INTCTL_RXDONE;
- mipsnet_update_irq(s);
-
- return size;
-}
-
-static uint64_t mipsnet_ioport_read(void *opaque, hwaddr addr,
- unsigned int size)
-{
- MIPSnetState *s = opaque;
- int ret = 0;
-
- addr &= 0x3f;
- switch (addr) {
- case MIPSNET_DEV_ID:
- ret = be32_to_cpu(0x4d495053); /* MIPS */
- break;
- case MIPSNET_DEV_ID + 4:
- ret = be32_to_cpu(0x4e455430); /* NET0 */
- break;
- case MIPSNET_BUSY:
- ret = s->busy;
- break;
- case MIPSNET_RX_DATA_COUNT:
- ret = s->rx_count;
- break;
- case MIPSNET_TX_DATA_COUNT:
- ret = s->tx_count;
- break;
- case MIPSNET_INT_CTL:
- ret = s->intctl;
- s->intctl &= ~MIPSNET_INTCTL_TESTBIT;
- break;
- case MIPSNET_INTERRUPT_INFO:
- /* XXX: This seems to be a per-VPE interrupt number. */
- ret = 0;
- break;
- case MIPSNET_RX_DATA_BUFFER:
- if (s->rx_count) {
- s->rx_count--;
- ret = s->rx_buffer[s->rx_read++];
- if (mipsnet_can_receive(s->nic->ncs)) {
- qemu_flush_queued_packets(qemu_get_queue(s->nic));
- }
- }
- break;
- /* Reads as zero. */
- case MIPSNET_TX_DATA_BUFFER:
- default:
- break;
- }
- trace_mipsnet_read(addr, ret);
- return ret;
-}
-
-static void mipsnet_ioport_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned int size)
-{
- MIPSnetState *s = opaque;
-
- addr &= 0x3f;
- trace_mipsnet_write(addr, val);
- switch (addr) {
- case MIPSNET_TX_DATA_COUNT:
- s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0;
- s->tx_written = 0;
- break;
- case MIPSNET_INT_CTL:
- if (val & MIPSNET_INTCTL_TXDONE) {
- s->intctl &= ~MIPSNET_INTCTL_TXDONE;
- } else if (val & MIPSNET_INTCTL_RXDONE) {
- s->intctl &= ~MIPSNET_INTCTL_RXDONE;
- } else if (val & MIPSNET_INTCTL_TESTBIT) {
- mipsnet_reset(s);
- s->intctl |= MIPSNET_INTCTL_TESTBIT;
- } else if (!val) {
- /* ACK testbit interrupt, flag was cleared on read. */
- }
- s->busy = !!s->intctl;
- mipsnet_update_irq(s);
- if (mipsnet_can_receive(s->nic->ncs)) {
- qemu_flush_queued_packets(qemu_get_queue(s->nic));
- }
- break;
- case MIPSNET_TX_DATA_BUFFER:
- s->tx_buffer[s->tx_written++] = val;
- if ((s->tx_written >= MAX_ETH_FRAME_SIZE)
- || (s->tx_written == s->tx_count)) {
- /* Send buffer. */
- trace_mipsnet_send(s->tx_written);
- qemu_send_packet(qemu_get_queue(s->nic),
- s->tx_buffer, s->tx_written);
- s->tx_count = s->tx_written = 0;
- s->intctl |= MIPSNET_INTCTL_TXDONE;
- s->busy = 1;
- mipsnet_update_irq(s);
- }
- break;
- /* Read-only registers */
- case MIPSNET_DEV_ID:
- case MIPSNET_BUSY:
- case MIPSNET_RX_DATA_COUNT:
- case MIPSNET_INTERRUPT_INFO:
- case MIPSNET_RX_DATA_BUFFER:
- default:
- break;
- }
-}
-
-static const VMStateDescription vmstate_mipsnet = {
- .name = "mipsnet",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (const VMStateField[]) {
- VMSTATE_UINT32(busy, MIPSnetState),
- VMSTATE_UINT32(rx_count, MIPSnetState),
- VMSTATE_UINT32(rx_read, MIPSnetState),
- VMSTATE_UINT32(tx_count, MIPSnetState),
- VMSTATE_UINT32(tx_written, MIPSnetState),
- VMSTATE_UINT32(intctl, MIPSnetState),
- VMSTATE_BUFFER(rx_buffer, MIPSnetState),
- VMSTATE_BUFFER(tx_buffer, MIPSnetState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static NetClientInfo net_mipsnet_info = {
- .type = NET_CLIENT_DRIVER_NIC,
- .size = sizeof(NICState),
- .receive = mipsnet_receive,
-};
-
-static const MemoryRegionOps mipsnet_ioport_ops = {
- .read = mipsnet_ioport_read,
- .write = mipsnet_ioport_write,
- .impl.min_access_size = 1,
- .impl.max_access_size = 4,
-};
-
-static void mipsnet_realize(DeviceState *dev, Error **errp)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- MIPSnetState *s = MIPS_NET(dev);
-
- memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s,
- "mipsnet-io", 36);
- sysbus_init_mmio(sbd, &s->io);
- sysbus_init_irq(sbd, &s->irq);
-
- s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
- object_get_typename(OBJECT(dev)), dev->id,
- &dev->mem_reentrancy_guard, s);
- qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-}
-
-static void mipsnet_sysbus_reset(DeviceState *dev)
-{
- MIPSnetState *s = MIPS_NET(dev);
- mipsnet_reset(s);
-}
-
-static const Property mipsnet_properties[] = {
- DEFINE_NIC_PROPERTIES(MIPSnetState, conf),
-};
-
-static void mipsnet_class_init(ObjectClass *klass, const void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = mipsnet_realize;
- set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
- dc->desc = "MIPS Simulator network device";
- device_class_set_legacy_reset(dc, mipsnet_sysbus_reset);
- dc->vmsd = &vmstate_mipsnet;
- device_class_set_props(dc, mipsnet_properties);
-}
-
-static const TypeInfo mipsnet_info = {
- .name = TYPE_MIPS_NET,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MIPSnetState),
- .class_init = mipsnet_class_init,
-};
-
-static void mipsnet_register_types(void)
-{
- type_register_static(&mipsnet_info);
-}
-
-type_init(mipsnet_register_types)
diff --git a/hw/net/trace-events b/hw/net/trace-events
index 72b69c4..e82d749 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -20,13 +20,6 @@ lan9118_phy_reset(void) ""
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
-# mipsnet.c
-mipsnet_send(uint32_t size) "sending len=%u"
-mipsnet_receive(uint32_t size) "receiving len=%u"
-mipsnet_read(uint64_t addr, uint32_t val) "read addr=0x%" PRIx64 " val=0x%x"
-mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64
-mipsnet_irq(uint32_t isr, uint32_t intctl) "set irq to %d (0x%02x)"
-
# ne2000.c
ne2000_read(uint64_t addr, uint64_t val) "read addr=0x%" PRIx64 " val=0x%" PRIx64
ne2000_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index c70b5ce..297196b 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -984,14 +984,15 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
slot = val;
- if (funcp != NULL) {
- if (*e != '.')
+ if (funcp != NULL && *e != '\0') {
+ if (*e != '.') {
return -1;
-
+ }
p = e + 1;
val = strtoul(p, &e, 16);
- if (e == p)
+ if (e == p) {
return -1;
+ }
func = val;
}
@@ -2054,13 +2055,15 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
int dom, busnr, devfn;
PCIDevice *pci_dev;
unsigned slot;
+ unsigned func;
+
PCIBus *bus;
if (!nd) {
return false;
}
- if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, NULL) < 0) {
+ if (!devaddr || pci_parse_devaddr(devaddr, &dom, &busnr, &slot, &func) < 0) {
error_report("Invalid PCI device address %s for device %s",
devaddr, model);
exit(1);
@@ -2071,7 +2074,7 @@ bool pci_init_nic_in_slot(PCIBus *rootbus, const char *model,
exit(1);
}
- devfn = PCI_DEVFN(slot, 0);
+ devfn = PCI_DEVFN(slot, func);
bus = pci_find_bus_nr(rootbus, busnr);
if (!bus) {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index d84c906..9c74f46 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "qemu/datadir.h"
+#include "qemu/log.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
@@ -1794,12 +1795,83 @@ static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp)
}
}
+static uint64_t pnv_handle_sprd_load(CPUPPCState *env)
+{
+ PowerPCCPU *cpu = env_archcpu(env);
+ PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
+ uint64_t sprc = env->spr[SPR_POWER_SPRC];
+
+ if (pc->big_core) {
+ pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
+ }
+
+ switch (sprc & 0x3e0) {
+ case 0: /* SCRATCH0-3 */
+ case 1: /* SCRATCH4-7 */
+ return pc->scratch[(sprc >> 3) & 0x7];
+
+ case 0x1e0: /* core thread state */
+ if (env->excp_model == POWERPC_EXCP_POWER9) {
+ /*
+ * Only implement for POWER9 because skiboot uses it to check
+ * big-core mode. Other bits are unimplemented so we would
+ * prefer to get unimplemented message on POWER10 if it were
+ * used anywhere.
+ */
+ if (pc->big_core) {
+ return PPC_BIT(63);
+ } else {
+ return 0;
+ }
+ }
+ /* fallthru */
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
+ TARGET_FMT_lx"\n", sprc);
+ break;
+ }
+ return 0;
+}
+
+static void pnv_handle_sprd_store(CPUPPCState *env, uint64_t val)
+{
+ PowerPCCPU *cpu = env_archcpu(env);
+ uint64_t sprc = env->spr[SPR_POWER_SPRC];
+ PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
+ int nr;
+
+ if (pc->big_core) {
+ pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
+ }
+
+ switch (sprc & 0x3e0) {
+ case 0: /* SCRATCH0-3 */
+ case 1: /* SCRATCH4-7 */
+ /*
+ * Log stores to SCRATCH, because some firmware uses these for
+ * debugging and logging, but they would normally be read by the BMC,
+ * which is not implemented in QEMU yet. This gives a way to get at the
+ * information. Could also dump these upon checkstop.
+ */
+ nr = (sprc >> 3) & 0x7;
+ pc->scratch[nr] = val;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
+ TARGET_FMT_lx"\n", sprc);
+ break;
+ }
+}
+
static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
{
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
Pnv9Chip *chip9 = PNV9_CHIP(dev);
PnvChip *chip = PNV_CHIP(dev);
Pnv9Psi *psi9 = &chip9->psi;
+ PowerPCCPU *cpu;
+ PowerPCCPUClass *cpu_class;
Error *local_err = NULL;
int i;
@@ -1827,6 +1899,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
return;
}
+ /* Set handlers for Special registers, such as SPRD */
+ cpu = chip->cores[0]->threads[0];
+ cpu_class = POWERPC_CPU_GET_CLASS(cpu);
+ cpu_class->load_sprd = pnv_handle_sprd_load;
+ cpu_class->store_sprd = pnv_handle_sprd_store;
+
/* XIVE interrupt controller (POWER9) */
object_property_set_int(OBJECT(&chip9->xive), "ic-bar",
PNV9_XIVE_IC_BASE(chip), &error_fatal);
@@ -2078,6 +2156,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
PnvChip *chip = PNV_CHIP(dev);
Pnv10Chip *chip10 = PNV10_CHIP(dev);
+ PowerPCCPU *cpu;
+ PowerPCCPUClass *cpu_class;
Error *local_err = NULL;
int i;
@@ -2105,6 +2185,12 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
return;
}
+ /* Set handlers for Special registers, such as SPRD */
+ cpu = chip->cores[0]->threads[0];
+ cpu_class = POWERPC_CPU_GET_CLASS(cpu);
+ cpu_class->load_sprd = pnv_handle_sprd_load;
+ cpu_class->store_sprd = pnv_handle_sprd_store;
+
/* XIVE2 interrupt controller (POWER10) */
object_property_set_int(OBJECT(&chip10->xive), "ic-bar",
PNV10_XIVE2_IC_BASE(chip), &error_fatal);
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index 1ebe0b8..4ada35b 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -579,11 +579,11 @@ static void mptsas_process_ioc_init(MPTSASState *s, MPIMsgIOCInit *req)
}
memset(&reply, 0, sizeof(reply));
- reply.WhoInit = s->who_init;
+ reply.WhoInit = req->WhoInit;
reply.MsgLength = sizeof(reply) / 4;
reply.Function = req->Function;
- reply.MaxDevices = s->max_devices;
- reply.MaxBuses = s->max_buses;
+ reply.MaxDevices = req->MaxDevices;
+ reply.MaxBuses = req->MaxBuses;
reply.MsgContext = req->MsgContext;
mptsas_fix_ioc_init_reply_endianness(&reply);
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8c29059..d7a496d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -195,7 +195,6 @@ static bool sd_is_emmc(SDState *sd)
static const char *sd_version_str(enum SDPhySpecificationVersion version)
{
static const char *sdphy_version[] = {
- [SD_PHY_SPECv1_10_VERS] = "v1.10",
[SD_PHY_SPECv2_00_VERS] = "v2.00",
[SD_PHY_SPECv3_01_VERS] = "v3.01",
};
@@ -407,11 +406,7 @@ static void sd_set_ocr(SDState *sd)
static void sd_set_scr(SDState *sd)
{
sd->scr[0] = 0 << 4; /* SCR structure version 1.0 */
- if (sd->spec_version == SD_PHY_SPECv1_10_VERS) {
- sd->scr[0] |= 1; /* Spec Version 1.10 */
- } else {
- sd->scr[0] |= 2; /* Spec Version 2.00 or Version 3.0X */
- }
+ sd->scr[0] |= 2; /* Spec Version 2.00 or Version 3.0X */
sd->scr[1] = (2 << 4) /* SDSC Card (Security Version 1.01) */
| 0b0101; /* 1-bit or 4-bit width bus modes */
sd->scr[2] = 0x00; /* Extended Security is not supported. */
@@ -838,14 +833,14 @@ static uint32_t sd_blk_len(SDState *sd)
/*
* This requires a disk image that has two boot partitions inserted at the
- * beginning of it. The size of the boot partitions is the "boot-size"
- * property.
+ * beginning of it, followed by an RPMB partition. The size of the boot
+ * partitions is the "boot-partition-size" property.
*/
-static uint32_t sd_bootpart_offset(SDState *sd)
+static uint32_t sd_part_offset(SDState *sd)
{
unsigned partition_access;
- if (!sd->boot_part_size || !sd_is_emmc(sd)) {
+ if (!sd_is_emmc(sd)) {
return 0;
}
@@ -854,9 +849,9 @@ static uint32_t sd_bootpart_offset(SDState *sd)
switch (partition_access) {
case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
return sd->boot_part_size * 2;
- case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+ case EXT_CSD_PART_CONFIG_ACC_BOOT1:
return 0;
- case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
+ case EXT_CSD_PART_CONFIG_ACC_BOOT2:
return sd->boot_part_size * 1;
default:
g_assert_not_reached();
@@ -1057,7 +1052,7 @@ static const VMStateDescription sd_vmstate = {
static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
{
trace_sdcard_read_block(addr, len);
- addr += sd_bootpart_offset(sd);
+ addr += sd_part_offset(sd);
if (!sd->blk || blk_pread(sd->blk, addr, len, sd->data, 0) < 0) {
fprintf(stderr, "sd_blk_read: read error on host side\n");
}
@@ -1066,7 +1061,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
{
trace_sdcard_write_block(addr, len);
- addr += sd_bootpart_offset(sd);
+ addr += sd_part_offset(sd);
if (!sd->blk || blk_pwrite(sd->blk, addr, len, sd->data, 0) < 0) {
fprintf(stderr, "sd_blk_write: write error on host side\n");
}
@@ -1555,9 +1550,6 @@ static sd_rsp_type_t sd_cmd_DE_SELECT_CARD(SDState *sd, SDRequest req)
/* CMD8 */
static sd_rsp_type_t sd_cmd_SEND_IF_COND(SDState *sd, SDRequest req)
{
- if (sd->spec_version < SD_PHY_SPECv2_00_VERS) {
- return sd_cmd_illegal(sd, req);
- }
if (sd->state != sd_idle_state) {
return sd_invalid_state_for_cmd(sd, req);
}
@@ -2773,7 +2765,7 @@ static void sd_realize(DeviceState *dev, Error **errp)
int ret;
switch (sd->spec_version) {
- case SD_PHY_SPECv1_10_VERS
+ case SD_PHY_SPECv2_00_VERS
... SD_PHY_SPECv3_01_VERS:
break;
default:
@@ -2818,6 +2810,15 @@ static void sd_realize(DeviceState *dev, Error **errp)
}
blk_set_dev_ops(sd->blk, &sd_block_ops, sd);
}
+ if (sd->boot_part_size % (128 * KiB) ||
+ sd->boot_part_size > 255 * 128 * KiB) {
+ g_autofree char *size_str = size_to_str(sd->boot_part_size);
+
+ error_setg(errp, "Invalid boot partition size: %s", size_str);
+ error_append_hint(errp,
+ "The boot partition size must be multiples of 128K"
+ "and not larger than 32640K.\n");
+ }
}
static void emmc_realize(DeviceState *dev, Error **errp)
diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h
index 91eb5b6..ce6bc4e 100644
--- a/hw/sd/sdmmc-internal.h
+++ b/hw/sd/sdmmc-internal.h
@@ -116,7 +116,8 @@ DECLARE_OBJ_CHECKERS(SDState, SDCardClass, SDMMC_COMMON, TYPE_SDMMC_COMMON)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_DEFAULT (0x0)
-#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT1 (0x1)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT2 (0x2)
#define EXT_CSD_PART_CONFIG_EN_MASK (0x7 << 3)
#define EXT_CSD_PART_CONFIG_EN_BOOT0 (0x1 << 3)