提交 c172a8b7 编写于 作者: Z Zihao Yu

riscv32-nemu: add vme

上级 de7f01f0
......@@ -15,8 +15,11 @@ static inline void outb(uintptr_t addr, uint8_t data) { *(volatile uint8_t *)M
static inline void outw(uintptr_t addr, uint16_t data) { *(volatile uint16_t *)MMIO_OFFSET(addr) = data; }
static inline void outl(uintptr_t addr, uint32_t data) { *(volatile uint32_t *)MMIO_OFFSET(addr) = data; }
#define PTE_V 0x2
#define PTE_D 0x4
#define PTE_V 0x01
#define PTE_R 0x02
#define PTE_W 0x04
#define PTE_X 0x08
#define PTE_U 0x10
// Page directory and page table constants
#define NR_PDE 1024 // # directory entries per page directory
......@@ -37,7 +40,10 @@ typedef uint32_t PDE;
#define OFF(va) ((uint32_t)(va) & 0xfff)
// Address in page table or page directory entry
#define PTE_ADDR(pte) ((uint32_t)(pte) & ~0xfff)
#define PTE_ADDR(pte) (((uint32_t)(pte) & ~0x3ff) << 2)
// construct virtual address from indexes and offset
#define PGADDR(d, t, o) ((uint32_t)((d) << PDXSHFT | (t) << PTXSHFT | (o)))
#endif
......
......@@ -8,7 +8,7 @@ void get_cur_as(_Context *c);
void _switch(_Context *c);
_Context* irq_handle(_Context *c) {
// get_cur_as(c);
get_cur_as(c);
_Context *next = c;
if (user_handler) {
......@@ -28,7 +28,7 @@ _Context* irq_handle(_Context *c) {
}
}
// _switch(next);
_switch(next);
return next;
}
......
......@@ -3,26 +3,65 @@
#define PG_ALIGN __attribute((aligned(PGSIZE)))
static PDE kpdirs[NR_PDE] PG_ALIGN;
static PTE kptabs[PMEM_SIZE / PGSIZE * 2] PG_ALIGN;
static void* (*pgalloc_usr)(size_t);
static void (*pgfree_usr)(void*);
_Area segments[] = { // Kernel memory mappings
{.start = (void*)0, .end = (void*)PMEM_SIZE}
{.start = (void*)0, .end = (void*)(0x400000)},
{.start = (void*)0x80000000u, .end = (void*)(0x80000000u + PMEM_SIZE)}
};
#define NR_KSEG_MAP (sizeof(segments) / sizeof(segments[0]))
static inline void set_satp(void *pdir) {
asm volatile("csrw satp, %0" : : "r"(0x80000000 | ((uintptr_t)pdir >> 12)));
}
int _vme_init(void* (*pgalloc_f)(size_t), void (*pgfree_f)(void*)) {
pgalloc_usr = pgalloc_f;
pgfree_usr = pgfree_f;
// make all PDEs invalid
int i;
for (i = 0; i < NR_PDE; i ++) {
kpdirs[i] = 0;
}
PTE *ptab = kptabs;
for (i = 0; i < NR_KSEG_MAP; i ++) {
uint32_t pdir_idx = (uintptr_t)segments[i].start / (PGSIZE * NR_PTE);
uint32_t pdir_idx_end = (uintptr_t)segments[i].end / (PGSIZE * NR_PTE);
for (; pdir_idx < pdir_idx_end; pdir_idx ++) {
// fill PDE
kpdirs[pdir_idx] = ((uintptr_t)ptab >> PGSHFT << 10) | PTE_V;
// fill PTE
PTE pte = (PGADDR(pdir_idx, 0, 0) >> PGSHFT << 10) | PTE_V;
PTE pte_end = (PGADDR(pdir_idx + 1, 0, 0) >> PGSHFT << 10) | PTE_V;
for (; pte < pte_end; pte += (1 << 10)) {
*ptab = pte;
ptab ++;
}
}
}
set_satp(kpdirs);
return 0;
}
int _protect(_Protect *p) {
p->ptr = (PDE*)(pgalloc_usr(1));
PDE *updir = (PDE*)(pgalloc_usr(1));
p->pgsize = 4096;
p->ptr = updir;
// map kernel space
for (int i = 0; i < NR_PDE; i ++) {
updir[i] = kpdirs[i];
}
return 0;
}
......@@ -35,6 +74,7 @@ void get_cur_as(_Context *c) {
}
void _switch(_Context *c) {
set_satp(c->prot->ptr);
cur_as = c->prot;
}
......@@ -42,12 +82,11 @@ int _map(_Protect *p, void *va, void *pa, int mode) {
PDE *pt = (PDE*)p->ptr;
PDE *pde = &pt[PDX(va)];
if (!(*pde & PTE_V)) {
*pde = PTE_V | (uint32_t)pgalloc_usr(1);
*pde = PTE_V | ((uint32_t)pgalloc_usr(1) >> PGSHFT << 10);
}
PTE *pte = &((PTE*)PTE_ADDR(*pde))[PTX(va)];
if (!(*pte & PTE_V)) {
assert(0);
//*pte = PTE_V | PTE_D | (((uint32_t)pa >> PGSHFT) << 6);
*pte = PTE_V | PTE_R | PTE_W | PTE_X | PTE_U | ((uint32_t)pa >> PGSHFT << 10);
}
return 0;
......@@ -58,6 +97,6 @@ _Context *_ucontext(_Protect *p, _Area ustack, _Area kstack, void *entry, void *
c->prot = p;
c->epc = (uintptr_t)entry;
c->status = 0x3;
//c->status = 0x3;
return c;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册