riscv: refactor smp init

This commit is contained in:
xvanc 2023-09-13 09:37:43 -05:00 committed by mintsuki
parent f33732a2e5
commit e3d65aa628
3 changed files with 36 additions and 85 deletions

View File

@ -937,19 +937,6 @@ FEAT_END
pagemap = build_pagemap(paging_mode, nx_available, ranges, ranges_count, pagemap = build_pagemap(paging_mode, nx_available, ranges, ranges_count,
physical_base, virtual_base, direct_map_offset); 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) #if defined (UEFI)
efi_exit_boot_services(); efi_exit_boot_services();
#endif #endif
@ -975,12 +962,7 @@ FEAT_START
smp_info = init_smp(&cpu_count, &bsp_mpidr, smp_info = init_smp(&cpu_count, &bsp_mpidr,
pagemap, LIMINE_MAIR(fb_attr), LIMINE_TCR(tsz, pa), LIMINE_SCTLR); pagemap, LIMINE_MAIR(fb_attr), LIMINE_TCR(tsz, pa), LIMINE_SCTLR);
#elif defined (__riscv64) #elif defined (__riscv64)
if (!have_bsp_hartid) { smp_info = init_smp(&cpu_count, pagemap);
printv("smp: failed to get bsp's hart id\n");
break;
}
smp_info = init_smp(&cpu_count, bsp_hartid, pagemap);
#else #else
#error Unknown architecture #error Unknown architecture
#endif #endif

View File

@ -541,68 +541,40 @@ static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *inf
return false; return false;
} }
struct limine_smp_info *init_smp(size_t *cpu_count, struct limine_smp_info *init_smp(size_t *cpu_count, pagemap_t pagemap) {
size_t bsp_hartid, size_t num_cpus = 0;
pagemap_t pagemap) { for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
// No RSDP means no ACPI. if (!(hart->flags & RISCV_HART_COPROC)) {
// Parsing the Device Tree is the only other method for detecting APs. num_cpus += 1;
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 *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; *cpu_count = 0;
for (struct riscv_hart *hart = hart_list; hart != NULL; hart = hart->next) {
// Try to start all APs if (hart->flags & RISCV_HART_COPROC) {
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; continue;
}
struct limine_smp_info *info_struct = &ret[*cpu_count]; struct limine_smp_info *info_struct = &ret[*cpu_count];
info_struct->processor_id = intc->acpi_processor_uid; info_struct->hartid = hart->hartid;
info_struct->hartid = intc->hartid; info_struct->processor_id = hart->acpi_uid;
// Do not try to restart the BSP // Don't try to start the BSP.
if (intc->hartid == bsp_hartid) { if (hart->hartid == bsp_hartid) {
(*cpu_count)++; *cpu_count += 1;
continue; continue;
} }
printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", intc->hartid); printv("smp: Found candidate AP for bring-up. Hart ID: %u\n", hart->hartid);
// Try to start the AP. // Try to start the AP.
size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level); size_t satp = make_satp(pagemap.paging_mode, pagemap.top_level);
if (!smp_start_ap(intc->hartid, satp, info_struct)) { if (!smp_start_ap(hart->hartid, satp, info_struct, hhdm_offset)) {
print("smp: FAILED to bring-up AP\n"); print("smp: FAILED to bring-up AP\n");
continue; continue;
} }
@ -610,8 +582,6 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
(*cpu_count)++; (*cpu_count)++;
continue; continue;
} }
}
}
return ret; return ret;
} }

View File

@ -32,7 +32,6 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
#elif defined (__riscv64) #elif defined (__riscv64)
struct limine_smp_info *init_smp(size_t *cpu_count, struct limine_smp_info *init_smp(size_t *cpu_count,
uint64_t bsp_hartid,
pagemap_t pagemap); pagemap_t pagemap);
#else #else