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 *currentContext = NULL;
struct mmu_context * mmuContextGetCurrent(){
return currentContext;
}
int mmuContextSetup()
{
struct mmu_context *initialCtx;
@ -84,6 +88,63 @@ struct mmu_context *mmuContextCreate()
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)
{
uint32_t flags;

View File

@ -1,3 +1,4 @@
#include "allocArea.h"
#include "paging.h"
#include "errno.h"
#include "kernel.h"
@ -269,6 +270,45 @@ int pagingSetCurrentPDPaddr(paddr_t paddrPD)
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)
{
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 pagingGetCurrentPDPaddr();
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 "kthread.h"
#include "mem.h"
#include "mmuContext.h"
#include "multiboot.h"
#include "paging.h"
#include "pit.h"
@ -163,6 +164,7 @@ void kmain(unsigned long magic, unsigned long addr)
printf("[Setup] allocation system\n");
areaInit(firstUsedByMem, lastUsedByMem, _stack_bottom, _stack_top);
mmuContextSetup();
cpu_context_subsystem_setup();
printf("[Setup] thread system\n");

View File

@ -6,3 +6,7 @@ struct mmu_context;
int mmuContextSetup();
struct mmu_context *mmuContextCreate();
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 "list.h"
#include "mem.h"
#include "mmuContext.h"
#include "paging.h"
#include "serial.h"
#include "stack.h"
@ -363,11 +364,23 @@ void testATAThread(){
}
}
void testATA(){
static void testATA(){
kthreadCreate("ATA_TEST", testATAThread, NULL);
//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)
{
testATA();
@ -402,4 +415,5 @@ void run_test(void)
test_backtrace();
testCoroutine();
testKthread();
testMMUContext();
}