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,
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

View File

@ -541,68 +541,40 @@ 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(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;
// 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)))
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->processor_id = intc->acpi_processor_uid;
info_struct->hartid = intc->hartid;
info_struct->hartid = hart->hartid;
info_struct->processor_id = hart->acpi_uid;
// Do not try to restart the BSP
if (intc->hartid == bsp_hartid) {
(*cpu_count)++;
// 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", intc->hartid);
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(intc->hartid, satp, info_struct)) {
if (!smp_start_ap(hart->hartid, satp, info_struct, hhdm_offset)) {
print("smp: FAILED to bring-up AP\n");
continue;
}
@ -610,8 +582,6 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
(*cpu_count)++;
continue;
}
}
}
return ret;
}

View File

@ -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