Integrate MMU context

This commit is contained in:
Mathieu Maret 2021-10-30 00:28:31 +02:00
parent 55e709adb5
commit 79a2bc58ae
6 changed files with 123 additions and 1 deletions

View File

@ -20,6 +20,10 @@ struct mmu_context {
static struct mmu_context *listContext = NULL; static struct mmu_context *listContext = NULL;
static struct mmu_context *currentContext = NULL; static struct mmu_context *currentContext = NULL;
struct mmu_context * mmuContextGetCurrent(){
return currentContext;
}
int mmuContextSetup() int mmuContextSetup()
{ {
struct mmu_context *initialCtx; struct mmu_context *initialCtx;
@ -84,6 +88,63 @@ struct mmu_context *mmuContextCreate()
return ctx; return ctx;
} }
int mmuContextRef(struct mmu_context *ctx)
{
uint32_t flags;
disable_IRQs(flags);
// ref == 0 => suppression
assert(ctx->ref > 0);
ctx->ref++;
restore_IRQs(flags);
return 0;
}
int mmuContextUnref(struct mmu_context *ctx)
{
uint32_t flags;
disable_IRQs(flags);
assert(ctx->ref > 0);
ctx->ref--;
if (ctx->ref == 0) {
list_delete(listContext, ctx);
pagingClearUserContext(ctx->vaddr_PD);
areaFree(ctx->vaddr_PD);
free(ctx);
}
restore_IRQs(flags);
return 0;
}
int mmuContextSwitch(struct mmu_context *ctx)
{
uint32_t flags;
disable_IRQs(flags);
assert(ctx->ref > 0);
assert(currentContext->ref > 0);
if (ctx != currentContext) {
struct mmu_context *prev = currentContext;
ctx->ref++;
currentContext = ctx;
pagingSetCurrentPDPaddr(ctx->paddr_PD);
mmuContextUnref(prev);
}
restore_IRQs(flags);
return 0;
}
int mmuContextSyncKernelPDE(int pdEntry, void *pde, size_t pdeSize) int mmuContextSyncKernelPDE(int pdEntry, void *pde, size_t pdeSize)
{ {
uint32_t flags; uint32_t flags;

View File

@ -1,3 +1,4 @@
#include "allocArea.h"
#include "paging.h" #include "paging.h"
#include "errno.h" #include "errno.h"
#include "kernel.h" #include "kernel.h"
@ -269,6 +270,45 @@ int pagingSetCurrentPDPaddr(paddr_t paddrPD)
return 0; return 0;
} }
// unmap page inside this MMU context
int pagingClearUserContext(vaddr_t vaddr_PD)
{
struct pde *pd = (struct pde *)vaddr_PD;
//Tmp pt to unref page they reference
struct pte *pt = (struct pte *)areaAlloc(1, 0);
if(pt == NULL)
return -ENOMEM;
for (int pdIdx = PAGING_BASE_USER_ADDRESS >> PD_SHIFT; pdIdx < 1024; pdIdx++) {
if(!pd[pdIdx].present){
memset(&pd[pdIdx], 0, sizeof(struct pde));
continue;
}
paddr_t ptAddr = pd[pdIdx].pt_addr << PT_SHIFT;
assert(!pageMap(ptAddr, (vaddr_t)pt, PAGING_MEM_USER | PAGING_MEM_WRITE));
for(int ptIdx = 0; ptIdx < 1024; ptIdx ++){
if(!pt[ptIdx].present){
memset(&pt[ptIdx], 0, sizeof(struct pte));
continue;
}
unrefPhyPage(pt[ptIdx].paddr);
memset(&pt[ptIdx], 0, sizeof(struct pte));
}
assert(!pageUnmap((vaddr_t)pt));
memset(&pd[pdIdx], 0, sizeof(struct pde));
unrefPhyPage(ptAddr);
}
areaFree((vaddr_t)pt);
return 0;
}
int pagingCopyKernelSpace(vaddr_t destVaddrPD, paddr_t destPaddrPD, vaddr_t srcVaddrPD) int pagingCopyKernelSpace(vaddr_t destVaddrPD, paddr_t destPaddrPD, vaddr_t srcVaddrPD)
{ {
struct pde *src_pd = (struct pde *)srcVaddrPD; struct pde *src_pd = (struct pde *)srcVaddrPD;

View File

@ -28,3 +28,4 @@ int pagingSetCurrentPDPaddr(paddr_t paddrPD);
paddr_t pagingGetPaddr(vaddr_t vaddr); paddr_t pagingGetPaddr(vaddr_t vaddr);
paddr_t pagingGetCurrentPDPaddr(); paddr_t pagingGetCurrentPDPaddr();
int pagingCopyKernelSpace(vaddr_t destVaddrPD, paddr_t destPaddrPD, vaddr_t srcVaddrPD); int pagingCopyKernelSpace(vaddr_t destVaddrPD, paddr_t destPaddrPD, vaddr_t srcVaddrPD);
int pagingClearUserContext(vaddr_t vaddr_PD);

View File

@ -11,6 +11,7 @@
#include "klibc.h" #include "klibc.h"
#include "kthread.h" #include "kthread.h"
#include "mem.h" #include "mem.h"
#include "mmuContext.h"
#include "multiboot.h" #include "multiboot.h"
#include "paging.h" #include "paging.h"
#include "pit.h" #include "pit.h"
@ -163,6 +164,7 @@ void kmain(unsigned long magic, unsigned long addr)
printf("[Setup] allocation system\n"); printf("[Setup] allocation system\n");
areaInit(firstUsedByMem, lastUsedByMem, _stack_bottom, _stack_top); areaInit(firstUsedByMem, lastUsedByMem, _stack_bottom, _stack_top);
mmuContextSetup();
cpu_context_subsystem_setup(); cpu_context_subsystem_setup();
printf("[Setup] thread system\n"); printf("[Setup] thread system\n");

View File

@ -6,3 +6,7 @@ struct mmu_context;
int mmuContextSetup(); int mmuContextSetup();
struct mmu_context *mmuContextCreate(); struct mmu_context *mmuContextCreate();
int mmuContextSyncKernelPDE(int pdEntry, void *pde, size_t pdeSize); int mmuContextSyncKernelPDE(int pdEntry, void *pde, size_t pdeSize);
int mmuContextSwitch(struct mmu_context *ctx);
struct mmu_context *mmuContextGetCurrent();
int mmuContextRef(struct mmu_context *ctx);
int mmuContextUnref(struct mmu_context *ctx);

View File

@ -7,6 +7,7 @@
#include "kthread.h" #include "kthread.h"
#include "list.h" #include "list.h"
#include "mem.h" #include "mem.h"
#include "mmuContext.h"
#include "paging.h" #include "paging.h"
#include "serial.h" #include "serial.h"
#include "stack.h" #include "stack.h"
@ -363,11 +364,23 @@ void testATAThread(){
} }
} }
void testATA(){ static void testATA(){
kthreadCreate("ATA_TEST", testATAThread, NULL); kthreadCreate("ATA_TEST", testATAThread, NULL);
//testATAThread(); //testATAThread();
} }
static void testMMUContext()
{
printf("Testing mmu\n");
struct mmu_context *current = mmuContextGetCurrent();
assert(current != NULL);
struct mmu_context *new = mmuContextCreate();
assert(new != NULL);
mmuContextSwitch(new);
mmuContextSwitch(current);
mmuContextUnref(new);
}
void run_test(void) void run_test(void)
{ {
testATA(); testATA();
@ -402,4 +415,5 @@ void run_test(void)
test_backtrace(); test_backtrace();
testCoroutine(); testCoroutine();
testKthread(); testKthread();
testMMUContext();
} }