!1067 [sync] PR-1051: sync qemu patch from code repository
From: @openeuler-sync-bot Reviewed-by: @imxcc Signed-off-by: @imxcc
This commit is contained in:
commit
02a1399a3b
@ -0,0 +1,236 @@
|
||||
From 2464d0d6115e1794468ff455e3acdb98e0d71a31 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Tue, 16 Jul 2024 12:14:56 +0100
|
||||
Subject: [PATCH 62/78] accel/kvm: Extract common KVM vCPU {creation,parking}
|
||||
code
|
||||
|
||||
KVM vCPU creation is done once during the vCPU realization when Qemu vCPU thread
|
||||
is spawned. This is common to all the architectures as of now.
|
||||
|
||||
Hot-unplug of vCPU results in destruction of the vCPU object in QOM but the
|
||||
corresponding KVM vCPU object in the Host KVM is not destroyed as KVM doesn't
|
||||
support vCPU removal. Therefore, its representative KVM vCPU object/context in
|
||||
Qemu is parked.
|
||||
|
||||
Refactor architecture common logic so that some APIs could be reused by vCPU
|
||||
Hotplug code of some architectures likes ARM, Loongson etc. Update new/old APIs
|
||||
with trace events. New APIs qemu_{create,park,unpark}_vcpu() can be externally
|
||||
called. No functional change is intended here.
|
||||
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Tested-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Tested-by: Miguel Luis <miguel.luis@oracle.com>
|
||||
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
|
||||
Reviewed-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
|
||||
Tested-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20240716111502.202344-2-salil.mehta@huawei.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 71 +++++++++++++++++++++---------------------
|
||||
accel/kvm/trace-events | 11 +++++++
|
||||
include/sysemu/kvm.h | 27 ++++++++++++++--
|
||||
3 files changed, 71 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index 8077630825..8dea8f98bb 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -141,7 +141,6 @@ static QemuMutex kml_slots_lock;
|
||||
#define kvm_slots_unlock() qemu_mutex_unlock(&kml_slots_lock)
|
||||
|
||||
static void kvm_slot_init_dirty_bitmap(KVMSlot *mem);
|
||||
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id);
|
||||
|
||||
static inline void kvm_resample_fd_remove(int gsi)
|
||||
{
|
||||
@@ -334,39 +333,57 @@ void kvm_park_vcpu(CPUState *cpu)
|
||||
{
|
||||
struct KVMParkedVcpu *vcpu;
|
||||
|
||||
+ trace_kvm_park_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
||||
+
|
||||
vcpu = g_malloc0(sizeof(*vcpu));
|
||||
vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
|
||||
vcpu->kvm_fd = cpu->kvm_fd;
|
||||
QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
|
||||
}
|
||||
|
||||
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
|
||||
+{
|
||||
+ struct KVMParkedVcpu *cpu;
|
||||
+ int kvm_fd = -ENOENT;
|
||||
+
|
||||
+ QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
|
||||
+ if (cpu->vcpu_id == vcpu_id) {
|
||||
+ QLIST_REMOVE(cpu, node);
|
||||
+ kvm_fd = cpu->kvm_fd;
|
||||
+ g_free(cpu);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ trace_kvm_unpark_vcpu(vcpu_id, kvm_fd > 0 ? "unparked" : "!found parked");
|
||||
+
|
||||
+ return kvm_fd;
|
||||
+}
|
||||
+
|
||||
int kvm_create_vcpu(CPUState *cpu)
|
||||
{
|
||||
- unsigned long vcpu_id = cpu->cpu_index;
|
||||
+ unsigned long vcpu_id = kvm_arch_vcpu_id(cpu);
|
||||
KVMState *s = kvm_state;
|
||||
- int ret;
|
||||
-
|
||||
- DPRINTF("kvm_create_vcpu\n");
|
||||
+ int kvm_fd;
|
||||
|
||||
/* check if the KVM vCPU already exist but is parked */
|
||||
- ret = kvm_get_vcpu(s, kvm_arch_vcpu_id(cpu));
|
||||
- if (ret > 0) {
|
||||
- goto found;
|
||||
- }
|
||||
-
|
||||
- /* create a new KVM vcpu */
|
||||
- ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
|
||||
- if (ret < 0) {
|
||||
- return ret;
|
||||
+ kvm_fd = kvm_unpark_vcpu(s, vcpu_id);
|
||||
+ if (kvm_fd < 0) {
|
||||
+ /* vCPU not parked: create a new KVM vCPU */
|
||||
+ kvm_fd = kvm_vm_ioctl(s, KVM_CREATE_VCPU, vcpu_id);
|
||||
+ if (kvm_fd < 0) {
|
||||
+ error_report("KVM_CREATE_VCPU IOCTL failed for vCPU %lu", vcpu_id);
|
||||
+ return kvm_fd;
|
||||
+ }
|
||||
}
|
||||
|
||||
-found:
|
||||
- cpu->vcpu_dirty = true;
|
||||
- cpu->kvm_fd = ret;
|
||||
+ cpu->kvm_fd = kvm_fd;
|
||||
cpu->kvm_state = s;
|
||||
+ cpu->vcpu_dirty = true;
|
||||
cpu->dirty_pages = 0;
|
||||
cpu->throttle_us_per_full = 0;
|
||||
|
||||
+ trace_kvm_create_vcpu(cpu->cpu_index, vcpu_id, kvm_fd);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -376,7 +393,7 @@ static int do_kvm_destroy_vcpu(CPUState *cpu)
|
||||
long mmap_size;
|
||||
int ret = 0;
|
||||
|
||||
- DPRINTF("kvm_destroy_vcpu\n");
|
||||
+ trace_kvm_destroy_vcpu(cpu->cpu_index, kvm_arch_vcpu_id(cpu));
|
||||
|
||||
ret = kvm_arch_destroy_vcpu(cpu);
|
||||
if (ret < 0) {
|
||||
@@ -415,24 +432,6 @@ void kvm_destroy_vcpu(CPUState *cpu)
|
||||
}
|
||||
}
|
||||
|
||||
-static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
|
||||
-{
|
||||
- struct KVMParkedVcpu *cpu;
|
||||
-
|
||||
- QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
|
||||
- if (cpu->vcpu_id == vcpu_id) {
|
||||
- int kvm_fd;
|
||||
-
|
||||
- QLIST_REMOVE(cpu, node);
|
||||
- kvm_fd = cpu->kvm_fd;
|
||||
- g_free(cpu);
|
||||
- return kvm_fd;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return -1;
|
||||
-}
|
||||
-
|
||||
int kvm_init_vcpu(CPUState *cpu, Error **errp)
|
||||
{
|
||||
KVMState *s = kvm_state;
|
||||
diff --git a/accel/kvm/trace-events b/accel/kvm/trace-events
|
||||
index 399aaeb0ec..9c880fdcf4 100644
|
||||
--- a/accel/kvm/trace-events
|
||||
+++ b/accel/kvm/trace-events
|
||||
@@ -9,6 +9,10 @@ kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p"
|
||||
kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
|
||||
kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
|
||||
kvm_init_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
|
||||
+kvm_create_vcpu(int cpu_index, unsigned long arch_cpu_id, int kvm_fd) "index: %d, id: %lu, kvm fd: %d"
|
||||
+kvm_destroy_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
|
||||
+kvm_park_vcpu(int cpu_index, unsigned long arch_cpu_id) "index: %d id: %lu"
|
||||
+kvm_unpark_vcpu(unsigned long arch_cpu_id, const char *msg) "id: %lu %s"
|
||||
kvm_irqchip_commit_routes(void) ""
|
||||
kvm_irqchip_add_msi_route(char *name, int vector, int virq) "dev %s vector %d virq %d"
|
||||
kvm_irqchip_update_msi_route(int virq) "Updating MSI route virq=%d"
|
||||
@@ -26,3 +30,10 @@ kvm_dirty_ring_reap(uint64_t count, int64_t t) "reaped %"PRIu64" pages (took %"P
|
||||
kvm_dirty_ring_reaper_kick(const char *reason) "%s"
|
||||
kvm_dirty_ring_flush(int finished) "%d"
|
||||
|
||||
+kvm_failed_get_vcpu_mmap_size(void) ""
|
||||
+kvm_cpu_exec(void) ""
|
||||
+kvm_interrupt_exit_request(void) ""
|
||||
+kvm_io_window_exit(void) ""
|
||||
+kvm_run_exit_system_event(int cpu_index, uint32_t event_type) "cpu_index %d, system_even_type %"PRIu32
|
||||
+kvm_convert_memory(uint64_t start, uint64_t size, const char *msg) "start 0x%" PRIx64 " size 0x%" PRIx64 " %s"
|
||||
+kvm_memory_fault(uint64_t start, uint64_t size, uint64_t flags) "start 0x%" PRIx64 " size 0x%" PRIx64 " flags 0x%" PRIx64
|
||||
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
|
||||
index 31af5f0e24..7ffb5e4992 100644
|
||||
--- a/include/sysemu/kvm.h
|
||||
+++ b/include/sysemu/kvm.h
|
||||
@@ -319,6 +319,31 @@ int kvm_create_device(KVMState *s, uint64_t type, bool test);
|
||||
*/
|
||||
bool kvm_device_supported(int vmfd, uint64_t type);
|
||||
|
||||
+/**
|
||||
+ * kvm_create_vcpu - Gets a parked KVM vCPU or creates a KVM vCPU
|
||||
+ * @cpu: QOM CPUState object for which KVM vCPU has to be fetched/created.
|
||||
+ *
|
||||
+ * @returns: 0 when success, errno (<0) when failed.
|
||||
+ */
|
||||
+int kvm_create_vcpu(CPUState *cpu);
|
||||
+
|
||||
+/**
|
||||
+ * kvm_park_vcpu - Park QEMU KVM vCPU context
|
||||
+ * @cpu: QOM CPUState object for which QEMU KVM vCPU context has to be parked.
|
||||
+ *
|
||||
+ * @returns: none
|
||||
+ */
|
||||
+void kvm_park_vcpu(CPUState *cpu);
|
||||
+
|
||||
+/**
|
||||
+ * kvm_unpark_vcpu - unpark QEMU KVM vCPU context
|
||||
+ * @s: KVM State
|
||||
+ * @vcpu_id: Architecture vCPU ID of the parked vCPU
|
||||
+ *
|
||||
+ * @returns: KVM fd
|
||||
+ */
|
||||
+int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id);
|
||||
+
|
||||
/* Arch specific hooks */
|
||||
|
||||
extern const KVMCapabilityInfo kvm_arch_required_capabilities[];
|
||||
@@ -440,8 +465,6 @@ void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
|
||||
|
||||
int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
|
||||
hwaddr *phys_addr);
|
||||
-int kvm_create_vcpu(CPUState *cpu);
|
||||
-void kvm_park_vcpu(CPUState *cpu);
|
||||
|
||||
#endif /* NEED_CPU_H */
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
46
accel-kvm-kvm-all-Fixes-the-missing-break-in-vCPU-un.patch
Normal file
46
accel-kvm-kvm-all-Fixes-the-missing-break-in-vCPU-un.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 9bbc73e18d36d75c5dd842e478ed1f1b47ed4222 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Thu, 1 Aug 2024 10:15:03 +0100
|
||||
Subject: [PATCH 68/78] accel/kvm/kvm-all: Fixes the missing break in vCPU
|
||||
unpark logic
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Loop should exit prematurely on successfully finding out the parked vCPU (struct
|
||||
KVMParkedVcpu) in the 'struct KVMState' maintained 'kvm_parked_vcpus' list of
|
||||
parked vCPUs.
|
||||
|
||||
Fixes: Coverity CID 1558552
|
||||
Fixes: 08c3286822 ("accel/kvm: Extract common KVM vCPU {creation,parking} code")
|
||||
Reported-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-id: 20240725145132.99355-1-salil.mehta@huawei.com
|
||||
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Message-ID: <CAFEAcA-3_d1c7XSXWkFubD-LsW5c5i95e6xxV09r2C9yGtzcdA@mail.gmail.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
accel/kvm/kvm-all.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
|
||||
index 8dea8f98bb..79d5671841 100644
|
||||
--- a/accel/kvm/kvm-all.c
|
||||
+++ b/accel/kvm/kvm-all.c
|
||||
@@ -351,6 +351,7 @@ int kvm_unpark_vcpu(KVMState *s, unsigned long vcpu_id)
|
||||
QLIST_REMOVE(cpu, node);
|
||||
kvm_fd = cpu->kvm_fd;
|
||||
g_free(cpu);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
27
fix-compile-error-on-loongarch.patch
Normal file
27
fix-compile-error-on-loongarch.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 0826efefea34a6fb6e17502f3a293572f109a261 Mon Sep 17 00:00:00 2001
|
||||
From: Xianglai Li <lixianglai@loongson.cn>
|
||||
Date: Thu, 5 Dec 2024 14:18:01 +0800
|
||||
Subject: [PATCH] fix compile error on loongarch
|
||||
|
||||
add cpu.h in loongarch_ipi.c
|
||||
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/intc/loongarch_ipi.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
|
||||
index e228669aa5..630bcb14ea 100644
|
||||
--- a/hw/intc/loongarch_ipi.c
|
||||
+++ b/hw/intc/loongarch_ipi.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/loongarch/virt.h"
|
||||
#include "migration/vmstate.h"
|
||||
+#include "target/loongarch/cpu.h"
|
||||
#include "target/loongarch/internals.h"
|
||||
#include "trace.h"
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
87
gdbstub-Add-helper-function-to-unregister-GDB-regist.patch
Normal file
87
gdbstub-Add-helper-function-to-unregister-GDB-regist.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From 7754cf384417295dc74add4e774c506d751671a9 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Tue, 16 Jul 2024 12:15:02 +0100
|
||||
Subject: [PATCH 67/78] gdbstub: Add helper function to unregister GDB register
|
||||
space
|
||||
|
||||
Add common function to help unregister the GDB register space. This shall be
|
||||
done in context to the CPU unrealization.
|
||||
|
||||
Note: These are common functions exported to arch specific code. For example,
|
||||
for ARM this code is being referred in associated arch specific patch-set:
|
||||
|
||||
Link: https://lore.kernel.org/qemu-devel/20230926103654.34424-1-salil.mehta@huawei.com/
|
||||
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Tested-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Tested-by: Miguel Luis <miguel.luis@oracle.com>
|
||||
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
|
||||
Reviewed-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Tested-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20240716111502.202344-8-salil.mehta@huawei.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
gdbstub/gdbstub.c | 7 +++++++
|
||||
hw/core/cpu-common.c | 4 ++++
|
||||
include/exec/gdbstub.h | 5 +++++
|
||||
3 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
|
||||
index f16006d2a8..31c3dae525 100644
|
||||
--- a/gdbstub/gdbstub.c
|
||||
+++ b/gdbstub/gdbstub.c
|
||||
@@ -584,8 +584,15 @@ void gdb_register_coprocessor(CPUState *cpu,
|
||||
|
||||
void gdb_unregister_coprocessor_all(CPUState *cpu)
|
||||
{
|
||||
+ /*
|
||||
+ * Safe to nuke everything. GDBRegisterState::xml is static const char so
|
||||
+ * it won't be freed
|
||||
+ */
|
||||
g_array_free(cpu->gdb_regs, true);
|
||||
+
|
||||
cpu->gdb_regs = NULL;
|
||||
+ cpu->gdb_num_regs = 0;
|
||||
+ cpu->gdb_num_g_regs = 0;
|
||||
}
|
||||
|
||||
static void gdb_process_breakpoint_remove_all(GDBProcess *p)
|
||||
diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
|
||||
index 82dae51a55..e36ca2c207 100644
|
||||
--- a/hw/core/cpu-common.c
|
||||
+++ b/hw/core/cpu-common.c
|
||||
@@ -262,6 +262,10 @@ static void cpu_common_finalize(Object *obj)
|
||||
{
|
||||
CPUState *cpu = CPU(obj);
|
||||
|
||||
+ /* If cleanup didn't happen in context to gdb_unregister_coprocessor_all */
|
||||
+ if (cpu->gdb_regs) {
|
||||
+ g_array_free(cpu->gdb_regs, TRUE);
|
||||
+ }
|
||||
qemu_lockcnt_destroy(&cpu->in_ioctl_lock);
|
||||
qemu_mutex_destroy(&cpu->work_mutex);
|
||||
}
|
||||
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
|
||||
index d123b838c2..e2e8dff051 100644
|
||||
--- a/include/exec/gdbstub.h
|
||||
+++ b/include/exec/gdbstub.h
|
||||
@@ -39,6 +39,11 @@ typedef int (*gdb_set_reg_cb)(CPUArchState *env, uint8_t *buf, int reg);
|
||||
void gdb_register_coprocessor(CPUState *cpu,
|
||||
gdb_get_reg_cb get_reg, gdb_set_reg_cb set_reg,
|
||||
int num_regs, const char *xml, int g_pos);
|
||||
+
|
||||
+/**
|
||||
+ * gdb_unregister_coprocessor_all() - unregisters supplemental set of registers
|
||||
+ * @cpu - the CPU associated with registers
|
||||
+ */
|
||||
void gdb_unregister_coprocessor_all(CPUState *cpu);
|
||||
|
||||
/**
|
||||
--
|
||||
2.39.1
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From a8416845f721aa5ba03446b3ccf83b096b7a0d77 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Tue, 16 Jul 2024 12:14:57 +0100
|
||||
Subject: [PATCH 63/78] hw/acpi: Move CPU ctrl-dev MMIO region len macro to
|
||||
common header file
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
CPU ctrl-dev MMIO region length could be used in ACPI GED and various other
|
||||
architecture specific places. Move ACPI_CPU_HOTPLUG_REG_LEN macro to more
|
||||
appropriate common header file.
|
||||
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
|
||||
Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Tested-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Tested-by: Miguel Luis <miguel.luis@oracle.com>
|
||||
Tested-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20240716111502.202344-3-salil.mehta@huawei.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
include/hw/acpi/cpu.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
|
||||
index fced952152..fa5b5e5f01 100644
|
||||
--- a/include/hw/acpi/cpu.h
|
||||
+++ b/include/hw/acpi/cpu.h
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "hw/boards.h"
|
||||
#include "hw/hotplug.h"
|
||||
|
||||
+#define ACPI_CPU_HOTPLUG_REG_LEN 12
|
||||
+
|
||||
typedef struct AcpiCpuStatus {
|
||||
CPUState *cpu;
|
||||
uint64_t arch_id;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
@ -0,0 +1,128 @@
|
||||
From ac96f216155002d0c874ff88e301e83495093085 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Tue, 16 Jul 2024 12:14:58 +0100
|
||||
Subject: [PATCH 64/78] hw/acpi: Update ACPI GED framework to support vCPU
|
||||
Hotplug
|
||||
|
||||
ACPI GED (as described in the ACPI 6.4 spec) uses an interrupt listed in the
|
||||
_CRS object of GED to intimate OSPM about an event. Later then demultiplexes the
|
||||
notified event by evaluating ACPI _EVT method to know the type of event. Use
|
||||
ACPI GED to also notify the guest kernel about any CPU hot(un)plug events.
|
||||
|
||||
Note, GED interface is used by many hotplug events like memory hotplug, NVDIMM
|
||||
hotplug and non-hotplug events like system power down event. Each of these can
|
||||
be selected using a bit in the 32 bit GED IO interface. A bit has been reserved
|
||||
for the CPU hotplug event.
|
||||
|
||||
ACPI CPU hotplug related initialization should only happen if ACPI_CPU_HOTPLUG
|
||||
support has been enabled for particular architecture. Add cpu_hotplug_hw_init()
|
||||
stub to avoid compilation break.
|
||||
|
||||
Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Reviewed-by: David Hildenbrand <david@redhat.com>
|
||||
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
|
||||
Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Tested-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Tested-by: Miguel Luis <miguel.luis@oracle.com>
|
||||
Reviewed-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Tested-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Message-Id: <20240716111502.202344-4-salil.mehta@huawei.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++-
|
||||
hw/acpi/generic_event_device.c | 37 ++++++++++++++++++++++++++
|
||||
include/hw/acpi/generic_event_device.h | 1 +
|
||||
3 files changed, 40 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
index 0bd3f9399f..3acd6fcd8b 100644
|
||||
--- a/docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
+++ b/docs/specs/acpi_hw_reduced_hotplug.rst
|
||||
@@ -64,7 +64,8 @@ GED IO interface (4 byte access)
|
||||
0: Memory hotplug event
|
||||
1: System power down event
|
||||
2: NVDIMM hotplug event
|
||||
- 3-31: Reserved
|
||||
+ 3: CPU hotplug event
|
||||
+ 4-31: Reserved
|
||||
|
||||
**write_access:**
|
||||
|
||||
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
|
||||
index 2ce7031f1a..755653dc26 100644
|
||||
--- a/hw/acpi/generic_event_device.c
|
||||
+++ b/hw/acpi/generic_event_device.c
|
||||
@@ -397,6 +397,42 @@ static const VMStateDescription vmstate_acpi_ged = {
|
||||
}
|
||||
};
|
||||
|
||||
+static void acpi_ged_realize(DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
+ AcpiGedState *s = ACPI_GED(dev);
|
||||
+ uint32_t ged_events;
|
||||
+ int i;
|
||||
+
|
||||
+ ged_events = ctpop32(s->ged_event_bitmap);
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(ged_supported_events) && ged_events; i++) {
|
||||
+ uint32_t event = s->ged_event_bitmap & ged_supported_events[i];
|
||||
+
|
||||
+ if (!event) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (event) {
|
||||
+ case ACPI_GED_CPU_HOTPLUG_EVT:
|
||||
+ /* initialize CPU Hotplug related regions */
|
||||
+ memory_region_init(&s->container_cpuhp, OBJECT(dev),
|
||||
+ "cpuhp container",
|
||||
+ ACPI_CPU_HOTPLUG_REG_LEN);
|
||||
+ sysbus_init_mmio(sbd, &s->container_cpuhp);
|
||||
+ cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev),
|
||||
+ &s->cpuhp_state, 0);
|
||||
+ break;
|
||||
+ }
|
||||
+ ged_events--;
|
||||
+ }
|
||||
+
|
||||
+ if (ged_events) {
|
||||
+ error_report("Unsupported events specified");
|
||||
+ abort();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void acpi_ged_initfn(Object *obj)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
@@ -447,6 +483,7 @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
|
||||
dc->desc = "ACPI Generic Event Device";
|
||||
device_class_set_props(dc, acpi_ged_properties);
|
||||
dc->vmsd = &vmstate_acpi_ged;
|
||||
+ dc->realize = acpi_ged_realize;
|
||||
|
||||
hc->plug = acpi_ged_device_plug_cb;
|
||||
hc->unplug_request = acpi_ged_unplug_request_cb;
|
||||
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
|
||||
index 8ed9534c57..d1df3c12e5 100644
|
||||
--- a/include/hw/acpi/generic_event_device.h
|
||||
+++ b/include/hw/acpi/generic_event_device.h
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "hw/acpi/cpu_hotplug.h"
|
||||
#include "hw/acpi/memory_hotplug.h"
|
||||
#include "hw/acpi/ghes.h"
|
||||
+#include "hw/acpi/cpu.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
|
||||
--
|
||||
2.39.1
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From 16d44ddb63becd559cc2185549c4b18d26feab60 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Tue, 16 Jul 2024 12:15:00 +0100
|
||||
Subject: [PATCH 65/78] hw/acpi: Update CPUs AML with cpu-(ctrl)dev change
|
||||
|
||||
CPUs Control device(\\_SB.PCI0) register interface for the x86 arch is IO port
|
||||
based and existing CPUs AML code assumes _CRS objects would evaluate to a system
|
||||
resource which describes IO Port address. But on ARM arch CPUs control
|
||||
device(\\_SB.PRES) register interface is memory-mapped hence _CRS object should
|
||||
evaluate to system resource which describes memory-mapped base address. Update
|
||||
build CPUs AML function to accept both IO/MEMORY region spaces and accordingly
|
||||
update the _CRS object.
|
||||
|
||||
Co-developed-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
||||
Tested-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Tested-by: Miguel Luis <miguel.luis@oracle.com>
|
||||
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
|
||||
Tested-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20240716111502.202344-6-salil.mehta@huawei.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/acpi/cpu.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
|
||||
index 292e1daca2..5e9093991e 100644
|
||||
--- a/hw/acpi/cpu.c
|
||||
+++ b/hw/acpi/cpu.c
|
||||
@@ -392,11 +392,13 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
|
||||
aml_name_decl("_UID", aml_string("CPU Hotplug resources")));
|
||||
aml_append(cpu_ctrl_dev, aml_mutex(CPU_LOCK, 0));
|
||||
|
||||
+ assert((rs == AML_SYSTEM_IO) || (rs == AML_SYSTEM_MEMORY));
|
||||
+
|
||||
crs = aml_resource_template();
|
||||
if (rs == AML_SYSTEM_IO) {
|
||||
aml_append(crs, aml_io(AML_DECODE16, base_addr, base_addr, 1,
|
||||
ACPI_CPU_HOTPLUG_REG_LEN));
|
||||
- } else {
|
||||
+ } else if (rs == AML_SYSTEM_MEMORY) {
|
||||
aml_append(crs, aml_memory32_fixed(base_addr,
|
||||
ACPI_CPU_HOTPLUG_REG_LEN, AML_READ_WRITE));
|
||||
}
|
||||
--
|
||||
2.39.1
|
||||
|
||||
237
hw-arm-virt-acpi-build.c-Migrate-SPCR-creation-to-co.patch
Normal file
237
hw-arm-virt-acpi-build.c-Migrate-SPCR-creation-to-co.patch
Normal file
@ -0,0 +1,237 @@
|
||||
From f6b4a18ba78b1daa2a69fccfb768ec2bdcafb1d4 Mon Sep 17 00:00:00 2001
|
||||
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
|
||||
Date: Sun, 28 Jan 2024 18:14:39 -0800
|
||||
Subject: [PATCH] hw/arm/virt-acpi-build.c: Migrate SPCR creation to common
|
||||
location
|
||||
|
||||
RISC-V should also generate the SPCR in a manner similar to ARM.
|
||||
Therefore, instead of replicating the code, relocate this function
|
||||
to the common AML build.
|
||||
|
||||
Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
|
||||
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
Message-ID: <20240129021440.17640-2-jeeheng.sia@starfivetech.com>
|
||||
[ Changes by AF:
|
||||
- Add missing Language SPCR entry
|
||||
]
|
||||
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/acpi/aml-build.c | 53 +++++++++++++++++++++++++++++
|
||||
hw/arm/virt-acpi-build.c | 68 +++++++++++++++----------------------
|
||||
include/hw/acpi/acpi-defs.h | 33 ++++++++++++++++++
|
||||
include/hw/acpi/aml-build.h | 4 +++
|
||||
4 files changed, 117 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
||||
index 0d4994baf..3fb996c03 100644
|
||||
--- a/hw/acpi/aml-build.c
|
||||
+++ b/hw/acpi/aml-build.c
|
||||
@@ -2016,6 +2016,59 @@ void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
|
||||
}
|
||||
}
|
||||
|
||||
+void build_spcr(GArray *table_data, BIOSLinker *linker,
|
||||
+ const AcpiSpcrData *f, const uint8_t rev,
|
||||
+ const char *oem_id, const char *oem_table_id)
|
||||
+{
|
||||
+ AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
|
||||
+ .oem_table_id = oem_table_id };
|
||||
+
|
||||
+ acpi_table_begin(&table, table_data);
|
||||
+ /* Interface type */
|
||||
+ build_append_int_noprefix(table_data, f->interface_type, 1);
|
||||
+ /* Reserved */
|
||||
+ build_append_int_noprefix(table_data, 0, 3);
|
||||
+ /* Base Address */
|
||||
+ build_append_gas(table_data, f->base_addr.id, f->base_addr.width,
|
||||
+ f->base_addr.offset, f->base_addr.size,
|
||||
+ f->base_addr.addr);
|
||||
+ /* Interrupt type */
|
||||
+ build_append_int_noprefix(table_data, f->interrupt_type, 1);
|
||||
+ /* IRQ */
|
||||
+ build_append_int_noprefix(table_data, f->pc_interrupt, 1);
|
||||
+ /* Global System Interrupt */
|
||||
+ build_append_int_noprefix(table_data, f->interrupt, 4);
|
||||
+ /* Baud Rate */
|
||||
+ build_append_int_noprefix(table_data, f->baud_rate, 1);
|
||||
+ /* Parity */
|
||||
+ build_append_int_noprefix(table_data, f->parity, 1);
|
||||
+ /* Stop Bits */
|
||||
+ build_append_int_noprefix(table_data, f->stop_bits, 1);
|
||||
+ /* Flow Control */
|
||||
+ build_append_int_noprefix(table_data, f->flow_control, 1);
|
||||
+ /* Language */
|
||||
+ build_append_int_noprefix(table_data, f->language, 1);
|
||||
+ /* Terminal Type */
|
||||
+ build_append_int_noprefix(table_data, f->terminal_type, 1);
|
||||
+ /* PCI Device ID */
|
||||
+ build_append_int_noprefix(table_data, f->pci_device_id, 2);
|
||||
+ /* PCI Vendor ID */
|
||||
+ build_append_int_noprefix(table_data, f->pci_vendor_id, 2);
|
||||
+ /* PCI Bus Number */
|
||||
+ build_append_int_noprefix(table_data, f->pci_bus, 1);
|
||||
+ /* PCI Device Number */
|
||||
+ build_append_int_noprefix(table_data, f->pci_device, 1);
|
||||
+ /* PCI Function Number */
|
||||
+ build_append_int_noprefix(table_data, f->pci_function, 1);
|
||||
+ /* PCI Flags */
|
||||
+ build_append_int_noprefix(table_data, f->pci_flags, 4);
|
||||
+ /* PCI Segment */
|
||||
+ build_append_int_noprefix(table_data, f->pci_segment, 1);
|
||||
+ /* Reserved */
|
||||
+ build_append_int_noprefix(table_data, 0, 4);
|
||||
+
|
||||
+ acpi_table_end(linker, &table);
|
||||
+}
|
||||
/*
|
||||
* ACPI spec, Revision 6.3
|
||||
* 5.2.29 Processor Properties Topology Table (PPTT)
|
||||
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
|
||||
index 86984b716..076781423 100644
|
||||
--- a/hw/arm/virt-acpi-build.c
|
||||
+++ b/hw/arm/virt-acpi-build.c
|
||||
@@ -717,48 +717,34 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
* Rev: 1.07
|
||||
*/
|
||||
static void
|
||||
-build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
+spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
|
||||
{
|
||||
- AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = vms->oem_id,
|
||||
- .oem_table_id = vms->oem_table_id };
|
||||
-
|
||||
- acpi_table_begin(&table, table_data);
|
||||
-
|
||||
- /* Interface Type */
|
||||
- build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */
|
||||
- build_append_int_noprefix(table_data, 0, 3); /* Reserved */
|
||||
- /* Base Address */
|
||||
- build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 3,
|
||||
- vms->memmap[VIRT_UART].base);
|
||||
- /* Interrupt Type */
|
||||
- build_append_int_noprefix(table_data,
|
||||
- (1 << 3) /* Bit[3] ARMH GIC interrupt */, 1);
|
||||
- build_append_int_noprefix(table_data, 0, 1); /* IRQ */
|
||||
- /* Global System Interrupt */
|
||||
- build_append_int_noprefix(table_data,
|
||||
- vms->irqmap[VIRT_UART] + ARM_SPI_BASE, 4);
|
||||
- build_append_int_noprefix(table_data, 3 /* 9600 */, 1); /* Baud Rate */
|
||||
- build_append_int_noprefix(table_data, 0 /* No Parity */, 1); /* Parity */
|
||||
- /* Stop Bits */
|
||||
- build_append_int_noprefix(table_data, 1 /* 1 Stop bit */, 1);
|
||||
- /* Flow Control */
|
||||
- build_append_int_noprefix(table_data,
|
||||
- (1 << 1) /* RTS/CTS hardware flow control */, 1);
|
||||
- /* Terminal Type */
|
||||
- build_append_int_noprefix(table_data, 0 /* VT100 */, 1);
|
||||
- build_append_int_noprefix(table_data, 0, 1); /* Language */
|
||||
- /* PCI Device ID */
|
||||
- build_append_int_noprefix(table_data, 0xffff /* not a PCI device*/, 2);
|
||||
- /* PCI Vendor ID */
|
||||
- build_append_int_noprefix(table_data, 0xffff /* not a PCI device*/, 2);
|
||||
- build_append_int_noprefix(table_data, 0, 1); /* PCI Bus Number */
|
||||
- build_append_int_noprefix(table_data, 0, 1); /* PCI Device Number */
|
||||
- build_append_int_noprefix(table_data, 0, 1); /* PCI Function Number */
|
||||
- build_append_int_noprefix(table_data, 0, 4); /* PCI Flags */
|
||||
- build_append_int_noprefix(table_data, 0, 1); /* PCI Segment */
|
||||
- build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
+ AcpiSpcrData serial = {
|
||||
+ .interface_type = 3, /* ARM PL011 UART */
|
||||
+ .base_addr.id = AML_AS_SYSTEM_MEMORY,
|
||||
+ .base_addr.width = 32,
|
||||
+ .base_addr.offset = 0,
|
||||
+ .base_addr.size = 3,
|
||||
+ .base_addr.addr = vms->memmap[VIRT_UART].base,
|
||||
+ .interrupt_type = (1 << 3),/* Bit[3] ARMH GIC interrupt*/
|
||||
+ .pc_interrupt = 0, /* IRQ */
|
||||
+ .interrupt = (vms->irqmap[VIRT_UART] + ARM_SPI_BASE),
|
||||
+ .baud_rate = 3, /* 9600 */
|
||||
+ .parity = 0, /* No Parity */
|
||||
+ .stop_bits = 1, /* 1 Stop bit */
|
||||
+ .flow_control = 1 << 1, /* RTS/CTS hardware flow control */
|
||||
+ .terminal_type = 0, /* VT100 */
|
||||
+ .language = 0, /* Language */
|
||||
+ .pci_device_id = 0xffff, /* not a PCI device*/
|
||||
+ .pci_vendor_id = 0xffff, /* not a PCI device*/
|
||||
+ .pci_bus = 0,
|
||||
+ .pci_device = 0,
|
||||
+ .pci_function = 0,
|
||||
+ .pci_flags = 0,
|
||||
+ .pci_segment = 0,
|
||||
+ };
|
||||
|
||||
- acpi_table_end(linker, &table);
|
||||
+ build_spcr(table_data, linker, &serial, 2, vms->oem_id, vms->oem_table_id);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1316,7 +1302,7 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
|
||||
}
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
- build_spcr(tables_blob, tables->linker, vms);
|
||||
+ spcr_setup(tables_blob, tables->linker, vms);
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_dbg2(tables_blob, tables->linker, vms);
|
||||
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
|
||||
index b1f389fb4..7a8b708cd 100644
|
||||
--- a/include/hw/acpi/acpi-defs.h
|
||||
+++ b/include/hw/acpi/acpi-defs.h
|
||||
@@ -90,6 +90,39 @@ typedef struct AcpiFadtData {
|
||||
unsigned *xdsdt_tbl_offset;
|
||||
} AcpiFadtData;
|
||||
|
||||
+typedef struct AcpiGas {
|
||||
+ uint8_t id; /* Address space ID */
|
||||
+ uint8_t width; /* Register bit width */
|
||||
+ uint8_t offset; /* Register bit offset */
|
||||
+ uint8_t size; /* Access size */
|
||||
+ uint64_t addr; /* Address */
|
||||
+} AcpiGas;
|
||||
+
|
||||
+/* SPCR (Serial Port Console Redirection table) */
|
||||
+typedef struct AcpiSpcrData {
|
||||
+ uint8_t interface_type;
|
||||
+ uint8_t reserved[3];
|
||||
+ struct AcpiGas base_addr;
|
||||
+ uint8_t interrupt_type;
|
||||
+ uint8_t pc_interrupt;
|
||||
+ uint32_t interrupt; /* Global system interrupt */
|
||||
+ uint8_t baud_rate;
|
||||
+ uint8_t parity;
|
||||
+ uint8_t stop_bits;
|
||||
+ uint8_t flow_control;
|
||||
+ uint8_t terminal_type;
|
||||
+ uint8_t language;
|
||||
+ uint8_t reserved1;
|
||||
+ uint16_t pci_device_id; /* Must be 0xffff if not PCI device */
|
||||
+ uint16_t pci_vendor_id; /* Must be 0xffff if not PCI device */
|
||||
+ uint8_t pci_bus;
|
||||
+ uint8_t pci_device;
|
||||
+ uint8_t pci_function;
|
||||
+ uint32_t pci_flags;
|
||||
+ uint8_t pci_segment;
|
||||
+ uint32_t reserved2;
|
||||
+} AcpiSpcrData;
|
||||
+
|
||||
#define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0)
|
||||
#define ACPI_FADT_ARM_PSCI_USE_HVC (1 << 1)
|
||||
|
||||
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
|
||||
index 91f9cbf4f..381ad4a8a 100644
|
||||
--- a/include/hw/acpi/aml-build.h
|
||||
+++ b/include/hw/acpi/aml-build.h
|
||||
@@ -506,4 +506,8 @@ void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
|
||||
|
||||
void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
|
||||
const char *oem_id, const char *oem_table_id);
|
||||
+
|
||||
+void build_spcr(GArray *table_data, BIOSLinker *linker,
|
||||
+ const AcpiSpcrData *f, const uint8_t rev,
|
||||
+ const char *oem_id, const char *oem_table_id);
|
||||
#endif
|
||||
--
|
||||
2.43.0
|
||||
|
||||
400
hw-loongarch-Add-KVM-IPI-device-support.patch
Normal file
400
hw-loongarch-Add-KVM-IPI-device-support.patch
Normal file
@ -0,0 +1,400 @@
|
||||
From 24e4e6742bdc8d804760e84f4e4bde5460e1e024 Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Sun, 8 Sep 2024 09:29:00 +0800
|
||||
Subject: [PATCH 72/78] hw/loongarch: Add KVM IPI device support
|
||||
|
||||
Added ipi interrupt controller for kvm emulation.
|
||||
The main process is to send the command word for
|
||||
creating an ipi device to the kernel.
|
||||
When the VM is saved, the ioctl obtains the ipi
|
||||
interrupt controller data in the kernel and saves it.
|
||||
When the VM is recovered, the saved data is sent to the kernel.
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/intc/Kconfig | 3 +
|
||||
hw/intc/loongarch_ipi_kvm.c | 207 ++++++++++++++++++++++++++++++++
|
||||
hw/intc/meson.build | 1 +
|
||||
hw/loongarch/Kconfig | 1 +
|
||||
hw/loongarch/virt.c | 35 ++++--
|
||||
include/hw/intc/loongarch_ipi.h | 23 ++++
|
||||
linux-headers/linux/kvm.h | 2 +
|
||||
target/loongarch/kvm/kvm.c | 4 +
|
||||
8 files changed, 263 insertions(+), 13 deletions(-)
|
||||
create mode 100644 hw/intc/loongarch_ipi_kvm.c
|
||||
|
||||
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
|
||||
index 97d550b06b..cbba74c22e 100644
|
||||
--- a/hw/intc/Kconfig
|
||||
+++ b/hw/intc/Kconfig
|
||||
@@ -93,6 +93,9 @@ config NIOS2_VIC
|
||||
config LOONGARCH_IPI
|
||||
bool
|
||||
|
||||
+config LOONGARCH_IPI_KVM
|
||||
+ bool
|
||||
+
|
||||
config LOONGARCH_PCH_PIC
|
||||
bool
|
||||
select UNIMP
|
||||
diff --git a/hw/intc/loongarch_ipi_kvm.c b/hw/intc/loongarch_ipi_kvm.c
|
||||
new file mode 100644
|
||||
index 0000000000..fd308eb0c0
|
||||
--- /dev/null
|
||||
+++ b/hw/intc/loongarch_ipi_kvm.c
|
||||
@@ -0,0 +1,207 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * LoongArch kvm ipi interrupt support
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "qemu/typedefs.h"
|
||||
+#include "hw/intc/loongarch_ipi.h"
|
||||
+#include "hw/sysbus.h"
|
||||
+#include "linux/kvm.h"
|
||||
+#include "migration/vmstate.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
+
|
||||
+#define IPI_DEV_FD_UNDEF -1
|
||||
+
|
||||
+static void kvm_ipi_access_regs(int fd, uint64_t addr,
|
||||
+ uint32_t *val, int is_write)
|
||||
+{
|
||||
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_IPI_GRP_REGS,
|
||||
+ addr, val, is_write, &error_abort);
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_ipi_pre_save(void *opaque)
|
||||
+{
|
||||
+ KVMLoongArchIPI *ipi = (KVMLoongArchIPI *)opaque;
|
||||
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_GET_CLASS(ipi);
|
||||
+ IPICore *cpu;
|
||||
+ uint64_t attr;
|
||||
+ int cpu_id = 0;
|
||||
+ int fd = ipi_class->dev_fd;
|
||||
+
|
||||
+ for (cpu_id = 0; cpu_id < ipi->num_cpu; cpu_id++) {
|
||||
+ cpu = &ipi->cpu[cpu_id];
|
||||
+ attr = (cpu_id << 16) | CORE_STATUS_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->status, false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_EN_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->en, false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_SET_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->set, false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_CLEAR_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->clear, false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_20;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[0], false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_28;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[2], false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_30;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[4], false);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_38;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[6], false);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_ipi_post_load(void *opaque, int version_id)
|
||||
+{
|
||||
+ KVMLoongArchIPI *ipi = (KVMLoongArchIPI *)opaque;
|
||||
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_GET_CLASS(ipi);
|
||||
+ IPICore *cpu;
|
||||
+ uint64_t attr;
|
||||
+ int cpu_id = 0;
|
||||
+ int fd = ipi_class->dev_fd;
|
||||
+
|
||||
+ for (cpu_id = 0; cpu_id < ipi->num_cpu; cpu_id++) {
|
||||
+ cpu = &ipi->cpu[cpu_id];
|
||||
+ attr = (cpu_id << 16) | CORE_STATUS_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->status, true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_EN_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->en, true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_SET_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->set, true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_CLEAR_OFF;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->clear, true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_20;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[0], true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_28;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[2], true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_30;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[4], true);
|
||||
+
|
||||
+ attr = (cpu_id << 16) | CORE_BUF_38;
|
||||
+ kvm_ipi_access_regs(fd, attr, &cpu->buf[6], true);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void kvm_loongarch_ipi_realize(DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ KVMLoongArchIPI *ipi = KVM_LOONGARCH_IPI(dev);
|
||||
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_GET_CLASS(dev);
|
||||
+ struct kvm_create_device cd = {0};
|
||||
+ Error *err = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (ipi->num_cpu == 0) {
|
||||
+ error_setg(errp, "num-cpu must be at least 1");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ipi_class->parent_realize(dev, &err);
|
||||
+ if (err) {
|
||||
+ error_propagate(errp, err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ipi->cpu = g_new0(IPICore, ipi->num_cpu);
|
||||
+ if (ipi->cpu == NULL) {
|
||||
+ error_setg(errp, "Memory allocation for ExtIOICore faile");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!ipi_class->is_created) {
|
||||
+ cd.type = KVM_DEV_TYPE_LA_IPI;
|
||||
+ ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd);
|
||||
+ if (ret < 0) {
|
||||
+ error_setg_errno(errp, errno, "Creating the KVM device failed");
|
||||
+ return;
|
||||
+ }
|
||||
+ ipi_class->is_created = true;
|
||||
+ ipi_class->dev_fd = cd.fd;
|
||||
+ fprintf(stdout, "Create LoongArch IPI irqchip in KVM done!\n");
|
||||
+ }
|
||||
+
|
||||
+ assert(ipi_class->dev_fd != IPI_DEV_FD_UNDEF);
|
||||
+}
|
||||
+
|
||||
+static Property kvm_loongarch_ipi_properties[] = {
|
||||
+ DEFINE_PROP_UINT32("num-cpu", KVMLoongArchIPI, num_cpu, 1),
|
||||
+ DEFINE_PROP_END_OF_LIST()
|
||||
+};
|
||||
+
|
||||
+static const VMStateDescription vmstate_kvm_ipi_core = {
|
||||
+ .name = "kvm-ipi-single",
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_UINT32(status, IPICore),
|
||||
+ VMSTATE_UINT32(en, IPICore),
|
||||
+ VMSTATE_UINT32(set, IPICore),
|
||||
+ VMSTATE_UINT32(clear, IPICore),
|
||||
+ VMSTATE_UINT32_ARRAY(buf, IPICore, 8),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const VMStateDescription vmstate_kvm_loongarch_ipi = {
|
||||
+ .name = TYPE_KVM_LOONGARCH_IPI,
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .pre_save = kvm_loongarch_ipi_pre_save,
|
||||
+ .post_load = kvm_loongarch_ipi_post_load,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(cpu, KVMLoongArchIPI, num_cpu,
|
||||
+ vmstate_kvm_ipi_core, IPICore),
|
||||
+
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void kvm_loongarch_ipi_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
+ KVMLoongArchIPIClass *ipi_class = KVM_LOONGARCH_IPI_CLASS(oc);
|
||||
+
|
||||
+ ipi_class->parent_realize = dc->realize;
|
||||
+ dc->realize = kvm_loongarch_ipi_realize;
|
||||
+
|
||||
+ ipi_class->is_created = false;
|
||||
+ ipi_class->dev_fd = IPI_DEV_FD_UNDEF;
|
||||
+
|
||||
+ device_class_set_props(dc, kvm_loongarch_ipi_properties);
|
||||
+
|
||||
+ dc->vmsd = &vmstate_kvm_loongarch_ipi;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo kvm_loongarch_ipi_info = {
|
||||
+ .name = TYPE_KVM_LOONGARCH_IPI,
|
||||
+ .parent = TYPE_SYS_BUS_DEVICE,
|
||||
+ .instance_size = sizeof(KVMLoongArchIPI),
|
||||
+ .class_size = sizeof(KVMLoongArchIPIClass),
|
||||
+ .class_init = kvm_loongarch_ipi_class_init,
|
||||
+};
|
||||
+
|
||||
+static void kvm_loongarch_ipi_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&kvm_loongarch_ipi_info);
|
||||
+}
|
||||
+
|
||||
+type_init(kvm_loongarch_ipi_register_types)
|
||||
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
|
||||
index ed355941d1..9deeeb51bb 100644
|
||||
--- a/hw/intc/meson.build
|
||||
+++ b/hw/intc/meson.build
|
||||
@@ -70,6 +70,7 @@ specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
|
||||
specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
|
||||
specific_ss.add(when: 'CONFIG_NIOS2_VIC', if_true: files('nios2_vic.c'))
|
||||
specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c'))
|
||||
+specific_ss.add(when: 'CONFIG_LOONGARCH_IPI_KVM', if_true: files('loongarch_ipi_kvm.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'))
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index b42a8573d4..1e761624c6 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -14,6 +14,7 @@ config LOONGARCH_VIRT
|
||||
select LOONGARCH_PCH_PIC
|
||||
select LOONGARCH_PCH_MSI
|
||||
select LOONGARCH_EXTIOI
|
||||
+ select LOONGARCH_IPI_KVM if KVM
|
||||
select LS7A_RTC
|
||||
select SMBIOS
|
||||
select ACPI_CPU_HOTPLUG
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 6159fd9470..f065eb75f8 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -829,16 +829,28 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
* +--------+ +---------+ +---------+
|
||||
*/
|
||||
|
||||
- /* Create IPI device */
|
||||
- ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
||||
- qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.max_cpus);
|
||||
- sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
||||
-
|
||||
- /* IPI iocsr memory region */
|
||||
- memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
|
||||
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
|
||||
- memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
|
||||
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ ipi = qdev_new(TYPE_KVM_LOONGARCH_IPI);
|
||||
+ qdev_prop_set_int32(ipi, "num-cpu", ms->smp.max_cpus);
|
||||
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
||||
+ } else {
|
||||
+ ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
||||
+ qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.max_cpus);
|
||||
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
||||
+
|
||||
+ /* IPI iocsr memory region */
|
||||
+ memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
|
||||
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
|
||||
+ memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
|
||||
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
||||
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
||||
+ cpu_state = qemu_get_cpu(cpu);
|
||||
+ cpudev = DEVICE(cpu_state);
|
||||
+
|
||||
+ /* connect ipi irq to cpu irq */
|
||||
+ qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* Add cpu interrupt-controller */
|
||||
fdt_add_cpuic_node(lvms, &cpuintc_phandle);
|
||||
@@ -849,9 +861,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
lacpu = LOONGARCH_CPU(cpu_state);
|
||||
env = &(lacpu->env);
|
||||
env->address_space_iocsr = &lvms->as_iocsr;
|
||||
-
|
||||
- /* connect ipi irq to cpu irq */
|
||||
- qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
|
||||
env->ipistate = ipi;
|
||||
}
|
||||
|
||||
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
|
||||
index 1c1e834849..601b4f18a7 100644
|
||||
--- a/include/hw/intc/loongarch_ipi.h
|
||||
+++ b/include/hw/intc/loongarch_ipi.h
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#define TYPE_LOONGARCH_IPI "loongarch_ipi"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
|
||||
+#define TYPE_KVM_LOONGARCH_IPI "loongarch-ipi-kvm"
|
||||
|
||||
typedef struct IPICore {
|
||||
uint32_t status;
|
||||
@@ -51,4 +52,26 @@ struct LoongArchIPI {
|
||||
IPICore *cpu;
|
||||
};
|
||||
|
||||
+struct KVMLoongArchIPI {
|
||||
+ SysBusDevice parent_obj;
|
||||
+ uint32_t num_cpu;
|
||||
+ IPICore *cpu;
|
||||
+};
|
||||
+typedef struct KVMLoongArchIPI KVMLoongArchIPI;
|
||||
+DECLARE_INSTANCE_CHECKER(KVMLoongArchIPI, KVM_LOONGARCH_IPI,
|
||||
+ TYPE_KVM_LOONGARCH_IPI)
|
||||
+
|
||||
+struct KVMLoongArchIPIClass {
|
||||
+ SysBusDeviceClass parent_class;
|
||||
+ DeviceRealize parent_realize;
|
||||
+
|
||||
+ bool is_created;
|
||||
+ int dev_fd;
|
||||
+
|
||||
+};
|
||||
+typedef struct KVMLoongArchIPIClass KVMLoongArchIPIClass;
|
||||
+DECLARE_CLASS_CHECKERS(KVMLoongArchIPIClass, KVM_LOONGARCH_IPI,
|
||||
+ TYPE_KVM_LOONGARCH_IPI)
|
||||
+
|
||||
+
|
||||
#endif
|
||||
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||
index eb30402c2d..ea1f821a9f 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -1470,6 +1470,8 @@ enum kvm_device_type {
|
||||
#define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME
|
||||
KVM_DEV_TYPE_RISCV_AIA,
|
||||
#define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA
|
||||
+ KVM_DEV_TYPE_LA_IPI,
|
||||
+#define KVM_DEV_TYPE_LA_IPI KVM_DEV_TYPE_LA_IPI
|
||||
KVM_DEV_TYPE_MAX,
|
||||
};
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 550f14269e..ab1ea3d4fd 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -1066,6 +1066,10 @@ int kvm_arch_get_default_type(MachineState *ms)
|
||||
int kvm_arch_init(MachineState *ms, KVMState *s)
|
||||
{
|
||||
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
|
||||
+ if(!kvm_vm_check_attr(kvm_state, KVM_LOONGARCH_VM_HAVE_IRQCHIP, KVM_LOONGARCH_VM_HAVE_IRQCHIP)) {
|
||||
+ s->kernel_irqchip_allowed = false;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
384
hw-loongarch-Add-KVM-extioi-device-support.patch
Normal file
384
hw-loongarch-Add-KVM-extioi-device-support.patch
Normal file
@ -0,0 +1,384 @@
|
||||
From 833cdea8037d9124cd2e0328739de1b85aaec2a2 Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Sun, 8 Sep 2024 09:50:50 +0800
|
||||
Subject: [PATCH 73/78] hw/loongarch: Add KVM extioi device support
|
||||
|
||||
Added extioi interrupt controller for kvm emulation.
|
||||
The main process is to send the command word for
|
||||
creating an extioi device to the kernel.
|
||||
When the VM is saved, the ioctl obtains the related
|
||||
data of the extioi interrupt controller in the kernel
|
||||
and saves it. When the VM is recovered, the saved data
|
||||
is sent to the kernel.
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/intc/Kconfig | 3 +
|
||||
hw/intc/loongarch_extioi_kvm.c | 150 +++++++++++++++++++++++++++++
|
||||
hw/intc/meson.build | 1 +
|
||||
hw/loongarch/Kconfig | 1 +
|
||||
hw/loongarch/virt.c | 50 +++++-----
|
||||
include/hw/intc/loongarch_extioi.h | 36 ++++++-
|
||||
include/hw/loongarch/virt.h | 15 +++
|
||||
linux-headers/linux/kvm.h | 2 +
|
||||
8 files changed, 232 insertions(+), 26 deletions(-)
|
||||
create mode 100644 hw/intc/loongarch_extioi_kvm.c
|
||||
|
||||
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
|
||||
index cbba74c22e..f1e8bd2fc9 100644
|
||||
--- a/hw/intc/Kconfig
|
||||
+++ b/hw/intc/Kconfig
|
||||
@@ -107,3 +107,6 @@ config LOONGARCH_PCH_MSI
|
||||
|
||||
config LOONGARCH_EXTIOI
|
||||
bool
|
||||
+
|
||||
+config LOONGARCH_EXTIOI_KVM
|
||||
+ bool
|
||||
diff --git a/hw/intc/loongarch_extioi_kvm.c b/hw/intc/loongarch_extioi_kvm.c
|
||||
new file mode 100644
|
||||
index 0000000000..f5bbc33255
|
||||
--- /dev/null
|
||||
+++ b/hw/intc/loongarch_extioi_kvm.c
|
||||
@@ -0,0 +1,150 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * LoongArch kvm extioi interrupt support
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "qemu/typedefs.h"
|
||||
+#include "hw/intc/loongarch_extioi.h"
|
||||
+#include "hw/sysbus.h"
|
||||
+#include "linux/kvm.h"
|
||||
+#include "migration/vmstate.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
+
|
||||
+static void kvm_extioi_access_regs(int fd, uint64_t addr,
|
||||
+ void *val, int is_write)
|
||||
+{
|
||||
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS,
|
||||
+ addr, val, is_write, &error_abort);
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_extioi_pre_save(void *opaque)
|
||||
+{
|
||||
+ KVMLoongArchExtIOI *s = (KVMLoongArchExtIOI *)opaque;
|
||||
+ KVMLoongArchExtIOIClass *class = KVM_LOONGARCH_EXTIOI_GET_CLASS(s);
|
||||
+ int fd = class->dev_fd;
|
||||
+
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_NODETYPE_START,
|
||||
+ (void *)s->nodetype, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_IPMAP_START, (void *)s->ipmap, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_ENABLE_START, (void *)s->enable, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_BOUNCE_START, (void *)s->bounce, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_ISR_START, (void *)s->isr, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_COREMAP_START,
|
||||
+ (void *)s->coremap, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_SW_COREMAP_FLAG,
|
||||
+ (void *)s->sw_coremap, false);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_COREISR_START,
|
||||
+ (void *)s->coreisr, false);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_extioi_post_load(void *opaque, int version_id)
|
||||
+{
|
||||
+ KVMLoongArchExtIOI *s = (KVMLoongArchExtIOI *)opaque;
|
||||
+ KVMLoongArchExtIOIClass *class = KVM_LOONGARCH_EXTIOI_GET_CLASS(s);
|
||||
+ int fd = class->dev_fd;
|
||||
+
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_NODETYPE_START,
|
||||
+ (void *)s->nodetype, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_IPMAP_START, (void *)s->ipmap, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_ENABLE_START, (void *)s->enable, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_BOUNCE_START, (void *)s->bounce, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_ISR_START, (void *)s->isr, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_COREMAP_START, (void *)s->coremap, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_SW_COREMAP_FLAG,
|
||||
+ (void *)s->sw_coremap, true);
|
||||
+ kvm_extioi_access_regs(fd, EXTIOI_COREISR_START, (void *)s->coreisr, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void kvm_loongarch_extioi_realize(DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ KVMLoongArchExtIOIClass *extioi_class = KVM_LOONGARCH_EXTIOI_GET_CLASS(dev);
|
||||
+ struct kvm_create_device cd = {0};
|
||||
+ Error *err = NULL;
|
||||
+ int ret,i;
|
||||
+
|
||||
+ extioi_class->parent_realize(dev, &err);
|
||||
+ if (err) {
|
||||
+ error_propagate(errp, err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!extioi_class->is_created) {
|
||||
+ cd.type = KVM_DEV_TYPE_LA_EXTIOI;
|
||||
+ ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd);
|
||||
+ if (ret < 0) {
|
||||
+ error_setg_errno(errp, errno,
|
||||
+ "Creating the KVM extioi device failed");
|
||||
+ return;
|
||||
+ }
|
||||
+ extioi_class->is_created = true;
|
||||
+ extioi_class->dev_fd = cd.fd;
|
||||
+ fprintf(stdout, "Create LoongArch extioi irqchip in KVM done!\n");
|
||||
+ }
|
||||
+
|
||||
+ kvm_async_interrupts_allowed = true;
|
||||
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
|
||||
+ if (kvm_has_gsi_routing()) {
|
||||
+ for (i = 0; i < 64; ++i) {
|
||||
+ kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
|
||||
+ }
|
||||
+ kvm_gsi_routing_allowed = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const VMStateDescription vmstate_kvm_extioi_core = {
|
||||
+ .name = "kvm-extioi-single",
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .pre_save = kvm_loongarch_extioi_pre_save,
|
||||
+ .post_load = kvm_loongarch_extioi_post_load,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_UINT32_ARRAY(nodetype, KVMLoongArchExtIOI,
|
||||
+ EXTIOI_IRQS_NODETYPE_COUNT / 2),
|
||||
+ VMSTATE_UINT32_ARRAY(bounce, KVMLoongArchExtIOI,
|
||||
+ EXTIOI_IRQS_GROUP_COUNT),
|
||||
+ VMSTATE_UINT32_ARRAY(isr, KVMLoongArchExtIOI, EXTIOI_IRQS / 32),
|
||||
+ VMSTATE_UINT32_2DARRAY(coreisr, KVMLoongArchExtIOI, EXTIOI_CPUS,
|
||||
+ EXTIOI_IRQS_GROUP_COUNT),
|
||||
+ VMSTATE_UINT32_ARRAY(enable, KVMLoongArchExtIOI, EXTIOI_IRQS / 32),
|
||||
+ VMSTATE_UINT32_ARRAY(ipmap, KVMLoongArchExtIOI,
|
||||
+ EXTIOI_IRQS_IPMAP_SIZE / 4),
|
||||
+ VMSTATE_UINT32_ARRAY(coremap, KVMLoongArchExtIOI, EXTIOI_IRQS / 4),
|
||||
+ VMSTATE_UINT8_ARRAY(sw_coremap, KVMLoongArchExtIOI, EXTIOI_IRQS),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static void kvm_loongarch_extioi_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
+ KVMLoongArchExtIOIClass *extioi_class = KVM_LOONGARCH_EXTIOI_CLASS(oc);
|
||||
+
|
||||
+ extioi_class->parent_realize = dc->realize;
|
||||
+ dc->realize = kvm_loongarch_extioi_realize;
|
||||
+ extioi_class->is_created = false;
|
||||
+ dc->vmsd = &vmstate_kvm_extioi_core;
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo kvm_loongarch_extioi_info = {
|
||||
+ .name = TYPE_KVM_LOONGARCH_EXTIOI,
|
||||
+ .parent = TYPE_SYS_BUS_DEVICE,
|
||||
+ .instance_size = sizeof(KVMLoongArchExtIOI),
|
||||
+ .class_size = sizeof(KVMLoongArchExtIOIClass),
|
||||
+ .class_init = kvm_loongarch_extioi_class_init,
|
||||
+};
|
||||
+
|
||||
+static void kvm_loongarch_extioi_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&kvm_loongarch_extioi_info);
|
||||
+}
|
||||
+
|
||||
+type_init(kvm_loongarch_extioi_register_types)
|
||||
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
|
||||
index 9deeeb51bb..a37d7da8aa 100644
|
||||
--- a/hw/intc/meson.build
|
||||
+++ b/hw/intc/meson.build
|
||||
@@ -74,3 +74,4 @@ specific_ss.add(when: 'CONFIG_LOONGARCH_IPI_KVM', if_true: files('loongarch_ipi_
|
||||
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'))
|
||||
+specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI_KVM', if_true: files('loongarch_extioi_kvm.c'))
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index 1e761624c6..1a47d44a64 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -15,6 +15,7 @@ config LOONGARCH_VIRT
|
||||
select LOONGARCH_PCH_MSI
|
||||
select LOONGARCH_EXTIOI
|
||||
select LOONGARCH_IPI_KVM if KVM
|
||||
+ select LOONGARCH_EXTIOI_KVM if KVM
|
||||
select LS7A_RTC
|
||||
select SMBIOS
|
||||
select ACPI_CPU_HOTPLUG
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index f065eb75f8..71e2a3735c 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -867,31 +867,33 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
lvms->ipi = ipi;
|
||||
|
||||
/* Create EXTIOI device */
|
||||
- extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
|
||||
- qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.max_cpus);
|
||||
- if (virt_is_veiointc_enabled(lvms)) {
|
||||
- qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
||||
- }
|
||||
- sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
|
||||
-
|
||||
- memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
|
||||
- sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
|
||||
- if (virt_is_veiointc_enabled(lvms)) {
|
||||
- memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
|
||||
- sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
|
||||
- }
|
||||
- lvms->extioi = extioi;
|
||||
-
|
||||
- /*
|
||||
- * connect ext irq to the cpu irq
|
||||
- * cpu_pin[9:2] <= intc_pin[7:0]
|
||||
- */
|
||||
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
||||
- cpudev = DEVICE(qemu_get_cpu(cpu));
|
||||
- for (pin = 0; pin < LS3A_INTC_IP; pin++) {
|
||||
- qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
|
||||
- qdev_get_gpio_in(cpudev, pin + 2));
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ extioi = qdev_new(TYPE_KVM_LOONGARCH_EXTIOI);
|
||||
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
|
||||
+ } else {
|
||||
+ extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
|
||||
+ qdev_prop_set_uint32(extioi, "num-cpu", ms->smp.max_cpus);
|
||||
+ if (virt_is_veiointc_enabled(lvms)) {
|
||||
+ qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
||||
}
|
||||
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
|
||||
+ memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
|
||||
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
|
||||
+ if (virt_is_veiointc_enabled(lvms)) {
|
||||
+ memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
|
||||
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
|
||||
+ }
|
||||
+ /*
|
||||
+ * connect ext irq to the cpu irq
|
||||
+ * cpu_pin[9:2] <= intc_pin[7:0]
|
||||
+ */
|
||||
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
||||
+ cpudev = DEVICE(qemu_get_cpu(cpu));
|
||||
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
|
||||
+ qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
|
||||
+ qdev_get_gpio_in(cpudev, pin + 2));
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
lvms->extioi = extioi;
|
||||
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
|
||||
index 722ffee1bc..9966cd98d3 100644
|
||||
--- a/include/hw/intc/loongarch_extioi.h
|
||||
+++ b/include/hw/intc/loongarch_extioi.h
|
||||
@@ -15,7 +15,7 @@
|
||||
#define EXTIOI_IRQS (256)
|
||||
#define EXTIOI_IRQS_BITMAP_SIZE (256 / 8)
|
||||
/* irq from EXTIOI is routed to no more than 4 cpus */
|
||||
-#define EXTIOI_CPUS (4)
|
||||
+#define EXTIOI_CPUS (256)
|
||||
/* map to ipnum per 32 irqs */
|
||||
#define EXTIOI_IRQS_IPMAP_SIZE (256 / 32)
|
||||
#define EXTIOI_IRQS_COREMAP_SIZE 256
|
||||
@@ -59,13 +59,17 @@
|
||||
#define EXTIOI_VIRT_COREMAP_START (0x40)
|
||||
#define EXTIOI_VIRT_COREMAP_END (0x240)
|
||||
|
||||
+#define EXTIOI_SW_COREMAP_FLAG (1 << 0)
|
||||
+
|
||||
typedef struct ExtIOICore {
|
||||
uint32_t coreisr[EXTIOI_IRQS_GROUP_COUNT];
|
||||
DECLARE_BITMAP(sw_isr[LS3A_INTC_IP], EXTIOI_IRQS);
|
||||
qemu_irq parent_irq[LS3A_INTC_IP];
|
||||
} ExtIOICore;
|
||||
|
||||
-#define TYPE_LOONGARCH_EXTIOI "loongarch.extioi"
|
||||
+#define TYPE_LOONGARCH_EXTIOI "loongarch-extioi"
|
||||
+#define TYPE_KVM_LOONGARCH_EXTIOI "loongarch-kvm-extioi"
|
||||
+
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchExtIOI, LOONGARCH_EXTIOI)
|
||||
struct LoongArchExtIOI {
|
||||
SysBusDevice parent_obj;
|
||||
@@ -87,4 +91,32 @@ struct LoongArchExtIOI {
|
||||
MemoryRegion extioi_system_mem;
|
||||
MemoryRegion virt_extend;
|
||||
};
|
||||
+
|
||||
+struct KVMLoongArchExtIOI {
|
||||
+ SysBusDevice parent_obj;
|
||||
+ /* hardware state */
|
||||
+ uint32_t nodetype[EXTIOI_IRQS_NODETYPE_COUNT / 2];
|
||||
+ uint32_t bounce[EXTIOI_IRQS_GROUP_COUNT];
|
||||
+ uint32_t isr[EXTIOI_IRQS / 32];
|
||||
+ uint32_t coreisr[EXTIOI_CPUS][EXTIOI_IRQS_GROUP_COUNT];
|
||||
+ uint32_t enable[EXTIOI_IRQS / 32];
|
||||
+ uint32_t ipmap[EXTIOI_IRQS_IPMAP_SIZE / 4];
|
||||
+ uint32_t coremap[EXTIOI_IRQS / 4];
|
||||
+ uint8_t sw_coremap[EXTIOI_IRQS];
|
||||
+};
|
||||
+typedef struct KVMLoongArchExtIOI KVMLoongArchExtIOI;
|
||||
+DECLARE_INSTANCE_CHECKER(KVMLoongArchExtIOI, KVM_LOONGARCH_EXTIOI,
|
||||
+ TYPE_KVM_LOONGARCH_EXTIOI)
|
||||
+
|
||||
+struct KVMLoongArchExtIOIClass {
|
||||
+ SysBusDeviceClass parent_class;
|
||||
+ DeviceRealize parent_realize;
|
||||
+
|
||||
+ bool is_created;
|
||||
+ int dev_fd;
|
||||
+};
|
||||
+typedef struct KVMLoongArchExtIOIClass KVMLoongArchExtIOIClass;
|
||||
+DECLARE_CLASS_CHECKERS(KVMLoongArchExtIOIClass, KVM_LOONGARCH_EXTIOI,
|
||||
+ TYPE_KVM_LOONGARCH_EXTIOI)
|
||||
+
|
||||
#endif /* LOONGARCH_EXTIOI_H */
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 98c990327b..168b40c31b 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -38,6 +38,21 @@
|
||||
|
||||
#define FDT_BASE 0x100000
|
||||
|
||||
+/* KVM_IRQ_LINE irq field index values */
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_SHIFT 24
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_MASK 0xff
|
||||
+#define KVM_LOONGARCH_IRQ_VCPU_SHIFT 16
|
||||
+#define KVM_LOONGARCH_IRQ_VCPU_MASK 0xff
|
||||
+#define KVM_LOONGARCH_IRQ_NUM_SHIFT 0
|
||||
+#define KVM_LOONGARCH_IRQ_NUM_MASK 0xffff
|
||||
+
|
||||
+/* irq_type field */
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_CPU_IP 0
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_CPU_IO 1
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_HT 2
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_MSI 3
|
||||
+#define KVM_LOONGARCH_IRQ_TYPE_IOAPIC 4
|
||||
+
|
||||
struct LoongArchVirtMachineState {
|
||||
/*< private >*/
|
||||
MachineState parent_obj;
|
||||
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||
index ea1f821a9f..0c0b82d1ef 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -1472,6 +1472,8 @@ enum kvm_device_type {
|
||||
#define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA
|
||||
KVM_DEV_TYPE_LA_IPI,
|
||||
#define KVM_DEV_TYPE_LA_IPI KVM_DEV_TYPE_LA_IPI
|
||||
+ KVM_DEV_TYPE_LA_EXTIOI,
|
||||
+#define KVM_DEV_TYPE_LA_EXTIOI KVM_DEV_TYPE_LA_EXTIOI
|
||||
KVM_DEV_TYPE_MAX,
|
||||
};
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
136
hw-loongarch-Add-KVM-pch-msi-device-support.patch
Normal file
136
hw-loongarch-Add-KVM-pch-msi-device-support.patch
Normal file
@ -0,0 +1,136 @@
|
||||
From 24bd774f8146247c7ac6071492f6016140a97267 Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Sun, 8 Sep 2024 22:18:50 +0800
|
||||
Subject: [PATCH 75/78] hw/loongarch: Add KVM pch msi device support
|
||||
|
||||
Added pch_msi interrupt controller handling
|
||||
during kernel emulation of irq chip.
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/intc/loongarch_pch_msi.c | 39 ++++++++++++++++++++++-------
|
||||
hw/loongarch/virt.c | 22 +++++++++-------
|
||||
include/hw/intc/loongarch_pch_msi.h | 2 +-
|
||||
3 files changed, 44 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/hw/intc/loongarch_pch_msi.c b/hw/intc/loongarch_pch_msi.c
|
||||
index ecf3ed0267..901c2c21be 100644
|
||||
--- a/hw/intc/loongarch_pch_msi.c
|
||||
+++ b/hw/intc/loongarch_pch_msi.c
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "hw/misc/unimp.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
+#include "hw/loongarch/virt.h"
|
||||
|
||||
static uint64_t loongarch_msi_mem_read(void *opaque, hwaddr addr, unsigned size)
|
||||
{
|
||||
@@ -26,14 +28,24 @@ static void loongarch_msi_mem_write(void *opaque, hwaddr addr,
|
||||
LoongArchPCHMSI *s = (LoongArchPCHMSI *)opaque;
|
||||
int irq_num;
|
||||
|
||||
- /*
|
||||
- * vector number is irq number from upper extioi intc
|
||||
- * need subtract irq base to get msi vector offset
|
||||
- */
|
||||
- irq_num = (val & 0xff) - s->irq_base;
|
||||
- trace_loongarch_msi_set_irq(irq_num);
|
||||
- assert(irq_num < s->irq_num);
|
||||
- qemu_set_irq(s->pch_msi_irq[irq_num], 1);
|
||||
+ MSIMessage msg = {
|
||||
+ .address = addr,
|
||||
+ .data = val,
|
||||
+ };
|
||||
+
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ kvm_irqchip_send_msi(kvm_state, msg);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * vector number is irq number from upper extioi intc
|
||||
+ * need subtract irq base to get msi vector offset
|
||||
+ */
|
||||
+ irq_num = (val & 0xff) - s->irq_base;
|
||||
+ trace_loongarch_msi_set_irq(irq_num);
|
||||
+ assert(irq_num < s->irq_num);
|
||||
+
|
||||
+ qemu_set_irq(s->pch_msi_irq[irq_num], 1);
|
||||
+ }
|
||||
}
|
||||
|
||||
static const MemoryRegionOps loongarch_pch_msi_ops = {
|
||||
@@ -46,7 +58,16 @@ static void pch_msi_irq_handler(void *opaque, int irq, int level)
|
||||
{
|
||||
LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque);
|
||||
|
||||
- qemu_set_irq(s->pch_msi_irq[irq], level);
|
||||
+ MSIMessage msg = {
|
||||
+ .address = 0,
|
||||
+ .data = irq,
|
||||
+ };
|
||||
+
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ kvm_irqchip_send_msi(kvm_state, msg);
|
||||
+ } else {
|
||||
+ qemu_set_irq(s->pch_msi_irq[irq], level);
|
||||
+ }
|
||||
}
|
||||
|
||||
static void loongarch_pch_msi_realize(DeviceState *dev, Error **errp)
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 270dcfd38f..5b0468f6cb 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -928,22 +928,26 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
for (i = 0; i < num; i++) {
|
||||
qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
|
||||
}
|
||||
+ }
|
||||
|
||||
- pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
|
||||
- start = num;
|
||||
- num = EXTIOI_IRQS - start;
|
||||
- qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
|
||||
- qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
|
||||
- d = SYS_BUS_DEVICE(pch_msi);
|
||||
- sysbus_realize_and_unref(d, &error_fatal);
|
||||
- sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
|
||||
+ pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
|
||||
+ num = VIRT_PCH_PIC_IRQ_NUM;
|
||||
+ start = num;
|
||||
+ num = EXTIOI_IRQS - start;
|
||||
+ qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
|
||||
+ qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
|
||||
+ d = SYS_BUS_DEVICE(pch_msi);
|
||||
+ sysbus_realize_and_unref(d, &error_fatal);
|
||||
+
|
||||
+ if (!(kvm_enabled() && kvm_irqchip_in_kernel())) {
|
||||
+ /* Connect pch_msi irqs to extioi */
|
||||
for (i = 0; i < num; i++) {
|
||||
- /* Connect pch_msi irqs to extioi */
|
||||
qdev_connect_gpio_out(DEVICE(d), i,
|
||||
qdev_get_gpio_in(extioi, i + start));
|
||||
}
|
||||
}
|
||||
|
||||
+ sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
|
||||
virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle);
|
||||
}
|
||||
|
||||
diff --git a/include/hw/intc/loongarch_pch_msi.h b/include/hw/intc/loongarch_pch_msi.h
|
||||
index b8586fb3b6..fd4ea97a83 100644
|
||||
--- a/include/hw/intc/loongarch_pch_msi.h
|
||||
+++ b/include/hw/intc/loongarch_pch_msi.h
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
-#define TYPE_LOONGARCH_PCH_MSI "loongarch_pch_msi"
|
||||
+#define TYPE_LOONGARCH_PCH_MSI "loongarch_pch_msi"
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHMSI, LOONGARCH_PCH_MSI)
|
||||
|
||||
/* MSI irq start from 32 to 255 */
|
||||
--
|
||||
2.39.1
|
||||
|
||||
487
hw-loongarch-Add-KVM-pch-pic-device-support.patch
Normal file
487
hw-loongarch-Add-KVM-pch-pic-device-support.patch
Normal file
@ -0,0 +1,487 @@
|
||||
From 30f88e80a47d9bcde08c44c0d752c22c11f2224c Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Sun, 8 Sep 2024 10:13:29 +0800
|
||||
Subject: [PATCH 74/78] hw/loongarch: Add KVM pch pic device support
|
||||
|
||||
Added pch_pic interrupt controller for kvm emulation.
|
||||
The main process is to send the command word for
|
||||
creating an pch_pic device to the kernel,
|
||||
Delivers the pch pic interrupt controller configuration
|
||||
register base address to the kernel.
|
||||
When the VM is saved, the ioctl obtains the pch_pic
|
||||
interrupt controller data in the kernel and saves it.
|
||||
When the VM is recovered, the saved data is sent to the kernel.
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/intc/Kconfig | 3 +
|
||||
hw/intc/loongarch_pch_pic.c | 24 +++-
|
||||
hw/intc/loongarch_pch_pic_kvm.c | 189 ++++++++++++++++++++++++++++
|
||||
hw/intc/meson.build | 1 +
|
||||
hw/loongarch/Kconfig | 1 +
|
||||
hw/loongarch/virt.c | 70 ++++++-----
|
||||
include/hw/intc/loongarch_pch_pic.h | 51 +++++++-
|
||||
linux-headers/linux/kvm.h | 2 +
|
||||
8 files changed, 303 insertions(+), 38 deletions(-)
|
||||
create mode 100644 hw/intc/loongarch_pch_pic_kvm.c
|
||||
|
||||
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
|
||||
index f1e8bd2fc9..91c7aa668e 100644
|
||||
--- a/hw/intc/Kconfig
|
||||
+++ b/hw/intc/Kconfig
|
||||
@@ -100,6 +100,9 @@ config LOONGARCH_PCH_PIC
|
||||
bool
|
||||
select UNIMP
|
||||
|
||||
+config LOONGARCH_PCH_PIC_KVM
|
||||
+ bool
|
||||
+
|
||||
config LOONGARCH_PCH_MSI
|
||||
select MSI_NONBROKEN
|
||||
bool
|
||||
diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
|
||||
index 6aa4cadfa4..beb4ac188d 100644
|
||||
--- a/hw/intc/loongarch_pch_pic.c
|
||||
+++ b/hw/intc/loongarch_pch_pic.c
|
||||
@@ -16,19 +16,28 @@
|
||||
#include "migration/vmstate.h"
|
||||
#include "trace.h"
|
||||
#include "qapi/error.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
|
||||
static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
|
||||
{
|
||||
uint64_t val;
|
||||
int irq;
|
||||
+ int kvm_irq;
|
||||
|
||||
if (level) {
|
||||
val = mask & s->intirr & ~s->int_mask;
|
||||
if (val) {
|
||||
irq = ctz64(val);
|
||||
s->intisr |= MAKE_64BIT_MASK(irq, 1);
|
||||
- qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
|
||||
- }
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ kvm_irq = (
|
||||
+ KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT)
|
||||
+ | (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | s->htmsi_vector[irq];
|
||||
+ kvm_set_irq(kvm_state, kvm_irq, !!level);
|
||||
+ } else {
|
||||
+ qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
|
||||
+ }
|
||||
+ }
|
||||
} else {
|
||||
/*
|
||||
* intirr means requested pending irq
|
||||
@@ -38,8 +47,15 @@ static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
|
||||
if (val) {
|
||||
irq = ctz64(val);
|
||||
s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
|
||||
- qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
|
||||
- }
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ kvm_irq = (
|
||||
+ KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT)
|
||||
+ | (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | s->htmsi_vector[irq];
|
||||
+ kvm_set_irq(kvm_state, kvm_irq, !!level);
|
||||
+ } else {
|
||||
+ qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/hw/intc/loongarch_pch_pic_kvm.c b/hw/intc/loongarch_pch_pic_kvm.c
|
||||
new file mode 100644
|
||||
index 0000000000..8f66d9a01f
|
||||
--- /dev/null
|
||||
+++ b/hw/intc/loongarch_pch_pic_kvm.c
|
||||
@@ -0,0 +1,189 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
+/*
|
||||
+ * LoongArch kvm pch pic interrupt support
|
||||
+ *
|
||||
+ * Copyright (C) 2024 Loongson Technology Corporation Limited
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
+#include "qemu/typedefs.h"
|
||||
+#include "hw/intc/loongarch_pch_pic.h"
|
||||
+#include "hw/sysbus.h"
|
||||
+#include "linux/kvm.h"
|
||||
+#include "migration/vmstate.h"
|
||||
+#include "qapi/error.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
+#include "hw/loongarch/virt.h"
|
||||
+#include "hw/pci-host/ls7a.h"
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
+static void kvm_pch_pic_access_regs(int fd, uint64_t addr,
|
||||
+ void *val, int is_write)
|
||||
+{
|
||||
+ kvm_device_access(fd, KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS,
|
||||
+ addr, val, is_write, &error_abort);
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_pch_pic_pre_save(void *opaque)
|
||||
+{
|
||||
+ KVMLoongArchPCHPIC *s = (KVMLoongArchPCHPIC *)opaque;
|
||||
+ KVMLoongArchPCHPICClass *class = KVM_LOONGARCH_PCH_PIC_GET_CLASS(s);
|
||||
+ int fd = class->dev_fd;
|
||||
+
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_MASK_START,
|
||||
+ (void *)&s->int_mask, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_HTMSI_EN_START,
|
||||
+ (void *)&s->htmsi_en, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_EDGE_START,
|
||||
+ (void *)&s->intedge, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_AUTO_CTRL0_START,
|
||||
+ (void *)&s->auto_crtl0, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_AUTO_CTRL1_START,
|
||||
+ (void *)&s->auto_crtl1, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_ROUTE_ENTRY_START,
|
||||
+ (void *)s->route_entry, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_HTMSI_VEC_START,
|
||||
+ (void *)s->htmsi_vector, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_INT_IRR_START,
|
||||
+ (void *)&s->intirr, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_INT_ISR_START,
|
||||
+ (void *)&s->intisr, false);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_POLARITY_START,
|
||||
+ (void *)&s->int_polarity, false);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_pch_pic_post_load(void *opaque, int version_id)
|
||||
+{
|
||||
+ KVMLoongArchPCHPIC *s = (KVMLoongArchPCHPIC *)opaque;
|
||||
+ KVMLoongArchPCHPICClass *class = KVM_LOONGARCH_PCH_PIC_GET_CLASS(s);
|
||||
+ int fd = class->dev_fd;
|
||||
+
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_MASK_START,
|
||||
+ (void *)&s->int_mask, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_HTMSI_EN_START,
|
||||
+ (void *)&s->htmsi_en, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_EDGE_START,
|
||||
+ (void *)&s->intedge, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_AUTO_CTRL0_START,
|
||||
+ (void *)&s->auto_crtl0, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_AUTO_CTRL1_START,
|
||||
+ (void *)&s->auto_crtl1, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_ROUTE_ENTRY_START,
|
||||
+ (void *)s->route_entry, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_HTMSI_VEC_START,
|
||||
+ (void *)s->htmsi_vector, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_INT_IRR_START,
|
||||
+ (void *)&s->intirr, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_INT_ISR_START,
|
||||
+ (void *)&s->intisr, true);
|
||||
+ kvm_pch_pic_access_regs(fd, PCH_PIC_POLARITY_START,
|
||||
+ (void *)&s->int_polarity, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void kvm_pch_pic_handler(void *opaque, int irq, int level)
|
||||
+{
|
||||
+ int kvm_irq;
|
||||
+
|
||||
+ if (kvm_enabled()) {
|
||||
+ kvm_irq = \
|
||||
+ (KVM_LOONGARCH_IRQ_TYPE_IOAPIC << KVM_LOONGARCH_IRQ_TYPE_SHIFT)
|
||||
+ | (0 << KVM_LOONGARCH_IRQ_VCPU_SHIFT) | irq;
|
||||
+ kvm_set_irq(kvm_state, kvm_irq, !!level);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void kvm_loongarch_pch_pic_realize(DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ KVMLoongArchPCHPICClass *pch_pic_class =
|
||||
+ KVM_LOONGARCH_PCH_PIC_GET_CLASS(dev);
|
||||
+ struct kvm_create_device cd = {0};
|
||||
+ uint64_t pch_pic_base = VIRT_PCH_REG_BASE;
|
||||
+ Error *err = NULL;
|
||||
+ int ret;
|
||||
+
|
||||
+ pch_pic_class->parent_realize(dev, &err);
|
||||
+ if (err) {
|
||||
+ error_propagate(errp, err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!pch_pic_class->is_created) {
|
||||
+ cd.type = KVM_DEV_TYPE_LA_PCH_PIC;
|
||||
+ ret = kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd);
|
||||
+ if (ret < 0) {
|
||||
+ error_setg_errno(errp, errno,
|
||||
+ "Creating the KVM pch pic device failed");
|
||||
+ return;
|
||||
+ }
|
||||
+ pch_pic_class->is_created = true;
|
||||
+ pch_pic_class->dev_fd = cd.fd;
|
||||
+ fprintf(stdout, "Create LoongArch pch pic irqchip in KVM done!\n");
|
||||
+
|
||||
+ ret = kvm_device_access(cd.fd, KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL,
|
||||
+ KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT,
|
||||
+ &pch_pic_base, true, NULL);
|
||||
+ if (ret < 0) {
|
||||
+ error_report(
|
||||
+ "KVM EXTIOI: failed to set the base address of EXTIOI");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ qdev_init_gpio_in(dev, kvm_pch_pic_handler, VIRT_PCH_PIC_IRQ_NUM);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const VMStateDescription vmstate_kvm_loongarch_pch_pic = {
|
||||
+ .name = TYPE_LOONGARCH_PCH_PIC,
|
||||
+ .version_id = 1,
|
||||
+ .minimum_version_id = 1,
|
||||
+ .pre_save = kvm_loongarch_pch_pic_pre_save,
|
||||
+ .post_load = kvm_loongarch_pch_pic_post_load,
|
||||
+ .fields = (const VMStateField[]) {
|
||||
+ VMSTATE_UINT64(int_mask, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(htmsi_en, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(intedge, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(intclr, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(auto_crtl0, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(auto_crtl1, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT8_ARRAY(route_entry, KVMLoongArchPCHPIC, 64),
|
||||
+ VMSTATE_UINT8_ARRAY(htmsi_vector, KVMLoongArchPCHPIC, 64),
|
||||
+ VMSTATE_UINT64(last_intirr, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(intirr, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(intisr, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_UINT64(int_polarity, KVMLoongArchPCHPIC),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static void kvm_loongarch_pch_pic_class_init(ObjectClass *oc, void *data)
|
||||
+{
|
||||
+ DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
+ KVMLoongArchPCHPICClass *pch_pic_class = KVM_LOONGARCH_PCH_PIC_CLASS(oc);
|
||||
+
|
||||
+ pch_pic_class->parent_realize = dc->realize;
|
||||
+ dc->realize = kvm_loongarch_pch_pic_realize;
|
||||
+ pch_pic_class->is_created = false;
|
||||
+ dc->vmsd = &vmstate_kvm_loongarch_pch_pic;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static const TypeInfo kvm_loongarch_pch_pic_info = {
|
||||
+ .name = TYPE_KVM_LOONGARCH_PCH_PIC,
|
||||
+ .parent = TYPE_SYS_BUS_DEVICE,
|
||||
+ .instance_size = sizeof(KVMLoongArchPCHPIC),
|
||||
+ .class_size = sizeof(KVMLoongArchPCHPICClass),
|
||||
+ .class_init = kvm_loongarch_pch_pic_class_init,
|
||||
+};
|
||||
+
|
||||
+static void kvm_loongarch_pch_pic_register_types(void)
|
||||
+{
|
||||
+ type_register_static(&kvm_loongarch_pch_pic_info);
|
||||
+}
|
||||
+
|
||||
+type_init(kvm_loongarch_pch_pic_register_types)
|
||||
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
|
||||
index a37d7da8aa..49b4501315 100644
|
||||
--- a/hw/intc/meson.build
|
||||
+++ b/hw/intc/meson.build
|
||||
@@ -75,3 +75,4 @@ specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_
|
||||
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_KVM', if_true: files('loongarch_extioi_kvm.c'))
|
||||
+specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC_KVM', if_true: files('loongarch_pch_pic_kvm.c'))
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index 1a47d44a64..16c854c0d5 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -15,6 +15,7 @@ config LOONGARCH_VIRT
|
||||
select LOONGARCH_PCH_MSI
|
||||
select LOONGARCH_EXTIOI
|
||||
select LOONGARCH_IPI_KVM if KVM
|
||||
+ select LOONGARCH_PCH_PIC_KVM if KVM
|
||||
select LOONGARCH_EXTIOI_KVM if KVM
|
||||
select LS7A_RTC
|
||||
select SMBIOS
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 71e2a3735c..270dcfd38f 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -901,45 +901,49 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
/* Add Extend I/O Interrupt Controller node */
|
||||
fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
|
||||
|
||||
- pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
|
||||
- num = VIRT_PCH_PIC_IRQ_NUM;
|
||||
- qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
|
||||
- d = SYS_BUS_DEVICE(pch_pic);
|
||||
- sysbus_realize_and_unref(d, &error_fatal);
|
||||
- memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE,
|
||||
- sysbus_mmio_get_region(d, 0));
|
||||
- memory_region_add_subregion(get_system_memory(),
|
||||
- VIRT_IOAPIC_REG_BASE + PCH_PIC_ROUTE_ENTRY_OFFSET,
|
||||
- sysbus_mmio_get_region(d, 1));
|
||||
- memory_region_add_subregion(get_system_memory(),
|
||||
- VIRT_IOAPIC_REG_BASE + PCH_PIC_INT_STATUS_LO,
|
||||
- sysbus_mmio_get_region(d, 2));
|
||||
-
|
||||
- /* Connect pch_pic irqs to extioi */
|
||||
- for (i = 0; i < num; i++) {
|
||||
- qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
|
||||
- }
|
||||
-
|
||||
/* Add PCH PIC node */
|
||||
fdt_add_pch_pic_node(lvms, &eiointc_phandle, &pch_pic_phandle);
|
||||
|
||||
- pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
|
||||
- start = num;
|
||||
- num = EXTIOI_IRQS - start;
|
||||
- qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
|
||||
- qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
|
||||
- d = SYS_BUS_DEVICE(pch_msi);
|
||||
- sysbus_realize_and_unref(d, &error_fatal);
|
||||
- sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
|
||||
- for (i = 0; i < num; i++) {
|
||||
- /* Connect pch_msi irqs to extioi */
|
||||
- qdev_connect_gpio_out(DEVICE(d), i,
|
||||
- qdev_get_gpio_in(extioi, i + start));
|
||||
- }
|
||||
-
|
||||
/* Add PCH MSI node */
|
||||
fdt_add_pch_msi_node(lvms, &eiointc_phandle, &pch_msi_phandle);
|
||||
|
||||
+ if (kvm_enabled() && kvm_irqchip_in_kernel()) {
|
||||
+ pch_pic = qdev_new(TYPE_KVM_LOONGARCH_PCH_PIC);
|
||||
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(pch_pic), &error_fatal);
|
||||
+ } else {
|
||||
+ pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
|
||||
+ num = VIRT_PCH_PIC_IRQ_NUM;
|
||||
+ qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
|
||||
+ d = SYS_BUS_DEVICE(pch_pic);
|
||||
+ sysbus_realize_and_unref(d, &error_fatal);
|
||||
+ memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE,
|
||||
+ sysbus_mmio_get_region(d, 0));
|
||||
+ memory_region_add_subregion(get_system_memory(),
|
||||
+ VIRT_IOAPIC_REG_BASE + PCH_PIC_ROUTE_ENTRY_OFFSET,
|
||||
+ sysbus_mmio_get_region(d, 1));
|
||||
+ memory_region_add_subregion(get_system_memory(),
|
||||
+ VIRT_IOAPIC_REG_BASE + PCH_PIC_INT_STATUS_LO,
|
||||
+ sysbus_mmio_get_region(d, 2));
|
||||
+ /* Connect pch_pic irqs to extioi */
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
|
||||
+ }
|
||||
+
|
||||
+ pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
|
||||
+ start = num;
|
||||
+ num = EXTIOI_IRQS - start;
|
||||
+ qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
|
||||
+ qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
|
||||
+ d = SYS_BUS_DEVICE(pch_msi);
|
||||
+ sysbus_realize_and_unref(d, &error_fatal);
|
||||
+ sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
|
||||
+ for (i = 0; i < num; i++) {
|
||||
+ /* Connect pch_msi irqs to extioi */
|
||||
+ qdev_connect_gpio_out(DEVICE(d), i,
|
||||
+ qdev_get_gpio_in(extioi, i + start));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
virt_devices_init(pch_pic, lvms, &pch_pic_phandle, &pch_msi_phandle);
|
||||
}
|
||||
|
||||
diff --git a/include/hw/intc/loongarch_pch_pic.h b/include/hw/intc/loongarch_pch_pic.h
|
||||
index d5437e88f2..77f4cd74a1 100644
|
||||
--- a/include/hw/intc/loongarch_pch_pic.h
|
||||
+++ b/include/hw/intc/loongarch_pch_pic.h
|
||||
@@ -7,7 +7,8 @@
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
-#define TYPE_LOONGARCH_PCH_PIC "loongarch_pch_pic"
|
||||
+#define TYPE_LOONGARCH_PCH_PIC "loongarch_pch_pic"
|
||||
+#define TYPE_KVM_LOONGARCH_PCH_PIC "loongarch_kvm_pch_pic"
|
||||
#define PCH_PIC_NAME(name) TYPE_LOONGARCH_PCH_PIC#name
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHPIC, LOONGARCH_PCH_PIC)
|
||||
|
||||
@@ -37,6 +38,19 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchPCHPIC, LOONGARCH_PCH_PIC)
|
||||
#define PCH_PIC_INT_POL_LO 0x3e0
|
||||
#define PCH_PIC_INT_POL_HI 0x3e4
|
||||
|
||||
+#define PCH_PIC_INT_ID_START PCH_PIC_INT_ID_LO
|
||||
+#define PCH_PIC_MASK_START PCH_PIC_INT_MASK_LO
|
||||
+#define PCH_PIC_HTMSI_EN_START PCH_PIC_HTMSI_EN_LO
|
||||
+#define PCH_PIC_EDGE_START PCH_PIC_INT_EDGE_LO
|
||||
+#define PCH_PIC_CLEAR_START PCH_PIC_INT_CLEAR_LO
|
||||
+#define PCH_PIC_AUTO_CTRL0_START PCH_PIC_AUTO_CTRL0_LO
|
||||
+#define PCH_PIC_AUTO_CTRL1_START PCH_PIC_AUTO_CTRL1_LO
|
||||
+#define PCH_PIC_ROUTE_ENTRY_START PCH_PIC_ROUTE_ENTRY_OFFSET
|
||||
+#define PCH_PIC_HTMSI_VEC_START PCH_PIC_HTMSI_VEC_OFFSET
|
||||
+#define PCH_PIC_INT_IRR_START 0x380
|
||||
+#define PCH_PIC_INT_ISR_START PCH_PIC_INT_STATUS_LO
|
||||
+#define PCH_PIC_POLARITY_START PCH_PIC_INT_POL_LO
|
||||
+
|
||||
#define STATUS_LO_START 0
|
||||
#define STATUS_HI_START 0x4
|
||||
#define POL_LO_START 0x40
|
||||
@@ -67,3 +81,38 @@ struct LoongArchPCHPIC {
|
||||
MemoryRegion iomem8;
|
||||
unsigned int irq_num;
|
||||
};
|
||||
+
|
||||
+struct KVMLoongArchPCHPIC {
|
||||
+ SysBusDevice parent_obj;
|
||||
+ uint64_t int_mask; /*0x020 interrupt mask register*/
|
||||
+ uint64_t htmsi_en; /*0x040 1=msi*/
|
||||
+ uint64_t intedge; /*0x060 edge=1 level =0*/
|
||||
+ uint64_t intclr; /*0x080 for clean edge int,set 1 clean,set 0 is noused*/
|
||||
+ uint64_t auto_crtl0; /*0x0c0*/
|
||||
+ uint64_t auto_crtl1; /*0x0e0*/
|
||||
+ uint64_t last_intirr; /* edge detection */
|
||||
+ uint64_t intirr; /* 0x380 interrupt request register */
|
||||
+ uint64_t intisr; /* 0x3a0 interrupt service register */
|
||||
+ /*
|
||||
+ * 0x3e0 interrupt level polarity selection
|
||||
+ * register 0 for high level trigger
|
||||
+ */
|
||||
+ uint64_t int_polarity;
|
||||
+
|
||||
+ uint8_t route_entry[64]; /*0x100 - 0x138*/
|
||||
+ uint8_t htmsi_vector[64]; /*0x200 - 0x238*/
|
||||
+};
|
||||
+typedef struct KVMLoongArchPCHPIC KVMLoongArchPCHPIC;
|
||||
+DECLARE_INSTANCE_CHECKER(KVMLoongArchPCHPIC, KVM_LOONGARCH_PCH_PIC,
|
||||
+ TYPE_KVM_LOONGARCH_PCH_PIC)
|
||||
+
|
||||
+struct KVMLoongArchPCHPICClass {
|
||||
+ SysBusDeviceClass parent_class;
|
||||
+ DeviceRealize parent_realize;
|
||||
+
|
||||
+ bool is_created;
|
||||
+ int dev_fd;
|
||||
+};
|
||||
+typedef struct KVMLoongArchPCHPICClass KVMLoongArchPCHPICClass;
|
||||
+DECLARE_CLASS_CHECKERS(KVMLoongArchPCHPICClass, KVM_LOONGARCH_PCH_PIC,
|
||||
+ TYPE_KVM_LOONGARCH_PCH_PIC)
|
||||
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
|
||||
index 0c0b82d1ef..887f8268e7 100644
|
||||
--- a/linux-headers/linux/kvm.h
|
||||
+++ b/linux-headers/linux/kvm.h
|
||||
@@ -1470,6 +1470,8 @@ enum kvm_device_type {
|
||||
#define KVM_DEV_TYPE_ARM_PV_TIME KVM_DEV_TYPE_ARM_PV_TIME
|
||||
KVM_DEV_TYPE_RISCV_AIA,
|
||||
#define KVM_DEV_TYPE_RISCV_AIA KVM_DEV_TYPE_RISCV_AIA
|
||||
+ KVM_DEV_TYPE_LA_PCH_PIC = 0x100,
|
||||
+#define KVM_DEV_TYPE_LA_PCH_PIC KVM_DEV_TYPE_LA_PCH_PIC
|
||||
KVM_DEV_TYPE_LA_IPI,
|
||||
#define KVM_DEV_TYPE_LA_IPI KVM_DEV_TYPE_LA_IPI
|
||||
KVM_DEV_TYPE_LA_EXTIOI,
|
||||
--
|
||||
2.39.1
|
||||
|
||||
49
hw-loongarch-Add-VM-mode-in-IOCSR-feature-register-i.patch
Normal file
49
hw-loongarch-Add-VM-mode-in-IOCSR-feature-register-i.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 0437c11a20b3c66882770e468518d33ff71a932a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Tue, 14 May 2024 10:51:09 +0800
|
||||
Subject: [PATCH 22/78] hw/loongarch: Add VM mode in IOCSR feature register in
|
||||
kvm mode
|
||||
|
||||
If VM runs in kvm mode, VM mode is added in IOCSR feature register.
|
||||
So guest can detect kvm hypervisor type and enable possible pv functions.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240514025109.3238398-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index e82e3b6792..c3514f9293 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "qapi/error.h"
|
||||
#include "hw/boards.h"
|
||||
#include "hw/char/serial.h"
|
||||
+#include "sysemu/kvm.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/qtest.h"
|
||||
#include "sysemu/runstate.h"
|
||||
@@ -914,12 +915,11 @@ static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr,
|
||||
ret = 0x11ULL;
|
||||
break;
|
||||
case FEATURE_REG:
|
||||
- ret = 1ULL << IOCSRF_MSI | 1ULL << IOCSRF_EXTIOI |
|
||||
- 1ULL << IOCSRF_CSRIPI;
|
||||
+ ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
|
||||
if (kvm_enabled()) {
|
||||
- ret |= 1ULL << IOCSRF_VM;
|
||||
+ ret |= BIT(IOCSRF_VM);
|
||||
}
|
||||
- break;
|
||||
+ return ret;
|
||||
case VENDOR_REG:
|
||||
ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */
|
||||
break;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
82
hw-loongarch-Add-acpi-SPCR-table-support.patch
Normal file
82
hw-loongarch-Add-acpi-SPCR-table-support.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From fe22e0efe4c1c99fc876a42446cb2c87f9457afb Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Sat, 7 Sep 2024 15:30:37 +0800
|
||||
Subject: [PATCH 37/78] hw/loongarch: Add acpi SPCR table support
|
||||
|
||||
Serial port console redirection table can be used for default serial
|
||||
port selection, like chosen stdout-path selection with FDT method.
|
||||
|
||||
With acpi SPCR table added, early debug console can be parsed from
|
||||
SPCR table with simple kernel parameter earlycon rather than
|
||||
earlycon=uart,mmio,0x1fe001e0
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240907073037.243353-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/acpi-build.c | 40 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index 33a92223d8..bcdec2e1cb 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -242,6 +242,44 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
acpi_table_end(linker, &table);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Serial Port Console Redirection Table (SPCR)
|
||||
+ * https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
|
||||
+ */
|
||||
+static void
|
||||
+spcr_setup(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
+{
|
||||
+ LoongArchVirtMachineState *lvms;
|
||||
+ AcpiSpcrData serial = {
|
||||
+ .interface_type = 0, /* 16550 compatible */
|
||||
+ .base_addr.id = AML_AS_SYSTEM_MEMORY,
|
||||
+ .base_addr.width = 32,
|
||||
+ .base_addr.offset = 0,
|
||||
+ .base_addr.size = 1,
|
||||
+ .base_addr.addr = VIRT_UART_BASE,
|
||||
+ .interrupt_type = 0, /* Interrupt not supported */
|
||||
+ .pc_interrupt = 0,
|
||||
+ .interrupt = VIRT_UART_IRQ,
|
||||
+ .baud_rate = 7, /* 115200 */
|
||||
+ .parity = 0,
|
||||
+ .stop_bits = 1,
|
||||
+ .flow_control = 0,
|
||||
+ .terminal_type = 3, /* ANSI */
|
||||
+ .language = 0, /* Language */
|
||||
+ .pci_device_id = 0xffff, /* not a PCI device*/
|
||||
+ .pci_vendor_id = 0xffff, /* not a PCI device*/
|
||||
+ .pci_bus = 0,
|
||||
+ .pci_device = 0,
|
||||
+ .pci_function = 0,
|
||||
+ .pci_flags = 0,
|
||||
+ .pci_segment = 0,
|
||||
+ };
|
||||
+
|
||||
+ lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
+ build_spcr(table_data, linker, &serial, 2, lvms->oem_id,
|
||||
+ lvms->oem_table_id);
|
||||
+}
|
||||
+
|
||||
typedef
|
||||
struct AcpiBuildState {
|
||||
/* Copy of table in RAM (for patching). */
|
||||
@@ -484,6 +522,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_srat(tables_blob, tables->linker, machine);
|
||||
+ acpi_add_table(table_offsets, tables_blob);
|
||||
+ spcr_setup(tables_blob, tables->linker, machine);
|
||||
|
||||
if (machine->numa_state->num_nodes) {
|
||||
if (machine->numa_state->have_numa_distance) {
|
||||
--
|
||||
2.39.1
|
||||
|
||||
56
hw-loongarch-Add-cells-missing-from-rtc-node.patch
Normal file
56
hw-loongarch-Add-cells-missing-from-rtc-node.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 7266141c658cd00426922534a7de4dd5d89486b2 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:51 +0800
|
||||
Subject: [PATCH 16/78] hw/loongarch: Add cells missing from rtc node
|
||||
|
||||
rtc node need interrupts and interrupt-parent cells.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-18-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index a6aea52ebb..0972ebd150 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -258,7 +258,8 @@ static void fdt_add_flash_node(LoongArchMachineState *lams)
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
-static void fdt_add_rtc_node(LoongArchMachineState *lams)
|
||||
+static void fdt_add_rtc_node(LoongArchMachineState *lams,
|
||||
+ uint32_t *pch_pic_phandle)
|
||||
{
|
||||
char *nodename;
|
||||
hwaddr base = VIRT_RTC_REG_BASE;
|
||||
@@ -267,8 +268,13 @@ static void fdt_add_rtc_node(LoongArchMachineState *lams)
|
||||
|
||||
nodename = g_strdup_printf("/rtc@%" PRIx64, base);
|
||||
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
- qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "loongson,ls7a-rtc");
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
+ "loongson,ls7a-rtc");
|
||||
qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
|
||||
+ VIRT_RTC_IRQ - VIRT_GSI_BASE , 0x4);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
|
||||
+ *pch_pic_phandle);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
@@ -677,7 +683,7 @@ static void loongarch_devices_init(DeviceState *pch_pic,
|
||||
sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
|
||||
qdev_get_gpio_in(pch_pic,
|
||||
VIRT_RTC_IRQ - VIRT_GSI_BASE));
|
||||
- fdt_add_rtc_node(lams);
|
||||
+ fdt_add_rtc_node(lams, pch_pic_phandle);
|
||||
|
||||
/* acpi ged */
|
||||
lams->acpi_ged = create_acpi_ged(pch_pic, lams);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
52
hw-loongarch-Add-cells-missing-from-uart-node.patch
Normal file
52
hw-loongarch-Add-cells-missing-from-uart-node.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 33994eff45e75e91acf0a4753fec77ad0027e4dd Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:50 +0800
|
||||
Subject: [PATCH 15/78] hw/loongarch: Add cells missing from uart node
|
||||
|
||||
uart node need interrupts and interrupt-parent cells.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-17-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 9 +++++++--
|
||||
1 file changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index ff9513034b..a6aea52ebb 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -272,7 +272,8 @@ static void fdt_add_rtc_node(LoongArchMachineState *lams)
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
-static void fdt_add_uart_node(LoongArchMachineState *lams)
|
||||
+static void fdt_add_uart_node(LoongArchMachineState *lams,
|
||||
+ uint32_t *pch_pic_phandle)
|
||||
{
|
||||
char *nodename;
|
||||
hwaddr base = VIRT_UART_BASE;
|
||||
@@ -285,6 +286,10 @@ static void fdt_add_uart_node(LoongArchMachineState *lams)
|
||||
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
|
||||
qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
|
||||
+ VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
|
||||
+ *pch_pic_phandle);
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
@@ -657,7 +662,7 @@ static void loongarch_devices_init(DeviceState *pch_pic,
|
||||
qdev_get_gpio_in(pch_pic,
|
||||
VIRT_UART_IRQ - VIRT_GSI_BASE),
|
||||
115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
||||
- fdt_add_uart_node(lams);
|
||||
+ fdt_add_uart_node(lams, pch_pic_phandle);
|
||||
|
||||
/* Network init */
|
||||
for (i = 0; i < nb_nics; i++) {
|
||||
--
|
||||
2.39.1
|
||||
|
||||
117
hw-loongarch-Add-init_cmdline.patch
Normal file
117
hw-loongarch-Add-init_cmdline.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 206b799cb8c218c744f4dcdaf161d11f14c21e0f Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:38 +0800
|
||||
Subject: [PATCH 04/78] hw/loongarch: Add init_cmdline
|
||||
|
||||
Add init_cmline and set boot_info->a0, a1
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-5-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 30 ++++++++++++++++++++++++++++++
|
||||
include/hw/loongarch/virt.h | 2 ++
|
||||
target/loongarch/cpu.h | 2 ++
|
||||
3 files changed, 34 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index fb6effbaff..127085bcc4 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -63,6 +63,16 @@ static const unsigned int slave_boot_code[] = {
|
||||
0x4c000020, /* jirl $zero, $ra,0 */
|
||||
};
|
||||
|
||||
+static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
|
||||
+{
|
||||
+ hwaddr cmdline_addr = p - start;
|
||||
+
|
||||
+ info->a0 = 1;
|
||||
+ info->a1 = cmdline_addr;
|
||||
+
|
||||
+ memcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE);
|
||||
+}
|
||||
+
|
||||
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
||||
{
|
||||
return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
|
||||
@@ -121,6 +131,10 @@ static void reset_load_elf(void *opaque)
|
||||
|
||||
cpu_reset(CPU(cpu));
|
||||
if (env->load_elf) {
|
||||
+ if (cpu == LOONGARCH_CPU(first_cpu)) {
|
||||
+ env->gpr[4] = env->boot_info->a0;
|
||||
+ env->gpr[5] = env->boot_info->a1;
|
||||
+ }
|
||||
cpu_set_pc(CPU(cpu), env->elf_address);
|
||||
}
|
||||
}
|
||||
@@ -158,8 +172,17 @@ static void loongarch_firmware_boot(LoongArchMachineState *lams,
|
||||
fw_cfg_add_kernel_info(info, lams->fw_cfg);
|
||||
}
|
||||
|
||||
+static void init_boot_rom(struct loongarch_boot_info *info, void *p)
|
||||
+{
|
||||
+ void *start = p;
|
||||
+
|
||||
+ init_cmdline(info, p, start);
|
||||
+ p += COMMAND_LINE_SIZE;
|
||||
+}
|
||||
+
|
||||
static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
{
|
||||
+ void *p, *bp;
|
||||
int64_t kernel_addr = 0;
|
||||
LoongArchCPU *lacpu;
|
||||
CPUState *cs;
|
||||
@@ -173,6 +196,12 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Load cmdline and system tables at [0 - 1 MiB] */
|
||||
+ p = g_malloc0(1 * MiB);
|
||||
+ bp = p;
|
||||
+ init_boot_rom(info, p);
|
||||
+ rom_add_blob_fixed_as("boot_info", bp, 1 * MiB, 0, &address_space_memory);
|
||||
+
|
||||
/* Load slave boot code at pflash0 . */
|
||||
void *boot_code = g_malloc0(VIRT_FLASH0_SIZE);
|
||||
memcpy(boot_code, &slave_boot_code, sizeof(slave_boot_code));
|
||||
@@ -190,6 +219,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
}
|
||||
|
||||
g_free(boot_code);
|
||||
+ g_free(bp);
|
||||
}
|
||||
|
||||
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 02c8234b8d..ffff075f63 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -33,6 +33,8 @@
|
||||
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
|
||||
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
|
||||
|
||||
+#define COMMAND_LINE_SIZE 512
|
||||
+
|
||||
struct LoongArchMachineState {
|
||||
/*< private >*/
|
||||
MachineState parent_obj;
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 0ed24051af..e3a15c593f 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -364,6 +364,8 @@ typedef struct CPUArchState {
|
||||
uint32_t mp_state;
|
||||
/* Store ipistate to access from this struct */
|
||||
DeviceState *ipistate;
|
||||
+
|
||||
+ struct loongarch_boot_info *boot_info;
|
||||
#endif
|
||||
struct {
|
||||
uint64_t guest_addr;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
64
hw-loongarch-Add-load-initrd.patch
Normal file
64
hw-loongarch-Add-load-initrd.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 02c5f52da7f9458c0fc41e43f181f6e9b7101b57 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:36 +0800
|
||||
Subject: [PATCH 02/78] hw/loongarch: Add load initrd
|
||||
|
||||
we load initrd ramdisk after kernel_high address
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-3-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 28 +++++++++++++++++++++++++++-
|
||||
1 file changed, 27 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index 9feed17db3..a5135fe542 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -22,7 +22,8 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
||||
|
||||
static int64_t load_kernel_info(struct loongarch_boot_info *info)
|
||||
{
|
||||
- uint64_t kernel_entry, kernel_low, kernel_high;
|
||||
+ uint64_t kernel_entry, kernel_low, kernel_high, initrd_size;
|
||||
+ ram_addr_t initrd_offset;
|
||||
ssize_t kernel_size;
|
||||
|
||||
kernel_size = load_elf(info->kernel_filename, NULL,
|
||||
@@ -37,6 +38,31 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
|
||||
load_elf_strerror(kernel_size));
|
||||
exit(1);
|
||||
}
|
||||
+
|
||||
+ if (info->initrd_filename) {
|
||||
+ initrd_size = get_image_size(info->initrd_filename);
|
||||
+ if (initrd_size > 0) {
|
||||
+ initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB);
|
||||
+
|
||||
+ if (initrd_offset + initrd_size > info->ram_size) {
|
||||
+ error_report("memory too small for initial ram disk '%s'",
|
||||
+ info->initrd_filename);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ initrd_size = load_image_targphys(info->initrd_filename, initrd_offset,
|
||||
+ info->ram_size - initrd_offset);
|
||||
+ }
|
||||
+
|
||||
+ if (initrd_size == (target_ulong)-1) {
|
||||
+ error_report("could not load initial ram disk '%s'",
|
||||
+ info->initrd_filename);
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ } else {
|
||||
+ initrd_size = 0;
|
||||
+ }
|
||||
+
|
||||
return kernel_entry;
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
103
hw-loongarch-Add-slave-cpu-boot_code.patch
Normal file
103
hw-loongarch-Add-slave-cpu-boot_code.patch
Normal file
@ -0,0 +1,103 @@
|
||||
From 2e3e7bcf92284f41c08fce29f6c6d45849721e71 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:37 +0800
|
||||
Subject: [PATCH 03/78] hw/loongarch: Add slave cpu boot_code
|
||||
|
||||
Load the slave CPU boot code at pflash0 and set
|
||||
the slave CPU elf_address to VIRT_FLASH0_BASE.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-4-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 61 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index a5135fe542..fb6effbaff 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -15,6 +15,54 @@
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
+static const unsigned int slave_boot_code[] = {
|
||||
+ /* Configure reset ebase. */
|
||||
+ 0x0400302c, /* csrwr $t0, LOONGARCH_CSR_EENTRY */
|
||||
+
|
||||
+ /* Disable interrupt. */
|
||||
+ 0x0380100c, /* ori $t0, $zero,0x4 */
|
||||
+ 0x04000180, /* csrxchg $zero, $t0, LOONGARCH_CSR_CRMD */
|
||||
+
|
||||
+ /* Clear mailbox. */
|
||||
+ 0x1400002d, /* lu12i.w $t1, 1(0x1) */
|
||||
+ 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */
|
||||
+ 0x06481da0, /* iocsrwr.d $zero, $t1 */
|
||||
+
|
||||
+ /* Enable IPI interrupt. */
|
||||
+ 0x1400002c, /* lu12i.w $t0, 1(0x1) */
|
||||
+ 0x0400118c, /* csrxchg $t0, $t0, LOONGARCH_CSR_ECFG */
|
||||
+ 0x02fffc0c, /* addi.d $t0, $r0,-1(0xfff) */
|
||||
+ 0x1400002d, /* lu12i.w $t1, 1(0x1) */
|
||||
+ 0x038011ad, /* ori $t1, $t1, CORE_EN_OFF */
|
||||
+ 0x064819ac, /* iocsrwr.w $t0, $t1 */
|
||||
+ 0x1400002d, /* lu12i.w $t1, 1(0x1) */
|
||||
+ 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */
|
||||
+
|
||||
+ /* Wait for wakeup <.L11>: */
|
||||
+ 0x06488000, /* idle 0x0 */
|
||||
+ 0x03400000, /* andi $zero, $zero, 0x0 */
|
||||
+ 0x064809ac, /* iocsrrd.w $t0, $t1 */
|
||||
+ 0x43fff59f, /* beqz $t0, -12(0x7ffff4) # 48 <.L11> */
|
||||
+
|
||||
+ /* Read and clear IPI interrupt. */
|
||||
+ 0x1400002d, /* lu12i.w $t1, 1(0x1) */
|
||||
+ 0x064809ac, /* iocsrrd.w $t0, $t1 */
|
||||
+ 0x1400002d, /* lu12i.w $t1, 1(0x1) */
|
||||
+ 0x038031ad, /* ori $t1, $t1, CORE_CLEAR_OFF */
|
||||
+ 0x064819ac, /* iocsrwr.w $t0, $t1 */
|
||||
+
|
||||
+ /* Disable IPI interrupt. */
|
||||
+ 0x1400002c, /* lu12i.w $t0, 1(0x1) */
|
||||
+ 0x04001180, /* csrxchg $zero, $t0, LOONGARCH_CSR_ECFG */
|
||||
+
|
||||
+ /* Read mail buf and jump to specified entry */
|
||||
+ 0x1400002d, /* lu12i.w $t1, 1(0x1) */
|
||||
+ 0x038081ad, /* ori $t1, $t1, CORE_BUF_20 */
|
||||
+ 0x06480dac, /* iocsrrd.d $t0, $t1 */
|
||||
+ 0x00150181, /* move $ra, $t0 */
|
||||
+ 0x4c000020, /* jirl $zero, $ra,0 */
|
||||
+};
|
||||
+
|
||||
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
||||
{
|
||||
return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
|
||||
@@ -125,11 +173,23 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Load slave boot code at pflash0 . */
|
||||
+ void *boot_code = g_malloc0(VIRT_FLASH0_SIZE);
|
||||
+ memcpy(boot_code, &slave_boot_code, sizeof(slave_boot_code));
|
||||
+ rom_add_blob_fixed("boot_code", boot_code, VIRT_FLASH0_SIZE, VIRT_FLASH0_BASE);
|
||||
+
|
||||
CPU_FOREACH(cs) {
|
||||
lacpu = LOONGARCH_CPU(cs);
|
||||
lacpu->env.load_elf = true;
|
||||
- lacpu->env.elf_address = kernel_addr;
|
||||
+ if (cs == first_cpu) {
|
||||
+ lacpu->env.elf_address = kernel_addr;
|
||||
+ } else {
|
||||
+ lacpu->env.elf_address = VIRT_FLASH0_BASE;
|
||||
+ }
|
||||
+ lacpu->env.boot_info = info;
|
||||
}
|
||||
+
|
||||
+ g_free(boot_code);
|
||||
}
|
||||
|
||||
void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
46
hw-loongarch-Change-the-tpm-support-by-default.patch
Normal file
46
hw-loongarch-Change-the-tpm-support-by-default.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 67c68371e457a85e460221a8c56d8dc93186f79f Mon Sep 17 00:00:00 2001
|
||||
From: Xianglai Li <lixianglai@loongson.cn>
|
||||
Date: Mon, 24 Jun 2024 11:23:00 +0800
|
||||
Subject: [PATCH 31/78] hw/loongarch: Change the tpm support by default
|
||||
|
||||
Add devices that support tpm by default,
|
||||
Fixed incomplete tpm acpi table information.
|
||||
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240624032300.999157-1-lixianglai@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
---
|
||||
hw/loongarch/Kconfig | 1 +
|
||||
hw/loongarch/acpi-build.c | 3 +++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index 7864050563..b2a3adb7dc 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -7,6 +7,7 @@ config LOONGARCH_VIRT
|
||||
imply VIRTIO_VGA
|
||||
imply PCI_DEVICES
|
||||
imply NVDIMM
|
||||
+ imply TPM_TIS_SYSBUS
|
||||
select SERIAL
|
||||
select VIRTIO_PCI
|
||||
select PLATFORM_BUS
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index 2555c6763c..6593476409 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -646,6 +646,9 @@ void loongarch_acpi_setup(LoongArchVirtMachineState *lvms)
|
||||
build_state, tables.rsdp,
|
||||
ACPI_BUILD_RSDP_FILE);
|
||||
|
||||
+ fw_cfg_add_file(lvms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
|
||||
+ acpi_data_len(tables.tcpalog));
|
||||
+
|
||||
qemu_register_reset(acpi_build_reset, build_state);
|
||||
acpi_build_reset(build_state);
|
||||
vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
39
hw-loongarch-Fix-length-for-lowram-in-ACPI-SRAT.patch
Normal file
39
hw-loongarch-Fix-length-for-lowram-in-ACPI-SRAT.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 087201cd62e71801855775c3aa6395c7e1c00cee Mon Sep 17 00:00:00 2001
|
||||
From: Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
Date: Tue, 20 Aug 2024 19:42:33 +0100
|
||||
Subject: [PATCH 33/78] hw/loongarch: Fix length for lowram in ACPI SRAT
|
||||
|
||||
The size of lowram should be "gap" instead of the whole node.
|
||||
|
||||
This is failing kernel's sanity check:
|
||||
|
||||
[ 0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x00000000-0xffffffff]
|
||||
[ 0.000000] ACPI: SRAT: Node 0 PXM 0 [mem 0x80000000-0x16fffffff]
|
||||
[ 0.000000] ACPI: SRAT: Node 1 PXM 1 [mem 0x170000000-0x26fffffff]
|
||||
[ 0.000000] Warning: node 0 [mem 0x00000000-0xffffffff] overlaps with itself [mem 0x80000000-0x16fffffff]
|
||||
|
||||
Fixes: fc100011f38d ("hw/loongarch: Refine acpi srat table for numa memory")
|
||||
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/acpi-build.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index 6593476409..1a9d25fc51 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -218,7 +218,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
* highram: [VIRT_HIGHMEM_BASE, +(len - gap))
|
||||
*/
|
||||
if (len >= gap) {
|
||||
- build_srat_memory(table_data, base, len, i, MEM_AFFINITY_ENABLED);
|
||||
+ build_srat_memory(table_data, base, gap, i, MEM_AFFINITY_ENABLED);
|
||||
len -= gap;
|
||||
base = VIRT_HIGHMEM_BASE;
|
||||
gap = machine->ram_size - VIRT_LOWMEM_SIZE;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
169
hw-loongarch-Init-efi_boot_memmap-table.patch
Normal file
169
hw-loongarch-Init-efi_boot_memmap-table.patch
Normal file
@ -0,0 +1,169 @@
|
||||
From 0245881108803abedf50e954d34ebcfff294d1c3 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:40 +0800
|
||||
Subject: [PATCH 06/78] hw/loongarch: Init efi_boot_memmap table
|
||||
|
||||
The efi_system_table adds a efi_boot_memmap configuration table.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-7-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 40 +++++++++++++++++++++++++++++++++++++
|
||||
hw/loongarch/virt.c | 11 ++--------
|
||||
include/hw/loongarch/boot.h | 27 +++++++++++++++++++++++++
|
||||
include/hw/loongarch/virt.h | 10 ++++++++++
|
||||
4 files changed, 79 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index 59889dbc90..527fc9c0be 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -63,8 +63,41 @@ static const unsigned int slave_boot_code[] = {
|
||||
0x4c000020, /* jirl $zero, $ra,0 */
|
||||
};
|
||||
|
||||
+static inline void *guidcpy(void *dst, const void *src)
|
||||
+{
|
||||
+ return memcpy(dst, src, sizeof(efi_guid_t));
|
||||
+}
|
||||
+
|
||||
+static void init_efi_boot_memmap(struct efi_system_table *systab,
|
||||
+ void *p, void *start)
|
||||
+{
|
||||
+ unsigned i;
|
||||
+ struct efi_boot_memmap *boot_memmap = p;
|
||||
+ efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
|
||||
+
|
||||
+ /* efi_configuration_table 1 */
|
||||
+ guidcpy(&systab->tables[0].guid, &tbl_guid);
|
||||
+ systab->tables[0].table = (struct efi_configuration_table *)(p - start);
|
||||
+ systab->nr_tables = 1;
|
||||
+
|
||||
+ boot_memmap->desc_size = sizeof(efi_memory_desc_t);
|
||||
+ boot_memmap->desc_ver = 1;
|
||||
+ boot_memmap->map_size = 0;
|
||||
+
|
||||
+ efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap);
|
||||
+ for (i = 0; i < memmap_entries; i++) {
|
||||
+ map = (void *)boot_memmap + sizeof(*map);
|
||||
+ map[i].type = memmap_table[i].type;
|
||||
+ map[i].phys_addr = ROUND_UP(memmap_table[i].address, 64 * KiB);
|
||||
+ map[i].num_pages = ROUND_DOWN(memmap_table[i].address +
|
||||
+ memmap_table[i].length - map[i].phys_addr, 64 * KiB);
|
||||
+ p += sizeof(efi_memory_desc_t);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
{
|
||||
+ void *bp_tables_start;
|
||||
struct efi_system_table *systab = p;
|
||||
|
||||
info->a2 = p - start;
|
||||
@@ -80,6 +113,13 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
|
||||
|
||||
systab->tables = p;
|
||||
+ bp_tables_start = p;
|
||||
+
|
||||
+ init_efi_boot_memmap(systab, p, start);
|
||||
+ p += ROUND_UP(sizeof(struct efi_boot_memmap) +
|
||||
+ sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
|
||||
+
|
||||
+ systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);
|
||||
}
|
||||
|
||||
static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index a0aee28f41..028356acf5 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -405,15 +405,8 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque)
|
||||
acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
|
||||
}
|
||||
|
||||
-struct memmap_entry {
|
||||
- uint64_t address;
|
||||
- uint64_t length;
|
||||
- uint32_t type;
|
||||
- uint32_t reserved;
|
||||
-};
|
||||
-
|
||||
-static struct memmap_entry *memmap_table;
|
||||
-static unsigned memmap_entries;
|
||||
+struct memmap_entry *memmap_table;
|
||||
+unsigned memmap_entries;
|
||||
|
||||
static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
|
||||
{
|
||||
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
|
||||
index cf0e4d4f91..76622af2e2 100644
|
||||
--- a/include/hw/loongarch/boot.h
|
||||
+++ b/include/hw/loongarch/boot.h
|
||||
@@ -21,6 +21,15 @@ typedef struct {
|
||||
uint8_t b[16];
|
||||
} efi_guid_t QEMU_ALIGNED(8);
|
||||
|
||||
+#define EFI_GUID(a, b, c, d...) (efi_guid_t){ { \
|
||||
+ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
|
||||
+ (b) & 0xff, ((b) >> 8) & 0xff, \
|
||||
+ (c) & 0xff, ((c) >> 8) & 0xff, d } }
|
||||
+
|
||||
+#define LINUX_EFI_BOOT_MEMMAP_GUID \
|
||||
+ EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, \
|
||||
+ 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
|
||||
+
|
||||
struct efi_config_table {
|
||||
efi_guid_t guid;
|
||||
uint64_t *ptr;
|
||||
@@ -56,6 +65,24 @@ struct efi_system_table {
|
||||
struct efi_configuration_table *tables;
|
||||
};
|
||||
|
||||
+typedef struct {
|
||||
+ uint32_t type;
|
||||
+ uint32_t pad;
|
||||
+ uint64_t phys_addr;
|
||||
+ uint64_t virt_addr;
|
||||
+ uint64_t num_pages;
|
||||
+ uint64_t attribute;
|
||||
+} efi_memory_desc_t;
|
||||
+
|
||||
+struct efi_boot_memmap {
|
||||
+ uint64_t map_size;
|
||||
+ uint64_t desc_size;
|
||||
+ uint32_t desc_ver;
|
||||
+ uint64_t map_key;
|
||||
+ uint64_t buff_size;
|
||||
+ efi_memory_desc_t map[32];
|
||||
+};
|
||||
+
|
||||
struct loongarch_boot_info {
|
||||
uint64_t ram_size;
|
||||
const char *kernel_filename;
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index ffff075f63..2f9eaf4b0e 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -35,6 +35,16 @@
|
||||
|
||||
#define COMMAND_LINE_SIZE 512
|
||||
|
||||
+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;
|
||||
+};
|
||||
+
|
||||
struct LoongArchMachineState {
|
||||
/*< private >*/
|
||||
MachineState parent_obj;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
105
hw-loongarch-Init-efi_fdt-table.patch
Normal file
105
hw-loongarch-Init-efi_fdt-table.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 605b2b372f972fffa2d198d8dee4cf37f335559d Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:42 +0800
|
||||
Subject: [PATCH 08/78] hw/loongarch: Init efi_fdt table
|
||||
|
||||
The efi_system_table adds a efi_fdt configuration table.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-9-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 11 +++++++++++
|
||||
hw/loongarch/virt.c | 6 ++----
|
||||
include/hw/loongarch/boot.h | 4 ++++
|
||||
include/hw/loongarch/virt.h | 2 ++
|
||||
4 files changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index c8b3e742b4..7d1630b2e7 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -113,6 +113,16 @@ static void init_efi_initrd_table(struct efi_system_table *systab,
|
||||
initrd_table->size = initrd_size;
|
||||
}
|
||||
|
||||
+static void init_efi_fdt_table(struct efi_system_table *systab)
|
||||
+{
|
||||
+ efi_guid_t tbl_guid = DEVICE_TREE_GUID;
|
||||
+
|
||||
+ /* efi_configuration_table 3 */
|
||||
+ guidcpy(&systab->tables[2].guid, &tbl_guid);
|
||||
+ systab->tables[2].table = (void *)FDT_BASE;
|
||||
+ systab->nr_tables = 3;
|
||||
+}
|
||||
+
|
||||
static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
{
|
||||
void *bp_tables_start;
|
||||
@@ -138,6 +148,7 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
|
||||
init_efi_initrd_table(systab, p, start);
|
||||
p += ROUND_UP(sizeof(struct efi_initrd), 64 * KiB);
|
||||
+ init_efi_fdt_table(systab);
|
||||
|
||||
systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);
|
||||
}
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 028356acf5..99a3dc8696 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -820,7 +820,6 @@ static void loongarch_init(MachineState *machine)
|
||||
int nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
NodeInfo *numa_info = machine->numa_state->nodes;
|
||||
int i;
|
||||
- hwaddr fdt_base;
|
||||
const CPUArchIdList *possible_cpus;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
CPUState *cpu;
|
||||
@@ -949,12 +948,11 @@ static void loongarch_init(MachineState *machine)
|
||||
* 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.
|
||||
*/
|
||||
- fdt_base = 1 * MiB;
|
||||
qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
|
||||
- rom_add_blob_fixed_as("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));
|
||||
+ rom_ptr_for_as(&address_space_memory, FDT_BASE, lams->fdt_size));
|
||||
|
||||
lams->bootinfo.ram_size = ram_size;
|
||||
loongarch_load_kernel(machine, &lams->bootinfo);
|
||||
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
|
||||
index 42d1ee3663..4ebcc89dcf 100644
|
||||
--- a/include/hw/loongarch/boot.h
|
||||
+++ b/include/hw/loongarch/boot.h
|
||||
@@ -34,6 +34,10 @@ typedef struct {
|
||||
EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, \
|
||||
0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
|
||||
|
||||
+#define DEVICE_TREE_GUID \
|
||||
+ EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, \
|
||||
+ 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
|
||||
+
|
||||
struct efi_config_table {
|
||||
efi_guid_t guid;
|
||||
uint64_t *ptr;
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 2f9eaf4b0e..673b57aa2b 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#define COMMAND_LINE_SIZE 512
|
||||
|
||||
+#define FDT_BASE 0x100000
|
||||
+
|
||||
extern struct memmap_entry *memmap_table;
|
||||
extern unsigned memmap_entries;
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
101
hw-loongarch-Init-efi_initrd-table.patch
Normal file
101
hw-loongarch-Init-efi_initrd-table.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From ad674827da4ab972a30d51818f7768de47336984 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:41 +0800
|
||||
Subject: [PATCH 07/78] hw/loongarch: Init efi_initrd table
|
||||
|
||||
The efi_system_table adds a efi_initrd configuration table.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-8-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 23 +++++++++++++++++++++--
|
||||
include/hw/loongarch/boot.h | 9 +++++++++
|
||||
2 files changed, 30 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index 527fc9c0be..c8b3e742b4 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -15,6 +15,9 @@
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
+ram_addr_t initrd_offset;
|
||||
+uint64_t initrd_size;
|
||||
+
|
||||
static const unsigned int slave_boot_code[] = {
|
||||
/* Configure reset ebase. */
|
||||
0x0400302c, /* csrwr $t0, LOONGARCH_CSR_EENTRY */
|
||||
@@ -95,6 +98,21 @@ static void init_efi_boot_memmap(struct efi_system_table *systab,
|
||||
}
|
||||
}
|
||||
|
||||
+static void init_efi_initrd_table(struct efi_system_table *systab,
|
||||
+ void *p, void *start)
|
||||
+{
|
||||
+ efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
|
||||
+ struct efi_initrd *initrd_table = p;
|
||||
+
|
||||
+ /* efi_configuration_table 2 */
|
||||
+ guidcpy(&systab->tables[1].guid, &tbl_guid);
|
||||
+ systab->tables[1].table = (struct efi_configuration_table *)(p - start);
|
||||
+ systab->nr_tables = 2;
|
||||
+
|
||||
+ initrd_table->base = initrd_offset;
|
||||
+ initrd_table->size = initrd_size;
|
||||
+}
|
||||
+
|
||||
static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
{
|
||||
void *bp_tables_start;
|
||||
@@ -118,6 +136,8 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
init_efi_boot_memmap(systab, p, start);
|
||||
p += ROUND_UP(sizeof(struct efi_boot_memmap) +
|
||||
sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB);
|
||||
+ init_efi_initrd_table(systab, p, start);
|
||||
+ p += ROUND_UP(sizeof(struct efi_initrd), 64 * KiB);
|
||||
|
||||
systab->tables = (struct efi_configuration_table *)(bp_tables_start - start);
|
||||
}
|
||||
@@ -139,8 +159,7 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
||||
|
||||
static int64_t load_kernel_info(struct loongarch_boot_info *info)
|
||||
{
|
||||
- uint64_t kernel_entry, kernel_low, kernel_high, initrd_size;
|
||||
- ram_addr_t initrd_offset;
|
||||
+ uint64_t kernel_entry, kernel_low, kernel_high;
|
||||
ssize_t kernel_size;
|
||||
|
||||
kernel_size = load_elf(info->kernel_filename, NULL,
|
||||
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
|
||||
index 76622af2e2..42d1ee3663 100644
|
||||
--- a/include/hw/loongarch/boot.h
|
||||
+++ b/include/hw/loongarch/boot.h
|
||||
@@ -30,6 +30,10 @@ typedef struct {
|
||||
EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, \
|
||||
0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
|
||||
|
||||
+#define LINUX_EFI_INITRD_MEDIA_GUID \
|
||||
+ EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, \
|
||||
+ 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
|
||||
+
|
||||
struct efi_config_table {
|
||||
efi_guid_t guid;
|
||||
uint64_t *ptr;
|
||||
@@ -83,6 +87,11 @@ struct efi_boot_memmap {
|
||||
efi_memory_desc_t map[32];
|
||||
};
|
||||
|
||||
+struct efi_initrd {
|
||||
+ uint64_t base;
|
||||
+ uint64_t size;
|
||||
+};
|
||||
+
|
||||
struct loongarch_boot_info {
|
||||
uint64_t ram_size;
|
||||
const char *kernel_filename;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
125
hw-loongarch-Init-efi_system_table.patch
Normal file
125
hw-loongarch-Init-efi_system_table.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From 65ae44689bfa6a1b697fea6ec0e72027fdddee95 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:39 +0800
|
||||
Subject: [PATCH 05/78] hw/loongarch: Init efi_system_table
|
||||
|
||||
Add init_systab and set boot_info->a2
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-6-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 22 +++++++++++++++++
|
||||
include/hw/loongarch/boot.h | 48 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 70 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index 127085bcc4..59889dbc90 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -63,6 +63,25 @@ static const unsigned int slave_boot_code[] = {
|
||||
0x4c000020, /* jirl $zero, $ra,0 */
|
||||
};
|
||||
|
||||
+static void init_systab(struct loongarch_boot_info *info, void *p, void *start)
|
||||
+{
|
||||
+ struct efi_system_table *systab = p;
|
||||
+
|
||||
+ info->a2 = p - start;
|
||||
+
|
||||
+ systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
|
||||
+ systab->hdr.revision = EFI_SPECIFICATION_VERSION;
|
||||
+ systab->hdr.revision = sizeof(struct efi_system_table),
|
||||
+ systab->fw_revision = FW_VERSION << 16 | FW_PATCHLEVEL << 8;
|
||||
+ systab->runtime = 0;
|
||||
+ systab->boottime = 0;
|
||||
+ systab->nr_tables = 0;
|
||||
+
|
||||
+ p += ROUND_UP(sizeof(struct efi_system_table), 64 * KiB);
|
||||
+
|
||||
+ systab->tables = p;
|
||||
+}
|
||||
+
|
||||
static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
|
||||
{
|
||||
hwaddr cmdline_addr = p - start;
|
||||
@@ -134,6 +153,7 @@ static void reset_load_elf(void *opaque)
|
||||
if (cpu == LOONGARCH_CPU(first_cpu)) {
|
||||
env->gpr[4] = env->boot_info->a0;
|
||||
env->gpr[5] = env->boot_info->a1;
|
||||
+ env->gpr[6] = env->boot_info->a2;
|
||||
}
|
||||
cpu_set_pc(CPU(cpu), env->elf_address);
|
||||
}
|
||||
@@ -178,6 +198,8 @@ static void init_boot_rom(struct loongarch_boot_info *info, void *p)
|
||||
|
||||
init_cmdline(info, p, start);
|
||||
p += COMMAND_LINE_SIZE;
|
||||
+
|
||||
+ init_systab(info, p, start);
|
||||
}
|
||||
|
||||
static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
|
||||
index 3275c1e295..cf0e4d4f91 100644
|
||||
--- a/include/hw/loongarch/boot.h
|
||||
+++ b/include/hw/loongarch/boot.h
|
||||
@@ -8,6 +8,54 @@
|
||||
#ifndef HW_LOONGARCH_BOOT_H
|
||||
#define HW_LOONGARCH_BOOT_H
|
||||
|
||||
+/* UEFI 2.10 */
|
||||
+#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249
|
||||
+#define EFI_2_100_SYSTEM_TABLE_REVISION ((2<<16) | (100))
|
||||
+#define EFI_SPECIFICATION_VERSION EFI_SYSTEM_TABLE_REVISION
|
||||
+#define EFI_SYSTEM_TABLE_REVISION EFI_2_100_SYSTEM_TABLE_REVISION
|
||||
+
|
||||
+#define FW_VERSION 0x1
|
||||
+#define FW_PATCHLEVEL 0x0
|
||||
+
|
||||
+typedef struct {
|
||||
+ uint8_t b[16];
|
||||
+} efi_guid_t QEMU_ALIGNED(8);
|
||||
+
|
||||
+struct efi_config_table {
|
||||
+ efi_guid_t guid;
|
||||
+ uint64_t *ptr;
|
||||
+ const char name[16];
|
||||
+};
|
||||
+
|
||||
+typedef struct {
|
||||
+ uint64_t signature;
|
||||
+ uint32_t revision;
|
||||
+ uint32_t headersize;
|
||||
+ uint32_t crc32;
|
||||
+ uint32_t reserved;
|
||||
+} efi_table_hdr_t;
|
||||
+
|
||||
+struct efi_configuration_table {
|
||||
+ efi_guid_t guid;
|
||||
+ void *table;
|
||||
+};
|
||||
+
|
||||
+struct efi_system_table {
|
||||
+ efi_table_hdr_t hdr;
|
||||
+ uint64_t fw_vendor; /* physical addr of CHAR16 vendor string */
|
||||
+ uint32_t fw_revision;
|
||||
+ uint64_t con_in_handle;
|
||||
+ uint64_t *con_in;
|
||||
+ uint64_t con_out_handle;
|
||||
+ uint64_t *con_out;
|
||||
+ uint64_t stderr_handle;
|
||||
+ uint64_t stderr_placeholder;
|
||||
+ uint64_t *runtime;
|
||||
+ uint64_t *boottime;
|
||||
+ uint64_t nr_tables;
|
||||
+ struct efi_configuration_table *tables;
|
||||
+};
|
||||
+
|
||||
struct loongarch_boot_info {
|
||||
uint64_t ram_size;
|
||||
const char *kernel_filename;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
390
hw-loongarch-Move-boot-functions-to-boot.c.patch
Normal file
390
hw-loongarch-Move-boot-functions-to-boot.c.patch
Normal file
@ -0,0 +1,390 @@
|
||||
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
|
||||
|
||||
108
hw-loongarch-Refine-acpi-srat-table-for-numa-memory.patch
Normal file
108
hw-loongarch-Refine-acpi-srat-table-for-numa-memory.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 1c9b7b7e76a63738721ac1092fdfff12ae87993a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 15 May 2024 17:39:22 +0800
|
||||
Subject: [PATCH 23/78] hw/loongarch: Refine acpi srat table for numa memory
|
||||
|
||||
One LoongArch virt machine platform, there is limitation for memory
|
||||
map information. The minimum memory size is 256M and minimum memory
|
||||
size for numa node0 is 256M also. With qemu numa qtest, it is possible
|
||||
that memory size of numa node0 is 128M.
|
||||
|
||||
Limitations for minimum memory size for both total memory and numa
|
||||
node0 is removed for acpi srat table creation.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240515093927.3453674-2-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/acpi-build.c | 58 +++++++++++++++++++++++----------------
|
||||
1 file changed, 34 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index 2b4e09bf37..2555c6763c 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -166,8 +166,9 @@ static void
|
||||
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;
|
||||
+ hwaddr len, base, gap;
|
||||
+ NodeInfo *numa_info;
|
||||
+ int nodes, nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lvms);
|
||||
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
|
||||
@@ -196,35 +197,44 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
build_append_int_noprefix(table_data, 0, 4); /* Reserved */
|
||||
}
|
||||
|
||||
- /* Node0 */
|
||||
- build_srat_memory(table_data, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE,
|
||||
- 0, MEM_AFFINITY_ENABLED);
|
||||
- mem_base = VIRT_HIGHMEM_BASE;
|
||||
- if (!nb_numa_nodes) {
|
||||
- mem_len = machine->ram_size - VIRT_LOWMEM_SIZE;
|
||||
- } else {
|
||||
- mem_len = machine->numa_state->nodes[0].node_mem - VIRT_LOWMEM_SIZE;
|
||||
+ base = VIRT_LOWMEM_BASE;
|
||||
+ gap = VIRT_LOWMEM_SIZE;
|
||||
+ numa_info = machine->numa_state->nodes;
|
||||
+ nodes = nb_numa_nodes;
|
||||
+ if (!nodes) {
|
||||
+ nodes = 1;
|
||||
}
|
||||
- if (mem_len)
|
||||
- build_srat_memory(table_data, mem_base, mem_len, 0, MEM_AFFINITY_ENABLED);
|
||||
-
|
||||
- /* Node1 - Nodemax */
|
||||
- if (nb_numa_nodes) {
|
||||
- mem_base += mem_len;
|
||||
- for (i = 1; i < nb_numa_nodes; ++i) {
|
||||
- if (machine->numa_state->nodes[i].node_mem > 0) {
|
||||
- build_srat_memory(table_data, mem_base,
|
||||
- machine->numa_state->nodes[i].node_mem, i,
|
||||
- MEM_AFFINITY_ENABLED);
|
||||
- mem_base += machine->numa_state->nodes[i].node_mem;
|
||||
- }
|
||||
+
|
||||
+ for (i = 0; i < nodes; i++) {
|
||||
+ if (nb_numa_nodes) {
|
||||
+ len = numa_info[i].node_mem;
|
||||
+ } else {
|
||||
+ len = machine->ram_size;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * memory for the node splited into two part
|
||||
+ * lowram: [base, +gap)
|
||||
+ * highram: [VIRT_HIGHMEM_BASE, +(len - gap))
|
||||
+ */
|
||||
+ if (len >= gap) {
|
||||
+ build_srat_memory(table_data, base, len, i, MEM_AFFINITY_ENABLED);
|
||||
+ len -= gap;
|
||||
+ base = VIRT_HIGHMEM_BASE;
|
||||
+ gap = machine->ram_size - VIRT_LOWMEM_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ if (len) {
|
||||
+ build_srat_memory(table_data, base, len, i, MEM_AFFINITY_ENABLED);
|
||||
+ base += len;
|
||||
+ gap -= len;
|
||||
}
|
||||
}
|
||||
|
||||
if (machine->device_memory) {
|
||||
build_srat_memory(table_data, machine->device_memory->base,
|
||||
memory_region_size(&machine->device_memory->mr),
|
||||
- nb_numa_nodes - 1,
|
||||
+ nodes - 1,
|
||||
MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
57
hw-loongarch-Refine-default-numa-id-calculation.patch
Normal file
57
hw-loongarch-Refine-default-numa-id-calculation.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From a9f9a4a0a60596f2e738e6e434c20a3f5266fa17 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Tue, 19 Mar 2024 10:26:06 +0800
|
||||
Subject: [PATCH 21/78] hw/loongarch: Refine default numa id calculation
|
||||
|
||||
With numa_test test case, there is subcase named test_def_cpu_split(),
|
||||
there are 8 sockets and 2 numa nodes. Here is command line:
|
||||
"-machine smp.cpus=8,smp.sockets=8 -numa node,memdev=ram -numa node"
|
||||
|
||||
The required result is:
|
||||
node 0 cpus: 0 2 4 6
|
||||
node 1 cpus: 1 3 5 7
|
||||
Test case numa_test fails on LoongArch, since the actual result is:
|
||||
node 0 cpus: 0 1 2 3
|
||||
node 1 cpus: 4 5 6 7
|
||||
|
||||
It will be better if all the cpus in one socket share the same numa
|
||||
node. Here socket id is used to calculate numa id in function
|
||||
virt_get_default_cpu_node_id().
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240319022606.2994565-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 11 +++++------
|
||||
1 file changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index e39989193e..e82e3b6792 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1278,15 +1278,14 @@ static CpuInstanceProperties virt_cpu_index_to_props(MachineState *ms,
|
||||
|
||||
static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
|
||||
{
|
||||
- int64_t nidx = 0;
|
||||
+ int64_t socket_id;
|
||||
|
||||
if (ms->numa_state->num_nodes) {
|
||||
- nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
|
||||
- if (ms->numa_state->num_nodes <= nidx) {
|
||||
- nidx = ms->numa_state->num_nodes - 1;
|
||||
- }
|
||||
+ socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
|
||||
+ return socket_id % ms->numa_state->num_nodes;
|
||||
+ } else {
|
||||
+ return 0;
|
||||
}
|
||||
- return nidx;
|
||||
}
|
||||
|
||||
static void virt_class_init(ObjectClass *oc, void *data)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
106
hw-loongarch-Refine-fadt-memory-table-for-numa-memor.patch
Normal file
106
hw-loongarch-Refine-fadt-memory-table-for-numa-memor.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From d39247ec5d4ef52a4b9422aaecccc284cbd1a5dd Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 15 May 2024 17:39:23 +0800
|
||||
Subject: [PATCH 24/78] hw/loongarch: Refine fadt memory table for numa memory
|
||||
|
||||
One LoongArch virt machine platform, there is limitation for memory
|
||||
map information. The minimum memory size is 256M and minimum memory
|
||||
size for numa node0 is 256M also. With qemu numa qtest, it is possible
|
||||
that memory size of numa node0 is 128M.
|
||||
|
||||
Limitations for minimum memory size for both total memory and numa
|
||||
node0 is removed for fadt numa memory table creation.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240515093927.3453674-3-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 46 ++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 43 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index c3514f9293..31a2598e7c 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -502,6 +502,48 @@ static void fdt_add_memory_node(MachineState *ms,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
+static void fdt_add_memory_nodes(MachineState *ms)
|
||||
+{
|
||||
+ hwaddr base, size, ram_size, gap;
|
||||
+ int i, nb_numa_nodes, nodes;
|
||||
+ NodeInfo *numa_info;
|
||||
+
|
||||
+ ram_size = ms->ram_size;
|
||||
+ base = VIRT_LOWMEM_BASE;
|
||||
+ gap = VIRT_LOWMEM_SIZE;
|
||||
+ nodes = nb_numa_nodes = ms->numa_state->num_nodes;
|
||||
+ numa_info = ms->numa_state->nodes;
|
||||
+ if (!nodes) {
|
||||
+ nodes = 1;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < nodes; i++) {
|
||||
+ if (nb_numa_nodes) {
|
||||
+ size = numa_info[i].node_mem;
|
||||
+ } else {
|
||||
+ size = ram_size;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * memory for the node splited into two part
|
||||
+ * lowram: [base, +gap)
|
||||
+ * highram: [VIRT_HIGHMEM_BASE, +(len - gap))
|
||||
+ */
|
||||
+ if (size >= gap) {
|
||||
+ fdt_add_memory_node(ms, base, gap, i);
|
||||
+ size -= gap;
|
||||
+ base = VIRT_HIGHMEM_BASE;
|
||||
+ gap = ram_size - VIRT_LOWMEM_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ if (size) {
|
||||
+ fdt_add_memory_node(ms, base, size, i);
|
||||
+ base += size;
|
||||
+ gap -= size;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void virt_build_smbios(LoongArchVirtMachineState *lvms)
|
||||
{
|
||||
MachineState *ms = MACHINE(lvms);
|
||||
@@ -1008,10 +1050,10 @@ static void virt_init(MachineState *machine)
|
||||
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
|
||||
}
|
||||
fdt_add_cpu_nodes(lvms);
|
||||
+ fdt_add_memory_nodes(machine);
|
||||
|
||||
/* Node0 memory */
|
||||
memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
|
||||
- fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0);
|
||||
memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.node0.lowram",
|
||||
machine->ram, offset, VIRT_LOWMEM_SIZE);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, &lvms->lowmem);
|
||||
@@ -1025,7 +1067,6 @@ static void virt_init(MachineState *machine)
|
||||
}
|
||||
phyAddr = VIRT_HIGHMEM_BASE;
|
||||
memmap_add_entry(phyAddr, highram_size, 1);
|
||||
- fdt_add_memory_node(machine, phyAddr, highram_size, 0);
|
||||
memory_region_init_alias(&lvms->highmem, NULL, "loongarch.node0.highram",
|
||||
machine->ram, offset, highram_size);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, &lvms->highmem);
|
||||
@@ -1041,7 +1082,6 @@ static void virt_init(MachineState *machine)
|
||||
offset, numa_info[i].node_mem);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
|
||||
memmap_add_entry(phyAddr, numa_info[i].node_mem, 1);
|
||||
- fdt_add_memory_node(machine, phyAddr, numa_info[i].node_mem, i);
|
||||
offset += numa_info[i].node_mem;
|
||||
phyAddr += numa_info[i].node_mem;
|
||||
}
|
||||
--
|
||||
2.39.1
|
||||
|
||||
120
hw-loongarch-Refine-fwcfg-memory-map.patch
Normal file
120
hw-loongarch-Refine-fwcfg-memory-map.patch
Normal file
@ -0,0 +1,120 @@
|
||||
From 88b12e40d6a479dfb376fb6a91ef24e07a59d33a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 15 May 2024 17:39:24 +0800
|
||||
Subject: [PATCH 25/78] hw/loongarch: Refine fwcfg memory map
|
||||
|
||||
Memory map table for fwcfg is used for UEFI BIOS, UEFI BIOS uses the first
|
||||
entry from fwcfg memory map as the first memory HOB, the second memory HOB
|
||||
will be used if the first memory HOB is used up.
|
||||
|
||||
Memory map table for fwcfg does not care about numa node, however in
|
||||
generic the first memory HOB is part of numa node0, so that runtime
|
||||
memory of UEFI which is allocated from the first memory HOB is located
|
||||
at numa node0.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240515093927.3453674-4-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 60 ++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 57 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 31a2598e7c..7e89921431 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1005,6 +1005,62 @@ static const MemoryRegionOps virt_iocsr_misc_ops = {
|
||||
},
|
||||
};
|
||||
|
||||
+static void fw_cfg_add_memory(MachineState *ms)
|
||||
+{
|
||||
+ hwaddr base, size, ram_size, gap;
|
||||
+ int nb_numa_nodes, nodes;
|
||||
+ NodeInfo *numa_info;
|
||||
+
|
||||
+ ram_size = ms->ram_size;
|
||||
+ base = VIRT_LOWMEM_BASE;
|
||||
+ gap = VIRT_LOWMEM_SIZE;
|
||||
+ nodes = nb_numa_nodes = ms->numa_state->num_nodes;
|
||||
+ numa_info = ms->numa_state->nodes;
|
||||
+ if (!nodes) {
|
||||
+ nodes = 1;
|
||||
+ }
|
||||
+
|
||||
+ /* add fw_cfg memory map of node0 */
|
||||
+ if (nb_numa_nodes) {
|
||||
+ size = numa_info[0].node_mem;
|
||||
+ } else {
|
||||
+ size = ram_size;
|
||||
+ }
|
||||
+
|
||||
+ if (size >= gap) {
|
||||
+ memmap_add_entry(base, gap, 1);
|
||||
+ size -= gap;
|
||||
+ base = VIRT_HIGHMEM_BASE;
|
||||
+ gap = ram_size - VIRT_LOWMEM_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ if (size) {
|
||||
+ memmap_add_entry(base, size, 1);
|
||||
+ base += size;
|
||||
+ }
|
||||
+
|
||||
+ if (nodes < 2) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* add fw_cfg memory map of other nodes */
|
||||
+ size = ram_size - numa_info[0].node_mem;
|
||||
+ gap = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE;
|
||||
+ if (base < gap && (base + size) > gap) {
|
||||
+ /*
|
||||
+ * memory map for the maining nodes splited into two part
|
||||
+ * lowram: [base, +(gap - base))
|
||||
+ * highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base)))
|
||||
+ */
|
||||
+ memmap_add_entry(base, gap - base, 1);
|
||||
+ size -= gap - base;
|
||||
+ base = VIRT_HIGHMEM_BASE;
|
||||
+ }
|
||||
+
|
||||
+ if (size)
|
||||
+ memmap_add_entry(base, size, 1);
|
||||
+}
|
||||
+
|
||||
static void virt_init(MachineState *machine)
|
||||
{
|
||||
LoongArchCPU *lacpu;
|
||||
@@ -1051,9 +1107,9 @@ static void virt_init(MachineState *machine)
|
||||
}
|
||||
fdt_add_cpu_nodes(lvms);
|
||||
fdt_add_memory_nodes(machine);
|
||||
+ fw_cfg_add_memory(machine);
|
||||
|
||||
/* Node0 memory */
|
||||
- memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
|
||||
memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.node0.lowram",
|
||||
machine->ram, offset, VIRT_LOWMEM_SIZE);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, &lvms->lowmem);
|
||||
@@ -1066,7 +1122,6 @@ static void virt_init(MachineState *machine)
|
||||
highram_size = ram_size - VIRT_LOWMEM_SIZE;
|
||||
}
|
||||
phyAddr = VIRT_HIGHMEM_BASE;
|
||||
- memmap_add_entry(phyAddr, highram_size, 1);
|
||||
memory_region_init_alias(&lvms->highmem, NULL, "loongarch.node0.highram",
|
||||
machine->ram, offset, highram_size);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, &lvms->highmem);
|
||||
@@ -1081,7 +1136,6 @@ static void virt_init(MachineState *machine)
|
||||
memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
|
||||
offset, numa_info[i].node_mem);
|
||||
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
|
||||
- memmap_add_entry(phyAddr, numa_info[i].node_mem, 1);
|
||||
offset += numa_info[i].node_mem;
|
||||
phyAddr += numa_info[i].node_mem;
|
||||
}
|
||||
--
|
||||
2.39.1
|
||||
|
||||
110
hw-loongarch-Refine-system-dram-memory-region.patch
Normal file
110
hw-loongarch-Refine-system-dram-memory-region.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 1a7f567308756a2a26020802b24fe7fd106cf84a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 15 May 2024 17:39:25 +0800
|
||||
Subject: [PATCH 26/78] hw/loongarch: Refine system dram memory region
|
||||
|
||||
For system dram memory region, it is not necessary to use numa node
|
||||
information. There is only low memory region and high memory region.
|
||||
|
||||
Remove numa node information for ddr memory region here, it can reduce
|
||||
memory region number on LoongArch virt machine.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240515093927.3453674-5-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 53 +++++++++++++++------------------------------
|
||||
1 file changed, 17 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 7e89921431..96755f5deb 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1065,14 +1065,10 @@ static void virt_init(MachineState *machine)
|
||||
{
|
||||
LoongArchCPU *lacpu;
|
||||
const char *cpu_model = machine->cpu_type;
|
||||
- ram_addr_t offset = 0;
|
||||
- ram_addr_t ram_size = machine->ram_size;
|
||||
- uint64_t highram_size = 0, phyAddr = 0;
|
||||
MemoryRegion *address_space_mem = get_system_memory();
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
- int nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
- NodeInfo *numa_info = machine->numa_state->nodes;
|
||||
int i;
|
||||
+ hwaddr base, size, ram_size = machine->ram_size;
|
||||
const CPUArchIdList *possible_cpus;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
CPUState *cpu;
|
||||
@@ -1110,40 +1106,27 @@ static void virt_init(MachineState *machine)
|
||||
fw_cfg_add_memory(machine);
|
||||
|
||||
/* Node0 memory */
|
||||
- memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.node0.lowram",
|
||||
- machine->ram, offset, VIRT_LOWMEM_SIZE);
|
||||
- memory_region_add_subregion(address_space_mem, phyAddr, &lvms->lowmem);
|
||||
-
|
||||
- offset += VIRT_LOWMEM_SIZE;
|
||||
- if (nb_numa_nodes > 0) {
|
||||
- assert(numa_info[0].node_mem > VIRT_LOWMEM_SIZE);
|
||||
- highram_size = numa_info[0].node_mem - VIRT_LOWMEM_SIZE;
|
||||
- } else {
|
||||
- highram_size = ram_size - VIRT_LOWMEM_SIZE;
|
||||
+ size = ram_size;
|
||||
+ base = VIRT_LOWMEM_BASE;
|
||||
+ if (size > VIRT_LOWMEM_SIZE) {
|
||||
+ size = VIRT_LOWMEM_SIZE;
|
||||
}
|
||||
- phyAddr = VIRT_HIGHMEM_BASE;
|
||||
- memory_region_init_alias(&lvms->highmem, NULL, "loongarch.node0.highram",
|
||||
- machine->ram, offset, highram_size);
|
||||
- memory_region_add_subregion(address_space_mem, phyAddr, &lvms->highmem);
|
||||
-
|
||||
- /* Node1 - Nodemax memory */
|
||||
- offset += highram_size;
|
||||
- phyAddr += highram_size;
|
||||
-
|
||||
- for (i = 1; i < nb_numa_nodes; i++) {
|
||||
- MemoryRegion *nodemem = g_new(MemoryRegion, 1);
|
||||
- g_autofree char *ramName = g_strdup_printf("loongarch.node%d.ram", i);
|
||||
- memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
|
||||
- offset, numa_info[i].node_mem);
|
||||
- memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
|
||||
- offset += numa_info[i].node_mem;
|
||||
- phyAddr += numa_info[i].node_mem;
|
||||
+
|
||||
+ memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.lowram",
|
||||
+ machine->ram, base, size);
|
||||
+ memory_region_add_subregion(address_space_mem, base, &lvms->lowmem);
|
||||
+ base += size;
|
||||
+ if (ram_size - size) {
|
||||
+ base = VIRT_HIGHMEM_BASE;
|
||||
+ memory_region_init_alias(&lvms->highmem, NULL, "loongarch.highram",
|
||||
+ machine->ram, VIRT_LOWMEM_BASE + size, ram_size - size);
|
||||
+ memory_region_add_subregion(address_space_mem, base, &lvms->highmem);
|
||||
+ base += ram_size - size;
|
||||
}
|
||||
|
||||
/* initialize device memory address space */
|
||||
if (machine->ram_size < machine->maxram_size) {
|
||||
ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size;
|
||||
- hwaddr device_mem_base;
|
||||
|
||||
if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
|
||||
error_report("unsupported amount of memory slots: %"PRIu64,
|
||||
@@ -1157,9 +1140,7 @@ static void virt_init(MachineState *machine)
|
||||
"%d bytes", TARGET_PAGE_SIZE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
- /* device memory base is the top of high memory address. */
|
||||
- device_mem_base = ROUND_UP(VIRT_HIGHMEM_BASE + highram_size, 1 * GiB);
|
||||
- machine_memory_devices_init(machine, device_mem_base, device_mem_size);
|
||||
+ machine_memory_devices_init(machine, base, device_mem_size);
|
||||
}
|
||||
|
||||
/* load the BIOS image. */
|
||||
--
|
||||
2.39.1
|
||||
|
||||
39
hw-loongarch-Remove-default-enable-with-VIRTIO_VGA-d.patch
Normal file
39
hw-loongarch-Remove-default-enable-with-VIRTIO_VGA-d.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 94fa0b75c098ca6fc987f103760c1e07695ffd1a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Fri, 23 Aug 2024 15:30:50 +0800
|
||||
Subject: [PATCH 34/78] hw/loongarch: Remove default enable with VIRTIO_VGA
|
||||
device
|
||||
|
||||
For virtio VGA deivce libvirt will select VIRTIO_VGA firstly rather than
|
||||
VIRTIO_GPU, VIRTIO_VGA device supports frame buffer however it requires
|
||||
legacy VGA compatible support. Frame buffer area 0xa0000 -- 0xc0000
|
||||
conflicts with low memory area 0 -- 0x10000000.
|
||||
|
||||
Here remove default support for VIRTIO_VGA device, VIRTIO_GPU is prefered
|
||||
on LoongArch system. For frame buffer video card support, standard VGA can
|
||||
be used.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240823073050.2619484-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/Kconfig | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index b2a3adb7dc..40944a8365 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -4,7 +4,6 @@ config LOONGARCH_VIRT
|
||||
depends on LOONGARCH64
|
||||
select PCI
|
||||
select PCI_EXPRESS_GENERIC_BRIDGE
|
||||
- imply VIRTIO_VGA
|
||||
imply PCI_DEVICES
|
||||
imply NVDIMM
|
||||
imply TPM_TIS_SYSBUS
|
||||
--
|
||||
2.39.1
|
||||
|
||||
46
hw-loongarch-Remove-minimum-and-default-memory-size.patch
Normal file
46
hw-loongarch-Remove-minimum-and-default-memory-size.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 858f16ea09fbbac9966ca73b6b86d290a36be6f5 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 15 May 2024 17:39:26 +0800
|
||||
Subject: [PATCH 27/78] hw/loongarch: Remove minimum and default memory size
|
||||
|
||||
Some qtest test cases such as numa use default memory size of generic
|
||||
machine class, which is 128M by fault.
|
||||
|
||||
Here generic default memory size is used, and also remove minimum memory
|
||||
size which is 1G originally.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240515093927.3453674-6-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 96755f5deb..11ba879e52 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1077,10 +1077,6 @@ static void virt_init(MachineState *machine)
|
||||
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||
}
|
||||
|
||||
- if (ram_size < 1 * GiB) {
|
||||
- error_report("ram_size must be greater than 1G.");
|
||||
- exit(1);
|
||||
- }
|
||||
create_fdt(lvms);
|
||||
|
||||
/* Create IOCSR space */
|
||||
@@ -1369,7 +1365,6 @@ static void virt_class_init(ObjectClass *oc, void *data)
|
||||
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
||||
|
||||
mc->init = virt_init;
|
||||
- mc->default_ram_size = 1 * GiB;
|
||||
mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||
mc->default_ram_id = "loongarch.ram";
|
||||
mc->max_cpus = LOONGARCH_MAX_CPUS;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
188
hw-loongarch-Rename-LOONGARCH_MACHINE-with-LOONGARCH.patch
Normal file
188
hw-loongarch-Rename-LOONGARCH_MACHINE-with-LOONGARCH.patch
Normal file
@ -0,0 +1,188 @@
|
||||
From 8e2986a6fc5dda2afbe33f723efdacd01f147b7a Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 8 May 2024 11:11:06 +0800
|
||||
Subject: [PATCH 19/78] hw/loongarch: Rename LOONGARCH_MACHINE with
|
||||
LOONGARCH_VIRT_MACHINE
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On LoongArch system, there is only virt machine type now, name
|
||||
LOONGARCH_MACHINE is confused, rename it with LOONGARCH_VIRT_MACHINE.
|
||||
Machine name about Other real hw boards can be added in future.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Message-ID: <20240508031110.2507477-2-maobibo@loongson.cn>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/acpi-build.c | 8 ++++----
|
||||
hw/loongarch/boot.c | 2 +-
|
||||
hw/loongarch/virt.c | 19 +++++++++----------
|
||||
include/hw/loongarch/virt.h | 4 ++--
|
||||
4 files changed, 16 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index f990405d04..fff3497c62 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -167,7 +167,7 @@ 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);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lams);
|
||||
const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
|
||||
AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id,
|
||||
@@ -279,7 +279,7 @@ static void
|
||||
build_la_ged_aml(Aml *dsdt, MachineState *machine)
|
||||
{
|
||||
uint32_t event;
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine);
|
||||
|
||||
build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
|
||||
HOTPLUG_HANDLER(lams->acpi_ged),
|
||||
@@ -391,7 +391,7 @@ static void
|
||||
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
{
|
||||
Aml *dsdt, *scope, *pkg;
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine);
|
||||
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id,
|
||||
.oem_table_id = lams->oem_table_id };
|
||||
|
||||
@@ -421,7 +421,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
|
||||
static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine);
|
||||
GArray *table_offsets;
|
||||
AcpiFadtData fadt_data;
|
||||
unsigned facs, rsdt, dsdt;
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index 03f6301a77..e37512729d 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -319,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)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(ms);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(ms);
|
||||
int i;
|
||||
|
||||
/* register reset function */
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 76b36539e2..cca220cb5b 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -970,7 +970,7 @@ static void loongarch_init(MachineState *machine)
|
||||
ram_addr_t ram_size = machine->ram_size;
|
||||
uint64_t highram_size = 0, phyAddr = 0;
|
||||
MemoryRegion *address_space_mem = get_system_memory();
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(machine);
|
||||
int nb_numa_nodes = machine->numa_state->num_nodes;
|
||||
NodeInfo *numa_info = machine->numa_state->nodes;
|
||||
int i;
|
||||
@@ -1121,7 +1121,7 @@ bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
|
||||
static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj);
|
||||
OnOffAuto acpi = lams->acpi;
|
||||
|
||||
visit_type_OnOffAuto(v, name, &acpi, errp);
|
||||
@@ -1130,14 +1130,14 @@ static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name,
|
||||
static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name,
|
||||
void *opaque, Error **errp)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj);
|
||||
|
||||
visit_type_OnOffAuto(v, name, &lams->acpi, errp);
|
||||
}
|
||||
|
||||
static void loongarch_machine_initfn(Object *obj)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(obj);
|
||||
|
||||
if (tcg_enabled()) {
|
||||
lams->veiointc = ON_OFF_AUTO_OFF;
|
||||
@@ -1172,7 +1172,7 @@ static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev,
|
||||
static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
|
||||
/* the acpi ged is always exist */
|
||||
hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev,
|
||||
@@ -1190,7 +1190,7 @@ static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev,
|
||||
static void virt_mem_unplug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
|
||||
hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp);
|
||||
pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams));
|
||||
@@ -1208,7 +1208,7 @@ static void virt_machine_device_unplug(HotplugHandler *hotplug_dev,
|
||||
static void virt_mem_plug(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
|
||||
pc_dimm_plug(PC_DIMM(dev), MACHINE(lams));
|
||||
hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged),
|
||||
@@ -1218,7 +1218,7 @@ static void virt_mem_plug(HotplugHandler *hotplug_dev,
|
||||
static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
- LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
|
||||
+ LoongArchMachineState *lams = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lams);
|
||||
|
||||
if (device_is_dynamic_sysbus(mc, dev)) {
|
||||
@@ -1300,7 +1300,6 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
|
||||
|
||||
- mc->desc = "Loongson-3A5000 LS7A1000 machine";
|
||||
mc->init = loongarch_init;
|
||||
mc->default_ram_size = 1 * GiB;
|
||||
mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||
@@ -1341,7 +1340,7 @@ static void loongarch_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
static const TypeInfo loongarch_machine_types[] = {
|
||||
{
|
||||
- .name = TYPE_LOONGARCH_MACHINE,
|
||||
+ .name = TYPE_LOONGARCH_VIRT_MACHINE,
|
||||
.parent = TYPE_MACHINE,
|
||||
.instance_size = sizeof(LoongArchMachineState),
|
||||
.class_init = loongarch_class_init,
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 36158c758f..0509b9a9af 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -66,8 +66,8 @@ struct LoongArchMachineState {
|
||||
struct loongarch_boot_info bootinfo;
|
||||
};
|
||||
|
||||
-#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
-OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE)
|
||||
+#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
+OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_VIRT_MACHINE)
|
||||
bool loongarch_is_acpi_enabled(LoongArchMachineState *lams);
|
||||
void loongarch_acpi_setup(LoongArchMachineState *lams);
|
||||
#endif
|
||||
--
|
||||
2.39.1
|
||||
|
||||
1324
hw-loongarch-Rename-LoongArchMachineState-with-Loong.patch
Normal file
1324
hw-loongarch-Rename-LoongArchMachineState-with-Loong.patch
Normal file
File diff suppressed because it is too large
Load Diff
47
hw-loongarch-boot-Use-warn_report-when-no-kernel-fil.patch
Normal file
47
hw-loongarch-boot-Use-warn_report-when-no-kernel-fil.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From b7217c8f9b3f1d611485bad1263e109484a743e3 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Wed, 30 Oct 2024 09:23:59 +0800
|
||||
Subject: [PATCH 77/78] hw/loongarch/boot: Use warn_report when no kernel
|
||||
filename
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When we run “qemu-system-loongarch64 -qmp stdio -vnc none -S”,
|
||||
we get an error message “Need kernel filename” and then we can't use qmp cmd to query some information.
|
||||
So, we just throw a warning and then the cpus starts running from address VIRT_FLASH0_BASE.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Message-ID: <20241030012359.4040817-1-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index cb668703bd..f258eefe9a 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -278,7 +278,7 @@ static void init_boot_rom(struct loongarch_boot_info *info, void *p)
|
||||
static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
{
|
||||
void *p, *bp;
|
||||
- int64_t kernel_addr = 0;
|
||||
+ int64_t kernel_addr = VIRT_FLASH0_BASE;
|
||||
LoongArchCPU *lacpu;
|
||||
CPUState *cs;
|
||||
|
||||
@@ -286,8 +286,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info)
|
||||
kernel_addr = load_kernel_info(info);
|
||||
} else {
|
||||
if(!qtest_enabled()) {
|
||||
- error_report("Need kernel filename\n");
|
||||
- exit(1);
|
||||
+ warn_report("No kernel provided, booting from flash drive.");
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
35
hw-loongarch-boot.c-fix-out-of-bound-reading.patch
Normal file
35
hw-loongarch-boot.c-fix-out-of-bound-reading.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From f9cc704bbcf8bb8a06095289921dc88944d0fe94 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Frolov <frolov@swemel.ru>
|
||||
Date: Fri, 28 Jun 2024 15:39:10 +0300
|
||||
Subject: [PATCH 30/78] hw/loongarch/boot.c: fix out-of-bound reading
|
||||
|
||||
memcpy() is trying to READ 512 bytes from memory,
|
||||
pointed by info->kernel_cmdline,
|
||||
which was (presumable) allocated by g_strdup("");
|
||||
Found with ASAN, making check with enabled sanitizers.
|
||||
|
||||
Signed-off-by: Dmitry Frolov <frolov@swemel.ru>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240628123910.577740-1-frolov@swemel.ru>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index b8e1aa18d5..cb668703bd 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -163,7 +163,7 @@ static void init_cmdline(struct loongarch_boot_info *info, void *p, void *start)
|
||||
info->a0 = 1;
|
||||
info->a1 = cmdline_addr;
|
||||
|
||||
- memcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE);
|
||||
+ g_strlcpy(p, info->kernel_cmdline, COMMAND_LINE_SIZE);
|
||||
}
|
||||
|
||||
static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
197
hw-loongarch-clean-code.patch
Normal file
197
hw-loongarch-clean-code.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From 4a74147e1b2e276eb2ad2855bafc3c0136bc18a3 Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Sun, 8 Sep 2024 22:34:57 +0800
|
||||
Subject: [PATCH 76/78] hw/loongarch: clean code
|
||||
|
||||
remove some unused code
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/kvm/kvm.c | 103 ---------------------------
|
||||
target/loongarch/kvm/kvm_loongarch.h | 2 -
|
||||
target/loongarch/machine.c | 20 ------
|
||||
3 files changed, 125 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index ab1ea3d4fd..0acdd5c4c1 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -684,53 +684,6 @@ static int kvm_check_cpucfg2(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int kvm_check_cpucfg6(CPUState *cs)
|
||||
-{
|
||||
- int ret;
|
||||
- uint64_t val;
|
||||
- struct kvm_device_attr attr = {
|
||||
- .group = KVM_LOONGARCH_VCPU_CPUCFG,
|
||||
- .attr = 6,
|
||||
- .addr = (uint64_t)&val,
|
||||
- };
|
||||
- LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
- CPULoongArchState *env = &cpu->env;
|
||||
-
|
||||
- ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
- if (!ret) {
|
||||
- kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
|
||||
-
|
||||
- if (FIELD_EX32(env->cpucfg[6], CPUCFG6, PMP)) {
|
||||
- /* Check PMP */
|
||||
- if (!FIELD_EX32(val, CPUCFG6, PMP)) {
|
||||
- error_report("'pmu' feature not supported by KVM on this host"
|
||||
- " Please disable 'pmu' with "
|
||||
- "'... -cpu XXX,pmu=off ...'\n");
|
||||
- exit(EXIT_FAILURE);
|
||||
- }
|
||||
- /* Check PMNUM */
|
||||
- int guest_pmnum = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMNUM);
|
||||
- int host_pmnum = FIELD_EX32(val, CPUCFG6, PMNUM);
|
||||
- if (guest_pmnum > host_pmnum){
|
||||
- warn_report("The guest pmnum %d larger than KVM support %d\n",
|
||||
- guest_pmnum, host_pmnum);
|
||||
- env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6,
|
||||
- PMNUM, host_pmnum);
|
||||
- }
|
||||
- /* Check PMBITS */
|
||||
- int guest_pmbits = FIELD_EX32(env->cpucfg[6], CPUCFG6, PMBITS);
|
||||
- int host_pmbits = FIELD_EX32(val, CPUCFG6, PMBITS);
|
||||
- if (guest_pmbits != host_pmbits) {
|
||||
- warn_report("The host not support PMBITS %d\n", guest_pmbits);
|
||||
- env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6,
|
||||
- PMBITS, host_pmbits);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
||||
{
|
||||
int i, ret = 0;
|
||||
@@ -745,12 +698,6 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
- if (i == 6) {
|
||||
- ret = kvm_check_cpucfg6(cs);
|
||||
- if (ret) {
|
||||
- return ret;
|
||||
- }
|
||||
- }
|
||||
val = env->cpucfg[i];
|
||||
ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
|
||||
if (ret < 0) {
|
||||
@@ -760,56 +707,6 @@ static int kvm_loongarch_put_cpucfg(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int kvm_loongarch_put_pvtime(LoongArchCPU *cpu)
|
||||
-{
|
||||
- CPULoongArchState *env = &cpu->env;
|
||||
- int err;
|
||||
- struct kvm_device_attr attr = {
|
||||
- .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
|
||||
- .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
|
||||
- .addr = (uint64_t)&env->st.guest_addr,
|
||||
- };
|
||||
-
|
||||
- err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr);
|
||||
- if (err != 0) {
|
||||
- /* It's ok even though kvm has not such attr */
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- err = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_DEVICE_ATTR, attr);
|
||||
- if (err != 0) {
|
||||
- error_report("PVTIME IPA: KVM_SET_DEVICE_ATTR: %s", strerror(-err));
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int kvm_loongarch_get_pvtime(LoongArchCPU *cpu)
|
||||
-{
|
||||
- CPULoongArchState *env = &cpu->env;
|
||||
- int err;
|
||||
- struct kvm_device_attr attr = {
|
||||
- .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
|
||||
- .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
|
||||
- .addr = (uint64_t)&env->st.guest_addr,
|
||||
- };
|
||||
-
|
||||
- err = kvm_vcpu_ioctl(CPU(cpu), KVM_HAS_DEVICE_ATTR, attr);
|
||||
- if (err != 0) {
|
||||
- /* It's ok even though kvm has not such attr */
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- err = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_DEVICE_ATTR, attr);
|
||||
- if (err != 0) {
|
||||
- error_report("PVTIME IPA: KVM_GET_DEVICE_ATTR: %s", strerror(-err));
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
int kvm_arch_get_registers(CPUState *cs)
|
||||
{
|
||||
int ret;
|
||||
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
|
||||
index 8482f9308d..1051a341ec 100644
|
||||
--- a/target/loongarch/kvm/kvm_loongarch.h
|
||||
+++ b/target/loongarch/kvm/kvm_loongarch.h
|
||||
@@ -11,8 +11,6 @@
|
||||
#define QEMU_KVM_LOONGARCH_H
|
||||
|
||||
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
|
||||
-int kvm_loongarch_put_pvtime(LoongArchCPU *cpu);
|
||||
-int kvm_loongarch_get_pvtime(LoongArchCPU *cpu);
|
||||
void kvm_arch_reset_vcpu(CPUState *cs);
|
||||
|
||||
#endif
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index fd69ea05dc..57abdddc09 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -112,24 +112,6 @@ static const VMStateDescription vmstate_lasx = {
|
||||
},
|
||||
};
|
||||
|
||||
-static int cpu_post_load(void *opaque, int version_id)
|
||||
-{
|
||||
-#ifdef CONFIG_KVM
|
||||
- LoongArchCPU *cpu = opaque;
|
||||
- kvm_loongarch_put_pvtime(cpu);
|
||||
-#endif
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int cpu_pre_save(void *opaque)
|
||||
-{
|
||||
-#ifdef CONFIG_KVM
|
||||
- LoongArchCPU *cpu = opaque;
|
||||
- kvm_loongarch_get_pvtime(cpu);
|
||||
-#endif
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static bool lbt_needed(void *opaque)
|
||||
{
|
||||
LoongArchCPU *cpu = opaque;
|
||||
@@ -190,8 +172,6 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
- .post_load = cpu_post_load,
|
||||
- .pre_save = cpu_pre_save,
|
||||
.fields = (const VMStateField[]) {
|
||||
VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
|
||||
VMSTATE_UINTTL(env.pc, LoongArchCPU),
|
||||
--
|
||||
2.39.1
|
||||
|
||||
91
hw-loongarch-fdt-adds-Extend-I-O-Interrupt-Controlle.patch
Normal file
91
hw-loongarch-fdt-adds-Extend-I-O-Interrupt-Controlle.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From ed42940a2d943fd0e666e46bbc9b599b9ed1bd75 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:45 +0800
|
||||
Subject: [PATCH 10/78] hw/loongarch: fdt adds Extend I/O Interrupt Controller
|
||||
|
||||
fdt adds Extend I/O Interrupt Controller,
|
||||
we use 'loongson,ls2k2000-eiointc'.
|
||||
|
||||
See:
|
||||
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongson-eiointc.c
|
||||
https://lore.kernel.org/r/764e02d924094580ac0f1d15535f4b98308705c6.1683279769.git.zhoubinbin@loongson.cn
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-12-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 30 +++++++++++++++++++++++++++++-
|
||||
include/hw/intc/loongarch_extioi.h | 1 +
|
||||
2 files changed, 30 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index fdc4a5d708..820eb52cba 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -150,6 +150,31 @@ static void fdt_add_cpuic_node(LoongArchMachineState *lams,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
+static void fdt_add_eiointc_node(LoongArchMachineState *lams,
|
||||
+ uint32_t *cpuintc_phandle,
|
||||
+ uint32_t *eiointc_phandle)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(lams);
|
||||
+ char *nodename;
|
||||
+ hwaddr extioi_base = APIC_BASE;
|
||||
+ hwaddr extioi_size = EXTIOI_SIZE;
|
||||
+
|
||||
+ *eiointc_phandle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
+ nodename = g_strdup_printf("/eiointc@%" PRIx64, extioi_base);
|
||||
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *eiointc_phandle);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
+ "loongson,ls2k2000-eiointc");
|
||||
+ qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
|
||||
+ *cpuintc_phandle);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupts", 3);
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0,
|
||||
+ extioi_base, 0x0, extioi_size);
|
||||
+ g_free(nodename);
|
||||
+}
|
||||
+
|
||||
static void fdt_add_flash_node(LoongArchMachineState *lams)
|
||||
{
|
||||
MachineState *ms = MACHINE(lams);
|
||||
@@ -574,7 +599,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
CPULoongArchState *env;
|
||||
CPUState *cpu_state;
|
||||
int cpu, pin, i, start, num;
|
||||
- uint32_t cpuintc_phandle;
|
||||
+ uint32_t cpuintc_phandle, eiointc_phandle;
|
||||
|
||||
/*
|
||||
* The connection of interrupts:
|
||||
@@ -652,6 +677,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Add Extend I/O Interrupt Controller node */
|
||||
+ fdt_add_eiointc_node(lams, &cpuintc_phandle, &eiointc_phandle);
|
||||
+
|
||||
pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
|
||||
num = VIRT_PCH_PIC_IRQ_NUM;
|
||||
qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
|
||||
diff --git a/include/hw/intc/loongarch_extioi.h b/include/hw/intc/loongarch_extioi.h
|
||||
index 98f348c49d..722ffee1bc 100644
|
||||
--- a/include/hw/intc/loongarch_extioi.h
|
||||
+++ b/include/hw/intc/loongarch_extioi.h
|
||||
@@ -39,6 +39,7 @@
|
||||
#define EXTIOI_COREISR_END (0xB20 - APIC_OFFSET)
|
||||
#define EXTIOI_COREMAP_START (0xC00 - APIC_OFFSET)
|
||||
#define EXTIOI_COREMAP_END (0xD00 - APIC_OFFSET)
|
||||
+#define EXTIOI_SIZE 0x800
|
||||
|
||||
#define EXTIOI_VIRT_BASE (0x40000000)
|
||||
#define EXTIOI_VIRT_SIZE (0x1000)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
69
hw-loongarch-fdt-adds-cpu-interrupt-controller-node.patch
Normal file
69
hw-loongarch-fdt-adds-cpu-interrupt-controller-node.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From cd506fbf0d9a00aa0f25de1e7bd26ad4335c8257 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:44 +0800
|
||||
Subject: [PATCH 09/78] hw/loongarch: fdt adds cpu interrupt controller node
|
||||
|
||||
fdt adds cpu interrupt controller node,
|
||||
we use 'loongson,cpu-interrupt-controller'.
|
||||
|
||||
See:
|
||||
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongarch-cpu.c
|
||||
https://lore.kernel.org/r/20221114113824.1880-2-liupeibao@loongson.cn
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-11-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 99a3dc8696..fdc4a5d708 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -133,6 +133,23 @@ static void virt_flash_map(LoongArchMachineState *lams,
|
||||
virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem);
|
||||
}
|
||||
|
||||
+static void fdt_add_cpuic_node(LoongArchMachineState *lams,
|
||||
+ uint32_t *cpuintc_phandle)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(lams);
|
||||
+ char *nodename;
|
||||
+
|
||||
+ *cpuintc_phandle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
+ nodename = g_strdup_printf("/cpuic");
|
||||
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *cpuintc_phandle);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
+ "loongson,cpu-interrupt-controller");
|
||||
+ qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1);
|
||||
+ g_free(nodename);
|
||||
+}
|
||||
+
|
||||
static void fdt_add_flash_node(LoongArchMachineState *lams)
|
||||
{
|
||||
MachineState *ms = MACHINE(lams);
|
||||
@@ -557,6 +574,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
CPULoongArchState *env;
|
||||
CPUState *cpu_state;
|
||||
int cpu, pin, i, start, num;
|
||||
+ uint32_t cpuintc_phandle;
|
||||
|
||||
/*
|
||||
* The connection of interrupts:
|
||||
@@ -591,6 +609,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
memory_region_add_subregion(&lams->system_iocsr, MAIL_SEND_ADDR,
|
||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
|
||||
|
||||
+ /* Add cpu interrupt-controller */
|
||||
+ fdt_add_cpuic_node(lams, &cpuintc_phandle);
|
||||
+
|
||||
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
||||
cpu_state = qemu_get_cpu(cpu);
|
||||
cpudev = DEVICE(cpu_state);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
93
hw-loongarch-fdt-adds-pch_msi-Controller.patch
Normal file
93
hw-loongarch-fdt-adds-pch_msi-Controller.patch
Normal file
@ -0,0 +1,93 @@
|
||||
From ea34d3896abfaf67cdf7fdb3cb205cc5a0e2e708 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:47 +0800
|
||||
Subject: [PATCH 12/78] hw/loongarch: fdt adds pch_msi Controller
|
||||
|
||||
fdt adds pch msi controller, we use 'loongson,pch-msi-1.0'.
|
||||
|
||||
See:
|
||||
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongson-pch-msi.c
|
||||
https://lore.kernel.org/r/20200528152757.1028711-6-jiaxun.yang@flygoat.com
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-14-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 33 ++++++++++++++++++++++++++++++++-
|
||||
include/hw/pci-host/ls7a.h | 1 +
|
||||
2 files changed, 33 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 36fcfd12eb..032106ebad 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -200,6 +200,34 @@ static void fdt_add_pch_pic_node(LoongArchMachineState *lams,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
+static void fdt_add_pch_msi_node(LoongArchMachineState *lams,
|
||||
+ uint32_t *eiointc_phandle,
|
||||
+ uint32_t *pch_msi_phandle)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(lams);
|
||||
+ char *nodename;
|
||||
+ hwaddr pch_msi_base = VIRT_PCH_MSI_ADDR_LOW;
|
||||
+ hwaddr pch_msi_size = VIRT_PCH_MSI_SIZE;
|
||||
+
|
||||
+ *pch_msi_phandle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
+ nodename = g_strdup_printf("/msi@%" PRIx64, pch_msi_base);
|
||||
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *pch_msi_phandle);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
+ "loongson,pch-msi-1.0");
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "reg",
|
||||
+ 0, pch_msi_base,
|
||||
+ 0, pch_msi_size);
|
||||
+ qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
|
||||
+ *eiointc_phandle);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "loongson,msi-base-vec",
|
||||
+ VIRT_PCH_PIC_IRQ_NUM);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "loongson,msi-num-vecs",
|
||||
+ EXTIOI_IRQS - VIRT_PCH_PIC_IRQ_NUM);
|
||||
+ g_free(nodename);
|
||||
+}
|
||||
+
|
||||
static void fdt_add_flash_node(LoongArchMachineState *lams)
|
||||
{
|
||||
MachineState *ms = MACHINE(lams);
|
||||
@@ -624,7 +652,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
CPULoongArchState *env;
|
||||
CPUState *cpu_state;
|
||||
int cpu, pin, i, start, num;
|
||||
- uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle;
|
||||
+ uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle, pch_msi_phandle;
|
||||
|
||||
/*
|
||||
* The connection of interrupts:
|
||||
@@ -741,6 +769,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
qdev_get_gpio_in(extioi, i + start));
|
||||
}
|
||||
|
||||
+ /* Add PCH MSI node */
|
||||
+ fdt_add_pch_msi_node(lams, &eiointc_phandle, &pch_msi_phandle);
|
||||
+
|
||||
loongarch_devices_init(pch_pic, lams);
|
||||
}
|
||||
|
||||
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
|
||||
index fe260f0183..cd7c9ec7bc 100644
|
||||
--- a/include/hw/pci-host/ls7a.h
|
||||
+++ b/include/hw/pci-host/ls7a.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
|
||||
#define VIRT_PCH_MSI_ADDR_LOW 0x2FF00000UL
|
||||
#define VIRT_PCH_REG_SIZE 0x400
|
||||
+#define VIRT_PCH_MSI_SIZE 0x8
|
||||
|
||||
/*
|
||||
* GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot
|
||||
--
|
||||
2.39.1
|
||||
|
||||
90
hw-loongarch-fdt-adds-pch_pic-Controller.patch
Normal file
90
hw-loongarch-fdt-adds-pch_pic-Controller.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From 78222abb3bde044b4520f23c6fc2f0f0bd805d2a Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:46 +0800
|
||||
Subject: [PATCH 11/78] hw/loongarch: fdt adds pch_pic Controller
|
||||
|
||||
fdt adds pch pic controller, we use 'loongson,pch-pic-1.0'
|
||||
|
||||
See:
|
||||
https://github.com/torvalds/linux/blob/v6.7/drivers/irqchip/irq-loongson-pch-pic.c
|
||||
https://lore.kernel.org/r/20200528152757.1028711-4-jiaxun.yang@flygoat.com
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-13-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 30 +++++++++++++++++++++++++++++-
|
||||
include/hw/pci-host/ls7a.h | 1 +
|
||||
2 files changed, 30 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 820eb52cba..36fcfd12eb 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -175,6 +175,31 @@ static void fdt_add_eiointc_node(LoongArchMachineState *lams,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
+static void fdt_add_pch_pic_node(LoongArchMachineState *lams,
|
||||
+ uint32_t *eiointc_phandle,
|
||||
+ uint32_t *pch_pic_phandle)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(lams);
|
||||
+ char *nodename;
|
||||
+ hwaddr pch_pic_base = VIRT_PCH_REG_BASE;
|
||||
+ hwaddr pch_pic_size = VIRT_PCH_REG_SIZE;
|
||||
+
|
||||
+ *pch_pic_phandle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
+ nodename = g_strdup_printf("/platic@%" PRIx64, pch_pic_base);
|
||||
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", *pch_pic_phandle);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
+ "loongson,pch-pic-1.0");
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0,
|
||||
+ pch_pic_base, 0, pch_pic_size);
|
||||
+ qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 2);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
|
||||
+ *eiointc_phandle);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "loongson,pic-base-vec", 0);
|
||||
+ g_free(nodename);
|
||||
+}
|
||||
+
|
||||
static void fdt_add_flash_node(LoongArchMachineState *lams)
|
||||
{
|
||||
MachineState *ms = MACHINE(lams);
|
||||
@@ -599,7 +624,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
CPULoongArchState *env;
|
||||
CPUState *cpu_state;
|
||||
int cpu, pin, i, start, num;
|
||||
- uint32_t cpuintc_phandle, eiointc_phandle;
|
||||
+ uint32_t cpuintc_phandle, eiointc_phandle, pch_pic_phandle;
|
||||
|
||||
/*
|
||||
* The connection of interrupts:
|
||||
@@ -699,6 +724,9 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
|
||||
}
|
||||
|
||||
+ /* Add PCH PIC node */
|
||||
+ fdt_add_pch_pic_node(lams, &eiointc_phandle, &pch_pic_phandle);
|
||||
+
|
||||
pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
|
||||
start = num;
|
||||
num = EXTIOI_IRQS - start;
|
||||
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
|
||||
index e753449593..fe260f0183 100644
|
||||
--- a/include/hw/pci-host/ls7a.h
|
||||
+++ b/include/hw/pci-host/ls7a.h
|
||||
@@ -24,6 +24,7 @@
|
||||
#define VIRT_PCH_REG_BASE 0x10000000UL
|
||||
#define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
|
||||
#define VIRT_PCH_MSI_ADDR_LOW 0x2FF00000UL
|
||||
+#define VIRT_PCH_REG_SIZE 0x400
|
||||
|
||||
/*
|
||||
* GSI_BASE is hard-coded with 64 in linux kernel, else kernel fails to boot
|
||||
--
|
||||
2.39.1
|
||||
|
||||
137
hw-loongarch-fdt-adds-pcie-irq_map-node.patch
Normal file
137
hw-loongarch-fdt-adds-pcie-irq_map-node.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From 1325effbd595781b9ab75dceab9f87944156c606 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:48 +0800
|
||||
Subject: [PATCH 13/78] hw/loongarch: fdt adds pcie irq_map node
|
||||
|
||||
This patch adds pcie irq_map node for FDT.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-15-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 73 ++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 69 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 032106ebad..c32cc3c818 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -379,7 +379,62 @@ static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams)
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
-static void fdt_add_pcie_node(const LoongArchMachineState *lams)
|
||||
+static void fdt_add_pcie_irq_map_node(const LoongArchMachineState *lams,
|
||||
+ char *nodename,
|
||||
+ uint32_t *pch_pic_phandle)
|
||||
+{
|
||||
+ int pin, dev;
|
||||
+ uint32_t irq_map_stride = 0;
|
||||
+ uint32_t full_irq_map[GPEX_NUM_IRQS *GPEX_NUM_IRQS * 10] = {};
|
||||
+ uint32_t *irq_map = full_irq_map;
|
||||
+ const MachineState *ms = MACHINE(lams);
|
||||
+
|
||||
+ /* This code creates a standard swizzle of interrupts such that
|
||||
+ * each device's first interrupt is based on it's PCI_SLOT number.
|
||||
+ * (See pci_swizzle_map_irq_fn())
|
||||
+ *
|
||||
+ * We only need one entry per interrupt in the table (not one per
|
||||
+ * possible slot) seeing the interrupt-map-mask will allow the table
|
||||
+ * to wrap to any number of devices.
|
||||
+ */
|
||||
+
|
||||
+ for (dev = 0; dev < GPEX_NUM_IRQS; dev++) {
|
||||
+ int devfn = dev * 0x8;
|
||||
+
|
||||
+ for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
|
||||
+ int irq_nr = 16 + ((pin + PCI_SLOT(devfn)) % GPEX_NUM_IRQS);
|
||||
+ int i = 0;
|
||||
+
|
||||
+ /* Fill PCI address cells */
|
||||
+ irq_map[i] = cpu_to_be32(devfn << 8);
|
||||
+ i += 3;
|
||||
+
|
||||
+ /* Fill PCI Interrupt cells */
|
||||
+ irq_map[i] = cpu_to_be32(pin + 1);
|
||||
+ i += 1;
|
||||
+
|
||||
+ /* Fill interrupt controller phandle and cells */
|
||||
+ irq_map[i++] = cpu_to_be32(*pch_pic_phandle);
|
||||
+ irq_map[i++] = cpu_to_be32(irq_nr);
|
||||
+
|
||||
+ if (!irq_map_stride) {
|
||||
+ irq_map_stride = i;
|
||||
+ }
|
||||
+ irq_map += irq_map_stride;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map,
|
||||
+ GPEX_NUM_IRQS * GPEX_NUM_IRQS *
|
||||
+ irq_map_stride * sizeof(uint32_t));
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupt-map-mask",
|
||||
+ 0x1800, 0, 0, 0x7);
|
||||
+}
|
||||
+
|
||||
+static void fdt_add_pcie_node(const LoongArchMachineState *lams,
|
||||
+ uint32_t *pch_pic_phandle,
|
||||
+ uint32_t *pch_msi_phandle)
|
||||
{
|
||||
char *nodename;
|
||||
hwaddr base_mmio = VIRT_PCI_MEM_BASE;
|
||||
@@ -410,6 +465,11 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams)
|
||||
2, base_pio, 2, size_pio,
|
||||
1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
|
||||
2, base_mmio, 2, size_mmio);
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map",
|
||||
+ 0, *pch_msi_phandle, 0, 0x10000);
|
||||
+
|
||||
+ fdt_add_pcie_irq_map_node(lams, nodename, pch_pic_phandle);
|
||||
+
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
@@ -569,7 +629,10 @@ static DeviceState *create_platform_bus(DeviceState *pch_pic)
|
||||
return dev;
|
||||
}
|
||||
|
||||
-static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams)
|
||||
+static void loongarch_devices_init(DeviceState *pch_pic,
|
||||
+ LoongArchMachineState *lams,
|
||||
+ uint32_t *pch_pic_phandle,
|
||||
+ uint32_t *pch_msi_phandle)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(lams);
|
||||
DeviceState *gpex_dev;
|
||||
@@ -615,6 +678,9 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
|
||||
gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
|
||||
}
|
||||
|
||||
+ /* Add pcie node */
|
||||
+ fdt_add_pcie_node(lams, pch_pic_phandle, pch_msi_phandle);
|
||||
+
|
||||
serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
|
||||
qdev_get_gpio_in(pch_pic,
|
||||
VIRT_UART_IRQ - VIRT_GSI_BASE),
|
||||
@@ -772,7 +838,7 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
|
||||
/* Add PCH MSI node */
|
||||
fdt_add_pch_msi_node(lams, &eiointc_phandle, &pch_msi_phandle);
|
||||
|
||||
- loongarch_devices_init(pch_pic, lams);
|
||||
+ loongarch_devices_init(pch_pic, lams, &pch_pic_phandle, &pch_msi_phandle);
|
||||
}
|
||||
|
||||
static void loongarch_firmware_init(LoongArchMachineState *lams)
|
||||
@@ -1048,7 +1114,6 @@ static void loongarch_init(MachineState *machine)
|
||||
lams->powerdown_notifier.notify = virt_powerdown_req;
|
||||
qemu_register_powerdown_notifier(&lams->powerdown_notifier);
|
||||
|
||||
- fdt_add_pcie_node(lams);
|
||||
/*
|
||||
* Since lowmem region starts from 0 and Linux kernel legacy start address
|
||||
* at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
|
||||
--
|
||||
2.39.1
|
||||
|
||||
67
hw-loongarch-fdt-remove-unused-irqchip-node.patch
Normal file
67
hw-loongarch-fdt-remove-unused-irqchip-node.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From e87697c72641ab2209d4004f573f47283d118235 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 26 Apr 2024 17:15:49 +0800
|
||||
Subject: [PATCH 14/78] hw/loongarch: fdt remove unused irqchip node
|
||||
|
||||
This patch removes the unused fdt irqchip node.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240426091551.2397867-16-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 31 +------------------------------
|
||||
1 file changed, 1 insertion(+), 30 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index c32cc3c818..ff9513034b 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -473,34 +473,6 @@ static void fdt_add_pcie_node(const LoongArchMachineState *lams,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
-static void fdt_add_irqchip_node(LoongArchMachineState *lams)
|
||||
-{
|
||||
- MachineState *ms = MACHINE(lams);
|
||||
- char *nodename;
|
||||
- uint32_t irqchip_phandle;
|
||||
-
|
||||
- irqchip_phandle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
- qemu_fdt_setprop_cell(ms->fdt, "/", "interrupt-parent", irqchip_phandle);
|
||||
-
|
||||
- nodename = g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE);
|
||||
- qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||
- qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 3);
|
||||
- qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
|
||||
- qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x2);
|
||||
- qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 0x2);
|
||||
- qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0);
|
||||
-
|
||||
- qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
|
||||
- "loongarch,ls7a");
|
||||
-
|
||||
- qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
|
||||
- 2, VIRT_IOAPIC_REG_BASE,
|
||||
- 2, PCH_PIC_ROUTE_ENTRY_OFFSET);
|
||||
-
|
||||
- qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", irqchip_phandle);
|
||||
- g_free(nodename);
|
||||
-}
|
||||
-
|
||||
static void fdt_add_memory_node(MachineState *ms,
|
||||
uint64_t base, uint64_t size, int node_id)
|
||||
{
|
||||
@@ -1103,8 +1075,7 @@ static void loongarch_init(MachineState *machine)
|
||||
|
||||
/* Initialize the IO interrupt subsystem */
|
||||
loongarch_irq_init(lams);
|
||||
- fdt_add_irqchip_node(lams);
|
||||
- platform_bus_add_all_fdt_nodes(machine->fdt, "/intc",
|
||||
+ platform_bus_add_all_fdt_nodes(machine->fdt, "/platic",
|
||||
VIRT_PLATFORM_BUS_BASEADDRESS,
|
||||
VIRT_PLATFORM_BUS_SIZE,
|
||||
VIRT_PLATFORM_BUS_IRQ);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
51
hw-loongarch-fix-cpu-hotplug-reset.patch
Normal file
51
hw-loongarch-fix-cpu-hotplug-reset.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From f3f7b49a8a323ebfe2be176985336aaf2c97c6c2 Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Mon, 9 Sep 2024 04:14:49 +0800
|
||||
Subject: [PATCH 78/78] hw/loongarch: fix cpu hotplug reset
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/boot.c | 2 +-
|
||||
hw/loongarch/virt.c | 1 +
|
||||
include/hw/loongarch/virt.h | 1 +
|
||||
3 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index f258eefe9a..53dcefbb55 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -216,7 +216,7 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info)
|
||||
return kernel_entry;
|
||||
}
|
||||
|
||||
-static void reset_load_elf(void *opaque)
|
||||
+void reset_load_elf(void *opaque)
|
||||
{
|
||||
LoongArchCPU *cpu = opaque;
|
||||
CPULoongArchState *env = &cpu->env;
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 5b0468f6cb..0c24e632bb 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1494,6 +1494,7 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
env = &(cpu->env);
|
||||
env->address_space_iocsr = &lvms->as_iocsr;
|
||||
|
||||
+ qemu_register_reset(reset_load_elf, LOONGARCH_CPU(qemu_get_cpu(cs->cpu_index)));
|
||||
env->ipistate = lvms->ipi;
|
||||
if (!(kvm_enabled() && kvm_irqchip_in_kernel())) {
|
||||
/* connect ipi irq to cpu irq, logic cpu index used here */
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 168b40c31b..a79ad41663 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -86,4 +86,5 @@ struct LoongArchVirtMachineState {
|
||||
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
|
||||
void loongarch_acpi_setup(LoongArchVirtMachineState *lvms);
|
||||
+void reset_load_elf(void *opaque);
|
||||
#endif
|
||||
--
|
||||
2.39.1
|
||||
|
||||
113
hw-loongarch-move-memory-map-to-boot.c.patch
Normal file
113
hw-loongarch-move-memory-map-to-boot.c.patch
Normal file
@ -0,0 +1,113 @@
|
||||
From 5e4d612de23539499b9a22986bebe9a3007edae1 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Tue, 7 May 2024 16:51:35 +0200
|
||||
Subject: [PATCH 18/78] hw/loongarch: move memory map to boot.c
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Ensure that it can be used even if virt.c is not included in the build, as
|
||||
is the case for --without-default-devices.
|
||||
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Acked-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-ID: <20240507145135.270803-1-pbonzini@redhat.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
.gitlab-ci.d/buildtest.yml | 5 +++--
|
||||
hw/loongarch/boot.c | 3 +++
|
||||
hw/loongarch/virt.c | 3 ---
|
||||
include/hw/loongarch/boot.h | 10 ++++++++++
|
||||
include/hw/loongarch/virt.h | 10 ----------
|
||||
5 files changed, 16 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
|
||||
index 3fb99e79e9..983c3c132e 100644
|
||||
--- a/.gitlab-ci.d/buildtest.yml
|
||||
+++ b/.gitlab-ci.d/buildtest.yml
|
||||
@@ -579,8 +579,9 @@ build-tci:
|
||||
- make check-tcg
|
||||
|
||||
# Check our reduced build configurations
|
||||
-# requires libfdt: aarch64, arm, i386, loongarch64, x86_64
|
||||
-# does not build without boards: i386, loongarch64, x86_64
|
||||
+# requires libfdt: aarch64, arm, i386, loongarch64, microblaze, microblazeel,
|
||||
+# mips64el, or1k, ppc, ppc64, riscv32, riscv64, rx, x86_64
|
||||
+# does not build without boards: i386, s390x, sh4, sh4eb, x86_64
|
||||
build-without-defaults:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
|
||||
index 7d1630b2e7..03f6301a77 100644
|
||||
--- a/hw/loongarch/boot.c
|
||||
+++ b/hw/loongarch/boot.c
|
||||
@@ -15,6 +15,9 @@
|
||||
#include "sysemu/reset.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
+struct memmap_entry *memmap_table;
|
||||
+unsigned memmap_entries;
|
||||
+
|
||||
ram_addr_t initrd_offset;
|
||||
uint64_t initrd_size;
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 0972ebd150..76b36539e2 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -543,9 +543,6 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque)
|
||||
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)
|
||||
{
|
||||
/* Ensure there are no duplicate entries. */
|
||||
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
|
||||
index 4ebcc89dcf..b3b870df1f 100644
|
||||
--- a/include/hw/loongarch/boot.h
|
||||
+++ b/include/hw/loongarch/boot.h
|
||||
@@ -104,6 +104,16 @@ struct loongarch_boot_info {
|
||||
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);
|
||||
|
||||
#endif /* HW_LOONGARCH_BOOT_H */
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 673b57aa2b..36158c758f 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -37,16 +37,6 @@
|
||||
|
||||
#define FDT_BASE 0x100000
|
||||
|
||||
-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;
|
||||
-};
|
||||
-
|
||||
struct LoongArchMachineState {
|
||||
/*< private >*/
|
||||
MachineState parent_obj;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
278
hw-loongarch-virt-Add-CPU-topology-support.patch
Normal file
278
hw-loongarch-virt-Add-CPU-topology-support.patch
Normal file
@ -0,0 +1,278 @@
|
||||
From 8d440efd992fd6be0aca55118a9b60c224f6eade Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 23 Oct 2024 15:13:10 +0800
|
||||
Subject: [PATCH 69/78] hw/loongarch/virt: Add CPU topology support
|
||||
|
||||
Add topological relationships for Loongarch VCPU and initialize
|
||||
topology member variables. Also physical cpu id calculation
|
||||
method comes from its topo information.
|
||||
|
||||
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-ID: <20241023071312.881866-2-maobibo@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
docs/system/loongarch/virt.rst | 31 +++++++++++++
|
||||
hw/loongarch/virt.c | 82 ++++++++++++++++++++++++++++------
|
||||
target/loongarch/cpu.c | 12 +++++
|
||||
target/loongarch/cpu.h | 11 +++++
|
||||
4 files changed, 122 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/docs/system/loongarch/virt.rst b/docs/system/loongarch/virt.rst
|
||||
index c37268b404..aa4719d4bd 100644
|
||||
--- a/docs/system/loongarch/virt.rst
|
||||
+++ b/docs/system/loongarch/virt.rst
|
||||
@@ -28,6 +28,37 @@ The ``qemu-system-loongarch64`` provides emulation for virt
|
||||
machine. You can specify the machine type ``virt`` and
|
||||
cpu type ``la464``.
|
||||
|
||||
+CPU Topology
|
||||
+------------
|
||||
+
|
||||
+The ``LA464`` type CPUs have the concept of Socket Core and Thread.
|
||||
+
|
||||
+For example:
|
||||
+
|
||||
+``-smp 1,maxcpus=M,sockets=S,cores=C,threads=T``
|
||||
+
|
||||
+The above parameters indicate that the machine has a maximum of ``M`` vCPUs and
|
||||
+``S`` sockets, each socket has ``C`` cores, each core has ``T`` threads,
|
||||
+and each thread corresponds to a vCPU.
|
||||
+
|
||||
+Then ``M`` ``S`` ``C`` ``T`` has the following relationship:
|
||||
+
|
||||
+``M = S * C * T``
|
||||
+
|
||||
+In the CPU topology relationship, When we know the ``socket_id`` ``core_id``
|
||||
+and ``thread_id`` of the CPU, we can calculate its ``arch_id``:
|
||||
+
|
||||
+``arch_id = (socket_id * S) + (core_id * C) + (thread_id * T)``
|
||||
+
|
||||
+Similarly, when we know the ``arch_id`` of the CPU,
|
||||
+we can also get its ``socket_id`` ``core_id`` and ``thread_id``:
|
||||
+
|
||||
+``socket_id = arch_id / (C * T)``
|
||||
+
|
||||
+``core_id = (arch_id / T) % C``
|
||||
+
|
||||
+``thread_id = arch_id % T``
|
||||
+
|
||||
Boot options
|
||||
------------
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 9510aa7a7e..8d1e53ff62 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1123,9 +1123,7 @@ static void virt_init(MachineState *machine)
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
int i;
|
||||
hwaddr base, size, ram_size = machine->ram_size;
|
||||
- const CPUArchIdList *possible_cpus;
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
- CPUState *cpu;
|
||||
|
||||
if (!cpu_model) {
|
||||
cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||
@@ -1143,14 +1141,39 @@ static void virt_init(MachineState *machine)
|
||||
memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
|
||||
|
||||
/* Init CPUs */
|
||||
- possible_cpus = mc->possible_cpu_arch_ids(machine);
|
||||
- for (i = 0; i < possible_cpus->len; i++) {
|
||||
- cpu = cpu_create(machine->cpu_type);
|
||||
- cpu->cpu_index = i;
|
||||
- machine->possible_cpus->cpus[i].cpu = OBJECT(cpu);
|
||||
- lacpu = LOONGARCH_CPU(cpu);
|
||||
+ mc->possible_cpu_arch_ids(machine);
|
||||
+ for (i = 0; i < machine->smp.cpus; i++) {
|
||||
+ Object *cpuobj;
|
||||
+ cpuobj = object_new(machine->cpu_type);
|
||||
+ lacpu = LOONGARCH_CPU(cpuobj);
|
||||
+
|
||||
lacpu->phy_id = machine->possible_cpus->cpus[i].arch_id;
|
||||
+ object_property_set_int(cpuobj, "socket-id",
|
||||
+ machine->possible_cpus->cpus[i].props.socket_id,
|
||||
+ NULL);
|
||||
+ object_property_set_int(cpuobj, "core-id",
|
||||
+ machine->possible_cpus->cpus[i].props.core_id,
|
||||
+ NULL);
|
||||
+ object_property_set_int(cpuobj, "thread-id",
|
||||
+ machine->possible_cpus->cpus[i].props.thread_id,
|
||||
+ NULL);
|
||||
+ /*
|
||||
+ * The CPU in place at the time of machine startup will also enter
|
||||
+ * the CPU hot-plug process when it is created, but at this time,
|
||||
+ * the GED device has not been created, resulting in exit in the CPU
|
||||
+ * hot-plug process, which can avoid the incumbent CPU repeatedly
|
||||
+ * applying for resources.
|
||||
+ *
|
||||
+ * The interrupt resource of the in-place CPU will be requested at
|
||||
+ * the current function call loongarch_irq_init().
|
||||
+ *
|
||||
+ * The interrupt resource of the subsequently inserted CPU will be
|
||||
+ * requested in the CPU hot-plug process.
|
||||
+ */
|
||||
+ qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
|
||||
+ object_unref(cpuobj);
|
||||
}
|
||||
+
|
||||
fdt_add_cpu_nodes(lvms);
|
||||
fdt_add_memory_nodes(machine);
|
||||
fw_cfg_add_memory(machine);
|
||||
@@ -1266,6 +1289,27 @@ static void virt_initfn(Object *obj)
|
||||
virt_flash_create(lvms);
|
||||
}
|
||||
|
||||
+static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
|
||||
+{
|
||||
+ int arch_id, sock_vcpu_num, core_vcpu_num;
|
||||
+
|
||||
+ /*
|
||||
+ * calculate total logical cpus across socket/core/thread.
|
||||
+ * For more information on how to calculate the arch_id,
|
||||
+ * you can refer to the CPU Topology chapter of the
|
||||
+ * docs/system/loongarch/virt.rst document.
|
||||
+ */
|
||||
+ sock_vcpu_num = topo->socket_id * (ms->smp.threads * ms->smp.cores);
|
||||
+ core_vcpu_num = topo->core_id * ms->smp.threads;
|
||||
+
|
||||
+ /* get vcpu-id(logical cpu index) for this vcpu from this topology */
|
||||
+ arch_id = (sock_vcpu_num + core_vcpu_num) + topo->thread_id;
|
||||
+
|
||||
+ assert(arch_id >= 0 && arch_id < ms->possible_cpus->len);
|
||||
+
|
||||
+ return arch_id;
|
||||
+}
|
||||
+
|
||||
static bool memhp_type_supported(DeviceState *dev)
|
||||
{
|
||||
/* we only support pc dimm now */
|
||||
@@ -1363,10 +1407,19 @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static void virt_get_cpu_topo_from_index(MachineState *ms,
|
||||
+ LoongArchCPUTopo *topo, int index)
|
||||
+{
|
||||
+ topo->socket_id = index / (ms->smp.cores * ms->smp.threads);
|
||||
+ topo->core_id = index / ms->smp.threads % ms->smp.cores;
|
||||
+ topo->thread_id = index % ms->smp.threads;
|
||||
+}
|
||||
+
|
||||
static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
||||
{
|
||||
int n;
|
||||
unsigned int max_cpus = ms->smp.max_cpus;
|
||||
+ LoongArchCPUTopo topo;
|
||||
|
||||
if (ms->possible_cpus) {
|
||||
assert(ms->possible_cpus->len == max_cpus);
|
||||
@@ -1377,17 +1430,18 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
|
||||
sizeof(CPUArchId) * max_cpus);
|
||||
ms->possible_cpus->len = max_cpus;
|
||||
for (n = 0; n < ms->possible_cpus->len; n++) {
|
||||
+ ms->possible_cpus->cpus[n].vcpus_count = ms->smp.threads;
|
||||
ms->possible_cpus->cpus[n].type = ms->cpu_type;
|
||||
- ms->possible_cpus->cpus[n].arch_id = n;
|
||||
+ virt_get_cpu_topo_from_index(ms, &topo, n);
|
||||
|
||||
ms->possible_cpus->cpus[n].props.has_socket_id = true;
|
||||
- ms->possible_cpus->cpus[n].props.socket_id =
|
||||
- n / (ms->smp.cores * ms->smp.threads);
|
||||
+ ms->possible_cpus->cpus[n].props.socket_id = topo.socket_id;
|
||||
ms->possible_cpus->cpus[n].props.has_core_id = true;
|
||||
- ms->possible_cpus->cpus[n].props.core_id =
|
||||
- n / ms->smp.threads % ms->smp.cores;
|
||||
+ ms->possible_cpus->cpus[n].props.core_id = topo.core_id;
|
||||
ms->possible_cpus->cpus[n].props.has_thread_id = true;
|
||||
- ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads;
|
||||
+ ms->possible_cpus->cpus[n].props.thread_id = topo.thread_id;
|
||||
+ ms->possible_cpus->cpus[n].arch_id =
|
||||
+ virt_get_arch_id_from_topo(ms, &topo);
|
||||
}
|
||||
return ms->possible_cpus;
|
||||
}
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index 2ee1d63989..673ed8ea18 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "kvm/kvm_loongarch.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "cpu.h"
|
||||
+#include "hw/qdev-properties.h"
|
||||
#include "internals.h"
|
||||
#include "fpu/softfloat-helpers.h"
|
||||
#include "cpu-csr.h"
|
||||
@@ -860,6 +861,15 @@ static int64_t loongarch_cpu_get_arch_id(CPUState *cs)
|
||||
}
|
||||
#endif
|
||||
|
||||
+static Property loongarch_cpu_properties[] = {
|
||||
+ DEFINE_PROP_INT32("socket-id", LoongArchCPU, socket_id, 0),
|
||||
+ DEFINE_PROP_INT32("core-id", LoongArchCPU, core_id, 0),
|
||||
+ DEFINE_PROP_INT32("thread-id", LoongArchCPU, thread_id, 0),
|
||||
+ DEFINE_PROP_INT32("node-id", LoongArchCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
|
||||
+
|
||||
+ DEFINE_PROP_END_OF_LIST()
|
||||
+};
|
||||
+
|
||||
static void loongarch_cpu_class_init(ObjectClass *c, void *data)
|
||||
{
|
||||
LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c);
|
||||
@@ -867,6 +877,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(c);
|
||||
ResettableClass *rc = RESETTABLE_CLASS(c);
|
||||
|
||||
+ device_class_set_props(dc, loongarch_cpu_properties);
|
||||
device_class_set_parent_realize(dc, loongarch_cpu_realizefn,
|
||||
&lacc->parent_realize);
|
||||
resettable_class_set_parent_phases(rc, NULL, loongarch_cpu_reset_hold, NULL,
|
||||
@@ -890,6 +901,7 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
|
||||
#ifdef CONFIG_TCG
|
||||
cc->tcg_ops = &loongarch_tcg_ops;
|
||||
#endif
|
||||
+ dc->user_creatable = true;
|
||||
}
|
||||
|
||||
static const gchar *loongarch32_gdb_arch_name(CPUState *cs)
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 4c90cf9ef3..9af622aba5 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -398,6 +398,12 @@ typedef struct CPUArchState {
|
||||
} st;
|
||||
} CPULoongArchState;
|
||||
|
||||
+typedef struct LoongArchCPUTopo {
|
||||
+ int32_t socket_id; /* socket-id of this VCPU */
|
||||
+ int32_t core_id; /* core-id of this VCPU */
|
||||
+ int32_t thread_id; /* thread-id of this VCPU */
|
||||
+} LoongArchCPUTopo;
|
||||
+
|
||||
/**
|
||||
* LoongArchCPU:
|
||||
* @env: #CPULoongArchState
|
||||
@@ -412,6 +418,10 @@ struct ArchCPU {
|
||||
uint32_t phy_id;
|
||||
OnOffAuto lbt;
|
||||
OnOffAuto pmu;
|
||||
+ int32_t socket_id; /* socket-id of this VCPU */
|
||||
+ int32_t core_id; /* core-id of this VCPU */
|
||||
+ int32_t thread_id; /* thread-id of this VCPU */
|
||||
+ int32_t node_id; /* NUMA node this CPU belongs to */
|
||||
|
||||
/* 'compatible' string for this CPU for Linux device trees */
|
||||
const char *dtb_compatible;
|
||||
@@ -430,6 +440,7 @@ struct LoongArchCPUClass {
|
||||
CPUClass parent_class;
|
||||
|
||||
DeviceRealize parent_realize;
|
||||
+ DeviceUnrealize parent_unrealize;
|
||||
ResettablePhases parent_phases;
|
||||
};
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
84
hw-loongarch-virt-Add-FDT-table-support-with-acpi-ge.patch
Normal file
84
hw-loongarch-virt-Add-FDT-table-support-with-acpi-ge.patch
Normal file
@ -0,0 +1,84 @@
|
||||
From fa276847efb3fd47a730d279f1b14705fe3991b1 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 18 Sep 2024 09:42:06 +0800
|
||||
Subject: [PATCH 39/78] hw/loongarch/virt: Add FDT table support with acpi ged
|
||||
pm register
|
||||
|
||||
ACPI ged is used for power management on LoongArch virt platform, in
|
||||
general it is parsed from acpi table. However if system boot directly from
|
||||
elf kernel, no UEFI bios is provided and acpi table cannot be used also.
|
||||
|
||||
Here acpi ged pm register is exposed with FDT table, it is compatbile
|
||||
with syscon method in FDT table, only that acpi ged pm register is accessed
|
||||
with 8-bit mode, rather with 32-bit mode.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Tested-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240918014206.2165821-3-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 39 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 39 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 9f47107379..9510aa7a7e 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -281,6 +281,44 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms,
|
||||
g_free(nodename);
|
||||
}
|
||||
|
||||
+static void fdt_add_ged_reset(LoongArchVirtMachineState *lvms)
|
||||
+{
|
||||
+ char *name;
|
||||
+ uint32_t ged_handle;
|
||||
+ MachineState *ms = MACHINE(lvms);
|
||||
+ hwaddr base = VIRT_GED_REG_ADDR;
|
||||
+ hwaddr size = ACPI_GED_REG_COUNT;
|
||||
+
|
||||
+ ged_handle = qemu_fdt_alloc_phandle(ms->fdt);
|
||||
+ name = g_strdup_printf("/ged@%" PRIx64, base);
|
||||
+ qemu_fdt_add_subnode(ms->fdt, name);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon");
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0x0, base, 0x0, size);
|
||||
+ /* 8 bit registers */
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "reg-shift", 0);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "reg-io-width", 1);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "phandle", ged_handle);
|
||||
+ ged_handle = qemu_fdt_get_phandle(ms->fdt, name);
|
||||
+ g_free(name);
|
||||
+
|
||||
+ name = g_strdup_printf("/reboot");
|
||||
+ qemu_fdt_add_subnode(ms->fdt, name);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot");
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "regmap", ged_handle);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "offset", ACPI_GED_REG_RESET);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "value", ACPI_GED_RESET_VALUE);
|
||||
+ g_free(name);
|
||||
+
|
||||
+ name = g_strdup_printf("/poweroff");
|
||||
+ qemu_fdt_add_subnode(ms->fdt, name);
|
||||
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff");
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "regmap", ged_handle);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "offset", ACPI_GED_REG_SLEEP_CTL);
|
||||
+ qemu_fdt_setprop_cell(ms->fdt, name, "value", ACPI_GED_SLP_EN |
|
||||
+ (ACPI_GED_SLP_TYP_S5 << ACPI_GED_SLP_TYP_POS));
|
||||
+ g_free(name);
|
||||
+}
|
||||
+
|
||||
static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
|
||||
uint32_t *pch_pic_phandle, hwaddr base,
|
||||
int irq, bool chosen)
|
||||
@@ -739,6 +777,7 @@ static void virt_devices_init(DeviceState *pch_pic,
|
||||
qdev_get_gpio_in(pch_pic,
|
||||
VIRT_RTC_IRQ - VIRT_GSI_BASE));
|
||||
fdt_add_rtc_node(lvms, pch_pic_phandle);
|
||||
+ fdt_add_ged_reset(lvms);
|
||||
|
||||
/* acpi ged */
|
||||
lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
346
hw-loongarch-virt-Add-basic-CPU-plug-support.patch
Normal file
346
hw-loongarch-virt-Add-basic-CPU-plug-support.patch
Normal file
@ -0,0 +1,346 @@
|
||||
From 212ea93178ad1e65e625ec6942ee9aff93dd5321 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 23 Oct 2024 15:13:11 +0800
|
||||
Subject: [PATCH 70/78] hw/loongarch/virt: Add basic CPU plug support
|
||||
|
||||
Implement interface for cpu hotplug function, and enable cpu hotplug
|
||||
feature on virt machine.
|
||||
|
||||
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-ID: <20241023071312.881866-3-maobibo@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/Kconfig | 1 +
|
||||
hw/loongarch/virt.c | 193 +++++++++++++++++++++++++++++++++++-
|
||||
include/hw/loongarch/virt.h | 1 +
|
||||
target/loongarch/cpu.c | 13 +++
|
||||
4 files changed, 206 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index 40944a8365..b42a8573d4 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -16,6 +16,7 @@ config LOONGARCH_VIRT
|
||||
select LOONGARCH_EXTIOI
|
||||
select LS7A_RTC
|
||||
select SMBIOS
|
||||
+ select ACPI_CPU_HOTPLUG
|
||||
select ACPI_PCI
|
||||
select ACPI_HW_REDUCED
|
||||
select FW_CFG_DMA
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 8d1e53ff62..e7734ed3c0 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -821,7 +821,7 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
|
||||
/* Create IPI device */
|
||||
ipi = qdev_new(TYPE_LOONGARCH_IPI);
|
||||
- qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.cpus);
|
||||
+ qdev_prop_set_uint32(ipi, "num-cpu", ms->smp.max_cpus);
|
||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
|
||||
|
||||
/* IPI iocsr memory region */
|
||||
@@ -845,9 +845,11 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
env->ipistate = ipi;
|
||||
}
|
||||
|
||||
+ lvms->ipi = ipi;
|
||||
+
|
||||
/* Create EXTIOI device */
|
||||
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.max_cpus);
|
||||
if (virt_is_veiointc_enabled(lvms)) {
|
||||
qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
|
||||
}
|
||||
@@ -873,6 +875,8 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
|
||||
}
|
||||
}
|
||||
|
||||
+ lvms->extioi = extioi;
|
||||
+
|
||||
/* Add Extend I/O Interrupt Controller node */
|
||||
fdt_add_eiointc_node(lvms, &cpuintc_phandle, &eiointc_phandle);
|
||||
|
||||
@@ -1310,6 +1314,181 @@ static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
|
||||
return arch_id;
|
||||
}
|
||||
|
||||
+/* find cpu slot in machine->possible_cpus by arch_id */
|
||||
+static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id, int *index)
|
||||
+{
|
||||
+ int n;
|
||||
+ for (n = 0; n < ms->possible_cpus->len; n++) {
|
||||
+ if (ms->possible_cpus->cpus[n].arch_id == arch_id) {
|
||||
+ if (index) {
|
||||
+ *index = n;
|
||||
+ }
|
||||
+ return &ms->possible_cpus->cpus[n];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ MachineState *ms = MACHINE(OBJECT(hotplug_dev));
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
|
||||
+ CPUState *cs = CPU(dev);
|
||||
+ CPUArchId *cpu_slot;
|
||||
+ Error *local_err = NULL;
|
||||
+ LoongArchCPUTopo topo;
|
||||
+ int arch_id, index;
|
||||
+
|
||||
+ if (dev->hotplugged && !mc->has_hotpluggable_cpus) {
|
||||
+ error_setg(&local_err, "CPU hotplug not supported for this machine");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* sanity check the cpu */
|
||||
+ if (!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) {
|
||||
+ error_setg(&local_err, "Invalid CPU type, expected cpu type: '%s'",
|
||||
+ ms->cpu_type);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((cpu->thread_id < 0) || (cpu->thread_id >= ms->smp.threads)) {
|
||||
+ error_setg(&local_err,
|
||||
+ "Invalid thread-id %u specified, must be in range 1:%u",
|
||||
+ cpu->thread_id, ms->smp.threads - 1);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((cpu->core_id < 0) || (cpu->core_id >= ms->smp.cores)) {
|
||||
+ error_setg(&local_err,
|
||||
+ "Invalid core-id %u specified, must be in range 1:%u",
|
||||
+ cpu->core_id, ms->smp.cores - 1);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((cpu->socket_id < 0) || (cpu->socket_id >= ms->smp.sockets)) {
|
||||
+ error_setg(&local_err,
|
||||
+ "Invalid socket-id %u specified, must be in range 1:%u",
|
||||
+ cpu->socket_id, ms->smp.sockets - 1);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ topo.socket_id = cpu->socket_id;
|
||||
+ topo.core_id = cpu->core_id;
|
||||
+ topo.thread_id = cpu->thread_id;
|
||||
+ arch_id = virt_get_arch_id_from_topo(ms, &topo);
|
||||
+ cpu_slot = virt_find_cpu_slot(ms, arch_id, &index);
|
||||
+ if (CPU(cpu_slot->cpu)) {
|
||||
+ error_setg(&local_err,
|
||||
+ "cpu(id%d=%d:%d:%d) with arch-id %" PRIu64 " exists",
|
||||
+ cs->cpu_index, cpu->socket_id, cpu->core_id,
|
||||
+ cpu->thread_id, cpu_slot->arch_id);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ cpu->phy_id = arch_id;
|
||||
+ /*
|
||||
+ * update cpu_index calculation method since it is easily used as index
|
||||
+ * with possible_cpus array by function virt_cpu_index_to_props
|
||||
+ */
|
||||
+ cs->cpu_index = index;
|
||||
+ numa_cpu_pre_plug(cpu_slot, dev, &local_err);
|
||||
+ return ;
|
||||
+
|
||||
+out:
|
||||
+ error_propagate(errp, local_err);
|
||||
+}
|
||||
+
|
||||
+static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
+ Error *local_err = NULL;
|
||||
+ HotplugHandlerClass *hhc;
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
|
||||
+ CPUState *cs = CPU(dev);
|
||||
+
|
||||
+ if (!lvms->acpi_ged) {
|
||||
+ error_setg(&local_err, "CPU hot unplug not supported without ACPI");
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (cs->cpu_index == 0) {
|
||||
+ error_setg(&local_err,
|
||||
+ "hot-unplug of boot cpu(id%d=%d:%d:%d) not supported",
|
||||
+ cs->cpu_index, cpu->socket_id,
|
||||
+ cpu->core_id, cpu->thread_id);
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ hhc = HOTPLUG_HANDLER_GET_CLASS(lvms->acpi_ged);
|
||||
+ hhc->unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &local_err);
|
||||
+}
|
||||
+
|
||||
+static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ CPUArchId *cpu_slot;
|
||||
+ HotplugHandlerClass *hhc;
|
||||
+ Error *local_err = NULL;
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
|
||||
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
+
|
||||
+ hhc = HOTPLUG_HANDLER_GET_CLASS(lvms->acpi_ged);
|
||||
+ hhc->unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &local_err);
|
||||
+ if (local_err) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id, NULL);
|
||||
+ cpu_slot->cpu = NULL;
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void virt_cpu_plug(HotplugHandler *hotplug_dev,
|
||||
+ DeviceState *dev, Error **errp)
|
||||
+{
|
||||
+ CPUArchId *cpu_slot;
|
||||
+ HotplugHandlerClass *hhc;
|
||||
+ Error *local_err = NULL;
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(dev);
|
||||
+ CPUState *cs = CPU(cpu);
|
||||
+ CPULoongArchState *env;
|
||||
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
|
||||
+ int pin;
|
||||
+
|
||||
+ if (lvms->acpi_ged) {
|
||||
+ env = &(cpu->env);
|
||||
+ env->address_space_iocsr = &lvms->as_iocsr;
|
||||
+
|
||||
+ env->ipistate = lvms->ipi;
|
||||
+ if (!(kvm_enabled() && kvm_irqchip_in_kernel())) {
|
||||
+ /* connect ipi irq to cpu irq, logic cpu index used here */
|
||||
+ qdev_connect_gpio_out(lvms->ipi, cs->cpu_index,
|
||||
+ qdev_get_gpio_in(dev, IRQ_IPI));
|
||||
+
|
||||
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
|
||||
+ qdev_connect_gpio_out(lvms->extioi, (cs->cpu_index * 8 + pin),
|
||||
+ qdev_get_gpio_in(dev, pin + 2));
|
||||
+ }
|
||||
+ }
|
||||
+ hhc = HOTPLUG_HANDLER_GET_CLASS(lvms->acpi_ged);
|
||||
+ hhc->plug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &local_err);
|
||||
+ if (local_err) {
|
||||
+ error_propagate(errp, local_err);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id, NULL);
|
||||
+ cpu_slot->cpu = OBJECT(dev);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static bool memhp_type_supported(DeviceState *dev)
|
||||
{
|
||||
/* we only support pc dimm now */
|
||||
@@ -1328,6 +1507,8 @@ static void virt_device_pre_plug(HotplugHandler *hotplug_dev,
|
||||
{
|
||||
if (memhp_type_supported(dev)) {
|
||||
virt_mem_pre_plug(hotplug_dev, dev, errp);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
|
||||
+ virt_cpu_pre_plug(hotplug_dev, dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1346,6 +1527,8 @@ static void virt_device_unplug_request(HotplugHandler *hotplug_dev,
|
||||
{
|
||||
if (memhp_type_supported(dev)) {
|
||||
virt_mem_unplug_request(hotplug_dev, dev, errp);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
|
||||
+ virt_cpu_unplug_request(hotplug_dev, dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1364,6 +1547,8 @@ static void virt_device_unplug(HotplugHandler *hotplug_dev,
|
||||
{
|
||||
if (memhp_type_supported(dev)) {
|
||||
virt_mem_unplug(hotplug_dev, dev, errp);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
|
||||
+ virt_cpu_unplug(hotplug_dev, dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1391,6 +1576,8 @@ static void virt_device_plug_cb(HotplugHandler *hotplug_dev,
|
||||
}
|
||||
} else if (memhp_type_supported(dev)) {
|
||||
virt_mem_plug(hotplug_dev, dev, errp);
|
||||
+ } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
|
||||
+ virt_cpu_plug(hotplug_dev, dev, errp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1400,6 +1587,7 @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
|
||||
if (device_is_dynamic_sysbus(mc, dev) ||
|
||||
+ object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) ||
|
||||
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
|
||||
memhp_type_supported(dev)) {
|
||||
return HOTPLUG_HANDLER(machine);
|
||||
@@ -1489,6 +1677,7 @@ static void virt_class_init(ObjectClass *oc, void *data)
|
||||
mc->numa_mem_supported = true;
|
||||
mc->auto_enable_numa_with_memhp = true;
|
||||
mc->auto_enable_numa_with_memdev = true;
|
||||
+ mc->has_hotpluggable_cpus = true;
|
||||
mc->get_hotplug_handler = virt_get_hotplug_handler;
|
||||
mc->default_nic = "virtio-net-pci";
|
||||
hc->plug = virt_device_plug_cb;
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 0a4d9a25f0..27c52af9f3 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -64,6 +64,7 @@ struct LoongArchVirtMachineState {
|
||||
AddressSpace as_iocsr;
|
||||
int features;
|
||||
struct loongarch_boot_info bootinfo;
|
||||
+ DeviceState *ipi;
|
||||
};
|
||||
|
||||
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index 673ed8ea18..ee764f0bc7 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -644,6 +644,17 @@ static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
|
||||
lacc->parent_realize(dev, errp);
|
||||
}
|
||||
|
||||
+static void loongarch_cpu_unrealizefn(DeviceState *dev)
|
||||
+{
|
||||
+ LoongArchCPUClass *mcc = LOONGARCH_CPU_GET_CLASS(dev);
|
||||
+
|
||||
+#ifndef CONFIG_USER_ONLY
|
||||
+ cpu_remove_sync(CPU(dev));
|
||||
+#endif
|
||||
+
|
||||
+ mcc->parent_unrealize(dev);
|
||||
+}
|
||||
+
|
||||
static bool loongarch_get_lsx(Object *obj, Error **errp)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
@@ -880,6 +891,8 @@ static void loongarch_cpu_class_init(ObjectClass *c, void *data)
|
||||
device_class_set_props(dc, loongarch_cpu_properties);
|
||||
device_class_set_parent_realize(dc, loongarch_cpu_realizefn,
|
||||
&lacc->parent_realize);
|
||||
+ device_class_set_parent_unrealize(dc, loongarch_cpu_unrealizefn,
|
||||
+ &lacc->parent_unrealize);
|
||||
resettable_class_set_parent_phases(rc, NULL, loongarch_cpu_reset_hold, NULL,
|
||||
&lacc->parent_phases);
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
46
hw-loongarch-virt-Add-description-for-virt-machine-t.patch
Normal file
46
hw-loongarch-virt-Add-description-for-virt-machine-t.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 080ca7865257d70b6be671cbc17a97c5ebffbd68 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Fri, 13 Sep 2024 17:52:02 +0800
|
||||
Subject: [PATCH 38/78] hw/loongarch/virt: Add description for virt machine
|
||||
type
|
||||
|
||||
The description about virt machine type is removed by mistake, add
|
||||
new description here. Here is output result with command
|
||||
"./qemu-system-loongarch64 -M help"
|
||||
|
||||
Supported machines are:
|
||||
none empty machine
|
||||
virt QEMU LoongArch Virtual Machine (default)
|
||||
x-remote Experimental remote machine
|
||||
|
||||
Without the patch, it shows as follows:
|
||||
Supported machines are:
|
||||
none empty machine
|
||||
virt (null) (default)
|
||||
x-remote Experimental remote machine
|
||||
|
||||
Fixes: ef2f11454c(hw/loongarch/virt: Replace Loongson IPI with LoongArch IPI)
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 79b16953d2..9f47107379 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1383,6 +1383,7 @@ static void virt_class_init(ObjectClass *oc, void *data)
|
||||
mc->init = virt_init;
|
||||
mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
|
||||
mc->default_ram_id = "loongarch.ram";
|
||||
+ mc->desc = "QEMU LoongArch Virtual Machine";
|
||||
mc->max_cpus = LOONGARCH_MAX_CPUS;
|
||||
mc->is_default = 1;
|
||||
mc->default_kernel_irqchip_split = false;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
59
hw-loongarch-virt-Remove-unused-assignment.patch
Normal file
59
hw-loongarch-virt-Remove-unused-assignment.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From 5e0ec61ac98a025124912fc47552550b471ab638 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 12 Jun 2024 11:36:37 +0800
|
||||
Subject: [PATCH 32/78] hw/loongarch/virt: Remove unused assignment
|
||||
|
||||
There is abuse usage about local variable gap. Remove
|
||||
duplicated assignment and solve Coverity reported error.
|
||||
|
||||
Resolves: Coverity CID 1546441
|
||||
Fixes: 3cc451cbce ("hw/loongarch: Refine fwcfg memory map")
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240612033637.167787-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 15 +++++++--------
|
||||
1 file changed, 7 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 12816c6023..a7283e6755 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -1034,7 +1034,6 @@ static void fw_cfg_add_memory(MachineState *ms)
|
||||
memmap_add_entry(base, gap, 1);
|
||||
size -= gap;
|
||||
base = VIRT_HIGHMEM_BASE;
|
||||
- gap = ram_size - VIRT_LOWMEM_SIZE;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
@@ -1047,17 +1046,17 @@ static void fw_cfg_add_memory(MachineState *ms)
|
||||
}
|
||||
|
||||
/* add fw_cfg memory map of other nodes */
|
||||
- size = ram_size - numa_info[0].node_mem;
|
||||
- gap = VIRT_LOWMEM_BASE + VIRT_LOWMEM_SIZE;
|
||||
- if (base < gap && (base + size) > gap) {
|
||||
+ if (numa_info[0].node_mem < gap && ram_size > gap) {
|
||||
/*
|
||||
* memory map for the maining nodes splited into two part
|
||||
- * lowram: [base, +(gap - base))
|
||||
- * highram: [VIRT_HIGHMEM_BASE, +(size - (gap - base)))
|
||||
+ * lowram: [base, +(gap - numa_info[0].node_mem))
|
||||
+ * highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap))
|
||||
*/
|
||||
- memmap_add_entry(base, gap - base, 1);
|
||||
- size -= gap - base;
|
||||
+ memmap_add_entry(base, gap - numa_info[0].node_mem, 1);
|
||||
+ size = ram_size - gap;
|
||||
base = VIRT_HIGHMEM_BASE;
|
||||
+ } else {
|
||||
+ size = ram_size - numa_info[0].node_mem;
|
||||
}
|
||||
|
||||
if (size)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
143
hw-loongarch-virt-Update-the-ACPI-table-for-hotplug-.patch
Normal file
143
hw-loongarch-virt-Update-the-ACPI-table-for-hotplug-.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From a3728999125cd9fc9e3e841b66a1677663933c27 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 23 Oct 2024 15:13:12 +0800
|
||||
Subject: [PATCH 71/78] hw/loongarch/virt: Update the ACPI table for hotplug
|
||||
cpu
|
||||
|
||||
On LoongArch virt machine, ACPI GED hardware is used for cpu
|
||||
hotplug, here cpu hotplug support feature is added on GED device,
|
||||
also cpu scan and reject method is added about CPU device in
|
||||
DSDT table.
|
||||
|
||||
Co-developed-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-ID: <20241023071312.881866-4-maobibo@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/acpi-build.c | 35 +++++++++++++++++++++++++++++++++--
|
||||
hw/loongarch/virt.c | 10 ++++++++++
|
||||
include/hw/loongarch/virt.h | 1 +
|
||||
3 files changed, 44 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index bcdec2e1cb..a54c5e0e70 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -47,6 +47,22 @@
|
||||
#define ACPI_BUILD_DPRINTF(fmt, ...)
|
||||
#endif
|
||||
|
||||
+static void virt_madt_cpu_entry(int uid,
|
||||
+ const CPUArchIdList *apic_ids,
|
||||
+ GArray *entry, bool force_enabled)
|
||||
+{
|
||||
+ uint32_t flags, apic_id = apic_ids->cpus[uid].arch_id;
|
||||
+
|
||||
+ flags = apic_ids->cpus[uid].cpu || force_enabled ? 1 /* Enabled */ : 0;
|
||||
+
|
||||
+ /* Rev 1.0b, Table 5-13 Processor Local APIC Structure */
|
||||
+ build_append_int_noprefix(entry, 0, 1); /* Type */
|
||||
+ build_append_int_noprefix(entry, 8, 1); /* Length */
|
||||
+ build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */
|
||||
+ build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */
|
||||
+ build_append_int_noprefix(entry, flags, 4); /* Flags */
|
||||
+}
|
||||
+
|
||||
/* build FADT */
|
||||
static void init_common_fadt_data(AcpiFadtData *data)
|
||||
{
|
||||
@@ -123,15 +139,17 @@ build_madt(GArray *table_data, BIOSLinker *linker,
|
||||
build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
|
||||
|
||||
for (i = 0; i < arch_ids->len; i++) {
|
||||
+ uint32_t flags;
|
||||
+
|
||||
/* Processor Core Interrupt Controller Structure */
|
||||
arch_id = arch_ids->cpus[i].arch_id;
|
||||
-
|
||||
+ flags = arch_ids->cpus[i].cpu ? 1 : 0;
|
||||
build_append_int_noprefix(table_data, 17, 1); /* Type */
|
||||
build_append_int_noprefix(table_data, 15, 1); /* Length */
|
||||
build_append_int_noprefix(table_data, 1, 1); /* Version */
|
||||
build_append_int_noprefix(table_data, i, 4); /* ACPI Processor ID */
|
||||
build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */
|
||||
- build_append_int_noprefix(table_data, 1, 4); /* Flags */
|
||||
+ build_append_int_noprefix(table_data, flags, 4); /* Flags */
|
||||
}
|
||||
|
||||
/* Extend I/O Interrupt Controller Structure */
|
||||
@@ -334,6 +352,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
|
||||
{
|
||||
uint32_t event;
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
+ CPUHotplugFeatures opts;
|
||||
|
||||
build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
|
||||
HOTPLUG_HANDLER(lvms->acpi_ged),
|
||||
@@ -346,6 +365,18 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
|
||||
AML_SYSTEM_MEMORY,
|
||||
VIRT_GED_MEM_ADDR);
|
||||
}
|
||||
+
|
||||
+ if (event & ACPI_GED_CPU_HOTPLUG_EVT) {
|
||||
+ opts.acpi_1_compatible = false;
|
||||
+ opts.has_legacy_cphp = false;
|
||||
+ opts.fw_unplugs_cpu = false;
|
||||
+ opts.smi_path = NULL;
|
||||
+
|
||||
+ build_cpus_aml(dsdt, machine, opts, virt_madt_cpu_entry, NULL,
|
||||
+ VIRT_GED_CPUHP_ADDR, "\\_SB",
|
||||
+ NULL, AML_SYSTEM_MEMORY);
|
||||
+ }
|
||||
+
|
||||
acpi_dsdt_add_power_button(dsdt);
|
||||
}
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index e7734ed3c0..6159fd9470 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -652,11 +652,17 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic,
|
||||
{
|
||||
DeviceState *dev;
|
||||
MachineState *ms = MACHINE(lvms);
|
||||
+ MachineClass *mc = MACHINE_GET_CLASS(lvms);
|
||||
uint32_t event = ACPI_GED_PWR_DOWN_EVT;
|
||||
|
||||
if (ms->ram_slots) {
|
||||
event |= ACPI_GED_MEM_HOTPLUG_EVT;
|
||||
}
|
||||
+
|
||||
+ if (mc->has_hotpluggable_cpus) {
|
||||
+ event |= ACPI_GED_CPU_HOTPLUG_EVT;
|
||||
+ }
|
||||
+
|
||||
dev = qdev_new(TYPE_ACPI_GED);
|
||||
qdev_prop_set_uint32(dev, "ged-event", event);
|
||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
||||
@@ -668,6 +674,10 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic,
|
||||
/* ged regs used for reset and power down */
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
|
||||
|
||||
+ if (mc->has_hotpluggable_cpus) {
|
||||
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, VIRT_GED_CPUHP_ADDR);
|
||||
+ }
|
||||
+
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
|
||||
qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - VIRT_GSI_BASE));
|
||||
return dev;
|
||||
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
|
||||
index 27c52af9f3..98c990327b 100644
|
||||
--- a/include/hw/loongarch/virt.h
|
||||
+++ b/include/hw/loongarch/virt.h
|
||||
@@ -32,6 +32,7 @@
|
||||
#define VIRT_GED_EVT_ADDR 0x100e0000
|
||||
#define VIRT_GED_MEM_ADDR (VIRT_GED_EVT_ADDR + ACPI_GED_EVT_SEL_LEN)
|
||||
#define VIRT_GED_REG_ADDR (VIRT_GED_MEM_ADDR + MEMORY_HOTPLUG_IO_LEN)
|
||||
+#define VIRT_GED_CPUHP_ADDR (VIRT_GED_REG_ADDR + ACPI_GED_REG_COUNT)
|
||||
|
||||
#define COMMAND_LINE_SIZE 512
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
77
hw-loongarch-virt-Use-MemTxAttrs-interface-for-misc-.patch
Normal file
77
hw-loongarch-virt-Use-MemTxAttrs-interface-for-misc-.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From b63b7b0b6c9bed8e1a316f3838aab7db2e8f2037 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Tue, 28 May 2024 16:38:54 +0800
|
||||
Subject: [PATCH 29/78] hw/loongarch/virt: Use MemTxAttrs interface for misc
|
||||
ops
|
||||
|
||||
Use MemTxAttrs interface read_with_attrs/write_with_attrs
|
||||
for virt_iocsr_misc_ops.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240528083855.1912757-3-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 18 ++++++++++--------
|
||||
1 file changed, 10 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index f7874bccf9..12816c6023 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -915,8 +915,8 @@ static void virt_firmware_init(LoongArchVirtMachineState *lvms)
|
||||
}
|
||||
|
||||
|
||||
-static MemTxResult loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
- unsigned size, MemTxAttrs attrs)
|
||||
+static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
+ unsigned size, MemTxAttrs attrs)
|
||||
{
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
|
||||
uint64_t features;
|
||||
@@ -945,9 +945,9 @@ static MemTxResult loongarch_qemu_write(void *opaque, hwaddr addr, uint64_t val,
|
||||
return MEMTX_OK;
|
||||
}
|
||||
|
||||
-static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr,
|
||||
- uint64_t *data,
|
||||
- unsigned size, MemTxAttrs attrs)
|
||||
+static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
|
||||
+ uint64_t *data,
|
||||
+ unsigned size, MemTxAttrs attrs)
|
||||
{
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
|
||||
uint64_t ret = 0;
|
||||
@@ -962,7 +962,7 @@ static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr,
|
||||
if (kvm_enabled()) {
|
||||
ret |= BIT(IOCSRF_VM);
|
||||
}
|
||||
- return ret;
|
||||
+ break;
|
||||
case VENDOR_REG:
|
||||
ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */
|
||||
break;
|
||||
@@ -986,6 +986,8 @@ static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr,
|
||||
ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
|
||||
}
|
||||
break;
|
||||
+ default:
|
||||
+ g_assert_not_reached();
|
||||
}
|
||||
|
||||
*data = ret;
|
||||
@@ -993,8 +995,8 @@ static MemTxResult loongarch_qemu_read(void *opaque, hwaddr addr,
|
||||
}
|
||||
|
||||
static const MemoryRegionOps virt_iocsr_misc_ops = {
|
||||
- .read_with_attrs = loongarch_qemu_read,
|
||||
- .write_with_attrs = loongarch_qemu_write,
|
||||
+ .read_with_attrs = virt_iocsr_misc_read,
|
||||
+ .write_with_attrs = virt_iocsr_misc_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
--
|
||||
2.39.1
|
||||
|
||||
66
hw-loongarch-virt-pass-random-seed-to-fdt.patch
Normal file
66
hw-loongarch-virt-pass-random-seed-to-fdt.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 573f3bec8137caf829457620380d794165c96a92 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Thu, 5 Sep 2024 17:33:16 +0200
|
||||
Subject: [PATCH 36/78] hw/loongarch: virt: pass random seed to fdt
|
||||
|
||||
If the FDT contains /chosen/rng-seed, then the Linux RNG will use it to
|
||||
initialize early. Set this using the usual guest random number
|
||||
generation function.
|
||||
|
||||
This is the same procedure that's done in b91b6b5a2c ("hw/microblaze:
|
||||
pass random seed to fdt"), e4b4f0b71c ("hw/riscv: virt: pass random seed
|
||||
to fdt"), c6fe3e6b4c ("hw/openrisc: virt: pass random seed to fdt"),
|
||||
67f7e426e5 ("hw/i386: pass RNG seed via setup_data entry"), c287941a4d
|
||||
("hw/rx: pass random seed to fdt"), 5e19cc68fb ("hw/mips: boston: pass
|
||||
random seed to fdt"), 6b23a67916 ("hw/nios2: virt: pass random seed to fdt")
|
||||
c4b075318e ("hw/ppc: pass random seed to fdt"), and 5242876f37
|
||||
("hw/arm/virt: dt: add rng-seed property").
|
||||
|
||||
These earlier commits later were amended to rerandomize the RNG seed on
|
||||
snapshot load, but the LoongArch code somehow already does that, despite
|
||||
not having this patch here, presumably due to some lucky copy and
|
||||
pasting.
|
||||
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240905153316.2038769-1-Jason@zx2c4.com>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index a6e9309064..79b16953d2 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "hw/block/flash.h"
|
||||
#include "hw/virtio/virtio-iommu.h"
|
||||
#include "qemu/error-report.h"
|
||||
+#include "qemu/guest-random.h"
|
||||
|
||||
static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
|
||||
{
|
||||
@@ -304,6 +305,7 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
|
||||
static void create_fdt(LoongArchVirtMachineState *lvms)
|
||||
{
|
||||
MachineState *ms = MACHINE(lvms);
|
||||
+ uint8_t rng_seed[32];
|
||||
|
||||
ms->fdt = create_device_tree(&lvms->fdt_size);
|
||||
if (!ms->fdt) {
|
||||
@@ -317,6 +319,10 @@ static void create_fdt(LoongArchVirtMachineState *lvms)
|
||||
qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
|
||||
qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
|
||||
qemu_fdt_add_subnode(ms->fdt, "/chosen");
|
||||
+
|
||||
+ /* Pass seed to RNG */
|
||||
+ qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
|
||||
+ qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
|
||||
}
|
||||
|
||||
static void fdt_add_cpu_nodes(const LoongArchVirtMachineState *lvms)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
172
hw-loongarch-virt-support-up-to-4-serial-ports.patch
Normal file
172
hw-loongarch-virt-support-up-to-4-serial-ports.patch
Normal file
@ -0,0 +1,172 @@
|
||||
From 04895c794652c5da1ece0cad82741bed9aa8ad02 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Sat, 7 Sep 2024 16:34:39 +0200
|
||||
Subject: [PATCH 35/78] hw/loongarch: virt: support up to 4 serial ports
|
||||
|
||||
In order to support additional channels of communication using
|
||||
`-serial`, add several serial ports, up to the standard 4 generally
|
||||
supported by the 8250 driver.
|
||||
|
||||
Fixed: https://lore.kernel.org/all/20240907143439.2792924-1-Jason@zx2c4.com/
|
||||
|
||||
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
|
||||
Tested-by: Bibo Mao <maobibo@loongson.cn>
|
||||
[gaosong: ACPI uart need't reverse order]
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240907143439.2792924-1-Jason@zx2c4.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/acpi-build.c | 23 +++++++++++++++--------
|
||||
hw/loongarch/virt.c | 27 +++++++++++++++++----------
|
||||
include/hw/pci-host/ls7a.h | 9 +++++----
|
||||
3 files changed, 37 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
|
||||
index 1a9d25fc51..33a92223d8 100644
|
||||
--- a/hw/loongarch/acpi-build.c
|
||||
+++ b/hw/loongarch/acpi-build.c
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "hw/acpi/generic_event_device.h"
|
||||
#include "hw/pci-host/gpex.h"
|
||||
+#include "sysemu/sysemu.h"
|
||||
#include "sysemu/tpm.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/acpi/aml-build.h"
|
||||
@@ -252,23 +253,27 @@ struct AcpiBuildState {
|
||||
MemoryRegion *linker_mr;
|
||||
} AcpiBuildState;
|
||||
|
||||
-static void build_uart_device_aml(Aml *table)
|
||||
+static void build_uart_device_aml(Aml *table, int index)
|
||||
{
|
||||
Aml *dev;
|
||||
Aml *crs;
|
||||
Aml *pkg0, *pkg1, *pkg2;
|
||||
- uint32_t uart_irq = VIRT_UART_IRQ;
|
||||
-
|
||||
- Aml *scope = aml_scope("_SB");
|
||||
- dev = aml_device("COMA");
|
||||
+ Aml *scope;
|
||||
+ uint32_t uart_irq;
|
||||
+ uint64_t base;
|
||||
+
|
||||
+ uart_irq = VIRT_UART_IRQ + index;
|
||||
+ base = VIRT_UART_BASE + index * VIRT_UART_SIZE;
|
||||
+ scope = aml_scope("_SB");
|
||||
+ dev = aml_device("COM%d", index);
|
||||
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
|
||||
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
|
||||
+ aml_append(dev, aml_name_decl("_UID", aml_int(index)));
|
||||
aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs,
|
||||
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
|
||||
AML_NON_CACHEABLE, AML_READ_WRITE,
|
||||
- 0, VIRT_UART_BASE, VIRT_UART_BASE + VIRT_UART_SIZE - 1,
|
||||
+ 0, base, base + VIRT_UART_SIZE - 1,
|
||||
0, VIRT_UART_SIZE));
|
||||
aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
|
||||
AML_SHARED, &uart_irq, 1));
|
||||
@@ -401,6 +406,7 @@ static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms)
|
||||
static void
|
||||
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
{
|
||||
+ int i;
|
||||
Aml *dsdt, *scope, *pkg;
|
||||
LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
|
||||
AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
|
||||
@@ -408,7 +414,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
|
||||
|
||||
acpi_table_begin(&table, table_data);
|
||||
dsdt = init_aml_allocator();
|
||||
- build_uart_device_aml(dsdt);
|
||||
+ for (i = 0; i < VIRT_UART_COUNT; i++)
|
||||
+ build_uart_device_aml(dsdt, i);
|
||||
build_pci_device_aml(dsdt, lvms);
|
||||
build_la_ged_aml(dsdt, machine);
|
||||
build_flash_aml(dsdt, lvms);
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index a7283e6755..a6e9309064 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -281,10 +281,10 @@ static void fdt_add_rtc_node(LoongArchVirtMachineState *lvms,
|
||||
}
|
||||
|
||||
static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
|
||||
- uint32_t *pch_pic_phandle)
|
||||
+ uint32_t *pch_pic_phandle, hwaddr base,
|
||||
+ int irq, bool chosen)
|
||||
{
|
||||
char *nodename;
|
||||
- hwaddr base = VIRT_UART_BASE;
|
||||
hwaddr size = VIRT_UART_SIZE;
|
||||
MachineState *ms = MACHINE(lvms);
|
||||
|
||||
@@ -293,9 +293,9 @@ static void fdt_add_uart_node(LoongArchVirtMachineState *lvms,
|
||||
qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
|
||||
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
|
||||
- qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
|
||||
- qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts",
|
||||
- VIRT_UART_IRQ - VIRT_GSI_BASE, 0x4);
|
||||
+ if (chosen)
|
||||
+ qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
|
||||
+ qemu_fdt_setprop_cells(ms->fdt, nodename, "interrupts", irq, 0x4);
|
||||
qemu_fdt_setprop_cell(ms->fdt, nodename, "interrupt-parent",
|
||||
*pch_pic_phandle);
|
||||
g_free(nodename);
|
||||
@@ -706,11 +706,18 @@ static void virt_devices_init(DeviceState *pch_pic,
|
||||
/* Add pcie node */
|
||||
fdt_add_pcie_node(lvms, pch_pic_phandle, pch_msi_phandle);
|
||||
|
||||
- serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
|
||||
- qdev_get_gpio_in(pch_pic,
|
||||
- VIRT_UART_IRQ - VIRT_GSI_BASE),
|
||||
- 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
|
||||
- fdt_add_uart_node(lvms, pch_pic_phandle);
|
||||
+ /*
|
||||
+ * Create uart fdt node in reverse order so that they appear
|
||||
+ * in the finished device tree lowest address first
|
||||
+ */
|
||||
+ for (i = VIRT_UART_COUNT; i --> 0;) {
|
||||
+ hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
|
||||
+ int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
|
||||
+ serial_mm_init(get_system_memory(), base, 0,
|
||||
+ qdev_get_gpio_in(pch_pic, irq),
|
||||
+ 115200, serial_hd(i), DEVICE_LITTLE_ENDIAN);
|
||||
+ fdt_add_uart_node(lvms, pch_pic_phandle, base, irq, i == 0);
|
||||
+ }
|
||||
|
||||
/* Network init */
|
||||
for (i = 0; i < nb_nics; i++) {
|
||||
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
|
||||
index cd7c9ec7bc..79d4ea8501 100644
|
||||
--- a/include/hw/pci-host/ls7a.h
|
||||
+++ b/include/hw/pci-host/ls7a.h
|
||||
@@ -36,17 +36,18 @@
|
||||
#define VIRT_PCH_PIC_IRQ_NUM 32
|
||||
#define VIRT_GSI_BASE 64
|
||||
#define VIRT_DEVICE_IRQS 16
|
||||
+#define VIRT_UART_COUNT 4
|
||||
#define VIRT_UART_IRQ (VIRT_GSI_BASE + 2)
|
||||
#define VIRT_UART_BASE 0x1fe001e0
|
||||
-#define VIRT_UART_SIZE 0X100
|
||||
-#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 3)
|
||||
+#define VIRT_UART_SIZE 0x100
|
||||
+#define VIRT_RTC_IRQ (VIRT_GSI_BASE + 6)
|
||||
#define VIRT_MISC_REG_BASE (VIRT_PCH_REG_BASE + 0x00080000)
|
||||
#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
|
||||
#define VIRT_RTC_LEN 0x100
|
||||
-#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 4)
|
||||
+#define VIRT_SCI_IRQ (VIRT_GSI_BASE + 7)
|
||||
|
||||
#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000
|
||||
#define VIRT_PLATFORM_BUS_SIZE 0x2000000
|
||||
#define VIRT_PLATFORM_BUS_NUM_IRQS 2
|
||||
-#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 5)
|
||||
+#define VIRT_PLATFORM_BUS_IRQ (VIRT_GSI_BASE + 8)
|
||||
#endif
|
||||
--
|
||||
2.39.1
|
||||
|
||||
40
linux-headers-loongarch-Add-kvm_para.h-and-unistd_64.patch
Normal file
40
linux-headers-loongarch-Add-kvm_para.h-and-unistd_64.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 734b877ee97c73c7cbeeb02c560b9b4e6a8c0dda Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Thu, 17 Oct 2024 10:07:07 +0800
|
||||
Subject: [PATCH 60/78] linux-headers: loongarch: Add kvm_para.h and
|
||||
unistd_64.h
|
||||
|
||||
KVM LBT supports on LoongArch depends on the linux-header file
|
||||
kvm_para.h, also unistd_64.h is required by unistd.h on LoongArch
|
||||
since 6.11, otherwise there will be compiling error such as:
|
||||
|
||||
linux-headers/asm/unistd.h:3:10: fatal error: asm/unistd_64.h: No such file or directory
|
||||
#include <asm/unistd_64.h>
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Acked-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20241017020708.1728620-2-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
scripts/update-linux-headers.sh | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
|
||||
index 34295c0fe5..88c76b8f69 100755
|
||||
--- a/scripts/update-linux-headers.sh
|
||||
+++ b/scripts/update-linux-headers.sh
|
||||
@@ -156,6 +156,10 @@ for arch in $ARCHLIST; do
|
||||
cp_portable "$tmpdir/bootparam.h" \
|
||||
"$output/include/standard-headers/asm-$arch"
|
||||
fi
|
||||
+ if [ $arch = loongarch ]; then
|
||||
+ cp "$hdrdir/include/asm/kvm_para.h" "$output/linux-headers/asm-loongarch/"
|
||||
+ cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-loongarch/"
|
||||
+ fi
|
||||
done
|
||||
|
||||
rm -rf "$output/linux-headers/linux"
|
||||
--
|
||||
2.39.1
|
||||
|
||||
60
loongarch-switch-boards-to-default-y.patch
Normal file
60
loongarch-switch-boards-to-default-y.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 0e0326de88282a601ea5178d421242d5b77afbfa Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Thu, 25 Jan 2024 13:36:37 +0100
|
||||
Subject: [PATCH 17/78] loongarch: switch boards to "default y"
|
||||
|
||||
Some targets use "default y" for boards to filter out those that require
|
||||
TCG. For consistency we are switching all other targets to do the same.
|
||||
Continue with Loongarch.
|
||||
|
||||
No changes to generated config-devices.mak file.
|
||||
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
.gitlab-ci.d/buildtest.yml | 2 ++
|
||||
configs/devices/loongarch64-softmmu/default.mak | 6 +++++-
|
||||
hw/loongarch/Kconfig | 2 ++
|
||||
3 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/.gitlab-ci.d/buildtest.yml b/.gitlab-ci.d/buildtest.yml
|
||||
index 91663946de..3fb99e79e9 100644
|
||||
--- a/.gitlab-ci.d/buildtest.yml
|
||||
+++ b/.gitlab-ci.d/buildtest.yml
|
||||
@@ -579,6 +579,8 @@ build-tci:
|
||||
- make check-tcg
|
||||
|
||||
# Check our reduced build configurations
|
||||
+# requires libfdt: aarch64, arm, i386, loongarch64, x86_64
|
||||
+# does not build without boards: i386, loongarch64, x86_64
|
||||
build-without-defaults:
|
||||
extends: .native_build_job_template
|
||||
needs:
|
||||
diff --git a/configs/devices/loongarch64-softmmu/default.mak b/configs/devices/loongarch64-softmmu/default.mak
|
||||
index 928bc117ef..ffe705836f 100644
|
||||
--- a/configs/devices/loongarch64-softmmu/default.mak
|
||||
+++ b/configs/devices/loongarch64-softmmu/default.mak
|
||||
@@ -1,3 +1,7 @@
|
||||
# Default configuration for loongarch64-softmmu
|
||||
|
||||
-CONFIG_LOONGARCH_VIRT=y
|
||||
+# Uncomment the following lines to disable these optional devices:
|
||||
+# CONFIG_PCI_DEVICES=n
|
||||
+
|
||||
+# Boards are selected by default, uncomment to keep out of the build.
|
||||
+# CONFIG_LOONGARCH_VIRT=n
|
||||
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
|
||||
index 5727efed6d..7864050563 100644
|
||||
--- a/hw/loongarch/Kconfig
|
||||
+++ b/hw/loongarch/Kconfig
|
||||
@@ -1,5 +1,7 @@
|
||||
config LOONGARCH_VIRT
|
||||
bool
|
||||
+ default y
|
||||
+ depends on LOONGARCH64
|
||||
select PCI
|
||||
select PCI_EXPRESS_GENERIC_BRIDGE
|
||||
imply VIRTIO_VGA
|
||||
--
|
||||
2.39.1
|
||||
|
||||
93
physmem-Add-helper-function-to-destroy-CPU-AddressSp.patch
Normal file
93
physmem-Add-helper-function-to-destroy-CPU-AddressSp.patch
Normal file
@ -0,0 +1,93 @@
|
||||
From 7efd5d829730d0481659cda91f725df3b141f469 Mon Sep 17 00:00:00 2001
|
||||
From: Salil Mehta <salil.mehta@huawei.com>
|
||||
Date: Tue, 16 Jul 2024 12:15:01 +0100
|
||||
Subject: [PATCH 66/78] physmem: Add helper function to destroy CPU
|
||||
AddressSpace
|
||||
|
||||
Virtual CPU Hot-unplug leads to unrealization of a CPU object. This also
|
||||
involves destruction of the CPU AddressSpace. Add common function to help
|
||||
destroy the CPU AddressSpace.
|
||||
|
||||
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||||
Tested-by: Vishnu Pajjuri <vishnu@os.amperecomputing.com>
|
||||
Reviewed-by: Gavin Shan <gshan@redhat.com>
|
||||
Tested-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
Tested-by: Miguel Luis <miguel.luis@oracle.com>
|
||||
Reviewed-by: Shaoqin Huang <shahuang@redhat.com>
|
||||
Tested-by: Zhao Liu <zhao1.liu@intel.com>
|
||||
Acked-by: Igor Mammedov <imammedo@redhat.com>
|
||||
Message-Id: <20240716111502.202344-7-salil.mehta@huawei.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
include/hw/core/cpu.h | 4 ++--
|
||||
system/physmem.c | 18 +++++++++++-------
|
||||
2 files changed, 13 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
|
||||
index ee04ee44c2..37f3a469c8 100644
|
||||
--- a/include/hw/core/cpu.h
|
||||
+++ b/include/hw/core/cpu.h
|
||||
@@ -495,8 +495,8 @@ struct CPUState {
|
||||
QemuMutex work_mutex;
|
||||
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
|
||||
|
||||
- CPUAddressSpace *cpu_ases;
|
||||
- int cpu_ases_ref_count;
|
||||
+ struct CPUAddressSpace *cpu_ases;
|
||||
+ int cpu_ases_count;
|
||||
int num_ases;
|
||||
AddressSpace *as;
|
||||
MemoryRegion *memory;
|
||||
diff --git a/system/physmem.c b/system/physmem.c
|
||||
index 2c8b83f811..c50ac24786 100644
|
||||
--- a/system/physmem.c
|
||||
+++ b/system/physmem.c
|
||||
@@ -761,7 +761,7 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
|
||||
|
||||
if (!cpu->cpu_ases) {
|
||||
cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
|
||||
- cpu->cpu_ases_ref_count = cpu->num_ases;
|
||||
+ cpu->cpu_ases_count = cpu->num_ases;
|
||||
}
|
||||
|
||||
newas = &cpu->cpu_ases[asidx];
|
||||
@@ -779,24 +779,28 @@ void cpu_address_space_destroy(CPUState *cpu, int asidx)
|
||||
{
|
||||
CPUAddressSpace *cpuas;
|
||||
|
||||
- assert(asidx < cpu->num_ases);
|
||||
- assert(asidx == 0 || !kvm_enabled());
|
||||
assert(cpu->cpu_ases);
|
||||
+ assert(asidx >= 0 && asidx < cpu->num_ases);
|
||||
+ /* KVM cannot currently support multiple address spaces. */
|
||||
+ assert(asidx == 0 || !kvm_enabled());
|
||||
|
||||
cpuas = &cpu->cpu_ases[asidx];
|
||||
if (tcg_enabled()) {
|
||||
memory_listener_unregister(&cpuas->tcg_as_listener);
|
||||
}
|
||||
|
||||
- cpuas->as->free_in_rcu = true;
|
||||
address_space_destroy(cpuas->as);
|
||||
+ g_free_rcu(cpuas->as, rcu);
|
||||
|
||||
- if (cpu->cpu_ases_ref_count == 1) {
|
||||
+ if (asidx == 0) {
|
||||
+ /* reset the convenience alias for address space 0 */
|
||||
+ cpu->as = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (--cpu->cpu_ases_count == 0) {
|
||||
g_free(cpu->cpu_ases);
|
||||
cpu->cpu_ases = NULL;
|
||||
}
|
||||
-
|
||||
- cpu->cpu_ases_ref_count--;
|
||||
}
|
||||
|
||||
AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
161
qemu.spec
161
qemu.spec
@ -3,7 +3,7 @@
|
||||
|
||||
Name: qemu
|
||||
Version: 8.2.0
|
||||
Release: 26
|
||||
Release: 27
|
||||
Epoch: 11
|
||||
Summary: QEMU is a generic and open source machine emulator and virtualizer
|
||||
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
|
||||
@ -485,6 +485,84 @@ Patch0468: target-m68k-Map-FPU-exceptions-to-FPSR-register.patch
|
||||
Patch0469: migration-fix-possible-int-overflow.patch
|
||||
Patch0470: tcg-Allow-top-bit-of-SIMD_DATA_BITS-to-be-set-in-sim.patch
|
||||
Patch0471: vdpa-dev-Fix-initialisation-order-to-restore-VDUSE-c.patch
|
||||
Patch0472: hw-loongarch-Move-boot-functions-to-boot.c.patch
|
||||
Patch0473: hw-loongarch-Add-load-initrd.patch
|
||||
Patch0474: hw-loongarch-Add-slave-cpu-boot_code.patch
|
||||
Patch0475: hw-loongarch-Add-init_cmdline.patch
|
||||
Patch0476: hw-loongarch-Init-efi_system_table.patch
|
||||
Patch0477: hw-loongarch-Init-efi_boot_memmap-table.patch
|
||||
Patch0478: hw-loongarch-Init-efi_initrd-table.patch
|
||||
Patch0479: hw-loongarch-Init-efi_fdt-table.patch
|
||||
Patch0480: hw-loongarch-fdt-adds-cpu-interrupt-controller-node.patch
|
||||
Patch0481: hw-loongarch-fdt-adds-Extend-I-O-Interrupt-Controlle.patch
|
||||
Patch0482: hw-loongarch-fdt-adds-pch_pic-Controller.patch
|
||||
Patch0483: hw-loongarch-fdt-adds-pch_msi-Controller.patch
|
||||
Patch0484: hw-loongarch-fdt-adds-pcie-irq_map-node.patch
|
||||
Patch0485: hw-loongarch-fdt-remove-unused-irqchip-node.patch
|
||||
Patch0486: hw-loongarch-Add-cells-missing-from-uart-node.patch
|
||||
Patch0487: hw-loongarch-Add-cells-missing-from-rtc-node.patch
|
||||
Patch0488: loongarch-switch-boards-to-default-y.patch
|
||||
Patch0489: hw-loongarch-move-memory-map-to-boot.c.patch
|
||||
Patch0490: hw-loongarch-Rename-LOONGARCH_MACHINE-with-LOONGARCH.patch
|
||||
Patch0491: hw-loongarch-Rename-LoongArchMachineState-with-Loong.patch
|
||||
Patch0492: hw-loongarch-Refine-default-numa-id-calculation.patch
|
||||
Patch0493: hw-loongarch-Add-VM-mode-in-IOCSR-feature-register-i.patch
|
||||
Patch0494: hw-loongarch-Refine-acpi-srat-table-for-numa-memory.patch
|
||||
Patch0495: hw-loongarch-Refine-fadt-memory-table-for-numa-memor.patch
|
||||
Patch0496: hw-loongarch-Refine-fwcfg-memory-map.patch
|
||||
Patch0497: hw-loongarch-Refine-system-dram-memory-region.patch
|
||||
Patch0498: hw-loongarch-Remove-minimum-and-default-memory-size.patch
|
||||
Patch0499: tests-libqos-Add-loongarch-virt-machine-node.patch
|
||||
Patch0500: hw-loongarch-virt-Use-MemTxAttrs-interface-for-misc-.patch
|
||||
Patch0501: hw-loongarch-boot.c-fix-out-of-bound-reading.patch
|
||||
Patch0502: hw-loongarch-Change-the-tpm-support-by-default.patch
|
||||
Patch0503: hw-loongarch-virt-Remove-unused-assignment.patch
|
||||
Patch0504: hw-loongarch-Fix-length-for-lowram-in-ACPI-SRAT.patch
|
||||
Patch0505: hw-loongarch-Remove-default-enable-with-VIRTIO_VGA-d.patch
|
||||
Patch0506: hw-loongarch-virt-support-up-to-4-serial-ports.patch
|
||||
Patch0507: hw-loongarch-virt-pass-random-seed-to-fdt.patch
|
||||
Patch0508: hw-loongarch-Add-acpi-SPCR-table-support.patch
|
||||
Patch0509: hw-loongarch-virt-Add-description-for-virt-machine-t.patch
|
||||
Patch0510: hw-loongarch-virt-Add-FDT-table-support-with-acpi-ge.patch
|
||||
Patch0511: hw-arm-virt-acpi-build.c-Migrate-SPCR-creation-to-co.patch
|
||||
Patch0512: target-loongarch-Add-TCG-macro-in-structure-CPUArchS.patch
|
||||
Patch0513: target-loongarch-Put-cpucfg-operation-before-CSR-reg.patch
|
||||
Patch0514: target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch
|
||||
Patch0515: target-loongarch-Add-loongarch-vector-property-uncon.patch
|
||||
Patch0516: target-loongarch-kvm-Add-software-breakpoint-support-sync-upstream.patch
|
||||
Patch0517: target-loongarch-Remove-avail_64-in-trans_srai_w-and.patch
|
||||
Patch0518: target-loongarch-Set-CSR_PRCFG1-and-CSR_PRCFG2-value.patch
|
||||
Patch0519: target-loongarch-Fix-cpu_reset-set-wrong-CSR_CRMD.patch
|
||||
Patch0520: target-loongarch-Add-compatible-support-about-VM-reb.patch
|
||||
Patch0521: target-loongarch-kvm-Add-vCPU-reset-function.patch
|
||||
Patch0522: target-loongarch-Support-QMP-dump-guest-memory.patch
|
||||
Patch0523: target-loongarch-fix-Werror-maybe-uninitialized-fals.patch
|
||||
Patch0524: target-loongarch-Use-explicit-little-endian-LD-ST-AP.patch
|
||||
Patch0525: target-loongarch-Avoid-bits-shift-exceeding-width-of.patch
|
||||
Patch0526: sync-loongarch-linux-headers.patch
|
||||
Patch0527: target-loongarch-Add-loongson-binary-translation-fea.patch
|
||||
Patch0528: target-loongarch-Implement-lbt-registers-save-restor.patch
|
||||
Patch0529: target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch
|
||||
Patch0530: linux-headers-loongarch-Add-kvm_para.h-and-unistd_64.patch
|
||||
Patch0531: target-loongarch-Add-steal-time-support-on-migration.patch
|
||||
Patch0532: accel-kvm-Extract-common-KVM-vCPU-creation-parking-c-sync-upstream.patch
|
||||
Patch0533: hw-acpi-Move-CPU-ctrl-dev-MMIO-region-len-macro-to-c-sync-upstream.patch
|
||||
Patch0534: hw-acpi-Update-ACPI-GED-framework-to-support-vCPU-Ho-sync-upstream.patch
|
||||
Patch0535: hw-acpi-Update-CPUs-AML-with-cpu-ctrl-dev-change-sync-upstream.patch
|
||||
Patch0536: physmem-Add-helper-function-to-destroy-CPU-AddressSp.patch
|
||||
Patch0537: gdbstub-Add-helper-function-to-unregister-GDB-regist.patch
|
||||
Patch0538: accel-kvm-kvm-all-Fixes-the-missing-break-in-vCPU-un.patch
|
||||
Patch0539: hw-loongarch-virt-Add-CPU-topology-support.patch
|
||||
Patch0540: hw-loongarch-virt-Add-basic-CPU-plug-support.patch
|
||||
Patch0541: hw-loongarch-virt-Update-the-ACPI-table-for-hotplug-.patch
|
||||
Patch0542: hw-loongarch-Add-KVM-IPI-device-support.patch
|
||||
Patch0543: hw-loongarch-Add-KVM-extioi-device-support.patch
|
||||
Patch0544: hw-loongarch-Add-KVM-pch-pic-device-support.patch
|
||||
Patch0545: hw-loongarch-Add-KVM-pch-msi-device-support.patch
|
||||
Patch0546: hw-loongarch-clean-code.patch
|
||||
Patch0547: hw-loongarch-boot-Use-warn_report-when-no-kernel-fil.patch
|
||||
Patch0548: hw-loongarch-fix-cpu-hotplug-reset.patch
|
||||
Patch0549: fix-compile-error-on-loongarch.patch
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: gcc
|
||||
@ -662,6 +740,7 @@ This package provides the QEMU system emulator for riscv.
|
||||
%package system-loongarch64
|
||||
Summary: Qemu-system-loongarch64
|
||||
Requires: qemu
|
||||
Requires: spice-gtk
|
||||
%description system-loongarch64
|
||||
This package provides the QEMU system emulator for loongarch64.
|
||||
|
||||
@ -1082,6 +1161,86 @@ getent passwd qemu >/dev/null || \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Dec 13 2024 Xianglai Li <lixianglai@loongson.cn> - 11:8.2.0-27
|
||||
- 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
|
||||
|
||||
* Thu Dec 12 2024 Jiabo Feng <fengjiabo1@huawei.com> - 11:8.2.0-26
|
||||
- vdpa-dev: Fix initialisation order to restore VDUSE compatibility
|
||||
- tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc()
|
||||
|
||||
97
sync-loongarch-linux-headers.patch
Normal file
97
sync-loongarch-linux-headers.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From 23cede66eaa62e8ec559cfa538a59e72375c9fa8 Mon Sep 17 00:00:00 2001
|
||||
From: gaosong <gaosong@loongson.cn>
|
||||
Date: Sun, 8 Sep 2024 03:28:16 +0800
|
||||
Subject: [PATCH 56/78] sync loongarch linux-headers
|
||||
|
||||
Signed-off-by: gaosong <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
linux-headers/asm-loongarch/kvm.h | 36 +++++++++++++++++++++++++++-
|
||||
linux-headers/asm-loongarch/unistd.h | 1 +
|
||||
2 files changed, 36 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h
|
||||
index 81fec85f0a..13c1280662 100644
|
||||
--- a/linux-headers/asm-loongarch/kvm.h
|
||||
+++ b/linux-headers/asm-loongarch/kvm.h
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
|
||||
#define KVM_DIRTY_LOG_PAGE_OFFSET 64
|
||||
+#define __KVM_HAVE_IRQ_LINE
|
||||
|
||||
#define KVM_GUESTDBG_USE_SW_BP 0x00010000
|
||||
/*
|
||||
@@ -66,6 +67,7 @@ struct kvm_fpu {
|
||||
#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL)
|
||||
#define KVM_REG_LOONGARCH_FPSIMD (KVM_REG_LOONGARCH | 0x30000ULL)
|
||||
#define KVM_REG_LOONGARCH_CPUCFG (KVM_REG_LOONGARCH | 0x40000ULL)
|
||||
+#define KVM_REG_LOONGARCH_LBT (KVM_REG_LOONGARCH | 0x50000ULL)
|
||||
#define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL)
|
||||
#define KVM_CSR_IDX_MASK 0x7fff
|
||||
#define KVM_CPUCFG_IDX_MASK 0x7fff
|
||||
@@ -79,13 +81,34 @@ struct kvm_fpu {
|
||||
/* Debugging: Special instruction for software breakpoint */
|
||||
#define KVM_REG_LOONGARCH_DEBUG_INST (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 3)
|
||||
|
||||
+/* LBT registers */
|
||||
+#define KVM_REG_LOONGARCH_LBT_SCR0 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 1)
|
||||
+#define KVM_REG_LOONGARCH_LBT_SCR1 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 2)
|
||||
+#define KVM_REG_LOONGARCH_LBT_SCR2 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 3)
|
||||
+#define KVM_REG_LOONGARCH_LBT_SCR3 (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 4)
|
||||
+#define KVM_REG_LOONGARCH_LBT_EFLAGS (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 5)
|
||||
+#define KVM_REG_LOONGARCH_LBT_FTOP (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | 6)
|
||||
+
|
||||
#define LOONGARCH_REG_SHIFT 3
|
||||
#define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT))
|
||||
#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG)
|
||||
#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG)
|
||||
+
|
||||
+/* Device Control API on vm fd */
|
||||
+#define KVM_LOONGARCH_VM_FEAT_CTRL 0
|
||||
+#define KVM_LOONGARCH_VM_FEAT_LSX 0
|
||||
+#define KVM_LOONGARCH_VM_FEAT_LASX 1
|
||||
+#define KVM_LOONGARCH_VM_FEAT_X86BT 2
|
||||
+#define KVM_LOONGARCH_VM_FEAT_ARMBT 3
|
||||
+#define KVM_LOONGARCH_VM_FEAT_MIPSBT 4
|
||||
+#define KVM_LOONGARCH_VM_FEAT_PMU 5
|
||||
+#define KVM_LOONGARCH_VM_FEAT_PV_IPI 6
|
||||
+#define KVM_LOONGARCH_VM_FEAT_PV_STEALTIME 7
|
||||
+
|
||||
+/* Device Control API on vcpu fd */
|
||||
#define KVM_LOONGARCH_VCPU_CPUCFG 0
|
||||
#define KVM_LOONGARCH_VCPU_PVTIME_CTRL 1
|
||||
-#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0
|
||||
+#define KVM_LOONGARCH_VCPU_PVTIME_GPA 0
|
||||
|
||||
struct kvm_debug_exit_arch {
|
||||
};
|
||||
@@ -112,4 +135,15 @@ struct kvm_iocsr_entry {
|
||||
#define KVM_IRQCHIP_NUM_PINS 64
|
||||
#define KVM_MAX_CORES 256
|
||||
|
||||
+#define KVM_LOONGARCH_VM_HAVE_IRQCHIP 0x40000001
|
||||
+
|
||||
+#define KVM_DEV_LOONGARCH_IPI_GRP_REGS 0x40000002
|
||||
+
|
||||
+#define KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS 0x40000003
|
||||
+
|
||||
+#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL 0x40000004
|
||||
+#define KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT 0
|
||||
+
|
||||
+#define KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS 0x40000005
|
||||
+
|
||||
#endif /* __UAPI_ASM_LOONGARCH_KVM_H */
|
||||
diff --git a/linux-headers/asm-loongarch/unistd.h b/linux-headers/asm-loongarch/unistd.h
|
||||
index fcb668984f..b344b1f917 100644
|
||||
--- a/linux-headers/asm-loongarch/unistd.h
|
||||
+++ b/linux-headers/asm-loongarch/unistd.h
|
||||
@@ -1,4 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
+#define __ARCH_WANT_NEW_STAT
|
||||
#define __ARCH_WANT_SYS_CLONE
|
||||
#define __ARCH_WANT_SYS_CLONE3
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
235
target-loongarch-Add-TCG-macro-in-structure-CPUArchS.patch
Normal file
235
target-loongarch-Add-TCG-macro-in-structure-CPUArchS.patch
Normal file
@ -0,0 +1,235 @@
|
||||
From 033e2a67885cf7347473e09454a6704074e05878 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Mon, 6 May 2024 09:19:12 +0800
|
||||
Subject: [PATCH 42/78] target/loongarch: Add TCG macro in structure
|
||||
CPUArchState
|
||||
|
||||
In structure CPUArchState some struct elements are only used in TCG
|
||||
mode, and it is not used in KVM mode. Macro CONFIG_TCG is added to
|
||||
make it simpiler in KVM mode, also there is the same modification
|
||||
in c code when these structure elements are used.
|
||||
|
||||
When VM runs in KVM mode, TLB entries are not used and do not need
|
||||
migrate. It is only useful when it runs in TCG mode.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20240506011912.2108842-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 7 +++--
|
||||
target/loongarch/cpu.h | 16 +++++++----
|
||||
target/loongarch/cpu_helper.c | 9 ++++++
|
||||
target/loongarch/machine.c | 52 ++++++++++++++++++++++++-----------
|
||||
4 files changed, 60 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index f7b5dae7ed..220d40fb01 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -536,7 +536,9 @@ static void loongarch_cpu_reset_hold(Object *obj)
|
||||
lacc->parent_phases.hold(obj);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_TCG
|
||||
env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3;
|
||||
+#endif
|
||||
env->fcsr0 = 0x0;
|
||||
|
||||
int n;
|
||||
@@ -581,7 +583,9 @@ static void loongarch_cpu_reset_hold(Object *obj)
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
env->pc = 0x1c000000;
|
||||
+#ifdef CONFIG_TCG
|
||||
memset(env->tlb, 0, sizeof(env->tlb));
|
||||
+#endif
|
||||
if (kvm_enabled()) {
|
||||
kvm_arch_reset_vcpu(env);
|
||||
}
|
||||
@@ -778,8 +782,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||
int i;
|
||||
|
||||
qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
|
||||
- qemu_fprintf(f, " FCSR0 0x%08x fp_status 0x%02x\n", env->fcsr0,
|
||||
- get_float_exception_flags(&env->fp_status));
|
||||
+ qemu_fprintf(f, " FCSR0 0x%08x\n", env->fcsr0);
|
||||
|
||||
/* gpr */
|
||||
for (i = 0; i < 32; i++) {
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index e3a15c593f..19bcad28de 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -275,6 +275,7 @@ union fpr_t {
|
||||
VReg vreg;
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_TCG
|
||||
struct LoongArchTLB {
|
||||
uint64_t tlb_misc;
|
||||
/* Fields corresponding to CSR_TLBELO0/1 */
|
||||
@@ -282,23 +283,18 @@ struct LoongArchTLB {
|
||||
uint64_t tlb_entry1;
|
||||
};
|
||||
typedef struct LoongArchTLB LoongArchTLB;
|
||||
+#endif
|
||||
|
||||
typedef struct CPUArchState {
|
||||
uint64_t gpr[32];
|
||||
uint64_t pc;
|
||||
|
||||
fpr_t fpr[32];
|
||||
- float_status fp_status;
|
||||
bool cf[8];
|
||||
-
|
||||
uint32_t fcsr0;
|
||||
- uint32_t fcsr0_mask;
|
||||
|
||||
uint32_t cpucfg[21];
|
||||
|
||||
- uint64_t lladdr; /* LL virtual address compared against SC */
|
||||
- uint64_t llval;
|
||||
-
|
||||
/* LoongArch CSRs */
|
||||
uint64_t CSR_CRMD;
|
||||
uint64_t CSR_PRMD;
|
||||
@@ -355,8 +351,16 @@ typedef struct CPUArchState {
|
||||
uint64_t CSR_DERA;
|
||||
uint64_t CSR_DSAVE;
|
||||
|
||||
+#ifdef CONFIG_TCG
|
||||
+ float_status fp_status;
|
||||
+ uint32_t fcsr0_mask;
|
||||
+ uint64_t lladdr; /* LL virtual address compared against SC */
|
||||
+ uint64_t llval;
|
||||
+#endif
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
+#ifdef CONFIG_TCG
|
||||
LoongArchTLB tlb[LOONGARCH_TLB_MAX];
|
||||
+#endif
|
||||
|
||||
AddressSpace *address_space_iocsr;
|
||||
bool load_elf;
|
||||
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
|
||||
index f68d63f466..39037eecb4 100644
|
||||
--- a/target/loongarch/cpu_helper.c
|
||||
+++ b/target/loongarch/cpu_helper.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "internals.h"
|
||||
#include "cpu-csr.h"
|
||||
|
||||
+#ifdef CONFIG_TCG
|
||||
static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
|
||||
int *prot, target_ulong address,
|
||||
int access_type, int index, int mmu_idx)
|
||||
@@ -154,6 +155,14 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
|
||||
|
||||
return TLBRET_NOMATCH;
|
||||
}
|
||||
+#else
|
||||
+static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
|
||||
+ int *prot, target_ulong address,
|
||||
+ MMUAccessType access_type, int mmu_idx)
|
||||
+{
|
||||
+ return TLBRET_NOMATCH;
|
||||
+}
|
||||
+#endif
|
||||
|
||||
static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
|
||||
target_ulong dmw)
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index ec5abe56db..4bbf495d6b 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "migration/cpu.h"
|
||||
+#include "sysemu/tcg.h"
|
||||
#include "vec.h"
|
||||
#include "kvm/kvm_loongarch.h"
|
||||
#include "sysemu/kvm.h"
|
||||
@@ -111,19 +112,6 @@ static const VMStateDescription vmstate_lasx = {
|
||||
},
|
||||
};
|
||||
|
||||
-/* TLB state */
|
||||
-const VMStateDescription vmstate_tlb = {
|
||||
- .name = "cpu/tlb",
|
||||
- .version_id = 0,
|
||||
- .minimum_version_id = 0,
|
||||
- .fields = (VMStateField[]) {
|
||||
- VMSTATE_UINT64(tlb_misc, LoongArchTLB),
|
||||
- VMSTATE_UINT64(tlb_entry0, LoongArchTLB),
|
||||
- VMSTATE_UINT64(tlb_entry1, LoongArchTLB),
|
||||
- VMSTATE_END_OF_LIST()
|
||||
- }
|
||||
-};
|
||||
-
|
||||
static int cpu_post_load(void *opaque, int version_id)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
@@ -142,6 +130,38 @@ static int cpu_pre_save(void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
|
||||
+static bool tlb_needed(void *opaque)
|
||||
+{
|
||||
+ return tcg_enabled();
|
||||
+}
|
||||
+
|
||||
+/* TLB state */
|
||||
+static const VMStateDescription vmstate_tlb_entry = {
|
||||
+ .name = "cpu/tlb_entry",
|
||||
+ .version_id = 0,
|
||||
+ .minimum_version_id = 0,
|
||||
+ .fields = (VMStateField[]) {
|
||||
+ VMSTATE_UINT64(tlb_misc, LoongArchTLB),
|
||||
+ VMSTATE_UINT64(tlb_entry0, LoongArchTLB),
|
||||
+ VMSTATE_UINT64(tlb_entry1, LoongArchTLB),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static const VMStateDescription vmstate_tlb = {
|
||||
+ .name = "cpu/tlb",
|
||||
+ .version_id = 0,
|
||||
+ .minimum_version_id = 0,
|
||||
+ .needed = tlb_needed,
|
||||
+ .fields = (const VMStateField[]) {
|
||||
+ VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
|
||||
+ 0, vmstate_tlb_entry, LoongArchTLB),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ }
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
/* LoongArch CPU state */
|
||||
const VMStateDescription vmstate_loongarch_cpu = {
|
||||
.name = "cpu",
|
||||
@@ -212,9 +232,6 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU),
|
||||
VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
|
||||
VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
|
||||
- /* TLB */
|
||||
- VMSTATE_STRUCT_ARRAY(env.tlb, LoongArchCPU, LOONGARCH_TLB_MAX,
|
||||
- 0, vmstate_tlb, LoongArchTLB),
|
||||
|
||||
VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
|
||||
|
||||
@@ -224,6 +241,9 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
&vmstate_fpu,
|
||||
&vmstate_lsx,
|
||||
&vmstate_lasx,
|
||||
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
|
||||
+ &vmstate_tlb,
|
||||
+#endif
|
||||
NULL
|
||||
}
|
||||
};
|
||||
--
|
||||
2.39.1
|
||||
|
||||
51
target-loongarch-Add-compatible-support-about-VM-reb.patch
Normal file
51
target-loongarch-Add-compatible-support-about-VM-reb.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From 2c6cf54ea2f52774f2587e7e66eed9beba3a3dec Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Tue, 27 Aug 2024 11:58:07 +0800
|
||||
Subject: [PATCH 50/78] target/loongarch: Add compatible support about VM
|
||||
reboot
|
||||
|
||||
With edk2-stable202408 LoongArch UEFI bios, CSR PGD register is set only
|
||||
if its value is equal to zero for boot cpu, it causes reboot issue. Since
|
||||
CSR PGD register is changed with linux kernel, UEFI BIOS cannot use it.
|
||||
|
||||
Add workaround to clear CSR registers relative with TLB in function
|
||||
loongarch_cpu_reset_hold(), so that VM can reboot with edk2-stable202408
|
||||
UEFI bios.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240827035807.3326293-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 14 ++++++++++++++
|
||||
1 file changed, 14 insertions(+)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index d8a31929b4..2038984d02 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -580,6 +580,20 @@ static void loongarch_cpu_reset_hold(Object *obj)
|
||||
env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0);
|
||||
env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
|
||||
env->CSR_TID = cs->cpu_index;
|
||||
+ /*
|
||||
+ * Workaround for edk2-stable202408, CSR PGD register is set only if
|
||||
+ * its value is equal to zero for boot cpu, it causes reboot issue.
|
||||
+ *
|
||||
+ * Here clear CSR registers relative with TLB.
|
||||
+ */
|
||||
+ env->CSR_PGDH = 0;
|
||||
+ env->CSR_PGDL = 0;
|
||||
+ env->CSR_PWCL = 0;
|
||||
+ env->CSR_PWCH = 0;
|
||||
+ env->CSR_STLBPS = 0;
|
||||
+ env->CSR_EENTRY = 0;
|
||||
+ env->CSR_TLBRENTRY = 0;
|
||||
+ env->CSR_MERRENTRY = 0;
|
||||
|
||||
for (n = 0; n < 4; n++) {
|
||||
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
46
target-loongarch-Add-loongarch-vector-property-uncon.patch
Normal file
46
target-loongarch-Add-loongarch-vector-property-uncon.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From f572c385e0d368cbf12acf7d6f0b33b5f2efd7f0 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Tue, 21 May 2024 16:05:48 +0800
|
||||
Subject: [PATCH 45/78] target/loongarch: Add loongarch vector property
|
||||
unconditionally
|
||||
|
||||
Currently LSX/LASX vector property is decided by the default value.
|
||||
Instead vector property should be added unconditionally, and it is
|
||||
irrelative with its default value. If vector is disabled by default,
|
||||
vector also can be enabled from command line.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240521080549.434197-2-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 12 ++++--------
|
||||
1 file changed, 4 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index 220d40fb01..f89740a5aa 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -720,14 +720,10 @@ void loongarch_cpu_post_init(Object *obj)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
|
||||
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
|
||||
- object_property_add_bool(obj, "lsx", loongarch_get_lsx,
|
||||
- loongarch_set_lsx);
|
||||
- }
|
||||
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
|
||||
- object_property_add_bool(obj, "lasx", loongarch_get_lasx,
|
||||
- loongarch_set_lasx);
|
||||
- }
|
||||
+ object_property_add_bool(obj, "lsx", loongarch_get_lsx,
|
||||
+ loongarch_set_lsx);
|
||||
+ object_property_add_bool(obj, "lasx", loongarch_get_lasx,
|
||||
+ loongarch_set_lasx);
|
||||
|
||||
if (kvm_enabled()) {
|
||||
object_property_add_bool(obj, "pmu", loongarch_get_pmu,
|
||||
--
|
||||
2.39.1
|
||||
|
||||
200
target-loongarch-Add-loongson-binary-translation-fea.patch
Normal file
200
target-loongarch-Add-loongson-binary-translation-fea.patch
Normal file
@ -0,0 +1,200 @@
|
||||
From 962f649aa5a06169f0ac23f61e273f0860942ebb Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Sun, 29 Sep 2024 15:04:04 +0800
|
||||
Subject: [PATCH 57/78] target/loongarch: Add loongson binary translation
|
||||
feature
|
||||
|
||||
Loongson Binary Translation (LBT) is used to accelerate binary
|
||||
translation, which contains 4 scratch registers (scr0 to scr3), x86/ARM
|
||||
eflags (eflags) and x87 fpu stack pointer (ftop).
|
||||
|
||||
Now LBT feature is added in kvm mode, not supported in TCG mode since
|
||||
it is not emulated. Feature variable lbt is added with OnOffAuto type,
|
||||
If lbt feature is not supported with KVM host, it reports error if there
|
||||
is lbt=on command line.
|
||||
|
||||
If there is no any command line about lbt parameter, it checks whether
|
||||
KVM host supports lbt feature and set the corresponding value in cpucfg.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240929070405.235200-2-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 20 ++++++++++
|
||||
target/loongarch/cpu.h | 6 +++
|
||||
target/loongarch/kvm/kvm.c | 57 ++++++++++++++++++++++++++-
|
||||
target/loongarch/loongarch-qmp-cmds.c | 2 +-
|
||||
4 files changed, 83 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index d6a13de901..a57067938d 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -737,6 +737,18 @@ static void loongarch_set_pmnum(Object *obj, Visitor *v,
|
||||
}
|
||||
}
|
||||
|
||||
+static bool loongarch_get_lbt(Object *obj, Error **errp)
|
||||
+{
|
||||
+ return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF;
|
||||
+}
|
||||
+
|
||||
+static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
+
|
||||
+ cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
|
||||
+}
|
||||
+
|
||||
void loongarch_cpu_post_init(Object *obj)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
@@ -756,6 +768,14 @@ void loongarch_cpu_post_init(Object *obj)
|
||||
loongarch_set_pmnum, NULL,
|
||||
(void *)&value);
|
||||
}
|
||||
+
|
||||
+ cpu->lbt = ON_OFF_AUTO_AUTO;
|
||||
+ object_property_add_bool(obj, "lbt", loongarch_get_lbt,
|
||||
+ loongarch_set_lbt);
|
||||
+ object_property_set_description(obj, "lbt",
|
||||
+ "Set off to disable Binary Tranlation.");
|
||||
+ } else {
|
||||
+ cpu->lbt = ON_OFF_AUTO_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 19bcad28de..3e2bcbf608 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -155,6 +155,7 @@ FIELD(CPUCFG2, LLFTP_VER, 15, 3)
|
||||
FIELD(CPUCFG2, LBT_X86, 18, 1)
|
||||
FIELD(CPUCFG2, LBT_ARM, 19, 1)
|
||||
FIELD(CPUCFG2, LBT_MIPS, 20, 1)
|
||||
+FIELD(CPUCFG2, LBT_ALL, 18, 3)
|
||||
FIELD(CPUCFG2, LSPW, 21, 1)
|
||||
FIELD(CPUCFG2, LAM, 22, 1)
|
||||
|
||||
@@ -285,6 +286,10 @@ struct LoongArchTLB {
|
||||
typedef struct LoongArchTLB LoongArchTLB;
|
||||
#endif
|
||||
|
||||
+enum loongarch_features {
|
||||
+ LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
|
||||
+};
|
||||
+
|
||||
typedef struct CPUArchState {
|
||||
uint64_t gpr[32];
|
||||
uint64_t pc;
|
||||
@@ -388,6 +393,7 @@ struct ArchCPU {
|
||||
CPULoongArchState env;
|
||||
QEMUTimer timer;
|
||||
uint32_t phy_id;
|
||||
+ OnOffAuto lbt;
|
||||
|
||||
/* 'compatible' string for this CPU for Linux device trees */
|
||||
const char *dtb_compatible;
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 90c8379c46..567404bdb5 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/kvm.h>
|
||||
|
||||
+#include "qapi/error.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/main-loop.h"
|
||||
@@ -786,17 +787,71 @@ static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
|
||||
}
|
||||
}
|
||||
|
||||
+static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct kvm_device_attr attr;
|
||||
+
|
||||
+ switch (feature) {
|
||||
+ case LOONGARCH_FEATURE_LBT:
|
||||
+ /*
|
||||
+ * Return all if all the LBT features are supported such as:
|
||||
+ * KVM_LOONGARCH_VM_FEAT_X86BT
|
||||
+ * KVM_LOONGARCH_VM_FEAT_ARMBT
|
||||
+ * KVM_LOONGARCH_VM_FEAT_MIPSBT
|
||||
+ */
|
||||
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
|
||||
+ attr.attr = KVM_LOONGARCH_VM_FEAT_X86BT;
|
||||
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
+ attr.attr = KVM_LOONGARCH_VM_FEAT_ARMBT;
|
||||
+ ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
+ attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT;
|
||||
+ ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
+ return (ret == 0);
|
||||
+ default:
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
|
||||
+{
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
+ bool kvm_supported;
|
||||
+
|
||||
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);
|
||||
+ if (cpu->lbt == ON_OFF_AUTO_ON) {
|
||||
+ if (kvm_supported) {
|
||||
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LBT_ALL, 7);
|
||||
+ } else {
|
||||
+ error_setg(errp, "'lbt' feature not supported by KVM on this host");
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
+ } else if ((cpu->lbt == ON_OFF_AUTO_AUTO) && kvm_supported) {
|
||||
+ env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LBT_ALL, 7);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
{
|
||||
uint64_t val;
|
||||
+ int ret;
|
||||
+ Error *local_err = NULL;
|
||||
|
||||
+ ret = 0;
|
||||
qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
|
||||
|
||||
if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
|
||||
brk_insn = val;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ ret = kvm_cpu_check_lbt(cs, &local_err);
|
||||
+ if (ret < 0) {
|
||||
+ error_report_err(local_err);
|
||||
+ }
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
int kvm_arch_destroy_vcpu(CPUState *cs)
|
||||
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
|
||||
index 2612f43de9..644b528824 100644
|
||||
--- a/target/loongarch/loongarch-qmp-cmds.c
|
||||
+++ b/target/loongarch/loongarch-qmp-cmds.c
|
||||
@@ -42,7 +42,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
|
||||
}
|
||||
|
||||
static const char *cpu_model_advertised_features[] = {
|
||||
- "lsx", "lasx", "pmu", "pmnum", NULL
|
||||
+ "lsx", "lasx", "lbt", "pmu", "pmnum", NULL
|
||||
};
|
||||
|
||||
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
--
|
||||
2.39.1
|
||||
|
||||
151
target-loongarch-Add-steal-time-support-on-migration.patch
Normal file
151
target-loongarch-Add-steal-time-support-on-migration.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 8febab6bcb01e3e10ca4ac0021bae2a812a4452b Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Mon, 30 Sep 2024 14:40:40 +0800
|
||||
Subject: [PATCH 61/78] target/loongarch: Add steal time support on migration
|
||||
|
||||
With pv steal time supported, VM machine needs get physical address
|
||||
of each vcpu and notify new host during migration. Here two
|
||||
functions kvm_get_stealtime/kvm_set_stealtime, and guest steal time
|
||||
physical address is only updated on KVM_PUT_FULL_STATE stage.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-ID: <20240930064040.753929-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.h | 3 ++
|
||||
target/loongarch/kvm/kvm.c | 65 ++++++++++++++++++++++++++++++++++++++
|
||||
target/loongarch/machine.c | 6 ++--
|
||||
3 files changed, 72 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 8ff00d17e1..4c90cf9ef3 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -369,6 +369,9 @@ typedef struct CPUArchState {
|
||||
uint64_t CSR_DBG;
|
||||
uint64_t CSR_DERA;
|
||||
uint64_t CSR_DSAVE;
|
||||
+ struct {
|
||||
+ uint64_t guest_addr;
|
||||
+ } stealtime;
|
||||
|
||||
#ifdef CONFIG_TCG
|
||||
float_status fp_status;
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 8b0f86a201..550f14269e 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -35,6 +35,55 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
|
||||
KVM_CAP_LAST_INFO
|
||||
};
|
||||
|
||||
+static int kvm_get_stealtime(CPUState *cs)
|
||||
+{
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+ int err;
|
||||
+ struct kvm_device_attr attr = {
|
||||
+ .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
|
||||
+ .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
|
||||
+ .addr = (uint64_t)&env->stealtime.guest_addr,
|
||||
+ };
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
|
||||
+ if (err) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, attr);
|
||||
+ if (err) {
|
||||
+ error_report("PVTIME: KVM_GET_DEVICE_ATTR: %s", strerror(errno));
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int kvm_set_stealtime(CPUState *cs)
|
||||
+{
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+ int err;
|
||||
+ struct kvm_device_attr attr = {
|
||||
+ .group = KVM_LOONGARCH_VCPU_PVTIME_CTRL,
|
||||
+ .attr = KVM_LOONGARCH_VCPU_PVTIME_GPA,
|
||||
+ .addr = (uint64_t)&env->stealtime.guest_addr,
|
||||
+ };
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr);
|
||||
+ if (err) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, attr);
|
||||
+ if (err) {
|
||||
+ error_report("PVTIME: KVM_SET_DEVICE_ATTR %s with gpa "TARGET_FMT_lx,
|
||||
+ strerror(errno), env->stealtime.guest_addr);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int kvm_loongarch_get_regs_core(CPUState *cs)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -790,6 +839,11 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = kvm_get_stealtime(cs);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ret = kvm_loongarch_get_mpstate(cs);
|
||||
return ret;
|
||||
}
|
||||
@@ -823,6 +877,17 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ if (level >= KVM_PUT_FULL_STATE) {
|
||||
+ /*
|
||||
+ * only KVM_PUT_FULL_STATE is required, kvm kernel will clear
|
||||
+ * guest_addr for KVM_PUT_RESET_STATE
|
||||
+ */
|
||||
+ ret = kvm_set_stealtime(cs);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = kvm_loongarch_put_mpstate(cs);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index 5d62aabd51..fd69ea05dc 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -188,8 +188,8 @@ static const VMStateDescription vmstate_tlb = {
|
||||
/* LoongArch CPU state */
|
||||
const VMStateDescription vmstate_loongarch_cpu = {
|
||||
.name = "cpu",
|
||||
- .version_id = 2,
|
||||
- .minimum_version_id = 2,
|
||||
+ .version_id = 3,
|
||||
+ .minimum_version_id = 3,
|
||||
.post_load = cpu_post_load,
|
||||
.pre_save = cpu_pre_save,
|
||||
.fields = (const VMStateField[]) {
|
||||
@@ -257,6 +257,8 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
|
||||
|
||||
VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
|
||||
+ /* PV steal time */
|
||||
+ VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
--
|
||||
2.39.1
|
||||
|
||||
42
target-loongarch-Avoid-bits-shift-exceeding-width-of.patch
Normal file
42
target-loongarch-Avoid-bits-shift-exceeding-width-of.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From fa79379bd4c5b72e11f14f24439d5d501b8cc98b Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Sat, 14 Sep 2024 14:46:45 +0800
|
||||
Subject: [PATCH 55/78] target/loongarch: Avoid bits shift exceeding width of
|
||||
bool type
|
||||
|
||||
Variable env->cf[i] is defined as bool type, it is treated as int type
|
||||
with shift operation. However the max possible width is 56 for the shift
|
||||
operation, exceeding the width of int type. And there is existing api
|
||||
read_fcc() which is converted to u64 type with bitwise shift, it can be
|
||||
used to dump fp registers into coredump note segment.
|
||||
|
||||
Resolves: Coverity CID 1561133
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20240914064645.2099169-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/arch_dump.c | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c
|
||||
index 4986db970e..d9e1120333 100644
|
||||
--- a/target/loongarch/arch_dump.c
|
||||
+++ b/target/loongarch/arch_dump.c
|
||||
@@ -97,11 +97,7 @@ static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f,
|
||||
|
||||
loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu));
|
||||
note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0);
|
||||
-
|
||||
- for (i = 0; i < 8; i++) {
|
||||
- note.fpu.fcc |= env->cf[i] << (8 * i);
|
||||
- }
|
||||
- note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc);
|
||||
+ note.fpu.fcc = cpu_to_dump64(s, read_fcc(env));
|
||||
|
||||
for (i = 0; i < 32; ++i) {
|
||||
note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
42
target-loongarch-Fix-cpu_reset-set-wrong-CSR_CRMD.patch
Normal file
42
target-loongarch-Fix-cpu_reset-set-wrong-CSR_CRMD.patch
Normal file
@ -0,0 +1,42 @@
|
||||
From d909e6bfef50fc67708358e455a3b53d869249e6 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 5 Jul 2024 10:18:39 +0800
|
||||
Subject: [PATCH 49/78] target/loongarch: Fix cpu_reset set wrong CSR_CRMD
|
||||
|
||||
After cpu_reset, DATF in CSR_CRMD is 0, DATM is 0.
|
||||
See the manual[1] 6.4.
|
||||
|
||||
[1]: https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/LoongArch-Vol1-v1.10-EN.pdf
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240705021839.1004374-2-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index 5bb9e5656a..d8a31929b4 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -554,13 +554,13 @@ static void loongarch_cpu_reset_hold(Object *obj)
|
||||
env->fcsr0 = 0x0;
|
||||
|
||||
int n;
|
||||
- /* Set csr registers value after reset */
|
||||
+ /* Set csr registers value after reset, see the manual 6.4. */
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1);
|
||||
env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0);
|
||||
- env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 1);
|
||||
- env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 1);
|
||||
+ env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0);
|
||||
+ env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0);
|
||||
|
||||
env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0);
|
||||
env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
191
target-loongarch-Implement-lbt-registers-save-restor.patch
Normal file
191
target-loongarch-Implement-lbt-registers-save-restor.patch
Normal file
@ -0,0 +1,191 @@
|
||||
From a7b08284143f7ace3635036bf0366cbec4d52c99 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Sun, 29 Sep 2024 15:04:05 +0800
|
||||
Subject: [PATCH 58/78] target/loongarch: Implement lbt registers save/restore
|
||||
function
|
||||
|
||||
Six registers scr0 - scr3, eflags and ftop are added in percpu vmstate.
|
||||
And two functions kvm_loongarch_get_lbt/kvm_loongarch_put_lbt are added
|
||||
to save/restore lbt registers.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240929070405.235200-3-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.h | 13 ++++++++
|
||||
target/loongarch/kvm/kvm.c | 62 ++++++++++++++++++++++++++++++++++++++
|
||||
target/loongarch/machine.c | 24 +++++++++++++++
|
||||
3 files changed, 99 insertions(+)
|
||||
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 3e2bcbf608..2f8c5cf2dd 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -18,6 +18,7 @@
|
||||
#endif
|
||||
#include "cpu-csr.h"
|
||||
#include "cpu-qom.h"
|
||||
+#include "qapi/qapi-types-common.h"
|
||||
|
||||
#define IOCSRF_TEMP 0
|
||||
#define IOCSRF_NODECNT 1
|
||||
@@ -290,6 +291,17 @@ enum loongarch_features {
|
||||
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
|
||||
};
|
||||
|
||||
+typedef struct LoongArchBT {
|
||||
+ /* scratch registers */
|
||||
+ uint64_t scr0;
|
||||
+ uint64_t scr1;
|
||||
+ uint64_t scr2;
|
||||
+ uint64_t scr3;
|
||||
+ /* loongarch eflags */
|
||||
+ uint32_t eflags;
|
||||
+ uint32_t ftop;
|
||||
+} lbt_t;
|
||||
+
|
||||
typedef struct CPUArchState {
|
||||
uint64_t gpr[32];
|
||||
uint64_t pc;
|
||||
@@ -297,6 +309,7 @@ typedef struct CPUArchState {
|
||||
fpr_t fpr[32];
|
||||
bool cf[8];
|
||||
uint32_t fcsr0;
|
||||
+ lbt_t lbt;
|
||||
|
||||
uint32_t cpucfg[21];
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 567404bdb5..118f66f742 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -486,6 +486,58 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int kvm_loongarch_put_lbt(CPUState *cs)
|
||||
+{
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+ uint64_t val;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* check whether vm support LBT firstly */
|
||||
+ if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* set six LBT registers including scr0-scr3, eflags, ftop */
|
||||
+ ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0);
|
||||
+ ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1);
|
||||
+ ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2);
|
||||
+ ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3);
|
||||
+ /*
|
||||
+ * Be cautious, KVM_REG_LOONGARCH_LBT_FTOP is defined as 64-bit however
|
||||
+ * lbt.ftop is 32-bit; the same with KVM_REG_LOONGARCH_LBT_EFLAGS register
|
||||
+ */
|
||||
+ val = env->lbt.eflags;
|
||||
+ ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val);
|
||||
+ val = env->lbt.ftop;
|
||||
+ ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int kvm_loongarch_get_lbt(CPUState *cs)
|
||||
+{
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+ uint64_t val;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* check whether vm support LBT firstly */
|
||||
+ if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* get six LBT registers including scr0-scr3, eflags, ftop */
|
||||
+ ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0);
|
||||
+ ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1);
|
||||
+ ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2);
|
||||
+ ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3);
|
||||
+ ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val);
|
||||
+ env->lbt.eflags = (uint32_t)val;
|
||||
+ ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val);
|
||||
+ env->lbt.ftop = (uint32_t)val;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void kvm_arch_reset_vcpu(CPUState *cs)
|
||||
{
|
||||
CPULoongArchState *env = cpu_env(cs);
|
||||
@@ -733,6 +785,11 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = kvm_loongarch_get_lbt(cs);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ret = kvm_loongarch_get_mpstate(cs);
|
||||
return ret;
|
||||
}
|
||||
@@ -761,6 +818,11 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ ret = kvm_loongarch_put_lbt(cs);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
ret = kvm_loongarch_put_mpstate(cs);
|
||||
return ret;
|
||||
}
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index 97e1152ffd..5d62aabd51 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -130,6 +130,29 @@ static int cpu_pre_save(void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool lbt_needed(void *opaque)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = opaque;
|
||||
+
|
||||
+ return !!FIELD_EX64(cpu->env.cpucfg[2], CPUCFG2, LBT_ALL);
|
||||
+}
|
||||
+
|
||||
+static const VMStateDescription vmstate_lbt = {
|
||||
+ .name = "cpu/lbt",
|
||||
+ .version_id = 0,
|
||||
+ .minimum_version_id = 0,
|
||||
+ .needed = lbt_needed,
|
||||
+ .fields = (const VMStateField[]) {
|
||||
+ VMSTATE_UINT64(env.lbt.scr0, LoongArchCPU),
|
||||
+ VMSTATE_UINT64(env.lbt.scr1, LoongArchCPU),
|
||||
+ VMSTATE_UINT64(env.lbt.scr2, LoongArchCPU),
|
||||
+ VMSTATE_UINT64(env.lbt.scr3, LoongArchCPU),
|
||||
+ VMSTATE_UINT32(env.lbt.eflags, LoongArchCPU),
|
||||
+ VMSTATE_UINT32(env.lbt.ftop, LoongArchCPU),
|
||||
+ VMSTATE_END_OF_LIST()
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
|
||||
static bool tlb_needed(void *opaque)
|
||||
{
|
||||
@@ -244,6 +267,7 @@ const VMStateDescription vmstate_loongarch_cpu = {
|
||||
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
|
||||
&vmstate_tlb,
|
||||
#endif
|
||||
+ &vmstate_lbt,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
--
|
||||
2.39.1
|
||||
|
||||
81
target-loongarch-Put-cpucfg-operation-before-CSR-reg.patch
Normal file
81
target-loongarch-Put-cpucfg-operation-before-CSR-reg.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From 717faefc8f56490ad94ef69b42c2d2491225ace8 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Sun, 28 Apr 2024 11:16:51 +0800
|
||||
Subject: [PATCH 43/78] target/loongarch: Put cpucfg operation before CSR
|
||||
register
|
||||
|
||||
On Loongarch, cpucfg is register for cpu feature, some other registers
|
||||
depend on cpucfg feature such as perf CSR registers. Here put cpucfg
|
||||
read/write operations before CSR register, so that KVM knows how many
|
||||
perf CSR registers are valid from pre-set cpucfg feature information.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240428031651.1354587-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/kvm/kvm.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 5c88270132..407d454919 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -714,22 +714,22 @@ int kvm_arch_get_registers(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_get_csr(cs);
|
||||
+ ret = kvm_loongarch_get_cpucfg(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_get_regs_fp(cs);
|
||||
+ ret = kvm_loongarch_get_csr(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_get_mpstate(cs);
|
||||
+ ret = kvm_loongarch_get_regs_fp(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_get_cpucfg(cs);
|
||||
+ ret = kvm_loongarch_get_mpstate(cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -742,22 +742,22 @@ int kvm_arch_put_registers(CPUState *cs, int level)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_put_csr(cs, level);
|
||||
+ ret = kvm_loongarch_put_cpucfg(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_put_regs_fp(cs);
|
||||
+ ret = kvm_loongarch_put_csr(cs, level);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_put_mpstate(cs);
|
||||
+ ret = kvm_loongarch_put_regs_fp(cs);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = kvm_loongarch_put_cpucfg(cs);
|
||||
+ ret = kvm_loongarch_put_mpstate(cs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
56
target-loongarch-Remove-avail_64-in-trans_srai_w-and.patch
Normal file
56
target-loongarch-Remove-avail_64-in-trans_srai_w-and.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 3b3fdfa6d5439298b883e2e223fa04a2209612f5 Mon Sep 17 00:00:00 2001
|
||||
From: Feiyang Chen <chris.chenfeiyang@gmail.com>
|
||||
Date: Fri, 28 Jun 2024 13:33:57 +1000
|
||||
Subject: [PATCH 47/78] target/loongarch: Remove avail_64 in trans_srai_w() and
|
||||
simplify it
|
||||
|
||||
Since srai.w is a valid instruction on la32, remove the avail_64 check
|
||||
and simplify trans_srai_w().
|
||||
|
||||
Fixes: c0c0461e3a06 ("target/loongarch: Add avail_64 to check la64-only instructions")
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Signed-off-by: Feiyang Chen <chris.chenfeiyang@gmail.com>
|
||||
Message-Id: <20240628033357.50027-1-chris.chenfeiyang@gmail.com>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/tcg/insn_trans/trans_shift.c.inc | 15 +++------------
|
||||
1 file changed, 3 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/tcg/insn_trans/trans_shift.c.inc b/target/loongarch/tcg/insn_trans/trans_shift.c.inc
|
||||
index 2f4bd6ff28..377307785a 100644
|
||||
--- a/target/loongarch/tcg/insn_trans/trans_shift.c.inc
|
||||
+++ b/target/loongarch/tcg/insn_trans/trans_shift.c.inc
|
||||
@@ -67,19 +67,9 @@ static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2)
|
||||
tcg_gen_rotr_tl(dest, src1, t0);
|
||||
}
|
||||
|
||||
-static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a)
|
||||
+static void gen_sari_w(TCGv dest, TCGv src1, target_long imm)
|
||||
{
|
||||
- TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
|
||||
- TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO);
|
||||
-
|
||||
- if (!avail_64(ctx)) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm);
|
||||
- gen_set_gpr(a->rd, dest, EXT_NONE);
|
||||
-
|
||||
- return true;
|
||||
+ tcg_gen_sextract_tl(dest, src1, imm, 32 - imm);
|
||||
}
|
||||
|
||||
TRANS(sll_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w)
|
||||
@@ -94,6 +84,7 @@ TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl)
|
||||
TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl)
|
||||
TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl)
|
||||
TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl)
|
||||
+TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w)
|
||||
TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl)
|
||||
TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
|
||||
TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl)
|
||||
--
|
||||
2.39.1
|
||||
|
||||
55
target-loongarch-Set-CSR_PRCFG1-and-CSR_PRCFG2-value.patch
Normal file
55
target-loongarch-Set-CSR_PRCFG1-and-CSR_PRCFG2-value.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From f677a8f2311e823a87ec70dbdbc07712d54e5a85 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Fri, 5 Jul 2024 10:18:38 +0800
|
||||
Subject: [PATCH 48/78] target/loongarch: Set CSR_PRCFG1 and CSR_PRCFG2 values
|
||||
|
||||
We set the value of register CSR_PRCFG3, but left out CSR_PRCFG1
|
||||
and CSR_PRCFG2. Set CSR_PRCFG1 and CSR_PRCFG2 according to the
|
||||
default values of the physical machine.
|
||||
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Message-Id: <20240705021839.1004374-1-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 17 ++++++++++++-----
|
||||
1 file changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index f89740a5aa..5bb9e5656a 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -472,6 +472,18 @@ static void loongarch_la464_initfn(Object *obj)
|
||||
env->cpucfg[20] = data;
|
||||
|
||||
env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
|
||||
+
|
||||
+ env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8);
|
||||
+ env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f);
|
||||
+ env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
|
||||
+
|
||||
+ env->CSR_PRCFG2 = 0x3ffff000;
|
||||
+
|
||||
+ env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
|
||||
+ env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
|
||||
+ env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
|
||||
+ env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
|
||||
+
|
||||
loongarch_cpu_post_init(obj);
|
||||
}
|
||||
|
||||
@@ -569,11 +581,6 @@ static void loongarch_cpu_reset_hold(Object *obj)
|
||||
env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0);
|
||||
env->CSR_TID = cs->cpu_index;
|
||||
|
||||
- env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2);
|
||||
- env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63);
|
||||
- env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
|
||||
- env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
|
||||
-
|
||||
for (n = 0; n < 4; n++) {
|
||||
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
|
||||
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);
|
||||
--
|
||||
2.39.1
|
||||
|
||||
237
target-loongarch-Support-QMP-dump-guest-memory.patch
Normal file
237
target-loongarch-Support-QMP-dump-guest-memory.patch
Normal file
@ -0,0 +1,237 @@
|
||||
From 2f19b259a16985ce515727c819c3a7eb4f41e6d0 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Thu, 22 Aug 2024 14:52:45 +0800
|
||||
Subject: [PATCH 52/78] target/loongarch: Support QMP dump-guest-memory
|
||||
|
||||
Add the support needed for creating prstatus elf notes. This allows
|
||||
us to use QMP dump-guest-memory.
|
||||
|
||||
Now ELF notes of LoongArch only supports general elf notes, LSX and
|
||||
LASX is not supported, since it is mainly used to dump guest memory.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Tested-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240822065245.2286214-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/arch_dump.c | 167 +++++++++++++++++++++++++++++++++++
|
||||
target/loongarch/cpu.c | 1 +
|
||||
target/loongarch/internals.h | 2 +
|
||||
target/loongarch/meson.build | 1 +
|
||||
4 files changed, 171 insertions(+)
|
||||
create mode 100644 target/loongarch/arch_dump.c
|
||||
|
||||
diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c
|
||||
new file mode 100644
|
||||
index 0000000000..4986db970e
|
||||
--- /dev/null
|
||||
+++ b/target/loongarch/arch_dump.c
|
||||
@@ -0,0 +1,167 @@
|
||||
+/*
|
||||
+ * Support for writing ELF notes for LoongArch architectures
|
||||
+ *
|
||||
+ * Copyright (c) 2023 Loongarch Technology
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms and conditions of the GNU General Public License,
|
||||
+ * version 2 or later, as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope it will be useful, but WITHOUT
|
||||
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
+ * more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License along with
|
||||
+ * this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "cpu.h"
|
||||
+#include "elf.h"
|
||||
+#include "sysemu/dump.h"
|
||||
+#include "internals.h"
|
||||
+
|
||||
+/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */
|
||||
+struct loongarch_user_regs {
|
||||
+ uint64_t gpr[32];
|
||||
+ uint64_t pad1[1];
|
||||
+ /* Special CSR registers. */
|
||||
+ uint64_t csr_era;
|
||||
+ uint64_t csr_badv;
|
||||
+ uint64_t pad2[10];
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360);
|
||||
+
|
||||
+/* struct elf_prstatus from include/uapi/linux/elfcore.h */
|
||||
+struct loongarch_elf_prstatus {
|
||||
+ char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */
|
||||
+ uint32_t pr_pid;
|
||||
+ /*
|
||||
+ * 76 == offsetof(struct elf_prstatus, pr_reg) -
|
||||
+ * offsetof(struct elf_prstatus, pr_ppid)
|
||||
+ */
|
||||
+ char pad2[76];
|
||||
+ struct loongarch_user_regs pr_reg;
|
||||
+ uint32_t pr_fpvalid;
|
||||
+ char pad3[4];
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480);
|
||||
+
|
||||
+/* struct user_fp_state from arch/loongarch/include/uapi/asm/ptrace.h */
|
||||
+struct loongarch_fpu_struct {
|
||||
+ uint64_t fpr[32];
|
||||
+ uint64_t fcc;
|
||||
+ unsigned int fcsr;
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 268);
|
||||
+
|
||||
+struct loongarch_note {
|
||||
+ Elf64_Nhdr hdr;
|
||||
+ char name[8]; /* align_up(sizeof("CORE"), 4) */
|
||||
+ union {
|
||||
+ struct loongarch_elf_prstatus prstatus;
|
||||
+ struct loongarch_fpu_struct fpu;
|
||||
+ };
|
||||
+} QEMU_PACKED;
|
||||
+
|
||||
+#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus)
|
||||
+#define LOONGARCH_PRSTATUS_NOTE_SIZE \
|
||||
+ (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_elf_prstatus))
|
||||
+#define LOONGARCH_PRFPREG_NOTE_SIZE \
|
||||
+ (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_fpu_struct))
|
||||
+
|
||||
+static void loongarch_note_init(struct loongarch_note *note, DumpState *s,
|
||||
+ const char *name, Elf64_Word namesz,
|
||||
+ Elf64_Word type, Elf64_Word descsz)
|
||||
+{
|
||||
+ memset(note, 0, sizeof(*note));
|
||||
+
|
||||
+ note->hdr.n_namesz = cpu_to_dump32(s, namesz);
|
||||
+ note->hdr.n_descsz = cpu_to_dump32(s, descsz);
|
||||
+ note->hdr.n_type = cpu_to_dump32(s, type);
|
||||
+
|
||||
+ memcpy(note->name, name, namesz);
|
||||
+}
|
||||
+
|
||||
+static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f,
|
||||
+ CPULoongArchState *env, int cpuid,
|
||||
+ DumpState *s)
|
||||
+{
|
||||
+ struct loongarch_note note;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ loongarch_note_init(¬e, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu));
|
||||
+ note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0);
|
||||
+
|
||||
+ for (i = 0; i < 8; i++) {
|
||||
+ note.fpu.fcc |= env->cf[i] << (8 * i);
|
||||
+ }
|
||||
+ note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc);
|
||||
+
|
||||
+ for (i = 0; i < 32; ++i) {
|
||||
+ note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]);
|
||||
+ }
|
||||
+
|
||||
+ ret = f(¬e, LOONGARCH_PRFPREG_NOTE_SIZE, s);
|
||||
+ if (ret < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
|
||||
+ int cpuid, DumpState *s)
|
||||
+{
|
||||
+ struct loongarch_note note;
|
||||
+ CPULoongArchState *env = &LOONGARCH_CPU(cs)->env;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS,
|
||||
+ sizeof(note.prstatus));
|
||||
+ note.prstatus.pr_pid = cpu_to_dump32(s, cpuid);
|
||||
+ note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1);
|
||||
+
|
||||
+ for (i = 0; i < 32; ++i) {
|
||||
+ note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->gpr[i]);
|
||||
+ }
|
||||
+ note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA);
|
||||
+ note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, env->CSR_BADV);
|
||||
+ ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s);
|
||||
+ if (ret < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s);
|
||||
+ if (ret < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int cpu_get_dump_info(ArchDumpInfo *info,
|
||||
+ const GuestPhysBlockList *guest_phys_blocks)
|
||||
+{
|
||||
+ info->d_machine = EM_LOONGARCH;
|
||||
+ info->d_endian = ELFDATA2LSB;
|
||||
+ info->d_class = ELFCLASS64;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
|
||||
+{
|
||||
+ size_t note_size = 0;
|
||||
+
|
||||
+ if (class == ELFCLASS64) {
|
||||
+ note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE;
|
||||
+ }
|
||||
+
|
||||
+ return note_size * nr_cpus;
|
||||
+}
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index 63d1f65608..d6a13de901 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -861,6 +861,7 @@ static struct TCGCPUOps loongarch_tcg_ops = {
|
||||
#include "hw/core/sysemu-cpu-ops.h"
|
||||
|
||||
static const struct SysemuCPUOps loongarch_sysemu_ops = {
|
||||
+ .write_elf64_note = loongarch_cpu_write_elf64_note,
|
||||
.get_phys_page_debug = loongarch_cpu_get_phys_page_debug,
|
||||
};
|
||||
|
||||
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
|
||||
index 944153b180..1a02427627 100644
|
||||
--- a/target/loongarch/internals.h
|
||||
+++ b/target/loongarch/internals.h
|
||||
@@ -72,5 +72,7 @@ void write_fcc(CPULoongArchState *env, uint64_t val);
|
||||
int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n);
|
||||
int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n);
|
||||
void loongarch_cpu_register_gdb_regs_for_features(CPUState *cs);
|
||||
+int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
|
||||
+ int cpuid, DumpState *s);
|
||||
|
||||
#endif
|
||||
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
|
||||
index e002e9aaf6..7817318287 100644
|
||||
--- a/target/loongarch/meson.build
|
||||
+++ b/target/loongarch/meson.build
|
||||
@@ -8,6 +8,7 @@ loongarch_ss.add(files(
|
||||
|
||||
loongarch_system_ss = ss.source_set()
|
||||
loongarch_system_ss.add(files(
|
||||
+ 'arch_dump.c',
|
||||
'cpu_helper.c',
|
||||
'loongarch-qmp-cmds.c',
|
||||
'machine.c',
|
||||
--
|
||||
2.39.1
|
||||
|
||||
64
target-loongarch-Use-explicit-little-endian-LD-ST-AP.patch
Normal file
64
target-loongarch-Use-explicit-little-endian-LD-ST-AP.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 43ac751187131f91b043ecf611ec795422b42c6c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
|
||||
Date: Fri, 4 Oct 2024 11:59:56 +0200
|
||||
Subject: [PATCH 54/78] target/loongarch: Use explicit little-endian LD/ST API
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The LoongArch architecture uses little endianness. Directly
|
||||
use the little-endian LD/ST API.
|
||||
|
||||
Mechanical change using:
|
||||
|
||||
$ end=le; \
|
||||
for acc in uw w l q tul; do \
|
||||
sed -i -e "s/ld${acc}_p(/ld${acc}_${end}_p(/" \
|
||||
-e "s/st${acc}_p(/st${acc}_${end}_p(/" \
|
||||
$(git grep -wlE '(ld|st)t?u?[wlq]_p' target/loongarch/); \
|
||||
done
|
||||
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
|
||||
Message-Id: <20241004163042.85922-13-philmd@linaro.org>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/gdbstub.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
|
||||
index f8e3324bae..cc72680c38 100644
|
||||
--- a/target/loongarch/gdbstub.c
|
||||
+++ b/target/loongarch/gdbstub.c
|
||||
@@ -68,10 +68,10 @@ int loongarch_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
|
||||
int length = 0;
|
||||
|
||||
if (is_la64(env)) {
|
||||
- tmp = ldq_p(mem_buf);
|
||||
+ tmp = ldq_le_p(mem_buf);
|
||||
read_length = 8;
|
||||
} else {
|
||||
- tmp = ldl_p(mem_buf);
|
||||
+ tmp = ldl_le_p(mem_buf);
|
||||
read_length = 4;
|
||||
}
|
||||
|
||||
@@ -104,13 +104,13 @@ static int loongarch_gdb_set_fpu(CPULoongArchState *env,
|
||||
int length = 0;
|
||||
|
||||
if (0 <= n && n < 32) {
|
||||
- env->fpr[n].vreg.D(0) = ldq_p(mem_buf);
|
||||
+ env->fpr[n].vreg.D(0) = ldq_le_p(mem_buf);
|
||||
length = 8;
|
||||
} else if (32 <= n && n < 40) {
|
||||
env->cf[n - 32] = ldub_p(mem_buf);
|
||||
length = 1;
|
||||
} else if (n == 40) {
|
||||
- env->fcsr0 = ldl_p(mem_buf);
|
||||
+ env->fcsr0 = ldl_le_p(mem_buf);
|
||||
length = 4;
|
||||
}
|
||||
return length;
|
||||
--
|
||||
2.39.1
|
||||
|
||||
73
target-loongarch-fix-Werror-maybe-uninitialized-fals.patch
Normal file
73
target-loongarch-fix-Werror-maybe-uninitialized-fals.patch
Normal file
@ -0,0 +1,73 @@
|
||||
From 1b5bad7f9b10bba438fe12082c8aa29805c03092 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
|
||||
Date: Tue, 24 Sep 2024 15:49:47 +0400
|
||||
Subject: [PATCH 53/78] target/loongarch: fix -Werror=maybe-uninitialized
|
||||
false-positive
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
../target/loongarch/gdbstub.c:55:20: error: ‘val’ may be used uninitialized [-Werror=maybe-uninitialized]
|
||||
55 | return gdb_get_reg32(mem_buf, val);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
../target/loongarch/gdbstub.c:39:18: note: ‘val’ was declared here
|
||||
39 | uint64_t val;
|
||||
|
||||
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
|
||||
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/gdbstub.c | 29 +++++++++++++++--------------
|
||||
1 file changed, 15 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
|
||||
index 5fc2f19e96..f8e3324bae 100644
|
||||
--- a/target/loongarch/gdbstub.c
|
||||
+++ b/target/loongarch/gdbstub.c
|
||||
@@ -33,28 +33,29 @@ void write_fcc(CPULoongArchState *env, uint64_t val)
|
||||
|
||||
int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
||||
{
|
||||
- LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
- CPULoongArchState *env = &cpu->env;
|
||||
- uint64_t val;
|
||||
-
|
||||
- if (0 <= n && n < 32) {
|
||||
- val = env->gpr[n];
|
||||
- } else if (n == 32) {
|
||||
- /* orig_a0 */
|
||||
- val = 0;
|
||||
- } else if (n == 33) {
|
||||
- val = env->pc;
|
||||
- } else if (n == 34) {
|
||||
- val = env->CSR_BADV;
|
||||
- }
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
|
||||
if (0 <= n && n <= 34) {
|
||||
+ uint64_t val;
|
||||
+
|
||||
+ if (n < 32) {
|
||||
+ val = env->gpr[n];
|
||||
+ } else if (n == 32) {
|
||||
+ /* orig_a0 */
|
||||
+ val = 0;
|
||||
+ } else if (n == 33) {
|
||||
+ val = env->pc;
|
||||
+ } else /* if (n == 34) */ {
|
||||
+ val = env->CSR_BADV;
|
||||
+ }
|
||||
+
|
||||
if (is_la64(env)) {
|
||||
return gdb_get_reg64(mem_buf, val);
|
||||
} else {
|
||||
return gdb_get_reg32(mem_buf, val);
|
||||
}
|
||||
}
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From 9a6ef31fa2fcf1f1257fb849cc6cabe2b4c440e0 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Fri, 7 Jun 2024 11:50:16 +0800
|
||||
Subject: [PATCH 46/78] target/loongarch/kvm: Add software breakpoint support
|
||||
|
||||
With KVM virtualization, debug exception is injected to guest kernel
|
||||
rather than host for normal break intruction. Here hypercall
|
||||
instruction with special code is used for sw breakpoint usage,
|
||||
and detailed instruction comes from kvm kernel with user API
|
||||
KVM_REG_LOONGARCH_DEBUG_INST.
|
||||
|
||||
Now only software breakpoint is supported, and it is allowed to
|
||||
insert/remove software breakpoint. We can debug guest kernel with gdb
|
||||
method after kernel is loaded, hardware breakpoint will be added in later.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Tested-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240607035016.2975799-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
configs/targets/loongarch64-softmmu.mak | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/configs/targets/loongarch64-softmmu.mak b/configs/targets/loongarch64-softmmu.mak
|
||||
index f23780fdd8..0034c33620 100644
|
||||
--- a/configs/targets/loongarch64-softmmu.mak
|
||||
+++ b/configs/targets/loongarch64-softmmu.mak
|
||||
@@ -1,5 +1,6 @@
|
||||
TARGET_ARCH=loongarch64
|
||||
TARGET_BASE_ARCH=loongarch
|
||||
+TARGET_KVM_HAVE_GUEST_DEBUG=y
|
||||
TARGET_SUPPORTS_MTTCG=y
|
||||
TARGET_XML_FILES= gdb-xml/loongarch-base32.xml gdb-xml/loongarch-base64.xml gdb-xml/loongarch-fpu.xml
|
||||
TARGET_NEED_FDT=y
|
||||
--
|
||||
2.39.1
|
||||
|
||||
68
target-loongarch-kvm-Add-vCPU-reset-function.patch
Normal file
68
target-loongarch-kvm-Add-vCPU-reset-function.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From ad00cc7da8ab03d6d612a3bd7ec0c4b7af594894 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Thu, 22 Aug 2024 10:28:27 +0800
|
||||
Subject: [PATCH 51/78] target/loongarch/kvm: Add vCPU reset function
|
||||
|
||||
KVM provides interface KVM_REG_LOONGARCH_VCPU_RESET to reset vCPU,
|
||||
it can be used to clear internal state about kvm kernel. vCPU reset
|
||||
function is added here for kvm mode.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240822022827.2273534-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 2 +-
|
||||
target/loongarch/kvm/kvm.c | 5 ++++-
|
||||
target/loongarch/kvm/kvm_loongarch.h | 2 +-
|
||||
3 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index 2038984d02..63d1f65608 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -608,7 +608,7 @@ static void loongarch_cpu_reset_hold(Object *obj)
|
||||
memset(env->tlb, 0, sizeof(env->tlb));
|
||||
#endif
|
||||
if (kvm_enabled()) {
|
||||
- kvm_arch_reset_vcpu(env);
|
||||
+ kvm_arch_reset_vcpu(cs);
|
||||
}
|
||||
#endif
|
||||
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 407d454919..90c8379c46 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -485,9 +485,12 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-void kvm_arch_reset_vcpu(CPULoongArchState *env)
|
||||
+void kvm_arch_reset_vcpu(CPUState *cs)
|
||||
{
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+
|
||||
env->mp_state = KVM_MP_STATE_RUNNABLE;
|
||||
+ kvm_set_one_reg(cs, KVM_REG_LOONGARCH_VCPU_RESET, 0);
|
||||
}
|
||||
|
||||
static int kvm_loongarch_get_mpstate(CPUState *cs)
|
||||
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
|
||||
index 551878a725..8482f9308d 100644
|
||||
--- a/target/loongarch/kvm/kvm_loongarch.h
|
||||
+++ b/target/loongarch/kvm/kvm_loongarch.h
|
||||
@@ -11,8 +11,8 @@
|
||||
#define QEMU_KVM_LOONGARCH_H
|
||||
|
||||
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
|
||||
-void kvm_arch_reset_vcpu(CPULoongArchState *env);
|
||||
int kvm_loongarch_put_pvtime(LoongArchCPU *cpu);
|
||||
int kvm_loongarch_get_pvtime(LoongArchCPU *cpu);
|
||||
+void kvm_arch_reset_vcpu(CPUState *cs);
|
||||
|
||||
#endif
|
||||
--
|
||||
2.39.1
|
||||
|
||||
40
target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch
Normal file
40
target-loongarch-kvm-Fix-VM-recovery-from-disk-failu.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 520e792f674a7ab192a9237519c4e0c8f50abc71 Mon Sep 17 00:00:00 2001
|
||||
From: Song Gao <gaosong@loongson.cn>
|
||||
Date: Wed, 8 May 2024 10:47:32 +0800
|
||||
Subject: [PATCH 44/78] target/loongarch/kvm: Fix VM recovery from disk
|
||||
failures
|
||||
|
||||
vmstate does not save kvm_state_conter,
|
||||
which can cause VM recovery from disk to fail.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Acked-by: Peter Xu <peterx@redhat.com>
|
||||
Message-Id: <20240508024732.3127792-1-gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/machine.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
|
||||
index 4bbf495d6b..97e1152ffd 100644
|
||||
--- a/target/loongarch/machine.c
|
||||
+++ b/target/loongarch/machine.c
|
||||
@@ -165,11 +165,11 @@ static const VMStateDescription vmstate_tlb = {
|
||||
/* LoongArch CPU state */
|
||||
const VMStateDescription vmstate_loongarch_cpu = {
|
||||
.name = "cpu",
|
||||
- .version_id = 1,
|
||||
- .minimum_version_id = 1,
|
||||
+ .version_id = 2,
|
||||
+ .minimum_version_id = 2,
|
||||
.post_load = cpu_post_load,
|
||||
.pre_save = cpu_pre_save,
|
||||
- .fields = (VMStateField[]) {
|
||||
+ .fields = (const VMStateField[]) {
|
||||
VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
|
||||
VMSTATE_UINTTL(env.pc, LoongArchCPU),
|
||||
|
||||
--
|
||||
2.39.1
|
||||
|
||||
233
target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch
Normal file
233
target-loongarch-kvm-Implement-LoongArch-PMU-extensi.patch
Normal file
@ -0,0 +1,233 @@
|
||||
From b87b4782e8147fd481becd946ca909edaaa58b41 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Wed, 18 Sep 2024 16:23:15 +0800
|
||||
Subject: [PATCH 59/78] target/loongarch/kvm: Implement LoongArch PMU extension
|
||||
|
||||
Implement PMU extension for LoongArch kvm mode. Use OnOffAuto type
|
||||
variable pmu to check the PMU feature. If the PMU Feature is not supported
|
||||
with KVM host, it reports error if there is pmu=on command line.
|
||||
|
||||
If there is no any command line about pmu parameter, it checks whether
|
||||
KVM host supports the PMU Feature and set the corresponding value in cpucfg.
|
||||
|
||||
This patch is based on lbt patch located at
|
||||
https://lore.kernel.org/qemu-devel/20240904061859.86615-1-maobibo@loongson.cn
|
||||
|
||||
Co-developed-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Reviewed-by: Song Gao <gaosong@loongson.cn>
|
||||
Message-Id: <20240918082315.2345034-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
target/loongarch/cpu.c | 63 +++++++--------------------
|
||||
target/loongarch/cpu.h | 2 +
|
||||
target/loongarch/kvm/kvm.c | 41 +++++++++++++++++
|
||||
target/loongarch/loongarch-qmp-cmds.c | 2 +-
|
||||
4 files changed, 59 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
|
||||
index a57067938d..2ee1d63989 100644
|
||||
--- a/target/loongarch/cpu.c
|
||||
+++ b/target/loongarch/cpu.c
|
||||
@@ -695,58 +695,28 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
|
||||
}
|
||||
}
|
||||
|
||||
-static bool loongarch_get_pmu(Object *obj, Error **errp)
|
||||
-{
|
||||
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
-
|
||||
- return !!(FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP));
|
||||
-}
|
||||
-
|
||||
-static void loongarch_set_pmu(Object *obj, bool value, Error **errp)
|
||||
-{
|
||||
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
-
|
||||
- cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMP, value);
|
||||
-}
|
||||
-
|
||||
-static void loongarch_get_pmnum(Object *obj, Visitor *v,
|
||||
- const char *name, void *opaque,
|
||||
- Error **errp)
|
||||
+static bool loongarch_get_lbt(Object *obj, Error **errp)
|
||||
{
|
||||
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
- uint32_t value = FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMNUM);
|
||||
-
|
||||
- visit_type_uint32(v, name, &value, errp);
|
||||
+ return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF;
|
||||
}
|
||||
|
||||
-static void loongarch_set_pmnum(Object *obj, Visitor *v,
|
||||
- const char *name, void *opaque,
|
||||
- Error **errp)
|
||||
+static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
- uint32_t *value= opaque;
|
||||
|
||||
- if (!visit_type_uint32(v, name, value, errp)) {
|
||||
- return;
|
||||
- }
|
||||
- if ((*value <= PMNUM_MAX) && (*value > 0)) {
|
||||
- cpu->env.cpucfg[6] = FIELD_DP32(cpu->env.cpucfg[6], CPUCFG6, PMNUM, *value -1);
|
||||
- } else {
|
||||
- error_report("Performance counter number need be in [1- %d]\n", PMNUM_MAX);
|
||||
- exit(EXIT_FAILURE);
|
||||
- }
|
||||
+ cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
|
||||
}
|
||||
|
||||
-static bool loongarch_get_lbt(Object *obj, Error **errp)
|
||||
+static bool loongarch_get_pmu(Object *obj, Error **errp)
|
||||
{
|
||||
- return LOONGARCH_CPU(obj)->lbt != ON_OFF_AUTO_OFF;
|
||||
+ return LOONGARCH_CPU(obj)->pmu != ON_OFF_AUTO_OFF;
|
||||
}
|
||||
|
||||
-static void loongarch_set_lbt(Object *obj, bool value, Error **errp)
|
||||
+static void loongarch_set_pmu(Object *obj, bool value, Error **errp)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
|
||||
|
||||
- cpu->lbt = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
|
||||
+ cpu->pmu = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
|
||||
}
|
||||
|
||||
void loongarch_cpu_post_init(Object *obj)
|
||||
@@ -759,21 +729,18 @@ void loongarch_cpu_post_init(Object *obj)
|
||||
loongarch_set_lasx);
|
||||
|
||||
if (kvm_enabled()) {
|
||||
- object_property_add_bool(obj, "pmu", loongarch_get_pmu,
|
||||
- loongarch_set_pmu);
|
||||
- if (FIELD_EX32(cpu->env.cpucfg[6], CPUCFG6, PMP)) {
|
||||
- uint32_t value = 4;
|
||||
- object_property_add(obj, "pmnum", "uint32",
|
||||
- loongarch_get_pmnum,
|
||||
- loongarch_set_pmnum, NULL,
|
||||
- (void *)&value);
|
||||
- }
|
||||
-
|
||||
cpu->lbt = ON_OFF_AUTO_AUTO;
|
||||
object_property_add_bool(obj, "lbt", loongarch_get_lbt,
|
||||
loongarch_set_lbt);
|
||||
object_property_set_description(obj, "lbt",
|
||||
"Set off to disable Binary Tranlation.");
|
||||
+
|
||||
+ cpu->pmu = ON_OFF_AUTO_AUTO;
|
||||
+ object_property_add_bool(obj, "pmu", loongarch_get_pmu,
|
||||
+ loongarch_set_pmu);
|
||||
+ object_property_set_description(obj, "pmu",
|
||||
+ "Set off to performance monitor unit.");
|
||||
+
|
||||
} else {
|
||||
cpu->lbt = ON_OFF_AUTO_OFF;
|
||||
}
|
||||
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
|
||||
index 2f8c5cf2dd..8ff00d17e1 100644
|
||||
--- a/target/loongarch/cpu.h
|
||||
+++ b/target/loongarch/cpu.h
|
||||
@@ -289,6 +289,7 @@ typedef struct LoongArchTLB LoongArchTLB;
|
||||
|
||||
enum loongarch_features {
|
||||
LOONGARCH_FEATURE_LBT, /* loongson binary translation extension */
|
||||
+ LOONGARCH_FEATURE_PMU,
|
||||
};
|
||||
|
||||
typedef struct LoongArchBT {
|
||||
@@ -407,6 +408,7 @@ struct ArchCPU {
|
||||
QEMUTimer timer;
|
||||
uint32_t phy_id;
|
||||
OnOffAuto lbt;
|
||||
+ OnOffAuto pmu;
|
||||
|
||||
/* 'compatible' string for this CPU for Linux device trees */
|
||||
const char *dtb_compatible;
|
||||
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
|
||||
index 118f66f742..8b0f86a201 100644
|
||||
--- a/target/loongarch/kvm/kvm.c
|
||||
+++ b/target/loongarch/kvm/kvm.c
|
||||
@@ -870,9 +870,18 @@ static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
|
||||
attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT;
|
||||
ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
return (ret == 0);
|
||||
+
|
||||
+ case LOONGARCH_FEATURE_PMU:
|
||||
+ attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
|
||||
+ attr.attr = KVM_LOONGARCH_VM_FEAT_PMU;
|
||||
+ ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
|
||||
+ return (ret == 0);
|
||||
+
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+ return false;
|
||||
}
|
||||
|
||||
static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
|
||||
@@ -896,6 +905,32 @@ static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int kvm_cpu_check_pmu(CPUState *cs, Error **errp)
|
||||
+{
|
||||
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
|
||||
+ CPULoongArchState *env = cpu_env(cs);
|
||||
+ bool kvm_supported;
|
||||
+
|
||||
+ kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PMU);
|
||||
+ if (cpu->pmu == ON_OFF_AUTO_ON) {
|
||||
+ if (!kvm_supported) {
|
||||
+ error_setg(errp, "'pmu' feature not supported by KVM on the host");
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
+ } else if (cpu->pmu != ON_OFF_AUTO_AUTO) {
|
||||
+ /* disable pmu if ON_OFF_AUTO_OFF is set */
|
||||
+ kvm_supported = false;
|
||||
+ }
|
||||
+
|
||||
+ if (kvm_supported) {
|
||||
+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMP, 1);
|
||||
+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMNUM, 3);
|
||||
+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMBITS, 63);
|
||||
+ env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, UPM, 1);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int kvm_arch_init_vcpu(CPUState *cs)
|
||||
{
|
||||
uint64_t val;
|
||||
@@ -913,6 +948,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
|
||||
if (ret < 0) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
+
|
||||
+ ret = kvm_cpu_check_pmu(cs, &local_err);
|
||||
+ if (ret < 0) {
|
||||
+ error_report_err(local_err);
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/target/loongarch/loongarch-qmp-cmds.c b/target/loongarch/loongarch-qmp-cmds.c
|
||||
index 644b528824..dc78a3ffa2 100644
|
||||
--- a/target/loongarch/loongarch-qmp-cmds.c
|
||||
+++ b/target/loongarch/loongarch-qmp-cmds.c
|
||||
@@ -42,7 +42,7 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
|
||||
}
|
||||
|
||||
static const char *cpu_model_advertised_features[] = {
|
||||
- "lsx", "lasx", "lbt", "pmu", "pmnum", NULL
|
||||
+ "lsx", "lasx", "lbt", "pmu", NULL
|
||||
};
|
||||
|
||||
CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
|
||||
--
|
||||
2.39.1
|
||||
|
||||
183
tests-libqos-Add-loongarch-virt-machine-node.patch
Normal file
183
tests-libqos-Add-loongarch-virt-machine-node.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From 254957f2de480901a063759d762d4b1eca5b5bb0 Mon Sep 17 00:00:00 2001
|
||||
From: Bibo Mao <maobibo@loongson.cn>
|
||||
Date: Tue, 28 May 2024 16:20:53 +0800
|
||||
Subject: [PATCH 28/78] tests/libqos: Add loongarch virt machine node
|
||||
|
||||
Add loongarch virt machine to the graph. It is a modified copy of
|
||||
the existing riscv virtmachine in riscv-virt-machine.c
|
||||
|
||||
It contains a generic-pcihost controller, and an extra function
|
||||
loongarch_config_qpci_bus() to configure GPEX pci host controller
|
||||
information, such as ecam and pio_base addresses.
|
||||
|
||||
Also hotplug handle checking about TYPE_VIRTIO_IOMMU_PCI device is
|
||||
added on loongarch virt machine, since virtio_mmu_pci device requires
|
||||
it.
|
||||
|
||||
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
|
||||
Acked-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-Id: <20240528082053.938564-1-maobibo@loongson.cn>
|
||||
Signed-off-by: Song Gao <gaosong@loongson.cn>
|
||||
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
|
||||
---
|
||||
hw/loongarch/virt.c | 2 +
|
||||
tests/qtest/libqos/loongarch-virt-machine.c | 114 ++++++++++++++++++++
|
||||
tests/qtest/libqos/meson.build | 1 +
|
||||
3 files changed, 117 insertions(+)
|
||||
create mode 100644 tests/qtest/libqos/loongarch-virt-machine.c
|
||||
|
||||
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
|
||||
index 11ba879e52..f7874bccf9 100644
|
||||
--- a/hw/loongarch/virt.c
|
||||
+++ b/hw/loongarch/virt.c
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "sysemu/tpm.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "hw/block/flash.h"
|
||||
+#include "hw/virtio/virtio-iommu.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
static bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
|
||||
@@ -1302,6 +1303,7 @@ static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
|
||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||
|
||||
if (device_is_dynamic_sysbus(mc, dev) ||
|
||||
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
|
||||
memhp_type_supported(dev)) {
|
||||
return HOTPLUG_HANDLER(machine);
|
||||
}
|
||||
diff --git a/tests/qtest/libqos/loongarch-virt-machine.c b/tests/qtest/libqos/loongarch-virt-machine.c
|
||||
new file mode 100644
|
||||
index 0000000000..c12089c015
|
||||
--- /dev/null
|
||||
+++ b/tests/qtest/libqos/loongarch-virt-machine.c
|
||||
@@ -0,0 +1,114 @@
|
||||
+/*
|
||||
+ * libqos driver framework
|
||||
+ *
|
||||
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License version 2.1 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
|
||||
+ */
|
||||
+
|
||||
+#include "qemu/osdep.h"
|
||||
+#include "../libqtest.h"
|
||||
+#include "qemu/module.h"
|
||||
+#include "libqos-malloc.h"
|
||||
+#include "qgraph.h"
|
||||
+#include "virtio-mmio.h"
|
||||
+#include "generic-pcihost.h"
|
||||
+#include "hw/pci/pci_regs.h"
|
||||
+
|
||||
+#define LOONGARCH_PAGE_SIZE 0x1000
|
||||
+#define LOONGARCH_VIRT_RAM_ADDR 0x100000
|
||||
+#define LOONGARCH_VIRT_RAM_SIZE 0xFF00000
|
||||
+
|
||||
+#define LOONGARCH_VIRT_PIO_BASE 0x18000000
|
||||
+#define LOONGARCH_VIRT_PCIE_PIO_OFFSET 0x4000
|
||||
+#define LOONGARCH_VIRT_PCIE_PIO_LIMIT 0x10000
|
||||
+#define LOONGARCH_VIRT_PCIE_ECAM_BASE 0x20000000
|
||||
+#define LOONGARCH_VIRT_PCIE_MMIO32_BASE 0x40000000
|
||||
+#define LOONGARCH_VIRT_PCIE_MMIO32_LIMIT 0x80000000
|
||||
+
|
||||
+typedef struct QVirtMachine QVirtMachine;
|
||||
+
|
||||
+struct QVirtMachine {
|
||||
+ QOSGraphObject obj;
|
||||
+ QGuestAllocator alloc;
|
||||
+ QVirtioMMIODevice virtio_mmio;
|
||||
+ QGenericPCIHost bridge;
|
||||
+};
|
||||
+
|
||||
+static void virt_destructor(QOSGraphObject *obj)
|
||||
+{
|
||||
+ QVirtMachine *machine = (QVirtMachine *) obj;
|
||||
+ alloc_destroy(&machine->alloc);
|
||||
+}
|
||||
+
|
||||
+static void *virt_get_driver(void *object, const char *interface)
|
||||
+{
|
||||
+ QVirtMachine *machine = object;
|
||||
+ if (!g_strcmp0(interface, "memory")) {
|
||||
+ return &machine->alloc;
|
||||
+ }
|
||||
+
|
||||
+ fprintf(stderr, "%s not present in loongarch/virtio\n", interface);
|
||||
+ g_assert_not_reached();
|
||||
+}
|
||||
+
|
||||
+static QOSGraphObject *virt_get_device(void *obj, const char *device)
|
||||
+{
|
||||
+ QVirtMachine *machine = obj;
|
||||
+ if (!g_strcmp0(device, "generic-pcihost")) {
|
||||
+ return &machine->bridge.obj;
|
||||
+ } else if (!g_strcmp0(device, "virtio-mmio")) {
|
||||
+ return &machine->virtio_mmio.obj;
|
||||
+ }
|
||||
+
|
||||
+ fprintf(stderr, "%s not present in loongarch/virt\n", device);
|
||||
+ g_assert_not_reached();
|
||||
+}
|
||||
+
|
||||
+static void loongarch_config_qpci_bus(QGenericPCIBus *qpci)
|
||||
+{
|
||||
+ qpci->gpex_pio_base = LOONGARCH_VIRT_PIO_BASE;
|
||||
+ qpci->bus.pio_alloc_ptr = LOONGARCH_VIRT_PCIE_PIO_OFFSET;
|
||||
+ qpci->bus.pio_limit = LOONGARCH_VIRT_PCIE_PIO_LIMIT;
|
||||
+ qpci->bus.mmio_alloc_ptr = LOONGARCH_VIRT_PCIE_MMIO32_BASE;
|
||||
+ qpci->bus.mmio_limit = LOONGARCH_VIRT_PCIE_MMIO32_LIMIT;
|
||||
+ qpci->ecam_alloc_ptr = LOONGARCH_VIRT_PCIE_ECAM_BASE;
|
||||
+}
|
||||
+
|
||||
+static void *qos_create_machine_loongarch_virt(QTestState *qts)
|
||||
+{
|
||||
+ QVirtMachine *machine = g_new0(QVirtMachine, 1);
|
||||
+
|
||||
+ alloc_init(&machine->alloc, 0,
|
||||
+ LOONGARCH_VIRT_RAM_ADDR,
|
||||
+ LOONGARCH_VIRT_RAM_ADDR + LOONGARCH_VIRT_RAM_SIZE,
|
||||
+ LOONGARCH_PAGE_SIZE);
|
||||
+
|
||||
+ qos_create_generic_pcihost(&machine->bridge, qts, &machine->alloc);
|
||||
+ loongarch_config_qpci_bus(&machine->bridge.pci);
|
||||
+
|
||||
+ machine->obj.get_device = virt_get_device;
|
||||
+ machine->obj.get_driver = virt_get_driver;
|
||||
+ machine->obj.destructor = virt_destructor;
|
||||
+ return machine;
|
||||
+}
|
||||
+
|
||||
+static void virt_machine_register_nodes(void)
|
||||
+{
|
||||
+ qos_node_create_machine_args("loongarch64/virt",
|
||||
+ qos_create_machine_loongarch_virt,
|
||||
+ " -cpu la464");
|
||||
+ qos_node_contains("loongarch64/virt", "generic-pcihost", NULL);
|
||||
+}
|
||||
+
|
||||
+libqos_init(virt_machine_register_nodes);
|
||||
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
|
||||
index 90aae42a22..482c9b2aab 100644
|
||||
--- a/tests/qtest/libqos/meson.build
|
||||
+++ b/tests/qtest/libqos/meson.build
|
||||
@@ -60,6 +60,7 @@ libqos_srcs = files(
|
||||
'arm-xilinx-zynq-a9-machine.c',
|
||||
'ppc64_pseries-machine.c',
|
||||
'x86_64_pc-machine.c',
|
||||
+ 'loongarch-virt-machine.c',
|
||||
)
|
||||
|
||||
if have_virtfs
|
||||
--
|
||||
2.39.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user