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-----

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>
This commit is contained in:
Richard Henderson 2025-09-03 05:49:44 +02:00
commit a10631b0cf
57 changed files with 330 additions and 784 deletions

View file

@ -1411,12 +1411,6 @@ F: include/hw/southbridge/piix.h
F: tests/functional/mips*/test_malta.py
F: tests/functional/mips*/test_tuxrun.py
Mipssim
R: Aleksandar Rikalo <arikalo@gmail.com>
S: Orphan
F: hw/mips/mipssim.c
F: hw/net/mipsnet.c
Fuloong 2E
M: Huacai Chen <chenhuacai@kernel.org>
M: Philippe Mathieu-Daudé <philmd@linaro.org>
@ -2268,6 +2262,7 @@ F: util/vfio-helpers.c
F: include/hw/vfio/
F: docs/devel/migration/vfio.rst
F: qapi/vfio.json
F: migration/vfio-stub.c
F: tests/functional/aarch64/test_device_passthrough.py
vfio-igd

View file

@ -6,4 +6,3 @@
# Boards are selected by default, uncomment to keep out of the build.
# CONFIG_MALTA=n
# CONFIG_MIPSSIM=n

View file

@ -18,7 +18,6 @@
*/
#include "qemu/osdep.h"
#include "cpu.h"
#include "accel/accel-cpu-ops.h"
#include "system/cpus.h"
#include "exec/cpu-common.h"
@ -27,10 +26,6 @@
#include "hw/core/cpu.h"
#include "trace/trace-root.h"
/* Validate correct placement of CPUArchState. */
QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0);
QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
/* enable or disable single step mode. EXCP_DEBUG is returned by the
CPU loop after each instruction */
void cpu_single_step(CPUState *cpu, int enabled)

View file

