diff --git a/arch/x86/mmuContext.c b/arch/x86/mmuContext.c new file mode 100644 index 0000000..d69c574 --- /dev/null +++ b/arch/x86/mmuContext.c @@ -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; +} diff --git a/arch/x86/paging.c b/arch/x86/paging.c index 8020a21..b8e8804 100644 --- a/arch/x86/paging.c +++ b/arch/x86/paging.c @@ -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); +} diff --git a/arch/x86/paging.h b/arch/x86/paging.h index d43e0a3..1c7702f 100644 --- a/arch/x86/paging.h +++ b/arch/x86/paging.h @@ -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(); diff --git a/core/mmuContext.h b/core/mmuContext.h new file mode 100644 index 0000000..32e581a --- /dev/null +++ b/core/mmuContext.h @@ -0,0 +1,5 @@ +#pragma once + +struct mmu_context; +int mmuContextSetup(); +struct mmu_context *mmuContextCreate();