metal-cos/sys/arm64/paging.c
2024-09-26 04:07:50 +08:00

94 lines
2.5 KiB
C

#include "include/pmap.h"
#include <machine/metalp.h>
#include <machine/paging.h>
#include <machine/pmap.h>
#include <machine/mrt.h>
#include <sys/types.h>
#include <string.h>
// page table for boot
static struct vmpt boot_pt;
#define BOOT_PD_NUM (4)
static struct vmpd boot_pd[BOOT_PD_NUM];
static struct vmpd boot_dev_pd[BOOT_PD_NUM];
void
vm_insert_pd(struct vmpt * pt, struct vmpd * pd, unsigned int pgshift, paddr_t paddr)
{
const uint64_t pfn = vm_get_pfn(pd->vaddr, pgshift);
int hash = vm_vahash(pfn);
struct vmpte * vmpte = &pt->entries[hash];
pd->next = vmpte->first;
vmpte->first = paddr;
}
void paging_init()
{
int ret;
memset(&boot_pd, 0, sizeof(boot_pd));
memset(&boot_pt, 0, sizeof(boot_pt));
// ident map the first 4GB
paddr_t cur = 0;
for (int i = 0; i < BOOT_PD_NUM; i++) {
boot_pd[i].attr = VMPD_ATTR_P | VMPD_ATTR_AO_KRW;
boot_pd[i].paddr = cur;
boot_pd[i].vaddr = MEM_DIRECTMAP_BASE + cur;
cur += (1 << REGION_DMAP_PGSHIFT);
vm_insert_pd(&boot_pt, &boot_pd[i], REGION_DMAP_PGSHIFT, (paddr_t)DMVA2PA(&boot_pd[i]));
}
// ident map the first 4GB to device memory space
cur = 0;
for (int i = 0; i < BOOT_PD_NUM; i++) {
boot_dev_pd[i].attr = VMPD_ATTR_P | VMPD_ATTR_DEV | VMPD_ATTR_AO_KRW;
boot_dev_pd[i].paddr = cur;
boot_dev_pd[i].vaddr = MEM_DIRECTMAP_DEV_BASE + cur;
cur += (1 << REGION_DMAP_PGSHIFT);
vm_insert_pd(&boot_pt, &boot_dev_pd[i], REGION_DMAP_PGSHIFT, (paddr_t)DMVA2PA(&boot_dev_pd[i]));
}
// set page table base
paddr_t ptb = (paddr_t)DMVA2PA(&boot_pt);
int idx = MRT_SET_MPTB_DMAP;
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_IDX, idx);
METAL_MROUTINE_SETARG(MRT_SET_MPTB_ARG_PTB, ptb);
METAL_MENTER(MRT_SET_MPTB_IDX);
METAL_MROUTINE_GETRET(MRT_SET_MPTB_RET_STATUS, ret);
if (ret != 0) {
hlt();
}
// set page table attribute override bits
uint64_t mtp = MTP_KERNEL;
METAL_MROUTINE_SETARG(MRT_SET_MTP_ARG_MTP, mtp);
METAL_MENTER(MRT_SET_MTP_IDX);
// // set MAIR
// #define MAIR_VAL ((0b11111111) | (0b00000000 << 8))
// // 0 = b11111111 = Normal, Inner/Outer WB/WA/RA
// // 1 = b00000000 = Device-nGnRnE
// __asm__ volatile (
// "ldr x0, =(" METAL_STR(MAIR_VAL) ");"
// "msr mair_el1, x0;"
// :
// :
// : "x0"
// );
// reset page tables
uint64_t zero = 0;
__asm__ volatile (
"msr ttbr0_el1, %x0;"
"msr ttbr1_el1, %x0;"
"TLBI VMALLE1;"
:
: "r" (zero)
:
);
}