[kvm-unit-tests PATCH 2/7] riscv: Add ACPI support for CPU initialization
Xiang W
wangxiang at iscas.ac.cn
Wed Sep 23 20:39:40 PDT 2026
When a DT is not provided, discover harts from the MADT RINTC
subtables (ACPI 6.6 type 24) instead of aborting in cpu_init_acpi().
Parse each RINTC entry for hart_id and ACPI UID, record them in
thread_info, and mark the CPU present only if it is Enabled in
the RINTC flags and SBI reports the hart as available.
Also add the RINTC MADT structure and the MADT types introduced
after GENERIC_TRANSLATOR so the RISC-V interrupt controller
entries can be identified.
Signed-off-by: Xiang W <wangxiang at iscas.ac.cn>
---
lib/acpi.h | 30 +++++++++++++++++++++++++++++-
lib/riscv/asm/processor.h | 1 +
lib/riscv/setup.c | 28 +++++++++++++++++++++++++++-
3 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/lib/acpi.h b/lib/acpi.h
index a62cd3a9..a905807d 100644
--- a/lib/acpi.h
+++ b/lib/acpi.h
@@ -226,6 +226,22 @@ struct acpi_madt_generic_translator {
u32 reserved2;
};
+/* 24: RISC-V Interrupt Controller (RINTC) Structure (ACPI 6.6) */
+struct acpi_madt_rintc {
+ u8 type;
+ u8 length;
+ u8 version;
+ u8 reserved; /* reserved - must be zero */
+ u32 flags;
+ u64 hart_id;
+ u32 uid;
+ u32 ext_intc_id;
+ u64 imsic_addr;
+ u32 imsic_size;
+};
+
+#define ACPI_RINTC_FLAGS_ENABLED 1
+
/* Values for MADT subtable type in struct acpi_subtable_header */
enum acpi_madt_type {
@@ -245,7 +261,19 @@ enum acpi_madt_type {
ACPI_MADT_TYPE_GENERIC_MSI_FRAME = 13,
ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR = 14,
ACPI_MADT_TYPE_GENERIC_TRANSLATOR = 15,
- ACPI_MADT_TYPE_RESERVED = 16 /* 16 and greater are reserved */
+ ACPI_MADT_TYPE_MULTIPROCESSOR_WAKEUP = 16,
+ ACPI_MADT_TYPE_CORE_PIC = 17,
+ ACPI_MADT_TYPE_LIO_PIC = 18,
+ ACPI_MADT_TYPE_HT_PIC = 19,
+ ACPI_MADT_TYPE_EIO_PIC = 20,
+ ACPI_MADT_TYPE_MSI_PIC = 21,
+ ACPI_MADT_TYPE_BIO_PIC = 22,
+ ACPI_MADT_TYPE_LPC_PIC = 23,
+ ACPI_MADT_TYPE_RINTC = 24,
+ ACPI_MADT_TYPE_IMSIC = 25,
+ ACPI_MADT_TYPE_APLIC = 26,
+ ACPI_MADT_TYPE_PLIC = 27,
+ ACPI_MADT_TYPE_RESERVED = 28 /* 28 and greater are reserved */
};
/* MADT Local APIC flags */
diff --git a/lib/riscv/asm/processor.h b/lib/riscv/asm/processor.h
index a3dab064..5a1df355 100644
--- a/lib/riscv/asm/processor.h
+++ b/lib/riscv/asm/processor.h
@@ -14,6 +14,7 @@ typedef void (*exception_fn)(struct pt_regs *);
struct thread_info {
int cpu;
unsigned long hartid;
+ unsigned long uid;
unsigned long isa[1];
unsigned long sp;
exception_fn exception_handlers[EXCEPTION_CAUSE_MAX];
diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c
index 8c22120d..72de2145 100644
--- a/lib/riscv/setup.c
+++ b/lib/riscv/setup.c
@@ -48,6 +48,29 @@ uint64_t timebase_frequency;
static struct mem_region riscv_mem_regions[NR_MEM_REGIONS + 1];
+#ifdef CONFIG_EFI
+#include <acpi.h>
+
+static int cpu_set_acpi(struct acpi_subtable_header *header)
+{
+ int cpu = nr_cpus++;
+ struct acpi_madt_rintc *intc = (void *)header;
+
+ assert_msg(cpu < NR_CPUS, "Number cpus exceeds maximum supported (%d).", NR_CPUS);
+
+ cpus[cpu].cpu = cpu;
+ cpus[cpu].hartid = intc->hart_id;
+ cpus[cpu].uid = intc->uid;
+
+ if (intc->flags & ACPI_RINTC_FLAGS_ENABLED) {
+ if (!sbi_hart_get_status(cpus[cpu].hartid).error)
+ set_cpu_present(cpu, true);
+ }
+
+ return 0;
+}
+#endif
+
static void cpu_set_fdt(int fdtnode __unused, u64 regval, void *info __unused)
{
int cpu = nr_cpus++;
@@ -63,7 +86,11 @@ static void cpu_set_fdt(int fdtnode __unused, u64 regval, void *info __unused)
static void cpu_init_acpi(void)
{
+#ifdef CONFIG_EFI
+ acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, cpu_set_acpi);
+#else
assert_msg(false, "ACPI not available");
+#endif
}
static void cpu_init(void)
@@ -226,7 +253,6 @@ void setup(const void *fdt, phys_addr_t freemem_start)
#ifdef CONFIG_EFI
#include <efi.h>
-#include <acpi.h>
extern unsigned long exception_vectors;
extern unsigned long boot_hartid;
--
2.47.3
More information about the kvm-riscv
mailing list