mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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:
@@ -650,7 +650,7 @@ build-tci:
|
||||
# Check our reduced build configurations
|
||||
# requires libfdt: aarch64, arm, i386, loongarch64, microblaze, microblazeel,
|
||||
# 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:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
|
||||
@@ -1242,7 +1242,9 @@ F: configs/devices/loongarch64-softmmu/default.mak
|
||||
F: hw/loongarch/
|
||||
F: include/hw/loongarch/virt.h
|
||||
F: include/hw/intc/loongarch_*.h
|
||||
F: include/hw/intc/loongson_ipi.h
|
||||
F: hw/intc/loongarch_*.c
|
||||
F: hw/intc/loongson_ipi.c
|
||||
F: include/hw/pci-host/ls7a.h
|
||||
F: hw/rtc/ls7a_rtc.c
|
||||
F: gdb-xml/loongarch*.xml
|
||||
@@ -1376,10 +1378,12 @@ Loongson-3 virtual platforms
|
||||
M: Huacai Chen <chenhuacai@kernel.org>
|
||||
R: Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
S: Maintained
|
||||
F: hw/intc/loongson_ipi.c
|
||||
F: hw/intc/loongson_liointc.c
|
||||
F: hw/mips/loongson3_bootp.c
|
||||
F: hw/mips/loongson3_bootp.h
|
||||
F: hw/mips/loongson3_virt.c
|
||||
F: include/hw/intc/loongson_ipi.h
|
||||
F: include/hw/intc/loongson_liointc.h
|
||||
F: tests/avocado/machine_mips_loongson3v.py
|
||||
|
||||
|
||||
@@ -1609,7 +1609,7 @@ bool qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
|
||||
name);
|
||||
goto fail;
|
||||
}
|
||||
tb = g_memdup(&bm->table, sizeof(bm->table));
|
||||
tb = g_memdup2(&bm->table, sizeof(bm->table));
|
||||
bm->table.offset = 0;
|
||||
bm->table.size = 0;
|
||||
QSIMPLEQ_INSERT_TAIL(&drop_tables, tb, entry);
|
||||
|
||||
@@ -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``
|
||||
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
|
||||
---------------
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "include/qemu/lockable.h"
|
||||
#include "qemu/lockable.h"
|
||||
#include "exec/tswap.h"
|
||||
#include "sysemu/runstate.h"
|
||||
#include "trace.h"
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "qemu/log.h"
|
||||
#include "hw/gpio/stm32l4x5_gpio.h"
|
||||
#include "hw/irq.h"
|
||||
#include "hw/clock.h"
|
||||
#include "hw/qdev-clock.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/visitor.h"
|
||||
@@ -426,8 +427,8 @@ static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
static const VMStateDescription vmstate_stm32l4x5_gpio = {
|
||||
.name = TYPE_STM32L4X5_GPIO,
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.fields = (VMStateField[]){
|
||||
VMSTATE_UINT32(moder, Stm32l4x5GpioState),
|
||||
VMSTATE_UINT32(otyper, Stm32l4x5GpioState),
|
||||
@@ -441,6 +442,7 @@ static const VMStateDescription vmstate_stm32l4x5_gpio = {
|
||||
VMSTATE_UINT32(ascr, Stm32l4x5GpioState),
|
||||
VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState),
|
||||
VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState),
|
||||
VMSTATE_CLOCK(clk, Stm32l4x5GpioState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
+8
-8
@@ -207,37 +207,37 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
|
||||
|
||||
val = cpu_to_le64(MIN_SEABIOS_HPPA_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);
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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]);
|
||||
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
||||
|
||||
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));
|
||||
|
||||
fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg);
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ config PC
|
||||
imply VGA_PCI
|
||||
imply VIRTIO_VGA
|
||||
imply NVDIMM
|
||||
select FDC_ISA
|
||||
imply FDC_ISA
|
||||
select I8259
|
||||
select I8254
|
||||
select PCKBD
|
||||
|
||||
+1
-1
@@ -278,7 +278,7 @@ static void microvm_devices_init(MicrovmMachineState *mms)
|
||||
default_firmware = x86_machine_is_acpi_enabled(x86ms)
|
||||
? MICROVM_BIOS_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)
|
||||
|
||||
+9
-4
@@ -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)
|
||||
{
|
||||
int val, nb, i;
|
||||
int val, nb;
|
||||
FloppyDriveType fd_type[2] = { FLOPPY_DRIVE_TYPE_NONE,
|
||||
FLOPPY_DRIVE_TYPE_NONE };
|
||||
|
||||
#ifdef CONFIG_FDC_ISA
|
||||
/* floppy type */
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
|
||||
cmos_get_fd_drive_type(fd_type[1]);
|
||||
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;
|
||||
DriveInfo *fd[MAX_FD];
|
||||
qemu_irq *a20_line;
|
||||
ISADevice *fdc, *i8042, *port92, *vmmouse;
|
||||
ISADevice *i8042, *port92, *vmmouse;
|
||||
|
||||
serial_hds_isa_init(isa_bus, 0, MAX_ISA_SERIAL_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];
|
||||
}
|
||||
if (create_fdctrl) {
|
||||
fdc = isa_new(TYPE_ISA_FDC);
|
||||
#ifdef CONFIG_FDC_ISA
|
||||
ISADevice *fdc = isa_new(TYPE_ISA_FDC);
|
||||
if (fdc) {
|
||||
isa_realize_and_unref(fdc, isa_bus, &error_fatal);
|
||||
isa_fdc_init_drives(fdc, fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!create_i8042) {
|
||||
|
||||
+4
-2
@@ -317,8 +317,8 @@ static void pc_init1(MachineState *machine, const char *pci_type)
|
||||
}
|
||||
|
||||
/* init basic PC hardware */
|
||||
pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc, true,
|
||||
0x4);
|
||||
pc_basic_device_init(pcms, isa_bus, x86ms->gsi, x86ms->rtc,
|
||||
!MACHINE_CLASS(pcmc)->no_floppy, 0x4);
|
||||
|
||||
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_display = "std";
|
||||
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);
|
||||
machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
|
||||
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;
|
||||
m->default_nic = "ne2k_isa";
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+5
-6
@@ -40,11 +40,10 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
int isa_bios_size;
|
||||
MemoryRegion *isa_bios;
|
||||
uint64_t flash_size;
|
||||
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 */
|
||||
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,
|
||||
&error_fatal);
|
||||
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,
|
||||
MemoryRegion *rom_memory)
|
||||
{
|
||||
X86MachineState *x86ms = X86_MACHINE(pcms);
|
||||
hwaddr total_size = 0;
|
||||
int i;
|
||||
BlockBackend *blk;
|
||||
@@ -185,7 +184,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
|
||||
|
||||
if (i == 0) {
|
||||
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 */
|
||||
if (sev_enabled()) {
|
||||
@@ -205,7 +204,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
|
||||
BlockBackend *pflash_blk[ARRAY_SIZE(pcms->flash)];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -226,7 +225,7 @@ void pc_system_firmware_init(PCMachineState *pcms,
|
||||
|
||||
if (!pflash_blk[0]) {
|
||||
/* 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 {
|
||||
if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
|
||||
/*
|
||||
|
||||
+23
-22
@@ -1128,17 +1128,29 @@ void x86_load_linux(X86MachineState *x86ms,
|
||||
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)
|
||||
{
|
||||
const char *bios_name;
|
||||
char *filename;
|
||||
MemoryRegion *bios, *isa_bios;
|
||||
int bios_size, isa_bios_size;
|
||||
int bios_size;
|
||||
ssize_t ret;
|
||||
|
||||
/* 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);
|
||||
if (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) {
|
||||
goto bios_error;
|
||||
}
|
||||
bios = g_malloc(sizeof(*bios));
|
||||
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
|
||||
memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size,
|
||||
&error_fatal);
|
||||
if (sev_enabled()) {
|
||||
/*
|
||||
* 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.
|
||||
* 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);
|
||||
x86_firmware_configure(ptr, bios_size);
|
||||
} else {
|
||||
if (!isapc_ram_fw) {
|
||||
memory_region_set_readonly(bios, true);
|
||||
}
|
||||
memory_region_set_readonly(&x86ms->bios, !isapc_ram_fw);
|
||||
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
|
||||
if (ret != 0) {
|
||||
goto bios_error;
|
||||
@@ -1174,22 +1184,13 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
|
||||
g_free(filename);
|
||||
|
||||
/* map the last 128KB of the BIOS in ISA space */
|
||||
isa_bios_size = MIN(bios_size, 128 * KiB);
|
||||
isa_bios = g_malloc(sizeof(*isa_bios));
|
||||
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);
|
||||
}
|
||||
x86_isa_bios_init(&x86ms->isa_bios, rom_memory, &x86ms->bios,
|
||||
!isapc_ram_fw);
|
||||
|
||||
/* map all the bios at the top of memory */
|
||||
memory_region_add_subregion(rom_memory,
|
||||
(uint32_t)(-bios_size),
|
||||
bios);
|
||||
&x86ms->bios);
|
||||
return;
|
||||
|
||||
bios_error:
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ config GOLDFISH_PIC
|
||||
config M68K_IRQC
|
||||
bool
|
||||
|
||||
config LOONGARCH_IPI
|
||||
config LOONGSON_IPI
|
||||
bool
|
||||
|
||||
config LOONGARCH_PCH_PIC
|
||||
|
||||
+2
-17
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "hw/intc/loongarch_ipi.h"
|
||||
#include "hw/irq.h"
|
||||
@@ -13,9 +14,8 @@
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/log.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/loongarch/virt.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "target/loongarch/internals.h"
|
||||
#include "target/loongarch/cpu.h"
|
||||
#include "trace.h"
|
||||
|
||||
static MemTxResult loongarch_ipi_readl(void *opaque, hwaddr addr,
|
||||
@@ -122,11 +122,6 @@ static MemTxResult mail_send(uint64_t val, MemTxAttrs attrs)
|
||||
CPUState *cs;
|
||||
|
||||
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);
|
||||
if (cs == NULL) {
|
||||
return MEMTX_DECODE_ERROR;
|
||||
@@ -146,11 +141,6 @@ static MemTxResult any_send(uint64_t val, MemTxAttrs attrs)
|
||||
CPUState *cs;
|
||||
|
||||
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);
|
||||
if (cs == NULL) {
|
||||
return MEMTX_DECODE_ERROR;
|
||||
@@ -201,11 +191,6 @@ static MemTxResult loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
|
||||
break;
|
||||
case IOCSR_IPI_SEND:
|
||||
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 */
|
||||
vector = extract8(val, 0, 5);
|
||||
cs = ipi_getcpu(cpuid);
|
||||
|
||||
@@ -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)
|
||||
+1
-1
@@ -68,7 +68,7 @@ specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c'))
|
||||
specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
|
||||
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_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_MSI', if_true: files('loongarch_pch_msi.c'))
|
||||
specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c'))
|
||||
|
||||
@@ -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_set(int id, int enable) "setting interrupt group %d to %d"
|
||||
|
||||
# loongarch_ipi.c
|
||||
loongarch_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
|
||||
loongarch_ipi_unsupported_cpuid(const char *s, uint32_t cpuid) "%s unsupported cpuid 0x%" PRIx32
|
||||
|
||||
# loongson_ipi.c
|
||||
loongson_ipi_read(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_pch_pic.c
|
||||
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
|
||||
|
||||
@@ -10,7 +10,7 @@ config LOONGARCH_VIRT
|
||||
select SERIAL
|
||||
select VIRTIO_PCI
|
||||
select PLATFORM_BUS
|
||||
select LOONGARCH_IPI
|
||||
select LOONGSON_IPI
|
||||
select LOONGARCH_PCH_PIC
|
||||
select LOONGARCH_PCH_MSI
|
||||
select LOONGARCH_EXTIOI
|
||||
|
||||
+49
-40
@@ -105,14 +105,15 @@ build_facs(GArray *table_data)
|
||||
|
||||
/* build MADT */
|
||||
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);
|
||||
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
|
||||
int i, arch_id;
|
||||
AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lvms->oem_id,
|
||||
.oem_table_id = lvms->oem_table_id };
|
||||
|
||||
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;
|
||||
uint64_t mem_len, mem_base;
|
||||
int nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lams);
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lvms);
|
||||
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
|
||||
AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lvms->oem_id,
|
||||
.oem_table_id = lvms->oem_table_id };
|
||||
|
||||
acpi_table_begin(&table, table_data);
|
||||
build_append_int_noprefix(table_data, 1, 4); /* Reserved */
|
||||
@@ -279,13 +280,13 @@ static void
|
||||
build_la_ged_aml(Aml *dsdt, MachineState *machine)
|
||||
{
|
||||
uint32_t event;
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
|
||||
build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
|
||||
HOTPLUG_HANDLER(lams->acpi_ged),
|
||||
HOTPLUG_HANDLER(lvms->acpi_ged),
|
||||
VIRT_SCI_IRQ, AML_SYSTEM_MEMORY,
|
||||
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);
|
||||
if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
|
||||
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);
|
||||
}
|
||||
|
||||
static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
|
||||
static void build_pci_device_aml(Aml *scope, LoongArchVirtMachineState *lvms)
|
||||
{
|
||||
struct GPEXConfig cfg = {
|
||||
.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.size = VIRT_PCI_CFG_SIZE,
|
||||
.irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS,
|
||||
.bus = lams->pci_bus,
|
||||
.bus = lvms->pci_bus,
|
||||
};
|
||||
|
||||
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;
|
||||
MemoryRegion *flash_mem;
|
||||
@@ -322,11 +323,11 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
|
||||
hwaddr flash1_base;
|
||||
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_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_size = memory_region_size(flash_mem);
|
||||
|
||||
@@ -352,7 +353,7 @@ static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
|
||||
}
|
||||
|
||||
#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);
|
||||
hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
|
||||
@@ -391,18 +392,18 @@ static void
|
||||
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
{
|
||||
Aml *dsdt, *scope, *pkg;
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
|
||||
.oem_table_id = lvms->oem_table_id };
|
||||
|
||||
acpi_table_begin(&table, table_data);
|
||||
dsdt = init_aml_allocator();
|
||||
build_uart_device_aml(dsdt);
|
||||
build_pci_device_aml(dsdt, lams);
|
||||
build_pci_device_aml(dsdt, lvms);
|
||||
build_la_ged_aml(dsdt, machine);
|
||||
build_flash_aml(dsdt, lams);
|
||||
build_flash_aml(dsdt, lvms);
|
||||
#ifdef CONFIG_TPM
|
||||
acpi_dsdt_add_tpm(dsdt, lams);
|
||||
acpi_dsdt_add_tpm(dsdt, lvms);
|
||||
#endif
|
||||
/* System State Package */
|
||||
scope = aml_scope("\\");
|
||||
@@ -421,7 +422,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
|
||||
static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
{
|
||||
LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
GArray *table_offsets;
|
||||
AcpiFadtData fadt_data;
|
||||
unsigned facs, rsdt, dsdt;
|
||||
@@ -455,14 +456,14 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
fadt_data.dsdt_tbl_offset = &dsdt;
|
||||
fadt_data.xdsdt_tbl_offset = &dsdt;
|
||||
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);
|
||||
build_madt(tables_blob, tables->linker, lams);
|
||||
build_madt(tables_blob, tables->linker, lvms);
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
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);
|
||||
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->have_numa_distance) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_slit(tables_blob, tables->linker, machine, lams->oem_id,
|
||||
lams->oem_table_id);
|
||||
build_slit(tables_blob, tables->linker, machine, lvms->oem_id,
|
||||
lvms->oem_table_id);
|
||||
}
|
||||
if (machine->numa_state->hmat_enabled) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
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),
|
||||
.size = cpu_to_le64(VIRT_PCI_CFG_SIZE),
|
||||
};
|
||||
build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id,
|
||||
lams->oem_table_id);
|
||||
build_mcfg(tables_blob, tables->linker, &mcfg, lvms->oem_id,
|
||||
lvms->oem_table_id);
|
||||
}
|
||||
|
||||
#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) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_tpm2(tables_blob, tables->linker,
|
||||
tables->tcpalog, lams->oem_id,
|
||||
lams->oem_table_id);
|
||||
tables->tcpalog, lvms->oem_id,
|
||||
lvms->oem_table_id);
|
||||
}
|
||||
#endif
|
||||
/* 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 = tables_blob->len;
|
||||
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 */
|
||||
{
|
||||
AcpiRsdpData rsdp_data = {
|
||||
.revision = 0,
|
||||
.oem_id = lams->oem_id,
|
||||
.oem_id = lvms->oem_id,
|
||||
.xsdt_tbl_offset = NULL,
|
||||
.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;
|
||||
AcpiBuildState *build_state;
|
||||
|
||||
if (!lams->fw_cfg) {
|
||||
if (!lvms->fw_cfg) {
|
||||
ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!loongarch_is_acpi_enabled(lams)) {
|
||||
if (!loongarch_is_acpi_enabled(lvms)) {
|
||||
ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
|
||||
return;
|
||||
}
|
||||
@@ -611,7 +620,7 @@ void loongarch_acpi_setup(LoongArchMachineState *lams)
|
||||
build_state = g_malloc0(sizeof *build_state);
|
||||
|
||||
acpi_build_tables_init(&tables);
|
||||
acpi_build(&tables, MACHINE(lams));
|
||||
acpi_build(&tables, MACHINE(lvms));
|
||||
|
||||
/* Now expose it all to Guest */
|
||||
build_state->table_mr = acpi_add_rom_blob(acpi_build_update,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user