riscv: refactor smp init
This commit is contained in:
parent
f33732a2e5
commit
e3d65aa628
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user