Misc HW patches

- Few more g_memdup() replaced by safer g_memdup2() wrapper (Phil)
 - Endianness access fixed in vfio-user config space (Mattias)
 - Replace qemu_mutex_lock() -> QEMU_LOCK_GUARD in system/physmem (Phil)
 - Per-AddressSpace bounce buffering (Mattias)
 - Allow to compile x86 PC machines without Floppy Controller (Thomas)
 - Cleanups around i386 "isa-bios" memory regions (Bernhard)
 - Remove unused usb rndis_config_parameter structure (David)
 - Migrate missing clock in STM32L4x5 GPIOs (Inès)
 - Deprecate PPC 'ref405ep' machine and 405 CPUs (Cédric)
 - Memory leak fixed in Loongarch Virt machine (Song Gao)
 - hw/loongarch/ code moved around (Paolo & Bibo Mao)
 - Emulate S3 suspend in loongson3_virt machine (Jiaxun)
 - Implement IOCSR address space in Loongson IPI (Jiaxun)
 - Use QEMU header path relative to include/ directory (Phil)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmY7+NgACgkQ4+MsLN6t
 wN4QdhAAnPGMoIGubXiZjrEmCuDU117Hm//g3wFdirn6pSr3XFWk+LGHurpgWzwf
 6AG2ERE6ouEqbZmhfnkLA9/3cSuS/6YgCDxfQ/2Z5N7hy5+GaG60paIk2iw4wJc+
 z+3EBBNp1MKP7etP/f7XvBbempOGHSENvH83ZEKTXln6oYe/HQWBoTChV/W6Uczv
 Txf45DJ6QPPQl7cBYqtLpg9Nmc4g6d3M5t5YWzkBrecvXiBlKdZnEsI5CBtmXM8D
 h7+wIyNMl0Nc3DgQWN1SsARFDUyHG4bE4K6MS2KkGLkfFF84o8rRtEPV0RvsT+g6
 0VkhZqLf+Gdq2w1IxCt1k5VCx8HK25+zWZypXlXY1o1dbfssqqbvXEh+3sws67eJ
 4Hn+8QIXZBsl/zUxBbw5/CVYTHmy4Aosc1TItvDsCPnlicfV2phKSxADlL/WJCCU
 IQBwDMtxNwYM/QMP3bRIN0xNNSpB0+kOzfkRf1hVQmxH+ObqIvvIA+RbI6NhjM3L
 qXw5o0+FltLg7kPGk4Fo/rlhfnydRAE/swrwYd3WRp0sKjDe0lV3r7Bu+FZ4imdB
 4u24FJK8ygcQOKiyHEX9cEkKruYAXeFmI3WglimYe5Po2LvIonsRLiqX97CGhgDX
 UM9Oo0Sr/0NnV7FnOW75OijNa2PE7pLVgWDjM3Xefmltqui7F/M=
 =uOIs
 -----END PGP SIGNATURE-----

Merge tag 'hw-misc-20240508' of https://github.com/philmd/qemu into staging

Misc HW patches

- Few more g_memdup() replaced by safer g_memdup2() wrapper (Phil)
- Endianness access fixed in vfio-user config space (Mattias)
- Replace qemu_mutex_lock() -> QEMU_LOCK_GUARD in system/physmem (Phil)
- Per-AddressSpace bounce buffering (Mattias)
- Allow to compile x86 PC machines without Floppy Controller (Thomas)
- Cleanups around i386 "isa-bios" memory regions (Bernhard)
- Remove unused usb rndis_config_parameter structure (David)
- Migrate missing clock in STM32L4x5 GPIOs (Inès)
- Deprecate PPC 'ref405ep' machine and 405 CPUs (Cédric)
- Memory leak fixed in Loongarch Virt machine (Song Gao)
- hw/loongarch/ code moved around (Paolo & Bibo Mao)
- Emulate S3 suspend in loongson3_virt machine (Jiaxun)
- Implement IOCSR address space in Loongson IPI (Jiaxun)
- Use QEMU header path relative to include/ directory (Phil)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmY7+NgACgkQ4+MsLN6t
# wN4QdhAAnPGMoIGubXiZjrEmCuDU117Hm//g3wFdirn6pSr3XFWk+LGHurpgWzwf
# 6AG2ERE6ouEqbZmhfnkLA9/3cSuS/6YgCDxfQ/2Z5N7hy5+GaG60paIk2iw4wJc+
# z+3EBBNp1MKP7etP/f7XvBbempOGHSENvH83ZEKTXln6oYe/HQWBoTChV/W6Uczv
# Txf45DJ6QPPQl7cBYqtLpg9Nmc4g6d3M5t5YWzkBrecvXiBlKdZnEsI5CBtmXM8D
# h7+wIyNMl0Nc3DgQWN1SsARFDUyHG4bE4K6MS2KkGLkfFF84o8rRtEPV0RvsT+g6
# 0VkhZqLf+Gdq2w1IxCt1k5VCx8HK25+zWZypXlXY1o1dbfssqqbvXEh+3sws67eJ
# 4Hn+8QIXZBsl/zUxBbw5/CVYTHmy4Aosc1TItvDsCPnlicfV2phKSxADlL/WJCCU
# IQBwDMtxNwYM/QMP3bRIN0xNNSpB0+kOzfkRf1hVQmxH+ObqIvvIA+RbI6NhjM3L
# qXw5o0+FltLg7kPGk4Fo/rlhfnydRAE/swrwYd3WRp0sKjDe0lV3r7Bu+FZ4imdB
# 4u24FJK8ygcQOKiyHEX9cEkKruYAXeFmI3WglimYe5Po2LvIonsRLiqX97CGhgDX
# UM9Oo0Sr/0NnV7FnOW75OijNa2PE7pLVgWDjM3Xefmltqui7F/M=
# =uOIs
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 09 May 2024 12:12:40 AM CEST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]

* tag 'hw-misc-20240508' of https://github.com/philmd/qemu: (28 commits)
  misc: Use QEMU header path relative to include/ directory
  hw/intc/loongson_ipi: Implement IOCSR address space for MIPS
  hw/intc/loongarch_ipi: Rename as loongson_ipi
  hw/intc/loongarch_ipi: Remove pointless MAX_CPU check
  hw/mips/loongson3_virt: Emulate suspend function
  hw/loongarch: Rename LoongArchMachineState with LoongArchVirtMachineState
  hw/loongarch: Rename LOONGARCH_MACHINE with LOONGARCH_VIRT_MACHINE
  hw/loongarch/virt: Fix memory leak
  hw/loongarch: move memory map to boot.c
  hw/ppc: Deprecate 'ref405ep' machine and 405 CPUs
  hw/gpio: Handle clock migration in STM32L4x5 gpios
  hw/usb/dev-network: Remove unused struct 'rndis_config_parameter'
  hw/i386/x86: Extract x86_isa_bios_init() from x86_bios_rom_init()
  hw/i386/x86: Don't leak "pc.bios" memory region
  hw/i386/x86: Don't leak "isa-bios" memory regions
  hw/i386: Have x86_bios_rom_init() take X86MachineState rather than MachineState
  hw/i386/x86: Eliminate two if statements in x86_bios_rom_init()
  hw/i386: Add the possibility to use i440fx and isapc without FDC
  hw/i386/Kconfig: Allow to compile Q35 without FDC_ISA
  hw/i386/pc: Allow to compile without CONFIG_FDC_ISA
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2024-05-09 05:45:56 +02:00
commit 1a648f7ae4
44 changed files with 836 additions and 411 deletions

View File

@ -650,7 +650,7 @@ build-tci:
# Check our reduced build configurations # Check our reduced build configurations
# requires libfdt: aarch64, arm, i386, loongarch64, microblaze, microblazeel, # requires libfdt: aarch64, arm, i386, loongarch64, microblaze, microblazeel,
# mips64el, or1k, ppc, ppc64, riscv32, riscv64, rx, x86_64 # mips64el, or1k, ppc, ppc64, riscv32, riscv64, rx, x86_64
# does not build without boards: i386, loongarch64, s390x, sh4, sh4eb, x86_64 # does not build without boards: i386, s390x, sh4, sh4eb, x86_64
build-without-defaults: build-without-defaults:
extends: .native_build_job_template extends: .native_build_job_template
needs: needs:

View File

@ -1242,7 +1242,9 @@ F: configs/devices/loongarch64-softmmu/default.mak
F: hw/loongarch/ F: hw/loongarch/
F: include/hw/loongarch/virt.h F: include/hw/loongarch/virt.h
F: include/hw/intc/loongarch_*.h F: include/hw/intc/loongarch_*.h
F: include/hw/intc/loongson_ipi.h
F: hw/intc/loongarch_*.c F: hw/intc/loongarch_*.c
F: hw/intc/loongson_ipi.c
F: include/hw/pci-host/ls7a.h F: include/hw/pci-host/ls7a.h
F: hw/rtc/ls7a_rtc.c F: hw/rtc/ls7a_rtc.c
F: gdb-xml/loongarch*.xml F: gdb-xml/loongarch*.xml
@ -1376,10 +1378,12 @@ Loongson-3 virtual platforms
M: Huacai Chen <chenhuacai@kernel.org> M: Huacai Chen <chenhuacai@kernel.org>
R: Jiaxun Yang <jiaxun.yang@flygoat.com> R: Jiaxun Yang <jiaxun.yang@flygoat.com>
S: Maintained S: Maintained
F: hw/intc/loongson_ipi.c
F: hw/intc/loongson_liointc.c F: hw/intc/loongson_liointc.c
F: hw/mips/loongson3_bootp.c F: hw/mips/loongson3_bootp.c
F: hw/mips/loongson3_bootp.h F: hw/mips/loongson3_bootp.h
F: hw/mips/loongson3_virt.c F: hw/mips/loongson3_virt.c
F: include/hw/intc/loongson_ipi.h
F: include/hw/intc/loongson_liointc.h F: include/hw/intc/loongson_liointc.h
F: tests/avocado/machine_mips_loongson3v.py F: tests/avocado/machine_mips_loongson3v.py

View File

@ -1609,7 +1609,7 @@ bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
name); name);
goto fail; goto fail;
} }
tb = g_memdup(&bm->table, sizeof(bm->table)); tb = g_memdup2(&bm->table, sizeof(bm->table));
bm->table.offset = 0; bm->table.offset = 0;
bm->table.size = 0; bm->table.size = 0;
QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry); QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry);

View File

