From e3d65aa628edec447877d6e22debd225ac670fba Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:37:43 -0500 Subject: [PATCH] riscv: refactor smp init --- common/protos/limine.c | 20 +-------- common/sys/smp.c | 100 +++++++++++++++-------------------------- common/sys/smp.h | 1 - 3 files changed, 36 insertions(+), 85 deletions(-) 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 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 *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 limine_smp_info *ret = ext_mem_alloc(max_cpus * sizeof(struct limine_smp_info)); + struct limine_smp_info *ret = ext_mem_alloc(num_cpus * sizeof(struct limine_smp_info)); + if (ret == NULL) { + panic(false, "out of memory"); + } + *cpu_count = 0; - - // 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; - } - - printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", intc->hartid); - - // 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; - } - - (*cpu_count)++; - continue; - } + 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]; + + info_struct->hartid = hart->hartid; + info_struct->processor_id = hart->acpi_uid; + + // Don't try to start the BSP. + if (hart->hartid == bsp_hartid) { + *cpu_count += 1; + continue; + } + + printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", hart->hartid); + + // 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