#include "uaddrspace.h" #include "alloc.h" #include "kernel.h" #include "klibc.h" #include "mem.h" #include "mmuContext.h" #include "process.h" #include "stdarg.h" #include "thread.h" #include "types.h" #include #include #include struct uAddrVirtualReg { uaddr_t addr; size_t size; int right; // PAGING_MEM_* uint32_t offset; // in the mappedRessource uint flags; struct mappedRessource *res; struct uAddrVirtualReg *nextInAddrSpace, *prevInAddrSpace; struct uAddrVirtualReg *nextInMappedRes, *prevInMappedRes; }; struct uAddrSpace { struct process *process; // The process that is represented by this AS struct mmu_context *ctx; // The corresponding MMU configuration struct uAddrVirtualReg *listVirtualReg; // List of Virtual Region used by this process uaddr_t heapStart; // Start of the Head size_t heapSize; // Hep size -> modified by brk() }; struct mappedRessourceOps { int (*open)(struct uAddrVirtualReg *vreg); int (*close)(struct uAddrVirtualReg *vreg); int (*unmap)(struct uAddrVirtualReg *vregi, uaddr_t addr, size_t size); int (*nopage)(struct uAddrVirtualReg *vregi, uaddr_t addr, int right); // Called by the pageflt handler when the page is missing }; struct mappedRessource { int right; // PAGING_MEM_* struct mappedRessourceOps *ops; struct uAddrVirtualReg *listVirtualReg; }; struct uAddrSpace *uAddrSpaceCreate(struct process *proc) { struct uAddrSpace *addr = (struct uAddrSpace *)malloc(sizeof(struct uAddrSpace)); if (addr == NULL) return NULL; addr->ctx = mmuContextCreate(); if (addr->ctx == NULL) { free(addr); return NULL; } addr->process = proc; return addr; } int uAddrSpaceDelete(struct uAddrSpace *addr) { // TODO Work on Virtual Region return mmuContextUnref(addr->ctx); } struct mmu_context *uAddrSpaceGetMMUContext(struct uAddrSpace *addr) { return addr->ctx; } int uAddrSpaceSetHeap(struct uAddrSpace *as, uaddr_t addr, size_t size) { as->heapStart = addr; as->heapSize = size; return 0; } uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop) { int incSize; assert(as->heapStart); if (!newHeapTop || newHeapTop < as->heapStart) return as->heapStart + as->heapSize; newHeapTop = ALIGN(newHeapTop, PAGE_SIZE); if (newHeapTop == as->heapStart + as->heapSize) return newHeapTop; incSize = ALIGN(newHeapTop - (as->heapStart + as->heapSize), PAGE_SIZE); if (incSize < 0){ //FIXME return as->heapStart + as->heapSize; } as->heapSize += incSize; return 0; } int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr) { pr_devel("Checking %p inside %p and %p", addr, as->heapStart, as->heapStart +as->heapSize); if (addr < as->heapStart || addr >= as->heapStart + as->heapSize) { return -1; } vaddr_t addrAlign = ALIGN_DOWN(addr, PAGE_SIZE); paddr_t ppage = allocPhyPage(1); if (0 != pageMap(addrAlign, ppage, PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ)) { return -1; } unrefPhyPage(ppage); return 0; }