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:
commit
a10631b0cf
57 changed files with 330 additions and 784 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -6,4 +6,3 @@
|
|||
|
||||
# Boards are selected by default, uncomment to keep out of the build.
|
||||
# CONFIG_MALTA=n
|
||||
# CONFIG_MIPSSIM=n
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
''''''''''''''''''''
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
----------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'))
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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 },
|
||||
{ }
|
||||
|
|
|
|||
|
|
@ -82,9 +82,6 @@ config OPENCORES_ETH
|
|||
config XGMAC
|
||||
bool
|
||||
|
||||
config MIPSNET
|
||||
bool
|
||||
|
||||
config ALLWINNER_EMAC
|
||||
bool
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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'))
|
||||
|
|
|
|||
297
hw/net/mipsnet.c
297
hw/net/mipsnet.c
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
15
hw/pci/pci.c
15
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) {
|
||||
|
|
|
|||
86
hw/ppc/pnv.c
86
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
37
hw/sd/sd.c
37
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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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'))
|
||||
|
|
|
|||
|
|
@ -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
16
migration/vfio-stub.c
Normal 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)
|
||||
{
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -147,6 +147,9 @@ tcg
|
|||
system
|
||||
~ .*/qemu(/system/.*|/accel/.*)
|
||||
|
||||
plugins
|
||||
~ .*/qemu(/contrib|/tests/tcg)?/plugins/.*
|
||||
|
||||
(headers)
|
||||
~ .*/qemu(/include/.*)
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue