Merge pull request #289 from xvanc/trunk
vmm/riscv: remove dependency on lower half identity map and fix bug in `vmm_max_paging_mode()`
This commit is contained in:
commit
6be9666290
|
@ -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
|
||||
|
|
|
@ -6,11 +6,19 @@ riscv_spinup:
|
|||
.option norelax
|
||||
csrci sstatus, 0x2
|
||||
csrw sie, zero
|
||||
|
||||
lla t0, 0f
|
||||
add t0, t0, a3
|
||||
csrw stvec, t0
|
||||
csrw satp, a2
|
||||
sfence.vma
|
||||
unimp
|
||||
.align 4
|
||||
0:
|
||||
csrw stvec, zero
|
||||
|
||||
mv t0, a0
|
||||
mv sp, a1
|
||||
csrw satp, a2
|
||||
|
||||
mv a0, zero
|
||||
mv a1, zero
|
||||
|
|
|
@ -312,7 +312,7 @@ int vmm_max_paging_mode(void)
|
|||
pt_entry_t entry = PT_FLAG_ACCESSED | PT_FLAG_DIRTY | PT_FLAG_RWX | PT_FLAG_VALID;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
table[i] = entry;
|
||||
entry += page_sizes[lvl];
|
||||
entry += page_sizes[lvl] >> 2;
|
||||
}
|
||||
|
||||
uint64_t satp = ((uint64_t)(6 + lvl) << 60) | ((uint64_t)table >> 12);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -11,15 +11,31 @@ 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
|
||||
sfence.vma
|
||||
unimp
|
||||
0:
|
||||
// Relocate the info struct to the higher half.
|
||||
add a0, t1, a0
|
||||
|
||||
// Zero all the things.
|
||||
// Preserve a0
|
||||
mv a1, zero
|
||||
|
|
|
@ -47,6 +47,11 @@ override INTERNALCFLAGS := \
|
|||
-I. \
|
||||
-I..
|
||||
|
||||
ifneq ($(findstring riscv,$(CC_FOR_TARGET)),)
|
||||
override INTERNALCFLAGS += -march=rv64imac -mabi=lp64 -mno-relax
|
||||
override INTERNALLDFLAGS += --no-relax
|
||||
endif
|
||||
|
||||
override INTERNALCFLAGS_MB := \
|
||||
-std=c11 \
|
||||
-ffreestanding \
|
||||
|
|
|
@ -32,6 +32,7 @@ SECTIONS
|
|||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.*)
|
||||
} :data
|
||||
|
||||
.dynamic : {
|
||||
|
@ -39,6 +40,7 @@ SECTIONS
|
|||
} :data :dynamic
|
||||
|
||||
.bss : {
|
||||
*(.sbss .sbss.*)
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
} :data
|
||||
|
|
Loading…
Reference in New Issue