riscv: refactor smp init
diff --git a/common/protos/limine.c b/common/protos/limine.c
index 671e7eed..0b2362b9 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -937,19 +937,6 @@ FEAT_END
pagemap = build_pagemap(paging_mode, nx_available, ranges, ranges_count,
physical_base, virtual_base, direct_map_offset);
-#if defined (__riscv64)
- // Fetch the BSP's Hart ID before exiting boot services.
- size_t bsp_hartid;
- bool have_bsp_hartid = false;
-
- RISCV_EFI_BOOT_PROTOCOL *riscv_boot_proto = get_riscv_boot_protocol();
- if (riscv_boot_proto != NULL) {
- if (riscv_boot_proto->GetBootHartId(riscv_boot_proto, &bsp_hartid) == EFI_SUCCESS) {
- have_bsp_hartid = true;
- }
- }
-#endif
-
#if defined (UEFI)
efi_exit_boot_services();
#endif
@@ -975,12 +962,7 @@ FEAT_START
smp_info = init_smp(&cpu_count, &bsp_mpidr,
pagemap, LIMINE_MAIR(fb_attr), LIMINE_TCR(tsz, pa), LIMINE_SCTLR);
#elif defined (__riscv64)
- if (!have_bsp_hartid) {
- printv("smp: failed to get bsp's hart id\n");
- break;
- }
-
- smp_info = init_smp(&cpu_count, bsp_hartid, pagemap);
+ smp_info = init_smp(&cpu_count, pagemap);
#else
#error Unknown architecture
#endif
diff --git a/common/sys/smp.c b/common/sys/smp.c
index 6abbdb44..5e8a5fcb 100644
--- a/common/sys/smp.c
+++ b/common/sys/smp.c
@@ -541,76 +541,46 @@ static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *inf
return false;
}
-struct limine_smp_info *init_smp(size_t *cpu_count,
- size_t bsp_hartid,
- pagemap_t pagemap) {
- // No RSDP means no ACPI.
- // Parsing the Device Tree is the only other method for detecting APs.
- if (acpi_get_rsdp() == NULL) {
- printv("smp: ACPI is required to detect APs.\n");
- return NULL;
+struct limine_smp_info *init_smp(size_t *cpu_count, pagemap_t pagemap) {
+ size_t num_cpus = 0;
+ for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
+ if (!(hart->flags & RISCV_HART_COPROC)) {
+ num_cpus += 1;
+ }
}
- struct madt *madt = acpi_get_table("APIC", 0);
- if (madt == NULL)
- return NULL;
-
- size_t max_cpus = 0;
- for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin;
- (uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length;
- madt_ptr += *(madt_ptr + 1)) {
- switch (*madt_ptr) {
- case 0x18: {
- struct madt_riscv_intc *intc = (void *)madt_ptr;
-
- // Check if we can actually try to start the AP
- if ((intc->flags & 1) ^ ((intc->flags >> 1) & 1))
- max_cpus++;
-
- continue;
- }
- }
+ struct limine_smp_info *ret = ext_mem_alloc(num_cpus * sizeof(struct limine_smp_info));
+ if (ret == NULL) {
+ panic(false, "out of memory");
}
- struct limine_smp_info *ret = ext_mem_alloc(max_cpus * sizeof(struct limine_smp_info));
*cpu_count = 0;
+ for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
+ if (hart->flags & RISCV_HART_COPROC) {
+ continue;
+ }
+ struct limine_smp_info *info_struct = &ret[*cpu_count];
- // Try to start all APs
- for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin;
- (uintptr_t)madt_ptr < (uintptr_t)madt + madt->header.length;
- madt_ptr += *(madt_ptr + 1)) {
- switch (*madt_ptr) {
- case 0x18: {
- struct madt_riscv_intc *intc = (void *)madt_ptr;
-
- // Check if we can actually try to start the AP
- if (!((intc->flags & 1) ^ ((intc->flags >> 1) & 1)))
- continue;
-
- struct limine_smp_info *info_struct = &ret[*cpu_count];
-
- info_struct->processor_id = intc->acpi_processor_uid;
- info_struct->hartid = intc->hartid;
-
- // Do not try to restart the BSP
- if (intc->hartid == bsp_hartid) {
- (*cpu_count)++;
- continue;
- }
+ info_struct->hartid = hart->hartid;
+ info_struct->processor_id = hart->acpi_uid;
- printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", intc->hartid);
+ // Don't try to start the BSP.
+ if (hart->hartid == bsp_hartid) {
+ *cpu_count += 1;
+ continue;
+ }
- // Try to start the AP.
- size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level);
- if (!smp_start_ap(intc->hartid, satp, info_struct)) {
- print("smp: FAILED to bring-up AP\n");
- continue;
- }
+ printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", hart->hartid);
- (*cpu_count)++;
- continue;
- }
+ // Try to start the AP.
+ size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level);
+ if (!smp_start_ap(hart->hartid, satp, info_struct, hhdm_offset)) {
+ print("smp: FAILED to bring-up AP\n");
+ continue;
}
+
+ (*cpu_count)++;
+ continue;
}
return ret;
diff --git a/common/sys/smp.h b/common/sys/smp.h
index b05de5f1..c2f706d1 100644
--- a/common/sys/smp.h
+++ b/common/sys/smp.h
@@ -32,7 +32,6 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
#elif defined (__riscv64)
struct limine_smp_info *init_smp(size_t *cpu_count,
- uint64_t bsp_hartid,
pagemap_t pagemap);
#else
