matos/core/uaddrspace.c

132 lines
3.1 KiB
C

#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 <assert.h>
#include <stddef.h>
#include <stdint.h>
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\n", 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;
}