user_space #4
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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");
|
||||||
|
@ -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);
|
||||||
|
16
tests/test.c
16
tests/test.c
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user