2022-08-09 16:15:00 +02:00
|
|
|
#include "uaddrspace.h"
|
|
|
|
#include "alloc.h"
|
|
|
|
#include "kernel.h"
|
2022-09-03 23:32:31 +02:00
|
|
|
#include "klibc.h"
|
2024-01-26 22:26:40 +01:00
|
|
|
#include "list.h"
|
2022-08-09 16:15:00 +02:00
|
|
|
#include "mem.h"
|
|
|
|
#include "mmuContext.h"
|
2024-01-29 21:47:24 +01:00
|
|
|
#include "paging.h"
|
2022-08-09 16:15:00 +02:00
|
|
|
#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)
|
|
|
|
{
|
2024-01-26 22:26:40 +01:00
|
|
|
struct uAddrSpace *addr = (struct uAddrSpace *)zalloc(sizeof(struct uAddrSpace));
|
2022-08-09 16:15:00 +02:00
|
|
|
|
|
|
|
if (addr == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
addr->ctx = mmuContextCreate();
|
|
|
|
|
|
|
|
if (addr->ctx == NULL) {
|
|
|
|
free(addr);
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr->process = proc;
|
2024-01-26 22:26:40 +01:00
|
|
|
list_init(addr->listVirtualReg);
|
2022-08-09 16:15:00 +02:00
|
|
|
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int uAddrSpaceDelete(struct uAddrSpace *addr)
|
|
|
|
{
|
2024-01-26 22:26:40 +01:00
|
|
|
struct uAddrVirtualReg *reg;
|
|
|
|
|
|
|
|
list_collapse_named(addr->listVirtualReg, reg, nextInAddrSpace, prevInAddrSpace) {
|
|
|
|
// TODO Implement me with real ressources
|
|
|
|
assertmsg(reg->res == NULL, "Unsupported mapper ressource");
|
|
|
|
// This is memory allocated for the heap just unmap it to free it
|
2024-01-29 21:47:24 +01:00
|
|
|
pr_devel("Freeing heap 0x%lx for process %s\n", reg->addr, processGetName(addr->process));
|
2024-01-26 22:26:40 +01:00
|
|
|
pageUnmap(reg->addr);
|
|
|
|
free(reg);
|
|
|
|
}
|
2022-08-09 16:15:00 +02:00
|
|
|
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){
|
2024-01-26 22:26:40 +01:00
|
|
|
//TODO how to free allocated page by uAddrSpaceCheckNAlloc
|
2022-08-09 16:15:00 +02:00
|
|
|
return as->heapStart + as->heapSize;
|
|
|
|
}
|
|
|
|
|
2022-09-03 23:32:31 +02:00
|
|
|
as->heapSize += incSize;
|
2022-08-09 16:15:00 +02:00
|
|
|
|
2024-01-26 22:26:40 +01:00
|
|
|
return as->heapStart + as->heapSize;
|
2022-09-03 23:32:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr)
|
|
|
|
{
|
2024-01-26 22:26:40 +01:00
|
|
|
struct uAddrVirtualReg *newReg;
|
|
|
|
int right = PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ;
|
|
|
|
|
2024-01-29 21:47:24 +01:00
|
|
|
pr_devel("Checking 0x%lx inside 0x%lx and 0x%lx\n", addr, as->heapStart, as->heapStart +as->heapSize);
|
2022-09-03 23:32:31 +02:00
|
|
|
if (addr < as->heapStart || addr >= as->heapStart + as->heapSize) {
|
|
|
|
return -1;
|
2022-08-09 16:15:00 +02:00
|
|
|
}
|
|
|
|
|
2024-01-26 22:26:40 +01:00
|
|
|
pr_devel("Alloc heap for process %s\n", processGetName(as->process));
|
|
|
|
|
2022-09-03 23:32:31 +02:00
|
|
|
vaddr_t addrAlign = ALIGN_DOWN(addr, PAGE_SIZE);
|
|
|
|
paddr_t ppage = allocPhyPage(1);
|
|
|
|
|
2024-01-26 22:26:40 +01:00
|
|
|
if (0 != pageMap(addrAlign, ppage, right))
|
|
|
|
goto free_ppage;
|
|
|
|
|
|
|
|
newReg = zalloc(sizeof(struct uAddrVirtualReg));
|
|
|
|
|
|
|
|
if (newReg == NULL)
|
|
|
|
goto free_ppage;
|
|
|
|
|
|
|
|
newReg->addr = addrAlign;
|
|
|
|
newReg->size = PAGE_SIZE;
|
|
|
|
newReg->right = right;
|
|
|
|
|
|
|
|
list_add_tail_named(as->listVirtualReg, newReg, nextInAddrSpace, prevInAddrSpace);
|
2022-09-03 23:32:31 +02:00
|
|
|
|
|
|
|
unrefPhyPage(ppage);
|
|
|
|
|
2022-08-09 16:15:00 +02:00
|
|
|
return 0;
|
2024-01-26 22:26:40 +01:00
|
|
|
free_ppage:
|
|
|
|
unrefPhyPage(ppage);
|
|
|
|
return -1;
|
2022-08-09 16:15:00 +02:00
|
|
|
}
|