@ -258,6 +258,14 @@ dropping the ``cheetah`` OMAP1 board, because we don't have any
test images for it and don't know of anybody who does; the ``sx1`` test images for it and don't know of anybody who does; the ``sx1``
and ``sx1-v1`` OMAP1 machines remain supported for now. and ``sx1-v1`` OMAP1 machines remain supported for now.
PPC 405 ``ref405ep`` machine (since 9.1)
''''''''''''''''''''''''''''''''''''''''
The ``ref405ep`` machine and PPC 405 CPU have no known users, firmware
images are not available, OpenWRT dropped support in 2019, U-Boot in
2017, Linux also is dropping support in 2024. It is time to let go of
this ancient hardware and focus on newer CPUs and platforms.
Backend options Backend options
--------------- ---------------

View File

@ -19,7 +19,7 @@
#include "qemu/iov.h" #include "qemu/iov.h"
#include "qemu/log.h" #include "qemu/log.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "include/qemu/lockable.h" #include "qemu/lockable.h"
#include "exec/tswap.h" #include "exec/tswap.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "trace.h" #include "trace.h"

View File

@ -20,6 +20,7 @@
#include "qemu/log.h" #include "qemu/log.h"
#include "hw/gpio/stm32l4x5_gpio.h" #include "hw/gpio/stm32l4x5_gpio.h"
#include "hw/irq.h" #include "hw/irq.h"
#include "hw/clock.h"
#include "hw/qdev-clock.h" #include "hw/qdev-clock.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "qapi/visitor.h" #include "qapi/visitor.h"
@ -426,8 +427,8 @@ static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp)
static const VMStateDescription vmstate_stm32l4x5_gpio = { static const VMStateDescription vmstate_stm32l4x5_gpio = {
.name = TYPE_STM32L4X5_GPIO, .name = TYPE_STM32L4X5_GPIO,
.version_id = 1, .version_id = 2,
.minimum_version_id = 1, .minimum_version_id = 2,
.fields = (VMStateField[]){ .fields = (VMStateField[]){
VMSTATE_UINT32(moder, Stm32l4x5GpioState), VMSTATE_UINT32(moder, Stm32l4x5GpioState),
VMSTATE_UINT32(otyper, Stm32l4x5GpioState), VMSTATE_UINT32(otyper, Stm32l4x5GpioState),
@ -441,6 +442,7 @@ static const VMStateDescription vmstate_stm32l4x5_gpio = {
VMSTATE_UINT32(ascr, Stm32l4x5GpioState), VMSTATE_UINT32(ascr, Stm32l4x5GpioState),
VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState), VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState),
VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState), VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState),
VMSTATE_CLOCK(clk, Stm32l4x5GpioState),
VMSTATE_END_OF_LIST() VMSTATE_END_OF_LIST()
} }
}; };

View File

@ -207,37 +207,37 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION); val = cpu_to_le64(MIN_SEABIOS_HPPA_VERSION);
fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version", fw_cfg_add_file(fw_cfg, "/etc/firmware-min-version",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup2(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries); val = cpu_to_le64(HPPA_TLB_ENTRIES - btlb_entries);
fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries", fw_cfg_add_file(fw_cfg, "/etc/cpu/tlb_entries",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup2(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(btlb_entries); val = cpu_to_le64(btlb_entries);
fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries", fw_cfg_add_file(fw_cfg, "/etc/cpu/btlb_entries",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup2(&val, sizeof(val)), sizeof(val));
len = strlen(mc->name) + 1; len = strlen(mc->name) + 1;
fw_cfg_add_file(fw_cfg, "/etc/hppa/machine", fw_cfg_add_file(fw_cfg, "/etc/hppa/machine",
g_memdup(mc->name, len), len); g_memdup2(mc->name, len), len);
val = cpu_to_le64(soft_power_reg); val = cpu_to_le64(soft_power_reg);
fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr", fw_cfg_add_file(fw_cfg, "/etc/hppa/power-button-addr",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup2(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(CPU_HPA + 16); val = cpu_to_le64(CPU_HPA + 16);
fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr", fw_cfg_add_file(fw_cfg, "/etc/hppa/rtc-addr",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup2(&val, sizeof(val)), sizeof(val));
val = cpu_to_le64(CPU_HPA + 24); val = cpu_to_le64(CPU_HPA + 24);
fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort", fw_cfg_add_file(fw_cfg, "/etc/hppa/DebugOutputPort",
g_memdup(&val, sizeof(val)), sizeof(val)); g_memdup2(&val, sizeof(val)), sizeof(val));
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]);
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
fw_cfg_add_file(fw_cfg, "/etc/qemu-version", fw_cfg_add_file(fw_cfg, "/etc/qemu-version",
g_memdup(qemu_version, sizeof(qemu_version)), g_memdup2(qemu_version, sizeof(qemu_version)),
sizeof(qemu_version)); sizeof(qemu_version));
fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg); fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg);

View File

@ -32,7 +32,7 @@ config PC
imply VGA_PCI imply VGA_PCI
imply VIRTIO_VGA imply VIRTIO_VGA
imply NVDIMM imply NVDIMM
select FDC_ISA imply FDC_ISA
select I8259 select I8259
select I8254 select I8254
select PCKBD select PCKBD

View File

@ -278,7 +278,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
default_firmware = x86_machine_is_acpi_enabled(x86ms) default_firmware = x86_machine_is_acpi_enabled(x86ms)
? MICROVM_BIOS_FILENAME ? MICROVM_BIOS_FILENAME
: MICROVM_QBOOT_FILENAME; : MICROVM_QBOOT_FILENAME;
x86_bios_rom_init(MACHINE(mms), default_firmware, get_system_memory(), true); x86_bios_rom_init(x86ms, default_firmware, get_system_memory(), true);
} }
static void microvm_memory_init(MicrovmMachineState *mms) static void microvm_memory_init(MicrovmMachineState *mms)

View File

@ -440,16 +440,19 @@ static void pc_boot_set(void *opaque, const char *boot_device, Error **errp)
static void pc_cmos_init_floppy(MC146818RtcState *rtc_state, ISADevice *floppy) static void pc_cmos_init_floppy(MC146818RtcState *rtc_state, ISADevice *floppy)
{ {
int val, nb, i; int val, nb;
FloppyDriveType fd_type[2] = { FLOPPY_DRIVE_TYPE_NONE, FloppyDriveType fd_type[2] = { FLOPPY_DRIVE_TYPE_NONE,
FLOPPY_DRIVE_TYPE_NONE }; FLOPPY_DRIVE_TYPE_NONE };
#ifdef CONFIG_FDC_ISA
/* floppy type */ /* floppy type */
if (floppy) { if (floppy) {
for (i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
fd_type[i] = isa_fdc_get_drive_type(floppy, i); fd_type[i] = isa_fdc_get_drive_type(floppy, i);
} }
} }
#endif
val = (cmos_get_fd_drive_type(fd_type[0]) << 4) | val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
cmos_get_fd_drive_type(fd_type[1]); cmos_get_fd_drive_type(fd_type[1]);
mc146818rtc_set_cmos_data(rtc_state, 0x10, val); mc146818rtc_set_cmos_data(rtc_state, 0x10, val);
@ -1133,7 +1136,7 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl,
int i; int i;
DriveInfo *fd[MAX_FD]; DriveInfo *fd[MAX_FD];
qemu_irq *a20_line; qemu_irq *a20_line;
ISADevice *fdc, *i8042, *port92, *vmmouse; ISADevice *i8042, *port92, *vmmouse;
serial_hds_isa_init(isa_bus, 0, MAX_ISA_SERIAL_PORTS); serial_hds_isa_init(isa_bus, 0, MAX_ISA_SERIAL_PORTS);
parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS); parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS);
@ -1143,11 +1146,13 @@ static void pc_superio_init(ISABus *isa_bus, bool create_fdctrl,
create_fdctrl |= !!fd[i]; create_fdctrl |= !!fd[i];
} }
if (create_fdctrl) { if (create_fdctrl) {
fdc = isa_new(TYPE_ISA_FDC); #ifdef CONFIG_FDC_ISA
ISADevice *fdc = isa_new(TYPE_ISA_FDC);
if (fdc) { if (fdc) {
isa_realize_and_unref(fdc, isa_bus, &error_fatal); isa_realize_and_unref(fdc, isa_bus, &error_fatal);
isa_fdc_init_drives(fdc, fd); isa_fdc_init_drives(fdc, fd);
} }
#endif
} }
if (!create_i8042) { if (!create_i8042) {

View File

@ -317,8 +317,8 @@ static void pc_init1(MachineState *machine, const char *pci_type)
} }
/* init basic PC hardware */ /* init basic PC hardware */
pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc, true, pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc,
0x4); !MACHINE_CLASS(pcmc)->no_floppy, 0x4);
pc_nic_init(pcmc, isa_bus, pcms->pcibus); pc_nic_init(pcmc, isa_bus, pcms->pcibus);
@ -501,6 +501,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
m->default_machine_opts = "firmware=bios-256k.bin"; m->default_machine_opts = "firmware=bios-256k.bin";
m->default_display = "std"; m->default_display = "std";
m->default_nic = "e1000"; m->default_nic = "e1000";
m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL); m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE); machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
@ -931,6 +932,7 @@ static void isapc_machine_options(MachineClass *m)
pcmc->has_reserved_memory = false; pcmc->has_reserved_memory = false;
m->default_nic = "ne2k_isa"; m->default_nic = "ne2k_isa";
m->default_cpu_type = X86_CPU_TYPE_NAME("486"); m->default_cpu_type = X86_CPU_TYPE_NAME("486");
m->no_floppy = !module_object_class_by_name(TYPE_ISA_FDC);
m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL); m->no_parallel = !module_object_class_by_name(TYPE_ISA_PARALLEL);
} }

View File

@ -40,11 +40,10 @@
#define FLASH_SECTOR_SIZE 4096 #define FLASH_SECTOR_SIZE 4096
static void pc_isa_bios_init(MemoryRegion *rom_memory, static void pc_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *rom_memory,
MemoryRegion *flash_mem) MemoryRegion *flash_mem)
{ {
int isa_bios_size; int isa_bios_size;
MemoryRegion *isa_bios;
uint64_t flash_size; uint64_t flash_size;
void *flash_ptr, *isa_bios_ptr; void *flash_ptr, *isa_bios_ptr;
@ -52,7 +51,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
/* map the last 128KB of the BIOS in ISA space */ /* map the last 128KB of the BIOS in ISA space */
isa_bios_size = MIN(flash_size, 128 * KiB); isa_bios_size = MIN(flash_size, 128 * KiB);
isa_bios = g_malloc(sizeof(*isa_bios));
memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size, memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size,
&error_fatal); &error_fatal);
memory_region_add_subregion_overlap(rom_memory, memory_region_add_subregion_overlap(rom_memory,
@ -136,6 +134,7 @@ void pc_system_flash_cleanup_unused(PCMachineState *pcms)
static void pc_system_flash_map(PCMachineState *pcms, static void pc_system_flash_map(PCMachineState *pcms,
MemoryRegion *rom_memory) MemoryRegion *rom_memory)
{ {
X86MachineState *x86ms = X86_MACHINE(pcms);
hwaddr total_size = 0; hwaddr total_size = 0;
int i; int i;
BlockBackend *blk; BlockBackend *blk;
@ -185,7 +184,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (i == 0) { if (i == 0) {
flash_mem = pflash_cfi01_get_memory(system_flash); flash_mem = pflash_cfi01_get_memory(system_flash);
pc_isa_bios_init(rom_memory, flash_mem); pc_isa_bios_init(&x86ms->isa_bios, rom_memory, flash_mem);
/* Encrypt the pflash boot ROM */ /* Encrypt the pflash boot ROM */
if (sev_enabled()) { if (sev_enabled()) {
@ -205,7 +204,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)]; BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
if (!pcmc->pci_enabled) { if (!pcmc->pci_enabled) {
x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, true); x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, true);
return; return;
} }
@ -226,7 +225,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
if (!pflash_blk[0]) { if (!pflash_blk[0]) {
/* Machine property pflash0 not set, use ROM mode */ /* Machine property pflash0 not set, use ROM mode */
x86_bios_rom_init(MACHINE(pcms), "bios.bin", rom_memory, false); x86_bios_rom_init(X86_MACHINE(pcms), "bios.bin", rom_memory, false);
} else { } else {
if (kvm_enabled() && !kvm_readonly_mem_enabled()) { if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
/* /*

View File

@ -1128,17 +1128,29 @@ void x86_load_linux(X86MachineState *x86ms,
nb_option_roms++; nb_option_roms++;
} }
void x86_bios_rom_init(MachineState *ms, const char *default_firmware, void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory,
MemoryRegion *bios, bool read_only)
{
uint64_t bios_size = memory_region_size(bios);
uint64_t isa_bios_size = MIN(bios_size, 128 * KiB);
memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
bios_size - isa_bios_size, isa_bios_size);
memory_region_add_subregion_overlap(isa_memory, 1 * MiB - isa_bios_size,
isa_bios, 1);
memory_region_set_readonly(isa_bios, read_only);
}
void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
MemoryRegion *rom_memory, bool isapc_ram_fw) MemoryRegion *rom_memory, bool isapc_ram_fw)
{ {
const char *bios_name; const char *bios_name;
char *filename; char *filename;
MemoryRegion *bios, *isa_bios; int bios_size;
int bios_size, isa_bios_size;
ssize_t ret; ssize_t ret;
/* BIOS load */ /* BIOS load */
bios_name = ms->firmware ?: default_firmware; bios_name = MACHINE(x86ms)->firmware ?: default_firmware;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (filename) { if (filename) {
bios_size = get_image_size(filename); bios_size = get_image_size(filename);
@ -1149,8 +1161,8 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
(bios_size % 65536) != 0) { (bios_size % 65536) != 0) {
goto bios_error; goto bios_error;
} }
bios = g_malloc(sizeof(*bios)); memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size,
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal); &error_fatal);
if (sev_enabled()) { if (sev_enabled()) {
/* /*
* The concept of a "reset" simply doesn't exist for * The concept of a "reset" simply doesn't exist for
@ -1159,13 +1171,11 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
* the firmware as rom to properly re-initialize on reset. * the firmware as rom to properly re-initialize on reset.
* Just go for a straight file load instead. * Just go for a straight file load instead.
*/ */
void *ptr = memory_region_get_ram_ptr(bios); void *ptr = memory_region_get_ram_ptr(&x86ms->bios);
load_image_size(filename, ptr, bios_size); load_image_size(filename, ptr, bios_size);
x86_firmware_configure(ptr, bios_size); x86_firmware_configure(ptr, bios_size);
} else { } else {
if (!isapc_ram_fw) { memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw);
memory_region_set_readonly(bios, true);
}
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
if (ret != 0) { if (ret != 0) {
goto bios_error; goto bios_error;
@ -1174,22 +1184,13 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
g_free(filename); g_free(filename);
/* map the last 128KB of the BIOS in ISA space */ /* map the last 128KB of the BIOS in ISA space */
isa_bios_size = MIN(bios_size, 128 * KiB); x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios,
isa_bios = g_malloc(sizeof(*isa_bios)); !isapc_ram_fw);
memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
bios_size - isa_bios_size, isa_bios_size);
memory_region_add_subregion_overlap(rom_memory,
0x100000 - isa_bios_size,
isa_bios,
1);
if (!isapc_ram_fw) {
memory_region_set_readonly(isa_bios, true);
}
/* map all the bios at the top of memory */ /* map all the bios at the top of memory */
memory_region_add_subregion(rom_memory, memory_region_add_subregion(rom_memory,
(uint32_t)(-bios_size), (uint32_t)(-bios_size),
bios); &x86ms->bios);
return; return;
bios_error: bios_error:

View File

@ -87,7 +87,7 @@ config GOLDFISH_PIC
config M68K_IRQC config M68K_IRQC
bool bool
config LOONGARCH_IPI config LOONGSON_IPI
bool bool
config LOONGARCH_PCH_PIC config LOONGARCH_PCH_PIC

View File

@ -6,6 +6,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/boards.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/intc/loongarch_ipi.h" #include "hw/intc/loongarch_ipi.h"
#include "hw/irq.h" #include "hw/irq.h"
@ -13,9 +14,8 @@
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/log.h" #include "qemu/log.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "hw/loongarch/virt.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "target/loongarch/internals.h" #include "target/loongarch/cpu.h"
#include "trace.h" #include "trace.h"
static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr, static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
@ -122,11 +122,6 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
CPUState *cs; CPUState *cs;
cpuid = extract32(val, 16, 10); cpuid = extract32(val, 16, 10);
if (cpuid >= LOONGARCH_MAX_CPUS) {
trace_loongarch_ipi_unsupported_cpuid("IOCSR_MAIL_SEND", cpuid);
return MEMTX_DECODE_ERROR;
}
cs = ipi_getcpu(cpuid); cs = ipi_getcpu(cpuid);
if (cs == NULL) { if (cs == NULL) {
return MEMTX_DECODE_ERROR; return MEMTX_DECODE_ERROR;
@ -146,11 +141,6 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
CPUState *cs; CPUState *cs;
cpuid = extract32(val, 16, 10); cpuid = extract32(val, 16, 10);
if (cpuid >= LOONGARCH_MAX_CPUS) {
trace_loongarch_ipi_unsupported_cpuid("IOCSR_ANY_SEND", cpuid);
return MEMTX_DECODE_ERROR;
}
cs = ipi_getcpu(cpuid); cs = ipi_getcpu(cpuid);
if (cs == NULL) { if (cs == NULL) {
return MEMTX_DECODE_ERROR; return MEMTX_DECODE_ERROR;
@ -201,11 +191,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
break; break;
case IOCSR_IPI_SEND: case IOCSR_IPI_SEND:
cpuid = extract32(val, 16, 10); cpuid = extract32(val, 16, 10);
if (cpuid >= LOONGARCH_MAX_CPUS) {
trace_loongarch_ipi_unsupported_cpuid("IOCSR_IPI_SEND", cpuid);
return MEMTX_DECODE_ERROR;
}
/* IPI status vector */ /* IPI status vector */
vector = extract8(val, 0, 5); vector = extract8(val, 0, 5);
cs = ipi_getcpu(cpuid); cs = ipi_getcpu(cpuid);

368
hw/intc/loongson_ipi.c Normal file
View File

@ -0,0 +1,368 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Loongson ipi interrupt support
*
* Copyright (C) 2021 Loongson Technology Corporation Limited
*/
#include "qemu/osdep.h"
#include "hw/boards.h"
#include "hw/sysbus.h"
#include "hw/intc/loongson_ipi.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "exec/address-spaces.h"
#include "migration/vmstate.h"
#ifdef TARGET_LOONGARCH64
#include "target/loongarch/cpu.h"
#endif
#ifdef TARGET_MIPS
#include "target/mips/cpu.h"
#endif
#include "trace.h"
static MemTxResult loongson_ipi_readl(void *opaque, hwaddr addr,
uint64_t *data,
unsigned size, MemTxAttrs attrs)
{
IPICore *s;
LoongsonIPI *ipi = opaque;
uint64_t ret = 0;
int index = 0;
s = &ipi->cpu[attrs.requester_id];
addr &= 0xff;
switch (addr) {
case CORE_STATUS_OFF:
ret = s->status;
break;
case CORE_EN_OFF:
ret = s->en;
break;
case CORE_SET_OFF:
ret = 0;
break;
case CORE_CLEAR_OFF:
ret = 0;
break;
case CORE_BUF_20 ... CORE_BUF_38 + 4:
index = (addr - CORE_BUF_20) >> 2;
ret = s->buf[index];
break;
default:
qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
break;
}
trace_loongson_ipi_read(size, (uint64_t)addr, ret);
*data = ret;
return MEMTX_OK;
}
static AddressSpace *get_cpu_iocsr_as(CPUState *cpu)
{
#ifdef TARGET_LOONGARCH64
return LOONGARCH_CPU(cpu)->env.address_space_iocsr;
#endif
#ifdef TARGET_MIPS
if (ase_lcsr_available(&MIPS_CPU(cpu)->env)) {
return &MIPS_CPU(cpu)->env.iocsr.as;
}
#endif
return NULL;
}
static MemTxResult send_ipi_data(CPUState *cpu, uint64_t val, hwaddr addr,
MemTxAttrs attrs)
{
int i, mask = 0, data = 0;
AddressSpace *iocsr_as = get_cpu_iocsr_as(cpu);
if (!iocsr_as) {
return MEMTX_DECODE_ERROR;
}
/*
* bit 27-30 is mask for byte writing,
* if the mask is 0, we need not to do anything.
*/
if ((val >> 27) & 0xf) {
data = address_space_ldl(iocsr_as, addr, attrs, NULL);
for (i = 0; i < 4; i++) {
/* get mask for byte writing */
if (val & (0x1 << (27 + i))) {
mask |= 0xff << (i * 8);
}
}
}
data &= mask;
data |= (val >> 32) & ~mask;
address_space_stl(iocsr_as, addr, data, attrs, NULL);
return MEMTX_OK;
}
static int archid_cmp(const void *a, const void *b)
{
CPUArchId *archid_a = (CPUArchId *)a;
CPUArchId *archid_b = (CPUArchId *)b;
return archid_a->arch_id - archid_b->arch_id;
}
static CPUArchId *find_cpu_by_archid(MachineState *ms, uint32_t id)
{
CPUArchId apic_id, *found_cpu;
apic_id.arch_id = id;
found_cpu = bsearch(&apic_id, ms->possible_cpus->cpus,
ms->possible_cpus->len, sizeof(*ms->possible_cpus->cpus),
archid_cmp);
return found_cpu;
}
static CPUState *ipi_getcpu(int arch_id)
{
MachineState *machine = MACHINE(qdev_get_machine());
CPUArchId *archid;
archid = find_cpu_by_archid(machine, arch_id);
if (archid) {
return CPU(archid->cpu);
}
return NULL;
}
static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
{
uint32_t cpuid;
hwaddr addr;
CPUState *cs;
cpuid = extract32(val, 16, 10);
cs = ipi_getcpu(cpuid);
if (cs == NULL) {
return MEMTX_DECODE_ERROR;
}
/* override requester_id */
addr = SMP_IPI_MAILBOX + CORE_BUF_20 + (val & 0x1c);
attrs.requester_id = cs->cpu_index;
return send_ipi_data(cs, val, addr, attrs);
}
static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
{
uint32_t cpuid;
hwaddr addr;
CPUState *cs;
cpuid = extract32(val, 16, 10);
cs = ipi_getcpu(cpuid);
if (cs == NULL) {
return MEMTX_DECODE_ERROR;
}
/* override requester_id */
addr = val & 0xffff;
attrs.requester_id = cs->cpu_index;
return send_ipi_data(cs, val, addr, attrs);
}
static MemTxResult loongson_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
unsigned size, MemTxAttrs attrs)
{
LoongsonIPI *ipi = opaque;
IPICore *s;
int index = 0;
uint32_t cpuid;
uint8_t vector;
CPUState *cs;
s = &ipi->cpu[attrs.requester_id];
addr &= 0xff;
trace_loongson_ipi_write(size, (uint64_t)addr, val);
switch (addr) {
case CORE_STATUS_OFF:
qemu_log_mask(LOG_GUEST_ERROR, "can not be written");
break;
case CORE_EN_OFF:
s->en = val;
break;
case CORE_SET_OFF:
s->status |= val;
if (s->status != 0 && (s->status & s->en) != 0) {
qemu_irq_raise(s->irq);
}
break;
case CORE_CLEAR_OFF:
s->status &= ~val;
if (s->status == 0 && s->en != 0) {
qemu_irq_lower(s->irq);
}
break;
case CORE_BUF_20 ... CORE_BUF_38 + 4:
index = (addr - CORE_BUF_20) >> 2;
s->buf[index] = val;
break;
case IOCSR_IPI_SEND:
cpuid = extract32(val, 16, 10);
/* IPI status vector */
vector = extract8(val, 0, 5);
cs = ipi_getcpu(cpuid);
if (cs == NULL) {
return MEMTX_DECODE_ERROR;
}
/* override requester_id */
attrs.requester_id = cs->cpu_index;
loongson_ipi_writel(ipi, CORE_SET_OFF, BIT(vector), 4, attrs);
break;
default:
qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
break;
}
return MEMTX_OK;
}
static const MemoryRegionOps loongson_ipi_ops = {
.read_with_attrs = loongson_ipi_readl,
.write_with_attrs = loongson_ipi_writel,
.impl.min_access_size = 4,
.impl.max_access_size = 4,
.valid.min_access_size = 4,
.valid.max_access_size = 8,
.endianness = DEVICE_LITTLE_ENDIAN,
};
/* mail send and any send only support writeq */
static MemTxResult loongson_ipi_writeq(void *opaque, hwaddr addr, uint64_t val,
unsigned size, MemTxAttrs attrs)
{
MemTxResult ret = MEMTX_OK;
addr &= 0xfff;
switch (addr) {
case MAIL_SEND_OFFSET:
ret = mail_send(val, attrs);
break;
case ANY_SEND_OFFSET:
ret = any_send(val, attrs);
break;
default:
break;
}
return ret;
}
static const MemoryRegionOps loongson_ipi64_ops = {
.write_with_attrs = loongson_ipi_writeq,
.impl.min_access_size = 8,
.impl.max_access_size = 8,
.valid.min_access_size = 8,
.valid.max_access_size = 8,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static void loongson_ipi_realize(DeviceState *dev, Error **errp)
{
LoongsonIPI *s = LOONGSON_IPI(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
int i;
if (s->num_cpu == 0) {
error_setg(errp, "num-cpu must be at least 1");
return;
}
memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), &loongson_ipi_ops,
s, "loongson_ipi_iocsr", 0x48);
/* loongson_ipi_iocsr performs re-entrant IO through ipi_send */
s->ipi_iocsr_mem.disable_reentrancy_guard = true;
sysbus_init_mmio(sbd, &s->ipi_iocsr_mem);
memory_region_init_io(&s->ipi64_iocsr_mem, OBJECT(dev),
&loongson_ipi64_ops,
s, "loongson_ipi64_iocsr", 0x118);
sysbus_init_mmio(sbd, &s->ipi64_iocsr_mem);
s->cpu = g_new0(IPICore, s->num_cpu);
if (s->cpu == NULL) {
error_setg(errp, "Memory allocation for ExtIOICore faile");
return;
}
for (i = 0; i < s->num_cpu; i++) {
qdev_init_gpio_out(dev, &s->cpu[i].irq, 1);
}
}
static const VMStateDescription vmstate_ipi_core = {
.name = "ipi-single",
.version_id = 2,
.minimum_version_id = 2,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(status, IPICore),
VMSTATE_UINT32(en, IPICore),
VMSTATE_UINT32(set, IPICore),
VMSTATE_UINT32(clear, IPICore),
VMSTATE_UINT32_ARRAY(buf, IPICore, IPI_MBX_NUM * 2),
VMSTATE_END_OF_LIST()
}
};
static const VMStateDescription vmstate_loongson_ipi = {
.name = TYPE_LOONGSON_IPI,
.version_id = 2,
.minimum_version_id = 2,
.fields = (const VMStateField[]) {
VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, LoongsonIPI, num_cpu,
vmstate_ipi_core, IPICore),
VMSTATE_END_OF_LIST()
}
};
static Property ipi_properties[] = {
DEFINE_PROP_UINT32("num-cpu", LoongsonIPI, num_cpu, 1),
DEFINE_PROP_END_OF_LIST(),
};
static void loongson_ipi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = loongson_ipi_realize;
device_class_set_props(dc, ipi_properties);
dc->vmsd = &vmstate_loongson_ipi;
}
static void loongson_ipi_finalize(Object *obj)
{
LoongsonIPI *s = LOONGSON_IPI(obj);
g_free(s->cpu);
}
static const TypeInfo loongson_ipi_info = {
.name = TYPE_LOONGSON_IPI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LoongsonIPI),
.class_init = loongson_ipi_class_init,
.instance_finalize = loongson_ipi_finalize,
};
static void loongson_ipi_register_types(void)
{
type_register_static(&loongson_ipi_info);
}
type_init(loongson_ipi_register_types)

View File

@ -68,7 +68,7 @@ specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c'))
specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'], specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
if_true: files('spapr_xive_kvm.c')) if_true: files('spapr_xive_kvm.c'))
specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c')) specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c')) specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: files('loongson_ipi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c'))

View File

@ -291,11 +291,9 @@ sh_intc_read(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PR
sh_intc_write(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PRIx64 " <- 0x%lx" sh_intc_write(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PRIx64 " <- 0x%lx"
sh_intc_set(int id, int enable) "setting interrupt group %d to %d" sh_intc_set(int id, int enable) "setting interrupt group %d to %d"
# loongarch_ipi.c # loongson_ipi.c
loongarch_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 loongson_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64
loongarch_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 loongson_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64
loongarch_ipi_unsupported_cpuid(const char *s, uint32_t cpuid) "%s unsupported cpuid 0x%" PRIx32
# loongarch_pch_pic.c # loongarch_pch_pic.c
loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d" loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d"
loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64

View File

@ -10,7 +10,7 @@ config LOONGARCH_VIRT
select SERIAL select SERIAL
select VIRTIO_PCI select VIRTIO_PCI
select PLATFORM_BUS select PLATFORM_BUS
select LOONGARCH_IPI select LOONGSON_IPI
select LOONGARCH_PCH_PIC select LOONGARCH_PCH_PIC
select LOONGARCH_PCH_MSI select LOONGARCH_PCH_MSI
select LOONGARCH_EXTIOI select LOONGARCH_EXTIOI

View File

@ -105,14 +105,15 @@ build_facs(GArray *table_data)
/* build MADT */ /* build MADT */
static void static void
build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams) build_madt(GArray *table_data, BIOSLinker *linker,
LoongArchVirtMachineState *lvms)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
MachineClass *mc = MACHINE_GET_CLASS(ms); MachineClass *mc = MACHINE_GET_CLASS(ms);
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
int i, arch_id; int i, arch_id;
AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id, AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lvms->oem_id,
.oem_table_id = lams->oem_table_id }; .oem_table_id = lvms->oem_table_id };
acpi_table_begin(&table, table_data); acpi_table_begin(&table, table_data);
@ -167,11 +168,11 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
int i, arch_id, node_id; int i, arch_id, node_id;
uint64_t mem_len, mem_base; uint64_t mem_len, mem_base;
int nb_numa_nodes = machine->numa_state->num_nodes; int nb_numa_nodes = machine->numa_state->num_nodes;
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
MachineClass *mc = MACHINE_GET_CLASS(lams); MachineClass *mc = MACHINE_GET_CLASS(lvms);
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine); const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id, AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lvms->oem_id,
.oem_table_id = lams->oem_table_id }; .oem_table_id = lvms->oem_table_id };
acpi_table_begin(&table, table_data); acpi_table_begin(&table, table_data);
build_append_int_noprefix(table_data, 1, 4); /* Reserved */ build_append_int_noprefix(table_data, 1, 4); /* Reserved */
@ -279,13 +280,13 @@ static void
build_la_ged_aml(Aml *dsdt, MachineState *machine) build_la_ged_aml(Aml *dsdt, MachineState *machine)
{ {
uint32_t event; uint32_t event;
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
build_ged_aml(dsdt, "\\_SB."GED_DEVICE, build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
HOTPLUG_HANDLER(lams->acpi_ged), HOTPLUG_HANDLER(lvms->acpi_ged),
VIRT_SCI_IRQ, AML_SYSTEM_MEMORY, VIRT_SCI_IRQ, AML_SYSTEM_MEMORY,
VIRT_GED_EVT_ADDR); VIRT_GED_EVT_ADDR);
event = object_property_get_uint(OBJECT(lams->acpi_ged), event = object_property_get_uint(OBJECT(lvms->acpi_ged),
"ged-event", &error_abort); "ged-event", &error_abort);
if (event & ACPI_GED_MEM_HOTPLUG_EVT) { if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL, build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL,
@ -295,7 +296,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
acpi_dsdt_add_power_button(dsdt); acpi_dsdt_add_power_button(dsdt);
} }
static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams) static void build_pci_device_aml(Aml *scope, LoongArchVirtMachineState *lvms)
{ {
struct GPEXConfig cfg = { struct GPEXConfig cfg = {
.mmio64.base = VIRT_PCI_MEM_BASE, .mmio64.base = VIRT_PCI_MEM_BASE,
@ -305,13 +306,13 @@ static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
.ecam.base = VIRT_PCI_CFG_BASE, .ecam.base = VIRT_PCI_CFG_BASE,
.ecam.size = VIRT_PCI_CFG_SIZE, .ecam.size = VIRT_PCI_CFG_SIZE,
.irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS, .irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS,
.bus = lams->pci_bus, .bus = lvms->pci_bus,
}; };
acpi_dsdt_add_gpex(scope, &cfg); acpi_dsdt_add_gpex(scope, &cfg);
} }
static void build_flash_aml(Aml *scope, LoongArchMachineState *lams) static void build_flash_aml(Aml *scope, LoongArchVirtMachineState *lvms)
{ {
Aml *dev, *crs; Aml *dev, *crs;
MemoryRegion *flash_mem; MemoryRegion *flash_mem;
@ -322,11 +323,11 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
hwaddr flash1_base; hwaddr flash1_base;
hwaddr flash1_size; hwaddr flash1_size;
flash_mem = pflash_cfi01_get_memory(lams->flash[0]); flash_mem = pflash_cfi01_get_memory(lvms->flash[0]);
flash0_base = flash_mem->addr; flash0_base = flash_mem->addr;
flash0_size = memory_region_size(flash_mem); flash0_size = memory_region_size(flash_mem);
flash_mem = pflash_cfi01_get_memory(lams->flash[1]); flash_mem = pflash_cfi01_get_memory(lvms->flash[1]);
flash1_base = flash_mem->addr; flash1_base = flash_mem->addr;
flash1_size = memory_region_size(flash_mem); flash1_size = memory_region_size(flash_mem);
@ -352,7 +353,7 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
} }
#ifdef CONFIG_TPM #ifdef CONFIG_TPM
static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms) static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms)
{ {
PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS; hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
@ -391,18 +392,18 @@ static void
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine) build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{ {
Aml *dsdt, *scope, *pkg; Aml *dsdt, *scope, *pkg;
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id, AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
.oem_table_id = lams->oem_table_id }; .oem_table_id = lvms->oem_table_id };
acpi_table_begin(&table, table_data); acpi_table_begin(&table, table_data);
dsdt = init_aml_allocator(); dsdt = init_aml_allocator();
build_uart_device_aml(dsdt); build_uart_device_aml(dsdt);
build_pci_device_aml(dsdt, lams); build_pci_device_aml(dsdt, lvms);
build_la_ged_aml(dsdt, machine); build_la_ged_aml(dsdt, machine);
build_flash_aml(dsdt, lams); build_flash_aml(dsdt, lvms);
#ifdef CONFIG_TPM #ifdef CONFIG_TPM
acpi_dsdt_add_tpm(dsdt, lams); acpi_dsdt_add_tpm(dsdt, lvms);
#endif #endif
/* System State Package */ /* System State Package */
scope = aml_scope("\\"); scope = aml_scope("\\");
@ -421,7 +422,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
static void acpi_build(AcpiBuildTables *tables, MachineState *machine) static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
GArray *table_offsets; GArray *table_offsets;
AcpiFadtData fadt_data; AcpiFadtData fadt_data;
unsigned facs, rsdt, dsdt; unsigned facs, rsdt, dsdt;
@ -455,14 +456,14 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
fadt_data.dsdt_tbl_offset = &dsdt; fadt_data.dsdt_tbl_offset = &dsdt;
fadt_data.xdsdt_tbl_offset = &dsdt; fadt_data.xdsdt_tbl_offset = &dsdt;
build_fadt(tables_blob, tables->linker, &fadt_data, build_fadt(tables_blob, tables->linker, &fadt_data,
lams->oem_id, lams->oem_table_id); lvms->oem_id, lvms->oem_table_id);
acpi_add_table(table_offsets, tables_blob); acpi_add_table(table_offsets, tables_blob);
build_madt(tables_blob, tables->linker, lams); build_madt(tables_blob, tables->linker, lvms);
acpi_add_table(table_offsets, tables_blob); acpi_add_table(table_offsets, tables_blob);
build_pptt(tables_blob, tables->linker, machine, build_pptt(tables_blob, tables->linker, machine,
lams->oem_id, lams->oem_table_id); lvms->oem_id, lvms->oem_table_id);
acpi_add_table(table_offsets, tables_blob); acpi_add_table(table_offsets, tables_blob);
build_srat(tables_blob, tables->linker, machine); build_srat(tables_blob, tables->linker, machine);
@ -470,13 +471,13 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
if (machine->numa_state->num_nodes) { if (machine->numa_state->num_nodes) {
if (machine->numa_state->have_numa_distance) { if (machine->numa_state->have_numa_distance) {
acpi_add_table(table_offsets, tables_blob); acpi_add_table(table_offsets, tables_blob);
build_slit(tables_blob, tables->linker, machine, lams->oem_id, build_slit(tables_blob, tables->linker, machine, lvms->oem_id,
lams->oem_table_id); lvms->oem_table_id);
} }
if (machine->numa_state->hmat_enabled) { if (machine->numa_state->hmat_enabled) {
acpi_add_table(table_offsets, tables_blob); acpi_add_table(table_offsets, tables_blob);
build_hmat(tables_blob, tables->linker, machine->numa_state, build_hmat(tables_blob, tables->linker, machine->numa_state,
lams->oem_id, lams->oem_table_id); lvms->oem_id, lvms->oem_table_id);
} }
} }
@ -486,8 +487,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
.base = cpu_to_le64(VIRT_PCI_CFG_BASE), .base = cpu_to_le64(VIRT_PCI_CFG_BASE),
.size = cpu_to_le64(VIRT_PCI_CFG_SIZE), .size = cpu_to_le64(VIRT_PCI_CFG_SIZE),
}; };
build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id, build_mcfg(tables_blob, tables->linker, &mcfg, lvms->oem_id,
lams->oem_table_id); lvms->oem_table_id);
} }
#ifdef CONFIG_TPM #ifdef CONFIG_TPM
@ -495,8 +496,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
acpi_add_table(table_offsets, tables_blob); acpi_add_table(table_offsets, tables_blob);
build_tpm2(tables_blob, tables->linker, build_tpm2(tables_blob, tables->linker,
tables->tcpalog, lams->oem_id, tables->tcpalog, lvms->oem_id,
lams->oem_table_id); lvms->oem_table_id);
} }
#endif #endif
/* Add tables supplied by user (if any) */ /* Add tables supplied by user (if any) */
@ -510,13 +511,13 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
/* RSDT is pointed to by RSDP */ /* RSDT is pointed to by RSDP */
rsdt = tables_blob->len; rsdt = tables_blob->len;
build_rsdt(tables_blob, tables->linker, table_offsets, build_rsdt(tables_blob, tables->linker, table_offsets,
lams->oem_id, lams->oem_table_id); lvms->oem_id, lvms->oem_table_id);
/* RSDP is in FSEG memory, so allocate it separately */ /* RSDP is in FSEG memory, so allocate it separately */
{ {
AcpiRsdpData rsdp_data = { AcpiRsdpData rsdp_data = {
.revision = 0, .revision = 0,
.oem_id = lams->oem_id, .oem_id = lvms->oem_id,
.xsdt_tbl_offset = NULL, .xsdt_tbl_offset = NULL,
.rsdt_tbl_offset = &rsdt, .rsdt_tbl_offset = &rsdt,
}; };
@ -593,17 +594,25 @@ static const VMStateDescription vmstate_acpi_build = {
}, },
}; };
void loongarch_acpi_setup(LoongArchMachineState *lams) static bool loongarch_is_acpi_enabled(LoongArchVirtMachineState *lvms)
{
if (lvms->acpi == ON_OFF_AUTO_OFF) {
return false;
}
return true;
}
void loongarch_acpi_setup(LoongArchVirtMachineState *lvms)
{ {
AcpiBuildTables tables; AcpiBuildTables tables;
AcpiBuildState *build_state; AcpiBuildState *build_state;
if (!lams->fw_cfg) { if (!lvms->fw_cfg) {
ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n"); ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
return; return;
} }
if (!loongarch_is_acpi_enabled(lams)) { if (!loongarch_is_acpi_enabled(lvms)) {
ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n"); ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
return; return;
} }
@ -611,7 +620,7 @@ void loongarch_acpi_setup(LoongArchMachineState *lams)
build_state = g_malloc0(sizeof *build_state); build_state = g_malloc0(sizeof *build_state);
acpi_build_tables_init(&tables); acpi_build_tables_init(&tables);
acpi_build(&tables, MACHINE(lams)); acpi_build(&tables, MACHINE(lvms));
/* Now expose it all to Guest */ /* Now expose it all to Guest */
build_state->table_mr = acpi_add_rom_blob(acpi_build_update, build_state->table_mr = acpi_add_rom_blob(acpi_build_update,

View File

@ -15,6 +15,9 @@
#include "sysemu/reset.h" #include "sysemu/reset.h"
#include "sysemu/qtest.h" #include "sysemu/qtest.h"
struct memmap_entry *memmap_table;
unsigned memmap_entries;
ram_addr_t initrd_offset; ram_addr_t initrd_offset;
uint64_t initrd_size; uint64_t initrd_size;
@ -256,10 +259,10 @@ static void fw_cfg_add_kernel_info(struct loongarch_boot_info *info,
} }
} }
static void loongarch_firmware_boot(LoongArchMachineState *lams, static void loongarch_firmware_boot(LoongArchVirtMachineState *lvms,
struct loongarch_boot_info *info) struct loongarch_boot_info *info)
{ {
fw_cfg_add_kernel_info(info, lams->fw_cfg); fw_cfg_add_kernel_info(info, lvms->fw_cfg);
} }
static void init_boot_rom(struct loongarch_boot_info *info, void *p) static void init_boot_rom(struct loongarch_boot_info *info, void *p)
@ -316,7 +319,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(ms); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
int i; int i;
/* register reset function */ /* register reset function */
@ -328,8 +331,8 @@ void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
info->kernel_cmdline = ms->kernel_cmdline; info->kernel_cmdline = ms->kernel_cmdline;
info->initrd_filename = ms->initrd_filename; info->initrd_filename = ms->initrd_filename;
if (lams->bios_loaded) { if (lvms->bios_loaded) {
loongarch_firmware_boot(lams, info); loongarch_firmware_boot(lvms, info);
} else { } else {
loongarch_direct_kernel_boot(info); loongarch_direct_kernel_boot(info);
} }

View File

@ -17,7 +17,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device,
fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); fw_cfg_modify_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]);
} }
FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms) FWCfgState *virt_fw_cfg_init(ram_addr_t ram_size, MachineState *ms)
{ {
FWCfgState *fw_cfg; FWCfgState *fw_cfg;
int max_cpus = ms->smp.max_cpus; int max_cpus = ms->smp.max_cpus;

View File

@ -11,5 +11,5 @@
#include "hw/boards.h" #include "hw/boards.h"
#include "hw/nvram/fw_cfg.h" #include "hw/nvram/fw_cfg.h"
FWCfgState *loongarch_fw_cfg_init(ram_addr_t ram_size, MachineState *ms); FWCfgState *virt_fw_cfg_init(ram_addr_t ram_size, MachineState *ms);
#endif #endif

View File

@ -21,7 +21,7 @@
#include "net/net.h" #include "net/net.h"
#include "hw/loader.h" #include "hw/loader.h"
#include "elf.h" #include "elf.h"
#include "hw/intc/loongarch_ipi.h" #include "hw/intc/loongson_ipi.h"
#include "hw/intc/loongarch_extioi.h" #include "hw/intc/loongarch_extioi.h"
#include "hw/intc/loongarch_pch_pic.h" #include "hw/intc/loongarch_pch_pic.h"
#include "hw/intc/loongarch_pch_msi.h" #include "hw/intc/loongarch_pch_msi.h"
@ -46,7 +46,7 @@
#include "hw/block/flash.h" #include "hw/block/flash.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams, static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
const char *name, const char *name,
const char *alias_prop_name) const char *alias_prop_name)
{ {
@ -61,16 +61,16 @@ static PFlashCFI01 *virt_flash_create1(LoongArchMachineState *lams,
qdev_prop_set_uint16(dev, "id2", 0x00); qdev_prop_set_uint16(dev, "id2", 0x00);
qdev_prop_set_uint16(dev, "id3", 0x00); qdev_prop_set_uint16(dev, "id3", 0x00);
qdev_prop_set_string(dev, "name", name); qdev_prop_set_string(dev, "name", name);
object_property_add_child(OBJECT(lams), name, OBJECT(dev)); object_property_add_child(OBJECT(lvms), name, OBJECT(dev));
object_property_add_alias(OBJECT(lams), alias_prop_name, object_property_add_alias(OBJECT(lvms), alias_prop_name,
OBJECT(dev), "drive"); OBJECT(dev), "drive");
return PFLASH_CFI01(dev); return PFLASH_CFI01(dev);
} }
static void virt_flash_create(LoongArchMachineState *lams) static void virt_flash_create(LoongArchVirtMachineState *lvms)
{ {
lams->flash[0] = virt_flash_create1(lams, "virt.flash0", "pflash0"); lvms->flash[0] = virt_flash_create1(lvms, "virt.flash0", "pflash0");
lams->flash[1] = virt_flash_create1(lams, "virt.flash1", "pflash1"); lvms->flash[1] = virt_flash_create1(lvms, "virt.flash1", "pflash1");
} }
static void virt_flash_map1(PFlashCFI01 *flash, static void virt_flash_map1(PFlashCFI01 *flash,
@ -96,20 +96,20 @@ static void virt_flash_map1(PFlashCFI01 *flash,
sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0)); sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
} }
static void virt_flash_map(LoongArchMachineState *lams, static void virt_flash_map(LoongArchVirtMachineState *lvms,
MemoryRegion *sysmem) MemoryRegion *sysmem)
{ {
PFlashCFI01 *flash0 = lams->flash[0]; PFlashCFI01 *flash0 = lvms->flash[0];
PFlashCFI01 *flash1 = lams->flash[1]; PFlashCFI01 *flash1 = lvms->flash[1];
virt_flash_map1(flash0, VIRT_FLASH0_BASE, VIRT_FLASH0_SIZE, sysmem); virt_flash_map1(flash0, VIRT_FLASH0_BASE, VIRT_FLASH0_SIZE, sysmem);
virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem); virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem);
} }
static void fdt_add_cpuic_node(LoongArchMachineState *lams, static void fdt_add_cpuic_node(LoongArchVirtMachineState *lvms,
uint32_t *cpuintc_phandle) uint32_t *cpuintc_phandle)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
char *nodename; char *nodename;
*cpuintc_phandle = qemu_fdt_alloc_phandle(ms->fdt); *cpuintc_phandle = qemu_fdt_alloc_phandle(ms->fdt);
@ -123,11 +123,11 @@ static void fdt_add_cpuic_node(LoongArchMachineState *lams,
g_free(nodename); g_free(nodename);
} }
static void fdt_add_eiointc_node(LoongArchMachineState *lams, static void fdt_add_eiointc_node(LoongArchVirtMachineState *lvms,
uint32_t *cpuintc_phandle, uint32_t *cpuintc_phandle,
uint32_t *eiointc_phandle) uint32_t *eiointc_phandle)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
char *nodename; char *nodename;
hwaddr extioi_base = APIC_BASE; hwaddr extioi_base = APIC_BASE;
hwaddr extioi_size = EXTIOI_SIZE; hwaddr extioi_size = EXTIOI_SIZE;
@ -148,11 +148,11 @@ static void fdt_add_eiointc_node(LoongArchMachineState *lams,
g_free(nodename); g_free(nodename);
} }
static void fdt_add_pch_pic_node(LoongArchMachineState *lams, static void fdt_add_pch_pic_node(LoongArchVirtMachineState *lvms,
uint32_t *eiointc_phandle, uint32_t *eiointc_phandle,
uint32_t *pch_pic_phandle) uint32_t *pch_pic_phandle)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
char *nodename; char *nodename;
hwaddr pch_pic_base = VIRT_PCH_REG_BASE; hwaddr pch_pic_base = VIRT_PCH_REG_BASE;
hwaddr pch_pic_size = VIRT_PCH_REG_SIZE; hwaddr pch_pic_size = VIRT_PCH_REG_SIZE;
@ -173,11 +173,11 @@ static void fdt_add_pch_pic_node(LoongArchMachineState *lams,
g_free(nodename); g_free(nodename);
} }
static void fdt_add_pch_msi_node(LoongArchMachineState *lams, static void fdt_add_pch_msi_node(LoongArchVirtMachineState *lvms,
uint32_t *eiointc_phandle, uint32_t *eiointc_phandle,
uint32_t *pch_msi_phandle) uint32_t *pch_msi_phandle)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
char *nodename; char *nodename;
hwaddr pch_msi_base = VIRT_PCH_MSI_ADDR_LOW; hwaddr pch_msi_base = VIRT_PCH_MSI_ADDR_LOW;
hwaddr pch_msi_size = VIRT_PCH_MSI_SIZE; hwaddr pch_msi_size = VIRT_PCH_MSI_SIZE;
@ -201,9 +201,9 @@ static void fdt_add_pch_msi_node(LoongArchMachineState *lams,
g_free(nodename); g_free(nodename);
} }
static void fdt_add_flash_node(LoongArchMachineState *lams) static void fdt_add_flash_node(LoongArchVirtMachineState *lvms)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
char *nodename; char *nodename;
MemoryRegion *flash_mem; MemoryRegion *flash_mem;
@ -213,11 +213,11 @@ static void fdt_add_flash_node(LoongArchMachineState *lams)
hwaddr flash1_base; hwaddr flash1_base;
hwaddr flash1_size; hwaddr flash1_size;
flash_mem = pflash_cfi01_get_memory(lams->flash[0]); flash_mem = pflash_cfi01_get_memory(lvms->flash[0]);
flash0_base = flash_mem->addr; flash0_base = flash_mem->addr;
flash0_size = memory_region_size(flash_mem); flash0_size = memory_region_size(flash_mem);
flash_mem = pflash_cfi01_get_memory(lams->flash[1]); flash_mem = pflash_cfi01_get_memory(lvms->flash[1]);
flash1_base = flash_mem->addr; flash1_base = flash_mem->addr;
flash1_size = memory_region_size(flash_mem); flash1_size = memory_region_size(flash_mem);
@ -231,13 +231,13 @@ static void fdt_add_flash_node(LoongArchMachineState *lams)
g_free(nodename); g_free(nodename);
} }
static void fdt_add_rtc_node(LoongArchMachineState *lams, static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms,
uint32_t *pch_pic_phandle) uint32_t *pch_pic_phandle)
{ {
char *nodename; char *nodename;
hwaddr base = VIRT_RTC_REG_BASE; hwaddr base = VIRT_RTC_REG_BASE;
hwaddr size = VIRT_RTC_LEN; hwaddr size = VIRT_RTC_LEN;
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
nodename = g_strdup_printf("/rtc@%" PRIx64, base); nodename = g_strdup_printf("/rtc@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename); qemu_fdt_add_subnode(ms->fdt, nodename);
@ -251,13 +251,13 @@ static void fdt_add_rtc_node(LoongArchMachineState *lams,
g_free(nodename); g_free(nodename);
} }
static void fdt_add_uart_node(LoongArchMachineState *lams, static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
uint32_t *pch_pic_phandle) uint32_t *pch_pic_phandle)
{ {
char *nodename; char *nodename;
hwaddr base = VIRT_UART_BASE; hwaddr base = VIRT_UART_BASE;
hwaddr size = VIRT_UART_SIZE; hwaddr size = VIRT_UART_SIZE;
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
nodename = g_strdup_printf("/serial@%" PRIx64, base); nodename = g_strdup_printf("/serial@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename); qemu_fdt_add_subnode(ms->fdt, nodename);
@ -272,11 +272,11 @@ static void fdt_add_uart_node(LoongArchMachineState *lams,
g_free(nodename); g_free(nodename);
} }
static void create_fdt(LoongArchMachineState *lams) static void create_fdt(LoongArchVirtMachineState *lvms)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
ms->fdt = create_device_tree(&lams->fdt_size); ms->fdt = create_device_tree(&lvms->fdt_size);
if (!ms->fdt) { if (!ms->fdt) {
error_report("create_device_tree() failed"); error_report("create_device_tree() failed");
exit(1); exit(1);
@ -290,10 +290,10 @@ static void create_fdt(LoongArchMachineState *lams)
qemu_fdt_add_subnode(ms->fdt, "/chosen"); qemu_fdt_add_subnode(ms->fdt, "/chosen");
} }
static void fdt_add_cpu_nodes(const LoongArchMachineState *lams) static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
{ {
int num; int num;
const MachineState *ms = MACHINE(lams); const MachineState *ms = MACHINE(lvms);
int smp_cpus = ms->smp.cpus; int smp_cpus = ms->smp.cpus;
qemu_fdt_add_subnode(ms->fdt, "/cpus"); qemu_fdt_add_subnode(ms->fdt, "/cpus");
@ -347,11 +347,11 @@ static void fdt_add_cpu_nodes(const LoongArchMachineState *lams)
} }
} }
static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams) static void fdt_add_fw_cfg_node(const LoongArchVirtMachineState *lvms)
{ {
char *nodename; char *nodename;
hwaddr base = VIRT_FWCFG_BASE; hwaddr base = VIRT_FWCFG_BASE;
const MachineState *ms = MACHINE(lams); const MachineState *ms = MACHINE(lvms);
nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base); nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename); qemu_fdt_add_subnode(ms->fdt, nodename);
@ -363,7 +363,7 @@ static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams)
g_free(nodename); g_free(nodename);
} }
static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams, static void fdt_add_pcie_irq_map_node(const LoongArchVirtMachineState *lvms,
char *nodename, char *nodename,
uint32_t *pch_pic_phandle) uint32_t *pch_pic_phandle)
{ {
@ -371,7 +371,7 @@ static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams,
uint32_t irq_map_stride = 0; uint32_t irq_map_stride = 0;
uint32_t full_irq_map[GPEX_NUM_IRQS *GPEX_NUM_IRQS * 10] = {}; uint32_t full_irq_map[GPEX_NUM_IRQS *GPEX_NUM_IRQS * 10] = {};
uint32_t *irq_map = full_irq_map; uint32_t *irq_map = full_irq_map;
const MachineState *ms = MACHINE(lams); const MachineState *ms = MACHINE(lvms);
/* This code creates a standard swizzle of interrupts such that /* This code creates a standard swizzle of interrupts such that
* each device's first interrupt is based on it's PCI_SLOT number. * each device's first interrupt is based on it's PCI_SLOT number.
@ -416,7 +416,7 @@ static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams,
0x1800, 0, 0, 0x7); 0x1800, 0, 0, 0x7);
} }
static void fdt_add_pcie_node(const LoongArchMachineState *lams, static void fdt_add_pcie_node(const LoongArchVirtMachineState *lvms,
uint32_t *pch_pic_phandle, uint32_t *pch_pic_phandle,
uint32_t *pch_msi_phandle) uint32_t *pch_msi_phandle)
{ {
@ -429,7 +429,7 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams,
hwaddr size_pcie = VIRT_PCI_CFG_SIZE; hwaddr size_pcie = VIRT_PCI_CFG_SIZE;
hwaddr base = base_pcie; hwaddr base = base_pcie;
const MachineState *ms = MACHINE(lams); const MachineState *ms = MACHINE(lvms);
nodename = g_strdup_printf("/pcie@%" PRIx64, base); nodename = g_strdup_printf("/pcie@%" PRIx64, base);
qemu_fdt_add_subnode(ms->fdt, nodename); qemu_fdt_add_subnode(ms->fdt, nodename);
@ -452,7 +452,7 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams,
qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map", qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map",
0, *pch_msi_phandle, 0, 0x10000); 0, *pch_msi_phandle, 0, 0x10000);
fdt_add_pcie_irq_map_node(lams, nodename, pch_pic_phandle); fdt_add_pcie_irq_map_node(lvms, nodename, pch_pic_phandle);
g_free(nodename); g_free(nodename);
} }
@ -473,15 +473,15 @@ static void fdt_add_memory_node(MachineState *ms,
g_free(nodename); g_free(nodename);
} }
static void virt_build_smbios(LoongArchMachineState *lams) static void virt_build_smbios(LoongArchVirtMachineState *lvms)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
MachineClass *mc = MACHINE_GET_CLASS(lams); MachineClass *mc = MACHINE_GET_CLASS(lvms);
uint8_t *smbios_tables, *smbios_anchor; uint8_t *smbios_tables, *smbios_anchor;
size_t smbios_tables_len, smbios_anchor_len; size_t smbios_tables_len, smbios_anchor_len;
const char *product = "QEMU Virtual Machine"; const char *product = "QEMU Virtual Machine";
if (!lams->fw_cfg) { if (!lvms->fw_cfg) {
return; return;
} }
@ -493,32 +493,29 @@ static void virt_build_smbios(LoongArchMachineState *lams)
&smbios_anchor, &smbios_anchor_len, &error_fatal); &smbios_anchor, &smbios_anchor_len, &error_fatal);
if (smbios_anchor) { if (smbios_anchor) {
fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-tables", fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-tables",
smbios_tables, smbios_tables_len); smbios_tables, smbios_tables_len);
fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-anchor", fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-anchor",
smbios_anchor, smbios_anchor_len); smbios_anchor, smbios_anchor_len);
} }
} }
static void virt_machine_done(Notifier *notifier, void *data) static void virt_done(Notifier *notifier, void *data)
{ {
LoongArchMachineState *lams = container_of(notifier, LoongArchVirtMachineState *lvms = container_of(notifier,
LoongArchMachineState, machine_done); LoongArchVirtMachineState, machine_done);
virt_build_smbios(lams); virt_build_smbios(lvms);
loongarch_acpi_setup(lams); loongarch_acpi_setup(lvms);
} }
static void virt_powerdown_req(Notifier *notifier, void *opaque) static void virt_powerdown_req(Notifier *notifier, void *opaque)
{ {
LoongArchMachineState *s = container_of(notifier, LoongArchVirtMachineState *s;
LoongArchMachineState, powerdown_notifier);
s = container_of(notifier, LoongArchVirtMachineState, powerdown_notifier);
acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS); acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
} }
struct memmap_entry *memmap_table;
unsigned memmap_entries;
static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
{ {
/* Ensure there are no duplicate entries. */ /* Ensure there are no duplicate entries. */
@ -535,10 +532,11 @@ static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
memmap_entries++; memmap_entries++;
} }
static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState *lams) static DeviceState *create_acpi_ged(DeviceState *pch_pic,
LoongArchVirtMachineState *lvms)
{ {
DeviceState *dev; DeviceState *dev;
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
uint32_t event = ACPI_GED_PWR_DOWN_EVT; uint32_t event = ACPI_GED_PWR_DOWN_EVT;
if (ms->ram_slots) { if (ms->ram_slots) {
@ -585,12 +583,12 @@ static DeviceState *create_platform_bus(DeviceState *pch_pic)
return dev; return dev;
} }
static void loongarch_devices_init(DeviceState *pch_pic, static void virt_devices_init(DeviceState *pch_pic,
LoongArchMachineState *lams, LoongArchVirtMachineState *lvms,
uint32_t *pch_pic_phandle, uint32_t *pch_pic_phandle,
uint32_t *pch_msi_phandle) uint32_t *pch_msi_phandle)
{ {
MachineClass *mc = MACHINE_GET_CLASS(lams); MachineClass *mc = MACHINE_GET_CLASS(lvms);
DeviceState *gpex_dev; DeviceState *gpex_dev;
SysBusDevice *d; SysBusDevice *d;
PCIBus *pci_bus; PCIBus *pci_bus;
@ -602,7 +600,7 @@ static void loongarch_devices_init(DeviceState *pch_pic,
d = SYS_BUS_DEVICE(gpex_dev); d = SYS_BUS_DEVICE(gpex_dev);
sysbus_realize_and_unref(d, &error_fatal); sysbus_realize_and_unref(d, &error_fatal);
pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus; pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
lams->pci_bus = pci_bus; lvms->pci_bus = pci_bus;
/* Map only part size_ecam bytes of ECAM space */ /* Map only part size_ecam bytes of ECAM space */
ecam_alias = g_new0(MemoryRegion, 1); ecam_alias = g_new0(MemoryRegion, 1);
@ -635,13 +633,13 @@ static void loongarch_devices_init(DeviceState *pch_pic,
} }
/* Add pcie node */ /* Add pcie node */
fdt_add_pcie_node(lams, pch_pic_phandle, pch_msi_phandle); fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0, serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
qdev_get_gpio_in(pch_pic, qdev_get_gpio_in(pch_pic,
VIRT_UART_IRQ - VIRT_GSI_BASE), VIRT_UART_IRQ - VIRT_GSI_BASE),
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN); 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
fdt_add_uart_node(lams, pch_pic_phandle); fdt_add_uart_node(lvms, pch_pic_phandle);
/* Network init */ /* Network init */
pci_init_nic_devices(pci_bus, mc->default_nic); pci_init_nic_devices(pci_bus, mc->default_nic);
@ -654,17 +652,17 @@ static void loongarch_devices_init(DeviceState *pch_pic,
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE, sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
qdev_get_gpio_in(pch_pic, qdev_get_gpio_in(pch_pic,
VIRT_RTC_IRQ - VIRT_GSI_BASE)); VIRT_RTC_IRQ - VIRT_GSI_BASE));
fdt_add_rtc_node(lams, pch_pic_phandle); fdt_add_rtc_node(lvms, pch_pic_phandle);
/* acpi ged */ /* acpi ged */
lams->acpi_ged = create_acpi_ged(pch_pic, lams); lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
/* platform bus */ /* platform bus */
lams->platform_bus_dev = create_platform_bus(pch_pic); lvms->platform_bus_dev = create_platform_bus(pch_pic);
} }
static void loongarch_irq_init(LoongArchMachineState *lams) static void virt_irq_init(LoongArchVirtMachineState *lvms)
{ {
MachineState *ms = MACHINE(lams); MachineState *ms = MACHINE(lvms);
DeviceState *pch_pic, *pch_msi, *cpudev; DeviceState *pch_pic, *pch_msi, *cpudev;
DeviceState *ipi, *extioi; DeviceState *ipi, *extioi;
SysBusDevice *d; SysBusDevice *d;
@ -697,25 +695,25 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
*/ */
/* Create IPI device */ /* Create IPI device */
ipi = qdev_new(TYPE_LOONGARCH_IPI); ipi = qdev_new(TYPE_LOONGSON_IPI);
qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus); qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus);
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
/* IPI iocsr memory region */ /* IPI iocsr memory region */
memory_region_add_subregion(&lams->system_iocsr, SMP_IPI_MAILBOX, memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0)); sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
memory_region_add_subregion(&lams->system_iocsr, MAIL_SEND_ADDR, memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1)); sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
/* Add cpu interrupt-controller */ /* Add cpu interrupt-controller */
fdt_add_cpuic_node(lams, &cpuintc_phandle); fdt_add_cpuic_node(lvms, &cpuintc_phandle);
for (cpu = 0; cpu < ms->smp.cpus; cpu++) { for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
cpu_state = qemu_get_cpu(cpu); cpu_state = qemu_get_cpu(cpu);
cpudev = DEVICE(cpu_state); cpudev = DEVICE(cpu_state);
lacpu = LOONGARCH_CPU(cpu_state); lacpu = LOONGARCH_CPU(cpu_state);
env = &(lacpu->env); env = &(lacpu->env);
env->address_space_iocsr = &lams->as_iocsr; env->address_space_iocsr = &lvms->as_iocsr;
/* connect ipi irq to cpu irq */ /* connect ipi irq to cpu irq */
qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI)); qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
@ -726,7 +724,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus); qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.cpus);
sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
memory_region_add_subregion(&lams->system_iocsr, APIC_BASE, memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
/* /*
@ -742,7 +740,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
} }
/* Add Extend I/O Interrupt Controller node */ /* Add Extend I/O Interrupt Controller node */
fdt_add_eiointc_node(lams, &cpuintc_phandle, &eiointc_phandle); fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC); pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
num = VIRT_PCH_PIC_IRQ_NUM; num = VIRT_PCH_PIC_IRQ_NUM;
@ -764,7 +762,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
} }
/* Add PCH PIC node */ /* Add PCH PIC node */
fdt_add_pch_pic_node(lams, &eiointc_phandle, &pch_pic_phandle); fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI); pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
start = num; start = num;
@ -781,30 +779,30 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
} }
/* Add PCH MSI node */ /* Add PCH MSI node */
fdt_add_pch_msi_node(lams, &eiointc_phandle, &pch_msi_phandle); fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
loongarch_devices_init(pch_pic, lams, &pch_pic_phandle, &pch_msi_phandle); virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle);
} }
static void loongarch_firmware_init(LoongArchMachineState *lams) static void virt_firmware_init(LoongArchVirtMachineState *lvms)
{ {
char *filename = MACHINE(lams)->firmware; char *filename = MACHINE(lvms)->firmware;
char *bios_name = NULL; char *bios_name = NULL;
int bios_size, i; int bios_size, i;
BlockBackend *pflash_blk0; BlockBackend *pflash_blk0;
MemoryRegion *mr; MemoryRegion *mr;
lams->bios_loaded = false; lvms->bios_loaded = false;
/* Map legacy -drive if=pflash to machine properties */ /* Map legacy -drive if=pflash to machine properties */
for (i = 0; i < ARRAY_SIZE(lams->flash); i++) { for (i = 0; i < ARRAY_SIZE(lvms->flash); i++) {
pflash_cfi01_legacy_drive(lams->flash[i], pflash_cfi01_legacy_drive(lvms->flash[i],
drive_get(IF_PFLASH, 0, i)); drive_get(IF_PFLASH, 0, i));
} }
virt_flash_map(lams, get_system_memory()); virt_flash_map(lvms, get_system_memory());
pflash_blk0 = pflash_cfi01_get_blk(lams->flash[0]); pflash_blk0 = pflash_cfi01_get_blk(lvms->flash[0]);
if (pflash_blk0) { if (pflash_blk0) {
if (filename) { if (filename) {
@ -812,7 +810,7 @@ static void loongarch_firmware_init(LoongArchMachineState *lams)
"options at once"); "options at once");
exit(1); exit(1);
} }
lams->bios_loaded = true; lvms->bios_loaded = true;
return; return;
} }
@ -823,24 +821,24 @@ static void loongarch_firmware_init(LoongArchMachineState *lams)
exit(1); exit(1);
} }
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lams->flash[0]), 0); mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lvms->flash[0]), 0);
bios_size = load_image_mr(bios_name, mr); bios_size = load_image_mr(bios_name, mr);
if (bios_size < 0) { if (bios_size < 0) {
error_report("Could not load ROM image '%s'", bios_name); error_report("Could not load ROM image '%s'", bios_name);
exit(1); exit(1);
} }
g_free(bios_name); g_free(bios_name);
lams->bios_loaded = true; lvms->bios_loaded = true;
} }
} }
static void loongarch_qemu_write(void *opaque, hwaddr addr, static void virt_iocsr_misc_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size) uint64_t val, unsigned size)
{ {
} }
static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size) static uint64_t virt_iocsr_misc_read(void *opaque, hwaddr addr, unsigned size)
{ {
switch (addr) { switch (addr) {
case VERSION_REG: case VERSION_REG:
@ -858,9 +856,9 @@ static uint64_t loongarch_qemu_read(void *opaque, hwaddr addr, unsigned size)
return 0ULL; return 0ULL;
} }
static const MemoryRegionOps loongarch_qemu_ops = { static const MemoryRegionOps virt_iocsr_misc_ops = {
.read = loongarch_qemu_read, .read = virt_iocsr_misc_read,
.write = loongarch_qemu_write, .write = virt_iocsr_misc_write,
.endianness = DEVICE_LITTLE_ENDIAN, .endianness = DEVICE_LITTLE_ENDIAN,
.valid = { .valid = {
.min_access_size = 4, .min_access_size = 4,
@ -872,7 +870,7 @@ static const MemoryRegionOps loongarch_qemu_ops = {
}, },
}; };
static void loongarch_init(MachineState *machine) static void virt_init(MachineState *machine)
{ {
LoongArchCPU *lacpu; LoongArchCPU *lacpu;
const char *cpu_model = machine->cpu_type; const char *cpu_model = machine->cpu_type;
@ -880,14 +878,13 @@ static void loongarch_init(MachineState *machine)
ram_addr_t ram_size = machine->ram_size; ram_addr_t ram_size = machine->ram_size;
uint64_t highram_size = 0, phyAddr = 0; uint64_t highram_size = 0, phyAddr = 0;
MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *address_space_mem = get_system_memory();
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
int nb_numa_nodes = machine->numa_state->num_nodes; int nb_numa_nodes = machine->numa_state->num_nodes;
NodeInfo *numa_info = machine->numa_state->nodes; NodeInfo *numa_info = machine->numa_state->nodes;
int i; int i;
const CPUArchIdList *possible_cpus; const CPUArchIdList *possible_cpus;
MachineClass *mc = MACHINE_GET_CLASS(machine); MachineClass *mc = MACHINE_GET_CLASS(machine);
CPUState *cpu; CPUState *cpu;
char *ramName = NULL;
if (!cpu_model) { if (!cpu_model) {
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
@ -897,16 +894,16 @@ static void loongarch_init(MachineState *machine)
error_report("ram_size must be greater than 1G."); error_report("ram_size must be greater than 1G.");
exit(1); exit(1);
} }
create_fdt(lams); create_fdt(lvms);
/* Create IOCSR space */ /* Create IOCSR space */
memory_region_init_io(&lams->system_iocsr, OBJECT(machine), NULL, memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL,
machine, "iocsr", UINT64_MAX); machine, "iocsr", UINT64_MAX);
address_space_init(&lams->as_iocsr, &lams->system_iocsr, "IOCSR"); address_space_init(&lvms->as_iocsr, &lvms->system_iocsr, "IOCSR");
memory_region_init_io(&lams->iocsr_mem, OBJECT(machine), memory_region_init_io(&lvms->iocsr_mem, OBJECT(machine),
&loongarch_qemu_ops, &virt_iocsr_misc_ops,
machine, "iocsr_misc", 0x428); machine, "iocsr_misc", 0x428);
memory_region_add_subregion(&lams->system_iocsr, 0, &lams->iocsr_mem); memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
/* Init CPUs */ /* Init CPUs */
possible_cpus = mc->possible_cpu_arch_ids(machine); possible_cpus = mc->possible_cpu_arch_ids(machine);
@ -917,14 +914,14 @@ static void loongarch_init(MachineState *machine)
lacpu = LOONGARCH_CPU(cpu); lacpu = LOONGARCH_CPU(cpu);
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id; lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
} }
fdt_add_cpu_nodes(lams); fdt_add_cpu_nodes(lvms);
/* Node0 memory */ /* Node0 memory */
memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1); memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0); fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0);
memory_region_init_alias(&lams->lowmem, NULL, "loongarch.node0.lowram", memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.node0.lowram",
machine->ram, offset, VIRT_LOWMEM_SIZE); machine->ram, offset, VIRT_LOWMEM_SIZE);
memory_region_add_subregion(address_space_mem, phyAddr, &lams->lowmem); memory_region_add_subregion(address_space_mem, phyAddr, &lvms->lowmem);
offset += VIRT_LOWMEM_SIZE; offset += VIRT_LOWMEM_SIZE;
if (nb_numa_nodes > 0) { if (nb_numa_nodes > 0) {
@ -936,9 +933,9 @@ static void loongarch_init(MachineState *machine)
phyAddr = VIRT_HIGHMEM_BASE; phyAddr = VIRT_HIGHMEM_BASE;
memmap_add_entry(phyAddr, highram_size, 1); memmap_add_entry(phyAddr, highram_size, 1);
fdt_add_memory_node(machine, phyAddr, highram_size, 0); fdt_add_memory_node(machine, phyAddr, highram_size, 0);
memory_region_init_alias(&lams->highmem, NULL, "loongarch.node0.highram", memory_region_init_alias(&lvms->highmem, NULL, "loongarch.node0.highram",
machine->ram, offset, highram_size); machine->ram, offset, highram_size);
memory_region_add_subregion(address_space_mem, phyAddr, &lams->highmem); memory_region_add_subregion(address_space_mem, phyAddr, &lvms->highmem);
/* Node1 - Nodemax memory */ /* Node1 - Nodemax memory */
offset += highram_size; offset += highram_size;
@ -946,7 +943,7 @@ static void loongarch_init(MachineState *machine)
for (i = 1; i < nb_numa_nodes; i++) { for (i = 1; i < nb_numa_nodes; i++) {
MemoryRegion *nodemem = g_new(MemoryRegion, 1); MemoryRegion *nodemem = g_new(MemoryRegion, 1);
ramName = g_strdup_printf("loongarch.node%d.ram", i); g_autofree char *ramName = g_strdup_printf("loongarch.node%d.ram", i);
memory_region_init_alias(nodemem, NULL, ramName, machine->ram, memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
offset, numa_info[i].node_mem); offset, numa_info[i].node_mem);
memory_region_add_subregion(address_space_mem, phyAddr, nodemem); memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
@ -979,30 +976,30 @@ static void loongarch_init(MachineState *machine)
} }
/* load the BIOS image. */ /* load the BIOS image. */
loongarch_firmware_init(lams); virt_firmware_init(lvms);
/* fw_cfg init */ /* fw_cfg init */
lams->fw_cfg = loongarch_fw_cfg_init(ram_size, machine); lvms->fw_cfg = virt_fw_cfg_init(ram_size, machine);
rom_set_fw(lams->fw_cfg); rom_set_fw(lvms->fw_cfg);
if (lams->fw_cfg != NULL) { if (lvms->fw_cfg != NULL) {
fw_cfg_add_file(lams->fw_cfg, "etc/memmap", fw_cfg_add_file(lvms->fw_cfg, "etc/memmap",
memmap_table, memmap_table,
sizeof(struct memmap_entry) * (memmap_entries)); sizeof(struct memmap_entry) * (memmap_entries));
} }
fdt_add_fw_cfg_node(lams); fdt_add_fw_cfg_node(lvms);
fdt_add_flash_node(lams); fdt_add_flash_node(lvms);
/* Initialize the IO interrupt subsystem */ /* Initialize the IO interrupt subsystem */
loongarch_irq_init(lams); virt_irq_init(lvms);
platform_bus_add_all_fdt_nodes(machine->fdt, "/platic", platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
VIRT_PLATFORM_BUS_BASEADDRESS, VIRT_PLATFORM_BUS_BASEADDRESS,
VIRT_PLATFORM_BUS_SIZE, VIRT_PLATFORM_BUS_SIZE,
VIRT_PLATFORM_BUS_IRQ); VIRT_PLATFORM_BUS_IRQ);
lams->machine_done.notify = virt_machine_done; lvms->machine_done.notify = virt_done;
qemu_add_machine_init_done_notifier(&lams->machine_done); qemu_add_machine_init_done_notifier(&lvms->machine_done);
/* connect powerdown request */ /* connect powerdown request */
lams->powerdown_notifier.notify = virt_powerdown_req; lvms->powerdown_notifier.notify = virt_powerdown_req;
qemu_register_powerdown_notifier(&lams->powerdown_notifier); qemu_register_powerdown_notifier(&lvms->powerdown_notifier);
/* /*
* Since lowmem region starts from 0 and Linux kernel legacy start address * Since lowmem region starts from 0 and Linux kernel legacy start address
@ -1011,49 +1008,41 @@ static void loongarch_init(MachineState *machine)
* Put the FDT into the memory map as a ROM image: this will ensure * Put the FDT into the memory map as a ROM image: this will ensure
* the FDT is copied again upon reset, even if addr points into RAM. * the FDT is copied again upon reset, even if addr points into RAM.
*/ */
qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size); qemu_fdt_dumpdtb(machine->fdt, lvms->fdt_size);
rom_add_blob_fixed_as("fdt", machine->fdt, lams->fdt_size, FDT_BASE, rom_add_blob_fixed_as("fdt", machine->fdt, lvms->fdt_size, FDT_BASE,
&address_space_memory); &address_space_memory);
qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds, qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
rom_ptr_for_as(&address_space_memory, FDT_BASE, lams->fdt_size)); rom_ptr_for_as(&address_space_memory, FDT_BASE, lvms->fdt_size));
lams->bootinfo.ram_size = ram_size; lvms->bootinfo.ram_size = ram_size;
loongarch_load_kernel(machine, &lams->bootinfo); loongarch_load_kernel(machine, &lvms->bootinfo);
} }
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams) static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{ {
if (lams->acpi == ON_OFF_AUTO_OFF) { LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
return false; OnOffAuto acpi = lvms->acpi;
}
return true;
}
static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
OnOffAuto acpi = lams->acpi;
visit_type_OnOffAuto(v, name, &acpi, errp); visit_type_OnOffAuto(v, name, &acpi, errp);
} }
static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name, static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp) void *opaque, Error **errp)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
visit_type_OnOffAuto(v, name, &lams->acpi, errp); visit_type_OnOffAuto(v, name, &lvms->acpi, errp);
} }
static void loongarch_machine_initfn(Object *obj) static void virt_initfn(Object *obj)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(obj); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
lams->acpi = ON_OFF_AUTO_AUTO; lvms->acpi = ON_OFF_AUTO_AUTO;
lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); lvms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); lvms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
virt_flash_create(lams); virt_flash_create(lvms);
} }
static bool memhp_type_supported(DeviceState *dev) static bool memhp_type_supported(DeviceState *dev)
@ -1069,7 +1058,7 @@ static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp); pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
} }
static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev, static void virt_device_pre_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
if (memhp_type_supported(dev)) { if (memhp_type_supported(dev)) {
@ -1080,14 +1069,14 @@ static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev,
static void virt_mem_unplug_request(HotplugHandler *hotplug_dev, static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
/* the acpi ged is always exist */ /* the acpi ged is always exist */
hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev, hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
errp); errp);
} }
static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev, static void virt_device_unplug_request(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
if (memhp_type_supported(dev)) { if (memhp_type_supported(dev)) {
@ -1098,14 +1087,14 @@ static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev,
static void virt_mem_unplug(HotplugHandler *hotplug_dev, static void virt_mem_unplug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp); hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp);
pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams)); pc_dimm_unplug(PC_DIMM(dev), MACHINE(lvms));
qdev_unrealize(dev); qdev_unrealize(dev);
} }
static void virt_machine_device_unplug(HotplugHandler *hotplug_dev, static void virt_device_unplug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
if (memhp_type_supported(dev)) { if (memhp_type_supported(dev)) {
@ -1116,31 +1105,32 @@ static void virt_machine_device_unplug(HotplugHandler *hotplug_dev,
static void virt_mem_plug(HotplugHandler *hotplug_dev, static void virt_mem_plug(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
pc_dimm_plug(PC_DIMM(dev), MACHINE(lams)); pc_dimm_plug(PC_DIMM(dev), MACHINE(lvms));
hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged), hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged),
dev, &error_abort); dev, &error_abort);
} }
static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev, static void virt_device_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp) DeviceState *dev, Error **errp)
{ {
LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev); LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
MachineClass *mc = MACHINE_GET_CLASS(lams); MachineClass *mc = MACHINE_GET_CLASS(lvms);
PlatformBusDevice *pbus;
if (device_is_dynamic_sysbus(mc, dev)) { if (device_is_dynamic_sysbus(mc, dev)) {
if (lams->platform_bus_dev) { if (lvms->platform_bus_dev) {
platform_bus_link_device(PLATFORM_BUS_DEVICE(lams->platform_bus_dev), pbus = PLATFORM_BUS_DEVICE(lvms->platform_bus_dev);
SYS_BUS_DEVICE(dev)); platform_bus_link_device(pbus, SYS_BUS_DEVICE(dev));
} }
} else if (memhp_type_supported(dev)) { } else if (memhp_type_supported(dev)) {
virt_mem_plug(hotplug_dev, dev, errp); virt_mem_plug(hotplug_dev, dev, errp);
} }
} }
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
DeviceState *dev) DeviceState *dev)
{ {
MachineClass *mc = MACHINE_GET_CLASS(machine); MachineClass *mc = MACHINE_GET_CLASS(machine);
@ -1180,8 +1170,8 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
return ms->possible_cpus; return ms->possible_cpus;
} }
static CpuInstanceProperties static CpuInstanceProperties virt_cpu_index_to_props(MachineState *ms,
virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index) unsigned cpu_index)
{ {
MachineClass *mc = MACHINE_GET_CLASS(ms); MachineClass *mc = MACHINE_GET_CLASS(ms);
const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms); const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
@ -1203,13 +1193,12 @@ static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
return nidx; return nidx;
} }
static void loongarch_class_init(ObjectClass *oc, void *data) static void virt_class_init(ObjectClass *oc, void *data)
{ {
MachineClass *mc = MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc);
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
mc->desc = "Loongson-3A5000 LS7A1000 machine"; mc->init = virt_init;
mc->init = loongarch_init;
mc->default_ram_size = 1 * GiB; mc->default_ram_size = 1 * GiB;
mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464"); mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
mc->default_ram_id = "loongarch.ram"; mc->default_ram_id = "loongarch.ram";
@ -1225,15 +1214,15 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
mc->numa_mem_supported = true; mc->numa_mem_supported = true;
mc->auto_enable_numa_with_memhp = true; mc->auto_enable_numa_with_memhp = true;
mc->auto_enable_numa_with_memdev = true; mc->auto_enable_numa_with_memdev = true;
mc->get_hotplug_handler = virt_machine_get_hotplug_handler; mc->get_hotplug_handler = virt_get_hotplug_handler;
mc->default_nic = "virtio-net-pci"; mc->default_nic = "virtio-net-pci";
hc->plug = loongarch_machine_device_plug_cb; hc->plug = virt_device_plug_cb;
hc->pre_plug = virt_machine_device_pre_plug; hc->pre_plug = virt_device_pre_plug;
hc->unplug_request = virt_machine_device_unplug_request; hc->unplug_request = virt_device_unplug_request;
hc->unplug = virt_machine_device_unplug; hc->unplug = virt_device_unplug;
object_class_property_add(oc, "acpi", "OnOffAuto", object_class_property_add(oc, "acpi", "OnOffAuto",
loongarch_get_acpi, loongarch_set_acpi, virt_get_acpi, virt_set_acpi,
NULL, NULL); NULL, NULL);
object_class_property_set_description(oc, "acpi", object_class_property_set_description(oc, "acpi",
"Enable ACPI"); "Enable ACPI");
@ -1243,13 +1232,13 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
#endif #endif
} }
static const TypeInfo loongarch_machine_types[] = { static const TypeInfo virt_machine_types[] = {
{ {
.name = TYPE_LOONGARCH_MACHINE, .name = TYPE_LOONGARCH_VIRT_MACHINE,
.parent = TYPE_MACHINE, .parent = TYPE_MACHINE,
.instance_size = sizeof(LoongArchMachineState), .instance_size = sizeof(LoongArchVirtMachineState),
.class_init = loongarch_class_init, .class_init = virt_class_init,
.instance_init = loongarch_machine_initfn, .instance_init = virt_initfn,
.interfaces = (InterfaceInfo[]) { .interfaces = (InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER }, { TYPE_HOTPLUG_HANDLER },
{ } { }
@ -1257,4 +1246,4 @@ static const TypeInfo loongarch_machine_types[] = {
} }
}; };
DEFINE_TYPES(loongarch_machine_types) DEFINE_TYPES(virt_machine_types)

View File

@ -148,4 +148,5 @@ void init_reset_system(struct efi_reset_system_t *reset)
reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8); reset->Shutdown = cpu_to_le64(0xffffffffbfc000a8);
reset->ResetCold = cpu_to_le64(0xffffffffbfc00080); reset->ResetCold = cpu_to_le64(0xffffffffbfc00080);
reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080); reset->ResetWarm = cpu_to_le64(0xffffffffbfc00080);
reset->DoSuspend = cpu_to_le64(0xffffffffbfc000d0);
} }

View File

@ -127,6 +127,9 @@ static void loongson3_pm_write(void *opaque, hwaddr addr,
case 0x00: case 0x00:
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
return; return;
case 0x01:
qemu_system_suspend_request();
return;
case 0xff: case 0xff:
qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
return; return;
@ -250,6 +253,17 @@ static void init_boot_rom(void)
0x240D00FF, /* li t1, 0xff */ 0x240D00FF, /* li t1, 0xff */
0xA18D0000, /* sb t1, (t0) */ 0xA18D0000, /* sb t1, (t0) */
0x1000FFFF, /* 1: b 1b */ 0x1000FFFF, /* 1: b 1b */
0x00000000, /* nop */
/* Suspend */
0x3C0C9000, /* dli t0, 0x9000000010080010 */
0x358C0000,
0x000C6438,
0x358C1008,
0x000C6438,
0x358C0010,
0x240D0001, /* li t1, 0x01 */
0xA18D0000, /* sb t1, (t0) */
0x03e00008, /* jr ra */
0x00000000 /* nop */ 0x00000000 /* nop */
}; };
@ -265,6 +279,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device,
static void fw_conf_init(unsigned long ram_size) static void fw_conf_init(unsigned long ram_size)
{ {
static const uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};
FWCfgState *fw_cfg; FWCfgState *fw_cfg;
hwaddr cfg_addr = virt_memmap[VIRT_FW_CFG].base; hwaddr cfg_addr = virt_memmap[VIRT_FW_CFG].base;
@ -274,6 +289,10 @@ static void fw_conf_init(unsigned long ram_size)
fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1); fw_cfg_add_i32(fw_cfg, FW_CFG_MACHINE_VERSION, 1);
fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz()); fw_cfg_add_i64(fw_cfg, FW_CFG_CPU_FREQ, get_cpu_freq_hz());
fw_cfg_add_file(fw_cfg, "etc/system-states",
g_memdup2(suspend, sizeof(suspend)), sizeof(suspend));
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
} }
@ -553,6 +572,7 @@ static void mips_loongson3_virt_init(MachineState *machine)
machine->ram, 0, virt_memmap[VIRT_LOWMEM].size); machine->ram, 0, virt_memmap[VIRT_LOWMEM].size);
memory_region_init_io(iomem, NULL, &loongson3_pm_ops, memory_region_init_io(iomem, NULL, &loongson3_pm_ops,
NULL, "loongson3_pm", virt_memmap[VIRT_PM].size); NULL, "loongson3_pm", virt_memmap[VIRT_PM].size);
qemu_register_wakeup_support();
memory_region_add_subregion(address_space_mem, memory_region_add_subregion(address_space_mem,
virt_memmap[VIRT_LOWMEM].base, ram); virt_memmap[VIRT_LOWMEM].base, ram);

View File

@ -350,6 +350,7 @@ static void ppc405_machine_class_init(ObjectClass *oc, void *data)
mc->init = ppc405_init; mc->init = ppc405_init;
mc->default_ram_size = 128 * MiB; mc->default_ram_size = 128 * MiB;
mc->default_ram_id = "ppc405.ram"; mc->default_ram_id = "ppc405.ram";
mc->deprecation_reason = "machine is old and unmaintained";
} }
static const TypeInfo ppc405_machine_type = { static const TypeInfo ppc405_machine_type = {

View File

@ -2188,10 +2188,9 @@ static int spapr_pci_post_load(void *opaque, int version_id)
int i; int i;
for (i = 0; i < sphb->msi_devs_num; ++i) { for (i = 0; i < sphb->msi_devs_num; ++i) {
key = g_memdup(&sphb->msi_devs[i].key, key = g_memdup2(&sphb->msi_devs[i].key, sizeof(sphb->msi_devs[i].key));
sizeof(sphb->msi_devs[i].key)); value = g_memdup2(&sphb->msi_devs[i].value,
value = g_memdup(&sphb->msi_devs[i].value, sizeof(sphb->msi_devs[i].value));
sizeof(sphb->msi_devs[i].value));
g_hash_table_insert(sphb->msi, key, value); g_hash_table_insert(sphb->msi, key, value);
} }
g_free(sphb->msi_devs); g_free(sphb->msi_devs);

View File

@ -281,7 +281,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf,
while (bytes > 0) { while (bytes > 0) {
len = (bytes > pci_access_width) ? pci_access_width : bytes; len = (bytes > pci_access_width) ? pci_access_width : bytes;
if (is_write) { if (is_write) {
memcpy(&val, ptr, len); val = ldn_le_p(ptr, len);
pci_host_config_write_common(o->pci_dev, offset, pci_host_config_write_common(o->pci_dev, offset,
pci_config_size(o->pci_dev), pci_config_size(o->pci_dev),
val, len); val, len);
@ -289,7 +289,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf,
} else { } else {
val = pci_host_config_read_common(o->pci_dev, offset, val = pci_host_config_read_common(o->pci_dev, offset,
pci_config_size(o->pci_dev), len); pci_config_size(o->pci_dev), len);
memcpy(ptr, &val, len); stn_le_p(ptr, len, val);
trace_vfu_cfg_read(offset, val); trace_vfu_cfg_read(offset, val);
} }
offset += len; offset += len;

View File

@ -8,7 +8,7 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
#include "hw/irq.h" #include "hw/irq.h"
#include "include/hw/register.h" #include "hw/register.h"
#include "qemu/timer.h" #include "qemu/timer.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"

View File

@ -475,14 +475,6 @@ struct rndis_packet_msg_type {
le32 Reserved; le32 Reserved;
}; };
struct rndis_config_parameter {
le32 ParameterNameOffset;
le32 ParameterNameLength;
le32 ParameterType;
le32 ParameterValueOffset;
le32 ParameterValueLength;
};
/* implementation specific */ /* implementation specific */
enum rndis_state enum rndis_state
{ {

View File

@ -147,8 +147,6 @@ void *cpu_physical_memory_map(hwaddr addr,
bool is_write); bool is_write);
void cpu_physical_memory_unmap(void *buffer, hwaddr len, void cpu_physical_memory_unmap(void *buffer, hwaddr len,
bool is_write, hwaddr access_len); bool is_write, hwaddr access_len);
void cpu_register_map_client(QEMUBH *bh);
void cpu_unregister_map_client(QEMUBH *bh);
bool cpu_physical_memory_is_io(hwaddr phys_addr); bool cpu_physical_memory_is_io(hwaddr phys_addr);

View File

@ -1112,6 +1112,19 @@ struct MemoryListener {
QTAILQ_ENTRY(MemoryListener) link_as; QTAILQ_ENTRY(MemoryListener) link_as;
}; };
typedef struct AddressSpaceMapClient {
QEMUBH *bh;
QLIST_ENTRY(AddressSpaceMapClient) link;
} AddressSpaceMapClient;
typedef struct {
MemoryRegion *mr;
void *buffer;
hwaddr addr;
hwaddr len;
bool in_use;
} BounceBuffer;
/** /**
* struct AddressSpace: describes a mapping of addresses to #MemoryRegion objects * struct AddressSpace: describes a mapping of addresses to #MemoryRegion objects
*/ */
@ -1129,6 +1142,12 @@ struct AddressSpace {
struct MemoryRegionIoeventfd *ioeventfds; struct MemoryRegionIoeventfd *ioeventfds;
QTAILQ_HEAD(, MemoryListener) listeners; QTAILQ_HEAD(, MemoryListener) listeners;
QTAILQ_ENTRY(AddressSpace) address_spaces_link; QTAILQ_ENTRY(AddressSpace) address_spaces_link;
/* Bounce buffer to use for this address space. */
BounceBuffer bounce;
/* List of callbacks to invoke when buffers free up */
QemuMutex map_client_list_lock;
QLIST_HEAD(, AddressSpaceMapClient) map_client_list;
}; };
typedef struct AddressSpaceDispatch AddressSpaceDispatch; typedef struct AddressSpaceDispatch AddressSpaceDispatch;
@ -2946,8 +2965,8 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, hwaddr len,
* May return %NULL and set *@plen to zero(0), if resources needed to perform * May return %NULL and set *@plen to zero(0), if resources needed to perform
* the mapping are exhausted. * the mapping are exhausted.
* Use only for reads OR writes - not for read-modify-write operations. * Use only for reads OR writes - not for read-modify-write operations.
* Use cpu_register_map_client() to know when retrying the map operation is * Use address_space_register_map_client() to know when retrying the map
* likely to succeed. * operation is likely to succeed.
* *
* @as: #AddressSpace to be accessed * @as: #AddressSpace to be accessed
* @addr: address within that address space * @addr: address within that address space
@ -2972,6 +2991,28 @@ void *address_space_map(AddressSpace *as, hwaddr addr,
void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
bool is_write, hwaddr access_len); bool is_write, hwaddr access_len);
/*
* address_space_register_map_client: Register a callback to invoke when
* resources for address_space_map() are available again.
*
* address_space_map may fail when there are not enough resources available,
* such as when bounce buffer memory would exceed the limit. The callback can
* be used to retry the address_space_map operation. Note that the callback
* gets automatically removed after firing.
*
* @as: #AddressSpace to be accessed
* @bh: callback to invoke when address_space_map() retry is appropriate
*/
void address_space_register_map_client(AddressSpace *as, QEMUBH *bh);
/*
* address_space_unregister_map_client: Unregister a callback that has
* previously been registered and not fired yet.
*
* @as: #AddressSpace to be accessed
* @bh: callback to unregister
*/
void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh);
/* Internal functions, part of the implementation of address_space_read. */ /* Internal functions, part of the implementation of address_space_read. */
MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,

View File

@ -18,6 +18,7 @@
#define HW_I386_X86_H #define HW_I386_X86_H
#include "exec/hwaddr.h" #include "exec/hwaddr.h"
#include "exec/memory.h"
#include "hw/boards.h" #include "hw/boards.h"
#include "hw/intc/ioapic.h" #include "hw/intc/ioapic.h"
@ -52,6 +53,18 @@ struct X86MachineState {
GMappedFile *initrd_mapped_file; GMappedFile *initrd_mapped_file;
HotplugHandler *acpi_dev; HotplugHandler *acpi_dev;
/*
* Map the whole BIOS just underneath the 4 GiB address boundary. Only used
* in the ROM (-bios) case.
*/
MemoryRegion bios;
/*
* Map the upper 128 KiB of the BIOS just underneath the 1 MiB address
* boundary.
*/
MemoryRegion isa_bios;
/* RAM information (sizes, addresses, configuration): */ /* RAM information (sizes, addresses, configuration): */
ram_addr_t below_4g_mem_size, above_4g_mem_size; ram_addr_t below_4g_mem_size, above_4g_mem_size;
@ -116,7 +129,9 @@ void x86_cpu_unplug_request_cb(HotplugHandler *hotplug_dev,
void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev, void x86_cpu_unplug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp); DeviceState *dev, Error **errp);
void x86_bios_rom_init(MachineState *ms, const char *default_firmware, void x86_isa_bios_init(MemoryRegion *isa_bios, MemoryRegion *isa_memory,
MemoryRegion *bios, bool read_only);
void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware,
MemoryRegion *rom_memory, bool isapc_ram_fw); MemoryRegion *rom_memory, bool isapc_ram_fw);
void x86_load_linux(X86MachineState *x86ms, void x86_load_linux(X86MachineState *x86ms,

View File

@ -1,12 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */ /* SPDX-License-Identifier: GPL-2.0-or-later */
/* /*
* LoongArch ipi interrupt header files * Loongson ipi interrupt header files
* *
* Copyright (C) 2021 Loongson Technology Corporation Limited * Copyright (C) 2021 Loongson Technology Corporation Limited
*/ */
#ifndef HW_LOONGARCH_IPI_H #ifndef HW_LOONGSON_IPI_H
#define HW_LOONGARCH_IPI_H #define HW_LOONGSON_IPI_H
#include "hw/sysbus.h" #include "hw/sysbus.h"
@ -30,8 +30,8 @@
#define IPI_MBX_NUM 4 #define IPI_MBX_NUM 4
#define TYPE_LOONGARCH_IPI "loongarch_ipi" #define TYPE_LOONGSON_IPI "loongson_ipi"
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI) OBJECT_DECLARE_SIMPLE_TYPE(LoongsonIPI, LOONGSON_IPI)
typedef struct IPICore { typedef struct IPICore {
uint32_t status; uint32_t status;
@ -43,7 +43,7 @@ typedef struct IPICore {
qemu_irq irq; qemu_irq irq;
} IPICore; } IPICore;
struct LoongArchIPI { struct LoongsonIPI {
SysBusDevice parent_obj; SysBusDevice parent_obj;
MemoryRegion ipi_iocsr_mem; MemoryRegion ipi_iocsr_mem;
MemoryRegion ipi64_iocsr_mem; MemoryRegion ipi64_iocsr_mem;

View File

@ -104,6 +104,16 @@ struct loongarch_boot_info {
uint64_t a0, a1, a2; uint64_t a0, a1, a2;
}; };
extern struct memmap_entry *memmap_table;
extern unsigned memmap_entries;
struct memmap_entry {
uint64_t address;
uint64_t length;
uint32_t type;
uint32_t reserved;
};
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info); void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info);
#endif /* HW_LOONGARCH_BOOT_H */ #endif /* HW_LOONGARCH_BOOT_H */

View File

@ -11,7 +11,7 @@
#include "target/loongarch/cpu.h" #include "target/loongarch/cpu.h"
#include "hw/boards.h" #include "hw/boards.h"
#include "qemu/queue.h" #include "qemu/queue.h"
#include "hw/intc/loongarch_ipi.h" #include "hw/intc/loongson_ipi.h"
#include "hw/block/flash.h" #include "hw/block/flash.h"
#include "hw/loongarch/boot.h" #include "hw/loongarch/boot.h"
@ -37,17 +37,7 @@
#define FDT_BASE 0x100000 #define FDT_BASE 0x100000
extern struct memmap_entry *memmap_table; struct LoongArchVirtMachineState {
extern unsigned memmap_entries;
struct memmap_entry {
uint64_t address;
uint64_t length;
uint32_t type;
uint32_t reserved;
};
struct LoongArchMachineState {
/*< private >*/ /*< private >*/
MachineState parent_obj; MachineState parent_obj;
@ -73,8 +63,7 @@ struct LoongArchMachineState {
struct loongarch_boot_info bootinfo; struct loongarch_boot_info bootinfo;
}; };
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt") #define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE) OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams); void loongarch_acpi_setup(LoongArchVirtMachineState *lvms);
void loongarch_acpi_setup(LoongArchMachineState *lams);
#endif #endif

View File

@ -169,7 +169,7 @@ static void dma_blk_cb(void *opaque, int ret)
if (dbs->iov.size == 0) { if (dbs->iov.size == 0) {
trace_dma_map_wait(dbs); trace_dma_map_wait(dbs);
dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs); dbs->bh = aio_bh_new(ctx, reschedule_dma, dbs);
cpu_register_map_client(dbs->bh); address_space_register_map_client(dbs->sg->as, dbs->bh);
return; return;
} }
@ -197,7 +197,7 @@ static void dma_aio_cancel(BlockAIOCB *acb)
} }
if (dbs->bh) { if (dbs->bh) {
cpu_unregister_map_client(dbs->bh); address_space_unregister_map_client(dbs->sg->as, dbs->bh);
qemu_bh_delete(dbs->bh); qemu_bh_delete(dbs->bh);
dbs->bh = NULL; dbs->bh = NULL;
} }

View File

@ -3174,6 +3174,9 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
as->ioeventfds = NULL; as->ioeventfds = NULL;
QTAILQ_INIT(&as->listeners); QTAILQ_INIT(&as->listeners);
QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link); QTAILQ_INSERT_TAIL(&address_spaces, as, address_spaces_link);
as->bounce.in_use = false;
qemu_mutex_init(&as->map_client_list_lock);
QLIST_INIT(&as->map_client_list);
as->name = g_strdup(name ? name : "anonymous"); as->name = g_strdup(name ? name : "anonymous");
address_space_update_topology(as); address_space_update_topology(as);
address_space_update_ioeventfds(as); address_space_update_ioeventfds(as);
@ -3181,6 +3184,10 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
static void do_address_space_destroy(AddressSpace *as) static void do_address_space_destroy(AddressSpace *as)
{ {
assert(!qatomic_read(&as->bounce.in_use));
assert(QLIST_EMPTY(&as->map_client_list));
qemu_mutex_destroy(&as->map_client_list_lock);
assert(QTAILQ_EMPTY(&as->listeners)); assert(QTAILQ_EMPTY(&as->listeners));
flatview_unref(as->current_map); flatview_unref(as->current_map);

View File

@ -25,6 +25,7 @@
#include "qemu/cacheflush.h" #include "qemu/cacheflush.h"
#include "qemu/hbitmap.h" #include "qemu/hbitmap.h"
#include "qemu/madvise.h" #include "qemu/madvise.h"
#include "qemu/lockable.h"
#ifdef CONFIG_TCG #ifdef CONFIG_TCG
#include "hw/core/tcg-cpu-ops.h" #include "hw/core/tcg-cpu-ops.h"
@ -3046,55 +3047,36 @@ void cpu_flush_icache_range(hwaddr start, hwaddr len)
NULL, len, FLUSH_CACHE); NULL, len, FLUSH_CACHE);
} }
typedef struct { static void
MemoryRegion *mr; address_space_unregister_map_client_do(AddressSpaceMapClient *client)
void *buffer;
hwaddr addr;
hwaddr len;
bool in_use;
} BounceBuffer;
static BounceBuffer bounce;
typedef struct MapClient {
QEMUBH *bh;
QLIST_ENTRY(MapClient) link;
} MapClient;
QemuMutex map_client_list_lock;
static QLIST_HEAD(, MapClient) map_client_list
= QLIST_HEAD_INITIALIZER(map_client_list);
static void cpu_unregister_map_client_do(MapClient *client)
{ {
QLIST_REMOVE(client, link); QLIST_REMOVE(client, link);
g_free(client); g_free(client);
} }
static void cpu_notify_map_clients_locked(void) static void address_space_notify_map_clients_locked(AddressSpace *as)
{ {
MapClient *client; AddressSpaceMapClient *client;
while (!QLIST_EMPTY(&map_client_list)) { while (!QLIST_EMPTY(&as->map_client_list)) {
client = QLIST_FIRST(&map_client_list); client = QLIST_FIRST(&as->map_client_list);
qemu_bh_schedule(client->bh); qemu_bh_schedule(client->bh);
cpu_unregister_map_client_do(client); address_space_unregister_map_client_do(client);
} }
} }
void cpu_register_map_client(QEMUBH *bh) void address_space_register_map_client(AddressSpace *as, QEMUBH *bh)
{ {
MapClient *client = g_malloc(sizeof(*client)); AddressSpaceMapClient *client = g_malloc(sizeof(*client));
qemu_mutex_lock(&map_client_list_lock); QEMU_LOCK_GUARD(&as->map_client_list_lock);
client->bh = bh; client->bh = bh;
QLIST_INSERT_HEAD(&map_client_list, client, link); QLIST_INSERT_HEAD(&as->map_client_list, client, link);
/* Write map_client_list before reading in_use. */ /* Write map_client_list before reading in_use. */
smp_mb(); smp_mb();
if (!qatomic_read(&bounce.in_use)) { if (!qatomic_read(&as->bounce.in_use)) {
cpu_notify_map_clients_locked(); address_space_notify_map_clients_locked(as);
} }
qemu_mutex_unlock(&map_client_list_lock);
} }
void cpu_exec_init_all(void) void cpu_exec_init_all(void)
@ -3110,28 +3092,25 @@ void cpu_exec_init_all(void)
finalize_target_page_bits(); finalize_target_page_bits();
io_mem_init(); io_mem_init();
memory_map_init(); memory_map_init();
qemu_mutex_init(&map_client_list_lock);
} }
void cpu_unregister_map_client(QEMUBH *bh) void address_space_unregister_map_client(AddressSpace *as, QEMUBH *bh)
{ {
MapClient *client; AddressSpaceMapClient *client;
qemu_mutex_lock(&map_client_list_lock); QEMU_LOCK_GUARD(&as->map_client_list_lock);
QLIST_FOREACH(client, &map_client_list, link) { QLIST_FOREACH(client, &as->map_client_list, link) {
if (client->bh == bh) { if (client->bh == bh) {
cpu_unregister_map_client_do(client); address_space_unregister_map_client_do(client);
break; break;
} }
} }
qemu_mutex_unlock(&map_client_list_lock);
} }
static void cpu_notify_map_clients(void) static void address_space_notify_map_clients(AddressSpace *as)
{ {
qemu_mutex_lock(&map_client_list_lock); QEMU_LOCK_GUARD(&as->map_client_list_lock);
cpu_notify_map_clients_locked(); address_space_notify_map_clients_locked(as);
qemu_mutex_unlock(&map_client_list_lock);
} }
static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len, static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len,
@ -3198,8 +3177,8 @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
* May map a subset of the requested range, given by and returned in *plen. * May map a subset of the requested range, given by and returned in *plen.
* May return NULL if resources needed to perform the mapping are exhausted. * May return NULL if resources needed to perform the mapping are exhausted.
* Use only for reads OR writes - not for read-modify-write operations. * Use only for reads OR writes - not for read-modify-write operations.
* Use cpu_register_map_client() to know when retrying the map operation is * Use address_space_register_map_client() to know when retrying the map
* likely to succeed. * operation is likely to succeed.
*/ */
void *address_space_map(AddressSpace *as, void *address_space_map(AddressSpace *as,
hwaddr addr, hwaddr addr,
@ -3222,25 +3201,25 @@ void *address_space_map(AddressSpace *as,
mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs); mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
if (!memory_access_is_direct(mr, is_write)) { if (!memory_access_is_direct(mr, is_write)) {
if (qatomic_xchg(&bounce.in_use, true)) { if (qatomic_xchg(&as->bounce.in_use, true)) {
*plen = 0; *plen = 0;
return NULL; return NULL;
} }
/* Avoid unbounded allocations */ /* Avoid unbounded allocations */
l = MIN(l, TARGET_PAGE_SIZE); l = MIN(l, TARGET_PAGE_SIZE);
bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l); as->bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);
bounce.addr = addr; as->bounce.addr = addr;
bounce.len = l; as->bounce.len = l;
memory_region_ref(mr); memory_region_ref(mr);
bounce.mr = mr; as->bounce.mr = mr;
if (!is_write) { if (!is_write) {
flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED, flatview_read(fv, addr, MEMTXATTRS_UNSPECIFIED,
bounce.buffer, l); as->bounce.buffer, l);
} }
*plen = l; *plen = l;
return bounce.buffer; return as->bounce.buffer;
} }
@ -3258,7 +3237,7 @@ void *address_space_map(AddressSpace *as,
void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
bool is_write, hwaddr access_len) bool is_write, hwaddr access_len)
{ {
if (buffer != bounce.buffer) { if (buffer != as->bounce.buffer) {
MemoryRegion *mr; MemoryRegion *mr;
ram_addr_t addr1; ram_addr_t addr1;
@ -3274,15 +3253,15 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
return; return;
} }
if (is_write) { if (is_write) {
address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED, address_space_write(as, as->bounce.addr, MEMTXATTRS_UNSPECIFIED,
bounce.buffer, access_len); as->bounce.buffer, access_len);
} }
qemu_vfree(bounce.buffer); qemu_vfree(as->bounce.buffer);
bounce.buffer = NULL; as->bounce.buffer = NULL;
memory_region_unref(bounce.mr); memory_region_unref(as->bounce.mr);
/* Clear in_use before reading map_client_list. */ /* Clear in_use before reading map_client_list. */
qatomic_set_mb(&bounce.in_use, false); qatomic_set_mb(&as->bounce.in_use, false);
cpu_notify_map_clients(); address_space_notify_map_clients(as);
} }
void *cpu_physical_memory_map(hwaddr addr, void *cpu_physical_memory_map(hwaddr addr,

View File

@ -19,7 +19,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "cpu.h" #include "cpu.h"
#include "include/gdbstub/helpers.h" #include "gdbstub/helpers.h"
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
static const int gpr_map[16] = { static const int gpr_map[16] = {

View File

@ -1188,7 +1188,7 @@ void ppc_hash64_init(PowerPCCPU *cpu)
return; return;
} }
cpu->hash64_opts = g_memdup(pcc->hash64_opts, sizeof(*cpu->hash64_opts)); cpu->hash64_opts = g_memdup2(pcc->hash64_opts, sizeof(*cpu->hash64_opts));
} }
void ppc_hash64_finalize(PowerPCCPU *cpu) void ppc_hash64_finalize(PowerPCCPU *cpu)

View File

@ -13,7 +13,7 @@
#include "libqtest.h" #include "libqtest.h"
#include "libqos/qgraph.h" #include "libqos/qgraph.h"
#include "libqos/pci.h" #include "libqos/pci.h"
#include "include/block/nvme.h" #include "block/nvme.h"
typedef struct QNvme QNvme; typedef struct QNvme QNvme;

View File

@ -13,7 +13,7 @@
#include "libqos/qgraph.h" #include "libqos/qgraph.h"
#include "libqos/pci.h" #include "libqos/pci.h"
#include "scsi/constants.h" #include "scsi/constants.h"
#include "include/block/ufs.h" #include "block/ufs.h"
/* Test images sizes in Bytes */ /* Test images sizes in Bytes */
#define TEST_IMAGE_SIZE (64 * 1024 * 1024) #define TEST_IMAGE_SIZE (64 * 1024 * 1024)