Anyone have any examples setting a new Sv39 page table on rv64? Working on jumping into Haiku’s kernel and a little stuck generating new page tables I feel like it’s csr instructions, but mmu stuff is always my weakness. None of the risc-v books I have detail the process well.
// Generate the final satp with our new sv39 mmu
uint64_t
arch_mmu_generate_satp(uint64_t sv39)
{
dprintf("%s called sv39: 0x%" B_PRIx64 "\n", __func__, sv39);
uint64_t satp = 0;
__asm__ __volatile__ ("csrr %0, satp" : "=r"(satp) : : );
dprintf(" current satp: 0x%" B_PRIx64 "\n", satp);
// Set sv39 mode
satp = (satp & ~RV64_SATP_MODE_MASK)
| ((uint64_t)RV64_SATP_MODE_SV39 << RV64_SATP_MODE_SHIFT);
// Our new sv39 table
satp = (satp & ~RV64_SATP_PPN_MASK)
| (sv39 << RV64_SATP_PPN_SHIFT);
// TODO: Do we need to set / change ASID?
dprintf(" new satp: 0x%" B_PRIx64 "\n", satp);
return satp;
}
then just before jumping into our kernel:
/* status_t arch_enter_kernel(uint64 satp, struct kernel_args *kernelArgs,
addr_t kernelEntry, addr_t kernelStackTop);
a0 - satp
a1 - kernelArgs
a2 - kernelEntry
a3 - kernelStackTop
*/
FUNCTION(arch_enter_kernel):
// Set the kernel stack
mv sp,a3
// Set new memory map for kernel
sfence.vma
csrw satp, a0
// Setup kernel args
mv a0,a1 // kernelArgs
mv a4,a2
li a1,0 // currentCPU=0
// call the kernel
jr a4
// return
li a0,-1 // B_ERROR
ret
FUNCTION_END(arch_enter_kernel)
Final SV39 at 0xfbff0000
arch_mmu_generate_satp called sv39: 0xfbff0000
current satp: 0x0
new satp: 0x80000000fbff0000
Calling ExitBootServices. So long, EFI!