user_space #4
79
arch/x86/mmuContext.c
Normal file
79
arch/x86/mmuContext.c
Normal file
@ -0,0 +1,79 @@
|
||||
#include "mmuContext.h"
|
||||
#include "alloc.h"
|
||||
#include "allocArea.h"
|
||||
#include "errno.h"
|
||||
#include "klibc.h"
|
||||
#include "irq.h"
|
||||
#include "list.h"
|
||||
#include "paging.h"
|
||||
#include "stdarg.h"
|
||||
#include "types.h"
|
||||
|
||||
struct mmu_context {
|
||||
paddr_t paddr_PD;
|
||||
vaddr_t vaddr_PD;
|
||||
uint32_t ref;
|
||||
|
||||
struct mmu_context *next, *prev;
|
||||
};
|
||||
|
||||
static struct mmu_context *listContext = NULL;
|
||||
static struct mmu_context *currentContext = NULL;
|
||||
|
||||
int mmuContextSetup()
|
||||
{
|
||||
struct mmu_context *initialCtx;
|
||||
int ret = 0;
|
||||
|
||||
initialCtx = malloc(sizeof(struct mmu_context));
|
||||
|
||||
if (initialCtx == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
initialCtx->paddr_PD = pagingGetCurrentPDPaddr();
|
||||
initialCtx->vaddr_PD = areaAlloc(1, 0);
|
||||
|
||||
ret = pageMap(initialCtx->vaddr_PD, initialCtx->paddr_PD,
|
||||
PAGING_MEM_WRITE | PAGING_MEM_READ);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_singleton(listContext, initialCtx);
|
||||
currentContext = initialCtx;
|
||||
|
||||
// We create the context and we are using it
|
||||
initialCtx->ref = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mmu_context *mmuContextCreate()
|
||||
{
|
||||
struct mmu_context *ctx;
|
||||
uint32_t flags;
|
||||
|
||||
ctx = malloc(sizeof(struct mmu_context));
|
||||
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
ctx->vaddr_PD = areaAlloc(1, AREA_PHY_MAP);
|
||||
|
||||
if (ctx->vaddr_PD == (vaddr_t)NULL) {
|
||||
pr_info("Fail to allocate MMU Context\n");
|
||||
free(ctx);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->paddr_PD = pagingGetPaddr(ctx->vaddr_PD);
|
||||
|
||||
ctx->ref = 1;
|
||||
|
||||
//TODO copy kernel space
|
||||
disable_IRQs(flags);
|
||||
list_add_tail(listContext, ctx);
|
||||
restore_IRQs(flags);
|
||||
|
||||
return ctx;
|
||||
}
|
@ -198,7 +198,38 @@ int pageUnmap(vaddr_t vaddr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
paddr_t pagingGetPaddr(vaddr_t vaddr)
|
||||
{
|
||||
/* Get the page directory entry and table entry index for this
|
||||
address */
|
||||
unsigned pdEntry = vaddr >> PD_SHIFT;
|
||||
unsigned ptEntry = vaddr >> PT_SHIFT;
|
||||
unsigned pageOffset = vaddr & PAGE_MASK;
|
||||
|
||||
/* Get the PD of the current context */
|
||||
struct pde *pd =
|
||||
(struct pde *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (PD_MIRROR_PAGE_IDX << PT_SHIFT));
|
||||
|
||||
/* Address of the PT in the mirroring */
|
||||
struct pte *pt = (struct pte *)((PD_MIRROR_PAGE_IDX << PD_SHIFT) + (pdEntry << PT_SHIFT));
|
||||
|
||||
/* No page mapped at this address ? */
|
||||
if (!pd[pdEntry].present)
|
||||
return (paddr_t)NULL;
|
||||
if (!pt[ptEntry].present)
|
||||
return (paddr_t)NULL;
|
||||
|
||||
return (pt[ptEntry].paddr << PT_SHIFT) + pageOffset;
|
||||
}
|
||||
|
||||
unsigned long getNbMappedPage(void)
|
||||
{
|
||||
return mappedPage;
|
||||
}
|
||||
|
||||
paddr_t pagingGetCurrentPDPaddr()
|
||||
{
|
||||
struct pdbr pdbr;
|
||||
asm volatile("movl %%cr3, %0\n": "=r"(pdbr));
|
||||
return (pdbr.pd_paddr << 12);
|
||||
}
|
||||
|
@ -10,3 +10,6 @@ int pagingSetup(paddr_t lowerKernelAddr, paddr_t upperKernelAddr);
|
||||
int pageMap(vaddr_t vaddr, paddr_t paddr, int flags);
|
||||
int pageUnmap(vaddr_t vaddr);
|
||||
unsigned long getNbMappedPage(void);
|
||||
|
||||
paddr_t pagingGetPaddr(vaddr_t vaddr);
|
||||
paddr_t pagingGetCurrentPDPaddr();
|
||||
|
5
core/mmuContext.h
Normal file
5
core/mmuContext.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
struct mmu_context;
|
||||
int mmuContextSetup();
|
||||
struct mmu_context *mmuContextCreate();
|
Loading…
Reference in New Issue
Block a user