#include "uaddrspace.h" #include "alloc.h" #include "kernel.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; } //WIP do it manually for (uaddr_t begin = ALIGN(as->heapStart + as->heapSize, PAGE_SIZE); begin < newHeapTop; begin += PAGE_SIZE) { paddr_t ppage = allocPhyPage(1); if (0 != pageMap(begin, ppage, PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ)) return (uaddr_t)NULL; unrefPhyPage(ppage); } return 0; }