limine/riscv: remove dependency on lower half identity map

This commit is contained in:
xvanc 2023-08-02 15:20:47 -05:00
parent 46d3dcd600
commit 56cdc669bf
No known key found for this signature in database
6 changed files with 39 additions and 13 deletions

View File

@ -99,7 +99,7 @@ noreturn void enter_in_el1(uint64_t entry, uint64_t sp, uint64_t sctlr,
uint64_t mair, uint64_t tcr, uint64_t ttbr0,
uint64_t ttbr1, uint64_t target_x0);
#elif defined (__riscv64)
noreturn void riscv_spinup(uint64_t entry, uint64_t sp, uint64_t satp);
noreturn void riscv_spinup(uint64_t entry, uint64_t sp, uint64_t satp, uint64_t direct_map_offset);
#if defined (UEFI)
RISCV_EFI_BOOT_PROTOCOL *get_riscv_boot_protocol(void);
#endif

View File

@ -6,11 +6,18 @@ riscv_spinup:
.option norelax
csrci sstatus, 0x2
csrw sie, zero
lla t0, 0f
add t0, t0, a3
csrw stvec, t0
csrw satp, a2
unimp
.align 4
0:
csrw stvec, zero
mv t0, a0
mv sp, a1
csrw satp, a2
mv a0, zero
mv a1, zero

View File

@ -963,7 +963,7 @@ FEAT_START
break;
}
smp_info = init_smp(&cpu_count, bsp_hartid, pagemap);
smp_info = init_smp(&cpu_count, bsp_hartid, pagemap, direct_map_offset);
#else
#error Unknown architecture
#endif
@ -1106,7 +1106,7 @@ FEAT_END
uint64_t reported_stack = reported_addr(stack);
uint64_t satp = make_satp(pagemap.paging_mode, pagemap.top_level);
riscv_spinup(entry_point, reported_stack, satp);
riscv_spinup(entry_point, reported_stack, satp, direct_map_offset);
#else
#error Unknown architecture
#endif

View File

@ -582,14 +582,17 @@ struct trampoline_passed_info {
uint64_t smp_tpl_booted_flag;
uint64_t smp_tpl_satp;
uint64_t smp_tpl_info_struct;
uint64_t smp_tpl_hhdm_offset;
};
static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *info_struct) {
static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *info_struct,
uint64_t hhdm_offset) {
static struct trampoline_passed_info passed_info;
passed_info.smp_tpl_booted_flag = 0;
passed_info.smp_tpl_satp = satp;
passed_info.smp_tpl_info_struct = (uint64_t)info_struct;
passed_info.smp_tpl_hhdm_offset = hhdm_offset;
asm volatile ("" ::: "memory");
@ -606,8 +609,9 @@ static bool smp_start_ap(size_t hartid, size_t satp, struct limine_smp_info *inf
}
struct limine_smp_info *init_smp(size_t *cpu_count,
size_t bsp_hartid,
pagemap_t pagemap) {
size_t bsp_hartid,
pagemap_t pagemap,
uint64_t hhdm_offset) {
// No RSDP means no ACPI.
// Parsing the Device Tree is the only other method for detecting APs.
if (acpi_get_rsdp() == NULL) {
@ -666,7 +670,7 @@ struct limine_smp_info *init_smp(size_t *cpu_count,
// 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(intc->hartid, satp, info_struct, hhdm_offset)) {
print("smp: FAILED to bring-up AP\n");
continue;
}

View File

@ -33,8 +33,9 @@ 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);
uint64_t bsp_hartid,
pagemap_t pagemap,
uint64_t hhdm_offset);
#else
#error Unknown architecture

View File

@ -11,15 +11,29 @@ smp_trampoline_start:
//
// All other registers are undefined.
ld a0, 16(a1)
ld t0, 8(a1)
csrw satp, t0
#define smp_tpl_booted_flag 0
#define smp_tpl_satp 8
#define smp_tpl_info_struct 16
#define smp_tpl_hhdm_offset 24
ld a0, smp_tpl_info_struct(a1)
ld t1, smp_tpl_hhdm_offset(a1)
// Tell the BSP we've started.
li t0, 1
fence rw, w
sd t0, (a1)
// Set `stvec` so we page fault into the higher half after loading `satp`.
lla t0, 0f
add t0, t1, t0
csrw stvec, t0
ld t0, smp_tpl_satp(a1)
csrw satp, t0
0:
// Relocate the info struct to the higher half.
add a0, t1, a0
// Zero all the things.
// Preserve a0
mv a1, zero