@ -121,7 +121,9 @@ qcrypto_gcrypt_hmac_bytesv(QCryptoHmac *hmac,
return -1;
}
if (*resultlen == 0) {
if (resultlen == NULL) {
return 0;
} else if (*resultlen == 0) {
*resultlen = ret;
*result = g_new0(uint8_t, *resultlen);
} else if (*resultlen != ret) {

View file

@ -104,7 +104,9 @@ qcrypto_glib_hmac_bytesv(QCryptoHmac *hmac,
return -1;
}
if (*resultlen == 0) {
if (resultlen == NULL) {
return 0;
} else if (*resultlen == 0) {
*resultlen = ret;
*result = g_new0(uint8_t, *resultlen);
} else if (*resultlen != ret) {

View file

@ -119,7 +119,9 @@ qcrypto_gnutls_hmac_bytesv(QCryptoHmac *hmac,
return -1;
}
if (*resultlen == 0) {
if (resultlen == NULL) {
return 0;
} else if (*resultlen == 0) {
*resultlen = ret;
*result = g_new0(uint8_t, *resultlen);
} else if (*resultlen != ret) {

View file

@ -164,7 +164,9 @@ qcrypto_nettle_hmac_bytesv(QCryptoHmac *hmac,
}
}
if (*resultlen == 0) {
if (resultlen == NULL) {
return 0;
} else if (*resultlen == 0) {
*resultlen = qcrypto_hmac_alg_map[hmac->alg].len;
*result = g_new0(uint8_t, *resultlen);
} else if (*resultlen != qcrypto_hmac_alg_map[hmac->alg].len) {

View file

@ -313,18 +313,6 @@ and serves as the initial engineering sample rather than a production version.
A newer revision, A1, is now supported, and the ``ast2700a1-evb`` should
replace the older A0 version.
Mips ``mipssim`` machine (since 10.0)
'''''''''''''''''''''''''''''''''''''
Linux dropped support for this virtual machine type in kernel v3.7, and
there does not seem to be anybody around who is still using this board
in QEMU: Most former MIPS-related people are working on other architectures
in their everyday job nowadays, and we are also not aware of anybody still
using old binaries with this board (i.e. there is also no binary available
online to check that this board did not completely bitrot yet). It is
recommended to use another MIPS machine for future MIPS code development
instead.
RISC-V default machine option (since 10.0)
''''''''''''''''''''''''''''''''''''''''''
@ -434,12 +422,6 @@ recommending to switch to their stable counterparts:
- "Zve64f" should be replaced with "zve64f"
- "Zve64d" should be replaced with "zve64d"
``-device sd-card,spec_version=1`` (since 9.1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SD physical layer specification v2.00 supersedes the v1.10 one.
v2.00 is the default since QEMU 3.0.0.
Block device options
''''''''''''''''''''

View file

@ -730,8 +730,8 @@ Use ``multifd-channels`` instead.
Use ``multifd-compression`` instead.
Incorrectly typed ``device_add`` arguments (since 9.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''
Incorrectly typed ``device_add`` arguments (removed in 9.2)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Due to shortcomings in the internal implementation of ``device_add``,
QEMU used to incorrectly accept certain invalid arguments. Any object
@ -1107,6 +1107,11 @@ were added for little endian CPUs. Big endian support was never tested
and likely never worked. Starting with QEMU v10.1, the machines are now
only available as little-endian machines.
Mips ``mipssim`` machine (removed in 10.2)
''''''''''''''''''''''''''''''''''''''''''
Linux dropped support for this virtual machine type in kernel v3.7, and
there was also no binary available online to use with that board.
linux-user mode CPUs
--------------------
@ -1186,6 +1191,11 @@ by using ``-machine graphics=off``.
The 'pvrdma' device and the whole RDMA subsystem have been removed.
``-device sd-card,spec_version=1`` (since 10.2)
'''''''''''''''''''''''''''''''''''''''''''''''
SD physical layer specification v2.00 supersedes the v1.10 one.
Related binaries
----------------

View file

@ -446,8 +446,8 @@ Low level memory management
===========================
Use of the ``malloc/free/realloc/calloc/valloc/memalign/posix_memalign``
APIs is not allowed in the QEMU codebase. Instead of these routines,
use the GLib memory allocation routines
or ``alloca/g_alloca/g_newa/g_newa0`` APIs is not allowed in the QEMU codebase.
Instead of these routines, use the GLib memory allocation routines
``g_malloc/g_malloc0/g_new/g_new0/g_realloc/g_free``
or QEMU's ``qemu_memalign/qemu_blockalign/qemu_vfree`` APIs.

View file

@ -12,8 +12,6 @@ machine types are emulated:
- An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
- MIPS emulator pseudo board \"mipssim\"
- A MIPS Magnum R4000 machine \"magnum\". This machine needs the
64-bit emulator.
@ -80,15 +78,6 @@ The Loongson-3 virtual platform emulation supports:
- Both KVM and TCG supported
The mipssim pseudo board emulation provides an environment similar to
what the proprietary MIPS emulator uses for running Linux. It supports:
- A range of MIPS CPUs, default is the 24Kf
- PC style serial port
- MIPSnet network emulation
.. include:: cpu-models-mips.rst.inc
.. _nanoMIPS-System-emulator:

View file

@ -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) {

View file

@ -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"

View file

@ -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,
};

View file

@ -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);
}
}

View file

@ -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)
{

View file

@ -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);

View file

@ -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;

View file

@ -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]);

View file

@ -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;
}

View file

@ -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'))

View file

@ -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"

View file

@ -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')

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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)

View file

@ -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 },
{ }

View file

@ -82,9 +82,6 @@ config OPENCORES_ETH
config XGMAC
bool
config MIPSNET
bool
config ALLWINNER_EMAC
bool

View file

@ -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;

View file

@ -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'))

View file

@ -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)

View file

@ -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

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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)

View file

@ -90,6 +90,12 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoHmac, qcrypto_hmac_free)
* The memory referenced in @result must be released with a call
* to g_free() when no longer required by the caller.
*
* If @result_len is set to a NULL pointer, no result will be returned, and
* the hmac object can be used for further invocations of qcrypto_hmac_bytes()
* or qcrypto_hmac_bytesv() until a non-NULL pointer is provided. This allows
* to build the hmac across memory regions that are not available at the same
* time.
*
* Returns:
* 0 on success, -1 on error
*/
@ -123,6 +129,12 @@ int qcrypto_hmac_bytesv(QCryptoHmac *hmac,
* The memory referenced in @result must be released with a call
* to g_free() when no longer required by the caller.
*
* If @result_len is set to a NULL pointer, no result will be returned, and
* the hmac object can be used for further invocations of qcrypto_hmac_bytes()
* or qcrypto_hmac_bytesv() until a non-NULL pointer is provided. This allows
* to build the hmac across memory regions that are not available at the same
* time.
*
* Returns:
* 0 on success, -1 on error
*/

View file

@ -56,6 +56,13 @@ typedef int64_t Elf64_Sxword;
#define EF_MIPS_ARCH_32R6 0x90000000 /* MIPS32r6 code. */
#define EF_MIPS_ARCH_64R6 0xa0000000 /* MIPS64r6 code. */
/* MIPS Architectural Extensions. */
#define EF_MIPS_ARCH_ASE 0x0f000000
#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000
#define EF_MIPS_ARCH_ASE_M16 0x04000000
#define EF_MIPS_ARCH_ASE_MDMX 0x08000000
/* The ABI of a file. */
#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */

View file

@ -62,6 +62,15 @@ static inline int qemu_target_page_bits(void)
return TARGET_PAGE_BITS;
}
size_t qemu_target_pages_to_MiB(size_t pages);
/* Convert target pages to MiB (2**20). */
static inline size_t qemu_target_pages_to_MiB(size_t pages)
{
int page_bits = TARGET_PAGE_BITS;
/* So far, the largest (non-huge) page size is 64k, i.e. 16 bits. */
g_assert(page_bits < 20);
return pages >> (20 - page_bits);
}
#endif

View file

@ -36,11 +36,32 @@ static inline void qemu_irq_pulse(qemu_irq irq)
/*
* Init a single IRQ. The irq is assigned with a handler, an opaque data
* and the interrupt number.
* and the interrupt number. The caller must free this with qemu_free_irq().
* If you are using this inside a device's init or realize method, then
* qemu_init_irq_child() is probably a better choice to avoid the need
* to manually clean up the IRQ.
*/
void qemu_init_irq(IRQState *irq, qemu_irq_handler handler, void *opaque,
int n);
/**
* qemu_init_irq_child: Initialize IRQ and make it a QOM child
* @parent: QOM object which owns this IRQ
* @propname: child property name
* @irq: pointer to IRQState to initialize
* @handler: handler function for incoming interrupts
* @opaque: opaque data to pass to @handler
* @n: interrupt number to pass to @handler
*
* Init a single IRQ and make the IRQ object a child of @parent with
* the child-property name @propname. The IRQ object will thus be
* automatically freed when @parent is destroyed.
*/
void qemu_init_irq_child(Object *parent, const char *propname,
IRQState *irq, qemu_irq_handler handler,
void *opaque, int n);
/**
* qemu_init_irqs: Initialize an array of IRQs.
*

View file

@ -56,7 +56,6 @@
#define AKE_SEQ_ERROR (1 << 3)
enum SDPhySpecificationVersion {
SD_PHY_SPECv1_10_VERS = 1,
SD_PHY_SPECv2_00_VERS = 2,
SD_PHY_SPECv3_01_VERS = 3,
};

View file

@ -38,6 +38,7 @@ struct SSIPeripheralClass {
/* if you have standard or no CS behaviour, just override transfer.
* This is called when the device cs is active (true by default).
* See ssi_transfer().
*/
uint32_t (*transfer)(SSIPeripheral *dev, uint32_t val);
/* called when the CS line changes. Optional, devices only need to implement
@ -52,6 +53,7 @@ struct SSIPeripheralClass {
* of the CS behaviour at the device level. transfer, set_cs, and
* cs_polarity are unused if this is overwritten. Transfer_raw will
* always be called for the device for every txrx access to the parent bus
* See ssi_transfer().
*/
uint32_t (*transfer_raw)(SSIPeripheral *dev, uint32_t val);
};
@ -110,6 +112,18 @@ bool ssi_realize_and_unref(DeviceState *dev, SSIBus *bus, Error **errp);
/* Master interface. */
SSIBus *ssi_create_bus(DeviceState *parent, const char *name);
/**
* Transfer a word on a SSI bus
* @bus: SSI bus
* @val: word to transmit
*
* At the same time, read a word and write the @val one on the SSI bus.
*
* SSI words might vary between 8 and 32 bits. The same number of bits
* written is received.
*
* Return: word value received
*/
uint32_t ssi_transfer(SSIBus *bus, uint32_t val);
DeviceState *ssi_get_cs(SSIBus *bus, uint8_t cs_index);

View file

@ -37,6 +37,12 @@ const char *get_elf_cpu_model(uint32_t eflags)
if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
return "mips32r6-generic";
}
if ((eflags & EF_MIPS_ARCH_ASE) == EF_MIPS_ARCH_ASE_MICROMIPS) {
return "M14Kc";
}
if ((eflags & EF_MIPS_ARCH_ASE) == EF_MIPS_ARCH_ASE_M16) {
return "74Kf";
}
if (eflags & EF_MIPS_NAN2008) {
return "P5600";
}

View file

@ -3876,7 +3876,8 @@ if have_block
endif
common_ss.add(files('cpu-common.c'))
specific_ss.add(files('cpu-target.c'))
user_ss.add(files('cpu-target.c'))
system_ss.add(files('cpu-target.c'))
subdir('system')
@ -3898,7 +3899,7 @@ if get_option('b_lto')
pagevary = declare_dependency(link_with: pagevary)
endif
common_ss.add(pagevary)
specific_ss.add(files('page-target.c', 'page-vary-target.c'))
specific_ss.add(files('page-vary-target.c'))
common_ss.add(files('target-info.c'))
specific_ss.add(files('target-info-stub.c'))

View file

@ -31,6 +31,7 @@ system_ss.add(files(
'multifd-zero-page.c',
'options.c',
'postcopy-ram.c',
'ram.c',
'savevm.c',
'socket.c',
'tls.c',
@ -48,7 +49,6 @@ system_ss.add(when: zstd, if_true: files('multifd-zstd.c'))
system_ss.add(when: qpl, if_true: files('multifd-qpl.c'))
system_ss.add(when: uadk, if_true: files('multifd-uadk.c'))
system_ss.add(when: qatzip, if_true: files('multifd-qatzip.c'))
specific_ss.add(when: 'CONFIG_SYSTEM_ONLY',
if_true: files('ram.c',
'vfio.c'))
system_ss.add(when: 'CONFIG_VFIO',
if_true: files('vfio.c'),
if_false: files('vfio-stub.c'))

16
migration/vfio-stub.c Normal file
View file

@ -0,0 +1,16 @@
/*
* QEMU live migration - stubs for VFIO
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "migration.h"
void migration_populate_vfio_info(MigrationInfo *info)
{
}
void migration_reset_vfio_bytes_transferred(void)
{
}

View file

@ -8,13 +8,8 @@
#include "qemu/osdep.h"
#include "qapi/qapi-types-migration.h"
#include "migration.h"
#include CONFIG_DEVICES
#ifdef CONFIG_VFIO
#include "hw/vfio/vfio-migration.h"
#endif
#ifdef CONFIG_VFIO
void migration_populate_vfio_info(MigrationInfo *info)
{
if (vfio_migration_active()) {
@ -27,12 +22,3 @@ void migration_reset_vfio_bytes_transferred(void)
{
vfio_migration_reset_bytes_transferred();
}
#else
void migration_populate_vfio_info(MigrationInfo *info)
{
}
void migration_reset_vfio_bytes_transferred(void)
{
}
#endif

View file

@ -1,21 +0,0 @@
/*
* QEMU page values getters (target independent)
*
* Copyright (c) 2003 Fabrice Bellard
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "qemu/osdep.h"
#include "exec/target_page.h"
/* Convert target pages to MiB (2**20). */
size_t qemu_target_pages_to_MiB(size_t pages)
{
int page_bits = TARGET_PAGE_BITS;
/* So far, the largest (non-huge) page size is 64k, i.e. 16 bits. */
g_assert(page_bits < 20);
return pages >> (20 - page_bits);
}

View file

@ -147,6 +147,9 @@ tcg
system
~ .*/qemu(/system/.*|/accel/.*)
plugins
~ .*/qemu(/contrib|/tests/tcg)?/plugins/.*
(headers)
~ .*/qemu(/include/.*)

View file

@ -12,6 +12,10 @@
#include "hw/boards.h"
#include "cpu.h"
/* Validate correct placement of CPUArchState. */
QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0);
QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState));
static const TargetInfo target_info_stub = {
.target_name = TARGET_NAME,
.target_arch = SYS_EMU_TARGET__MAX,

View file

@ -652,7 +652,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
return 0;
}
if ((entry & (1 << psn)) && hugepg) {
if (extract64(entry, psn, 1) && hugepg) {
*huge_page = true;
*hgpg_directory_hit = true;
entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);

View file

@ -1522,6 +1522,10 @@ struct PowerPCCPUClass {
void (*init_proc)(CPUPPCState *env);
int (*check_pow)(CPUPPCState *env);
int (*check_attn)(CPUPPCState *env);
/* Handlers to be set by the machine initialising the chips */
uint64_t (*load_sprd)(CPUPPCState *env);
void (*store_sprd)(CPUPPCState *env, uint64_t val);
};
static inline bool ppc_cpu_core_single_threaded(CPUState *cs)

View file

@ -2760,11 +2760,11 @@ int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
uint16_t n_valid, uint16_t n_invalid, Error **errp)
{
struct kvm_get_htab_header *buf;
size_t chunksize = sizeof(*buf) + n_valid * HASH_PTE_SIZE_64;
size_t chunksize = sizeof(struct kvm_get_htab_header)
+ n_valid * HASH_PTE_SIZE_64;
g_autofree struct kvm_get_htab_header *buf = g_malloc(chunksize);
ssize_t rc;
buf = alloca(chunksize);
buf->index = index;
buf->n_valid = n_valid;
buf->n_invalid = n_invalid;

View file

@ -328,69 +328,22 @@ target_ulong helper_load_sprd(CPUPPCState *env)
* accessed by powernv machines.
*/
PowerPCCPU *cpu = env_archcpu(env);
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
target_ulong sprc = env->spr[SPR_POWER_SPRC];
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
if (pc->big_core) {
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
if (pcc->load_sprd) {
return pcc->load_sprd(env);
}
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;
}
void helper_store_sprd(CPUPPCState *env, target_ulong val)
{
target_ulong sprc = env->spr[SPR_POWER_SPRC];
PowerPCCPU *cpu = env_archcpu(env);
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
int nr;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
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;
if (pcc->store_sprd) {
return pcc->store_sprd(env, val);
}
}