:: commit e3d65aa628edec447877d6e22debd225ac670fba

xvanc <xvancm@gmail.com> — 2023-09-13 14:37

parents: f33732a2e5

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
tab: 248 wrap: offon