- fix compile error on loongarch
- hw/loongarch: fix cpu hotplug reset
- hw/loongarch/boot: Use warn_report when no kernel filename
- hw/loongarch: clean code
- hw/loongarch: Add KVM pch msi device support
- hw/loongarch: Add KVM pch pic device support
- hw/loongarch: Add KVM extioi device support
- hw/loongarch: Add KVM IPI device support
- hw/loongarch/virt: Update the ACPI table for hotplug cpu
- hw/loongarch/virt: Add basic CPU plug support
- hw/loongarch/virt: Add CPU topology support
- accel/kvm/kvm-all: Fixes the missing break in vCPU unpark logic
- gdbstub: Add helper function to unregister GDB register space
- physmem: Add helper function to destroy CPU AddressSpace
- hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
- hw/acpi: Update ACPI GED framework to support vCPU Hotplug
- hw/acpi: Move CPU ctrl-dev MMIO region len macro to common header file
- accel/kvm: Extract common KVM vCPU {creation,parking} code
- target/loongarch: Add steal time support on migration
- linux-headers: loongarch: Add kvm_para.h and unistd_64.h
- target/loongarch/kvm: Implement LoongArch PMU extension
- target/loongarch: Implement lbt registers save/restore function
- target/loongarch: Add loongson binary translation feature
- sync loongarch linux-headers
- target/loongarch: Avoid bits shift exceeding width of bool type
- target/loongarch: Use explicit little-endian LD/ST API
- target/loongarch: fix -Werror=maybe-uninitialized false-positive
- target/loongarch: Support QMP dump-guest-memory
- target/loongarch/kvm: Add vCPU reset function
- target/loongarch: Add compatible support about VM reboot
- target/loongarch: Fix cpu_reset set wrong CSR_CRMD
- target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
- target/loongarch: Remove avail_64 in trans_srai_w() and simplify it
- target/loongarch/kvm: Add software breakpoint support
- target/loongarch: Add loongarch vector property unconditionally
- target/loongarch/kvm: Fix VM recovery from disk failures
- target/loongarch: Put cpucfg operation before CSR register
- target/loongarch: Add TCG macro in structure CPUArchState
- hw/arm/virt-acpi-build.c: Migrate SPCR creation to common location
- hw/loongarch/virt: Add FDT table support with acpi ged pm register
- hw/loongarch/virt: Add description for virt machine type
- hw/loongarch: Add acpi SPCR table support
- hw/loongarch: virt: pass random seed to fdt
- hw/loongarch: virt: support up to 4 serial ports
- hw/loongarch: Remove default enable with VIRTIO_VGA device
- hw/loongarch: Fix length for lowram in ACPI SRAT
- hw/loongarch/virt: Remove unused assignment
- hw/loongarch: Change the tpm support by default
- hw/loongarch/boot.c: fix out-of-bound reading
- hw/loongarch/virt: Use MemTxAttrs interface for misc ops
- tests/libqos: Add loongarch virt machine node
- hw/loongarch: Remove minimum and default memory size
- hw/loongarch: Refine system dram memory region
- hw/loongarch: Refine fwcfg memory map
- hw/loongarch: Refine fadt memory table for numa memory
- hw/loongarch: Refine acpi srat table for numa memory
- hw/loongarch: Add VM mode in IOCSR feature register in kvm mode
- hw/loongarch: Refine default numa id calculation
- hw/loongarch: Rename LoongArchMachineState with LoongArchVirtMachineState
- hw/loongarch: Rename LOONGARCH_MACHINE with LOONGARCH_VIRT_MACHINE
- hw/loongarch: move memory map to boot.c
- loongarch: switch boards to "default y"
- hw/loongarch: Add cells missing from rtc node
- hw/loongarch: Add cells missing from uart node
- hw/loongarch: fdt remove unused irqchip node
- hw/loongarch: fdt adds pcie irq_map node
- hw/loongarch: fdt adds pch_msi Controller
- hw/loongarch: fdt adds pch_pic Controller
- hw/loongarch: fdt adds Extend I/O Interrupt Controller
- hw/loongarch: fdt adds cpu interrupt controller node
- hw/loongarch: Init efi_fdt table
- hw/loongarch: Init efi_initrd table
- hw/loongarch: Init efi_boot_memmap table
- hw/loongarch: Init efi_system_table
- hw/loongarch: Add init_cmdline
- hw/loongarch: Add slave cpu boot_code
- hw/loongarch: Add load initrd
- hw/loongarch: Move boot functions to boot.c
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
(cherry picked from commit 04ca9e6c8ff19630116722240ae0136cea831c5c)
391 lines
12 KiB
Diff
391 lines
12 KiB
Diff
From 2414b74bec88f4db58040a683191d3c3828f81ab Mon Sep 17 00:00:00 2001
|
|
From: Song Gao <gaosong@loongson.cn>
|
|
Date: Fri, 26 Apr 2024 17:15:35 +0800
|
|
Subject: [PATCH 01/78] hw/loongarch: Move boot functions to boot.c
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Move some boot functions to boot.c and struct
|
|
loongarch_boot_info into struct LoongArchMachineState.
|
|
|
|
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
|
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
|
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
|
Message-Id: <20240426091551.2397867-2-gaosong@loongson.cn>
|
|
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
|
---
|
|
hw/loongarch/boot.c | 128 ++++++++++++++++++++++++++++++++++++
|
|
hw/loongarch/meson.build | 1 +
|
|
hw/loongarch/virt.c | 121 +++-------------------------------
|
|
include/hw/loongarch/boot.h | 21 ++++++
|
|
include/hw/loongarch/virt.h | 2 +
|
|
5 files changed, 160 insertions(+), 113 deletions(-)
|
|
create mode 100644 hw/loongarch/boot.c
|
|
create mode 100644 include/hw/loongarch/boot.h
|
|
|
|
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
|
new file mode 100644
|
|
index 0000000000..9feed17db3
|
|
--- /dev/null
|
|
+++ b/hw/loongarch/boot.c
|
|
@@ -0,0 +1,128 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
+/*
|
|
+ * LoongArch boot helper functions.
|
|
+ *
|
|
+ * Copyright (c) 2023 Loongson Technology Corporation Limited
|
|
+ */
|
|
+
|
|
+#include "qemu/osdep.h"
|
|
+#include "qemu/units.h"
|
|
+#include "target/loongarch/cpu.h"
|
|
+#include "hw/loongarch/virt.h"
|
|
+#include "hw/loader.h"
|
|
+#include "elf.h"
|
|
+#include "qemu/error-report.h"
|
|
+#include "sysemu/reset.h"
|
|
+#include "sysemu/qtest.h"
|
|
+
|
|
+static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
|
+{
|
|
+ return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
|
|
+}
|
|
+
|
|
+static int64_t load_kernel_info(struct loongarch_boot_info *info)
|
|
+{
|
|
+ uint64_t kernel_entry, kernel_low, kernel_high;
|
|
+ ssize_t kernel_size;
|
|
+
|
|
+ kernel_size = load_elf(info->kernel_filename, NULL,
|
|
+ cpu_loongarch_virt_to_phys, NULL,
|
|
+ &kernel_entry, &kernel_low,
|
|
+ &kernel_high, NULL, 0,
|
|
+ EM_LOONGARCH, 1, 0);
|
|
+
|
|
+ if (kernel_size < 0) {
|
|
+ error_report("could not load kernel '%s': %s",
|
|
+ info->kernel_filename,
|
|
+ load_elf_strerror(kernel_size));
|
|
+ exit(1);
|
|
+ }
|
|
+ return kernel_entry;
|
|
+}
|
|
+
|
|
+static void reset_load_elf(void *opaque)
|
|
+{
|
|
+ LoongArchCPU *cpu = opaque;
|
|
+ CPULoongArchState *env = &cpu->env;
|
|
+
|
|
+ cpu_reset(CPU(cpu));
|
|
+ if (env->load_elf) {
|
|
+ cpu_set_pc(CPU(cpu), env->elf_address);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void fw_cfg_add_kernel_info(struct loongarch_boot_info *info,
|
|
+ FWCfgState *fw_cfg)
|
|
+{
|
|
+ /*
|
|
+ * Expose the kernel, the command line, and the initrd in fw_cfg.
|
|
+ * We don't process them here at all, it's all left to the
|
|
+ * firmware.
|
|
+ */
|
|
+ load_image_to_fw_cfg(fw_cfg,
|
|
+ FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
|
|
+ info->kernel_filename,
|
|
+ false);
|
|
+
|
|
+ if (info->initrd_filename) {
|
|
+ load_image_to_fw_cfg(fw_cfg,
|
|
+ FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
|
|
+ info->initrd_filename, false);
|
|
+ }
|
|
+
|
|
+ if (info->kernel_cmdline) {
|
|
+ fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
|
|
+ strlen(info->kernel_cmdline) + 1);
|
|
+ fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
|
|
+ info->kernel_cmdline);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void loongarch_firmware_boot(LoongArchMachineState *lams,
|
|
+ struct loongarch_boot_info *info)
|
|
+{
|
|
+ fw_cfg_add_kernel_info(info, lams->fw_cfg);
|
|
+}
|
|
+
|
|
+static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
|
+{
|
|
+ int64_t kernel_addr = 0;
|
|
+ LoongArchCPU *lacpu;
|
|
+ CPUState *cs;
|
|
+
|
|
+ if (info->kernel_filename) {
|
|
+ kernel_addr = load_kernel_info(info);
|
|
+ } else {
|
|
+ if(!qtest_enabled()) {
|
|
+ error_report("Need kernel filename\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ CPU_FOREACH(cs) {
|
|
+ lacpu = LOONGARCH_CPU(cs);
|
|
+ lacpu->env.load_elf = true;
|
|
+ lacpu->env.elf_address = kernel_addr;
|
|
+ }
|
|
+}
|
|
+
|
|
+void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
|
|
+{
|
|
+ LoongArchMachineState *lams = LOONGARCH_MACHINE(ms);
|
|
+ int i;
|
|
+
|
|
+ /* register reset function */
|
|
+ for (i = 0; i < ms->smp.cpus; i++) {
|
|
+ qemu_register_reset(reset_load_elf, LOONGARCH_CPU(qemu_get_cpu(i)));
|
|
+ }
|
|
+
|
|
+ info->kernel_filename = ms->kernel_filename;
|
|
+ info->kernel_cmdline = ms->kernel_cmdline;
|
|
+ info->initrd_filename = ms->initrd_filename;
|
|
+
|
|
+ if (lams->bios_loaded) {
|
|
+ loongarch_firmware_boot(lams, info);
|
|
+ } else {
|
|
+ loongarch_direct_kernel_boot(info);
|
|
+ }
|
|
+}
|
|
diff --git a/hw/loongarch/meson.build b/hw/loongarch/meson.build
|
|
index c0421502ab..d306d82c2e 100644
|
|
--- a/hw/loongarch/meson.build
|
|
+++ b/hw/loongarch/meson.build
|
|
@@ -1,6 +1,7 @@
|
|
loongarch_ss = ss.source_set()
|
|
loongarch_ss.add(files(
|
|
'fw_cfg.c',
|
|
+ 'boot.c',
|
|
))
|
|
loongarch_ss.add(when: 'CONFIG_LOONGARCH_VIRT', if_true: [files('virt.c'), fdt])
|
|
loongarch_ss.add(when: 'CONFIG_ACPI', if_true: files('acpi-build.c'))
|
|
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
|
index eca3b94581..a0aee28f41 100644
|
|
--- a/hw/loongarch/virt.c
|
|
+++ b/hw/loongarch/virt.c
|
|
@@ -48,14 +48,6 @@
|
|
#include "hw/block/flash.h"
|
|
#include "qemu/error-report.h"
|
|
|
|
-
|
|
-struct loaderparams {
|
|
- uint64_t ram_size;
|
|
- const char *kernel_filename;
|
|
- const char *kernel_cmdline;
|
|
- const char *initrd_filename;
|
|
-};
|
|
-
|
|
static bool virt_is_veiointc_enabled(LoongArchMachineState *lams)
|
|
{
|
|
if (lams->veiointc == ON_OFF_AUTO_OFF) {
|
|
@@ -439,31 +431,6 @@ static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
|
|
memmap_entries++;
|
|
}
|
|
|
|
-static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
|
-{
|
|
- return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
|
|
-}
|
|
-
|
|
-static int64_t load_kernel_info(const struct loaderparams *loaderparams)
|
|
-{
|
|
- uint64_t kernel_entry, kernel_low, kernel_high;
|
|
- ssize_t kernel_size;
|
|
-
|
|
- kernel_size = load_elf(loaderparams->kernel_filename, NULL,
|
|
- cpu_loongarch_virt_to_phys, NULL,
|
|
- &kernel_entry, &kernel_low,
|
|
- &kernel_high, NULL, 0,
|
|
- EM_LOONGARCH, 1, 0);
|
|
-
|
|
- if (kernel_size < 0) {
|
|
- error_report("could not load kernel '%s': %s",
|
|
- loaderparams->kernel_filename,
|
|
- load_elf_strerror(kernel_size));
|
|
- exit(1);
|
|
- }
|
|
- return kernel_entry;
|
|
-}
|
|
-
|
|
static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState *lams)
|
|
{
|
|
DeviceState *dev;
|
|
@@ -755,67 +722,6 @@ static void loongarch_firmware_init(LoongArchMachineState *lams)
|
|
}
|
|
}
|
|
|
|
-static void reset_load_elf(void *opaque)
|
|
-{
|
|
- LoongArchCPU *cpu = opaque;
|
|
- CPULoongArchState *env = &cpu->env;
|
|
-
|
|
- cpu_reset(CPU(cpu));
|
|
- if (env->load_elf) {
|
|
- cpu_set_pc(CPU(cpu), env->elf_address);
|
|
- }
|
|
-}
|
|
-
|
|
-static void fw_cfg_add_kernel_info(const struct loaderparams *loaderparams,
|
|
- FWCfgState *fw_cfg)
|
|
-{
|
|
- /*
|
|
- * Expose the kernel, the command line, and the initrd in fw_cfg.
|
|
- * We don't process them here at all, it's all left to the
|
|
- * firmware.
|
|
- */
|
|
- load_image_to_fw_cfg(fw_cfg,
|
|
- FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
|
|
- loaderparams->kernel_filename,
|
|
- false);
|
|
-
|
|
- if (loaderparams->initrd_filename) {
|
|
- load_image_to_fw_cfg(fw_cfg,
|
|
- FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
|
|
- loaderparams->initrd_filename, false);
|
|
- }
|
|
-
|
|
- if (loaderparams->kernel_cmdline) {
|
|
- fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
|
|
- strlen(loaderparams->kernel_cmdline) + 1);
|
|
- fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
|
|
- loaderparams->kernel_cmdline);
|
|
- }
|
|
-}
|
|
-
|
|
-static void loongarch_firmware_boot(LoongArchMachineState *lams,
|
|
- const struct loaderparams *loaderparams)
|
|
-{
|
|
- fw_cfg_add_kernel_info(loaderparams, lams->fw_cfg);
|
|
-}
|
|
-
|
|
-static void loongarch_direct_kernel_boot(LoongArchMachineState *lams,
|
|
- const struct loaderparams *loaderparams)
|
|
-{
|
|
- MachineState *machine = MACHINE(lams);
|
|
- int64_t kernel_addr = 0;
|
|
- LoongArchCPU *lacpu;
|
|
- int i;
|
|
-
|
|
- kernel_addr = load_kernel_info(loaderparams);
|
|
- if (!machine->firmware) {
|
|
- for (i = 0; i < machine->smp.cpus; i++) {
|
|
- lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
|
|
- lacpu->env.load_elf = true;
|
|
- lacpu->env.elf_address = kernel_addr;
|
|
- }
|
|
- }
|
|
-}
|
|
|
|
static MemTxResult loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val,
|
|
unsigned size, MemTxAttrs attrs)
|
|
@@ -925,7 +831,6 @@ static void loongarch_init(MachineState *machine)
|
|
const CPUArchIdList *possible_cpus;
|
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
|
CPUState *cpu;
|
|
- struct loaderparams loaderparams = { };
|
|
|
|
if (!cpu_model) {
|
|
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
|
@@ -1028,24 +933,8 @@ static void loongarch_init(MachineState *machine)
|
|
sizeof(struct memmap_entry) * (memmap_entries));
|
|
}
|
|
fdt_add_fw_cfg_node(lams);
|
|
- loaderparams.ram_size = ram_size;
|
|
- loaderparams.kernel_filename = machine->kernel_filename;
|
|
- loaderparams.kernel_cmdline = machine->kernel_cmdline;
|
|
- loaderparams.initrd_filename = machine->initrd_filename;
|
|
- /* load the kernel. */
|
|
- if (loaderparams.kernel_filename) {
|
|
- if (lams->bios_loaded) {
|
|
- loongarch_firmware_boot(lams, &loaderparams);
|
|
- } else {
|
|
- loongarch_direct_kernel_boot(lams, &loaderparams);
|
|
- }
|
|
- }
|
|
fdt_add_flash_node(lams);
|
|
- /* register reset function */
|
|
- for (i = 0; i < machine->smp.cpus; i++) {
|
|
- lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
|
|
- qemu_register_reset(reset_load_elf, lacpu);
|
|
- }
|
|
+
|
|
/* Initialize the IO interrupt subsystem */
|
|
loongarch_irq_init(lams);
|
|
fdt_add_irqchip_node(lams);
|
|
@@ -1069,7 +958,13 @@ static void loongarch_init(MachineState *machine)
|
|
*/
|
|
fdt_base = 1 * MiB;
|
|
qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
|
|
- rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base);
|
|
+ rom_add_blob_fixed_as("fdt", machine->fdt, lams->fdt_size, fdt_base,
|
|
+ &address_space_memory);
|
|
+ qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
|
|
+ rom_ptr_for_as(&address_space_memory, fdt_base, lams->fdt_size));
|
|
+
|
|
+ lams->bootinfo.ram_size = ram_size;
|
|
+ loongarch_load_kernel(machine, &lams->bootinfo);
|
|
}
|
|
|
|
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
|
|
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
|
|
new file mode 100644
|
|
index 0000000000..3275c1e295
|
|
--- /dev/null
|
|
+++ b/include/hw/loongarch/boot.h
|
|
@@ -0,0 +1,21 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
+/*
|
|
+ * Definitions for LoongArch boot.
|
|
+ *
|
|
+ * Copyright (C) 2023 Loongson Technology Corporation Limited
|
|
+ */
|
|
+
|
|
+#ifndef HW_LOONGARCH_BOOT_H
|
|
+#define HW_LOONGARCH_BOOT_H
|
|
+
|
|
+struct loongarch_boot_info {
|
|
+ uint64_t ram_size;
|
|
+ const char *kernel_filename;
|
|
+ const char *kernel_cmdline;
|
|
+ const char *initrd_filename;
|
|
+ uint64_t a0, a1, a2;
|
|
+};
|
|
+
|
|
+void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info);
|
|
+
|
|
+#endif /* HW_LOONGARCH_BOOT_H */
|
|
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
|
index 99447fd1d6..02c8234b8d 100644
|
|
--- a/include/hw/loongarch/virt.h
|
|
+++ b/include/hw/loongarch/virt.h
|
|
@@ -13,6 +13,7 @@
|
|
#include "qemu/queue.h"
|
|
#include "hw/intc/loongarch_ipi.h"
|
|
#include "hw/block/flash.h"
|
|
+#include "hw/loongarch/boot.h"
|
|
|
|
#define LOONGARCH_MAX_CPUS 256
|
|
|
|
@@ -58,6 +59,7 @@ struct LoongArchMachineState {
|
|
MemoryRegion iocsr_mem;
|
|
AddressSpace as_iocsr;
|
|
int features;
|
|
+ struct loongarch_boot_info bootinfo;
|
|
};
|
|
|
|
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
|
|
--
|
|
2.39.1
|
|
|