mem stuff

This commit is contained in:
2020-05-28 15:25:12 +02:00
parent 404ae75cfa
commit 1b82f81d8c
2 changed files with 957 additions and 65 deletions

View File

@@ -55,6 +55,10 @@
* it's cutting (there are many) and why, and more importantly, how.
*/
/* under dumbvm, always have 72k of user stack */
/* (this must be > 64K so argument blocks of size ARG_MAX will fit) */
#define DUMBVM_STACKPAGES 18
/*
* Bitmap utils
@@ -63,11 +67,6 @@
#define resetBit(A,k) ( A[(k/32)] &= ~(1 << (k%32)) )
#define checkBit(A,k) ( A[(k/32)] & (1 << (k%32)) )
/* under dumbvm, always have 72k of user stack */
/* (this must be > 64K so argument blocks of size ARG_MAX will fit) */
#define DUMBVM_STACKPAGES 18
/*
* Wrap ram_stealmem in a spinlock.
*/
@@ -77,26 +76,35 @@ static struct spinlock freemem_lock = SPINLOCK_INITIALIZER;
static uint32_t *freeRamFrames = NULL;
static unsigned long *allocSize = NULL;
static int nRamFrames = 0;
static int allocTableActive = 0;
static int isTableActive () {
int active;
spinlock_acquire(&freemem_lock);
active = allocTableActive;
spinlock_release(&freemem_lock);
return active;
}
void
vm_bootstrap(void)
{
int i;
nRamFrames = ((int)ram_getsize())/PAGE_SIZE;
/* alloc freeRamFrame and allocSize */
int i;
nRamFrames = ((int)ram_getsize())/PAGE_SIZE;
/* alloc freeRamFrame and allocSize */
freeRamFrames = kmalloc(sizeof(uint32_t)*(nRamFrames/32 + 1));
if (freeRamFrames==NULL) return;
if (freeRamFrames==NULL) return;
allocSize = kmalloc(sizeof(unsigned long)*nRamFrames);
if (allocSize==NULL) {
if (allocSize==NULL) {
/* reset to disable this vm management */
freeRamFrames = NULL; return;
}
for (i=0; i<nRamFrames; i++) {
for (i=0; i<nRamFrames; i++) {
if (i<(nRamFrames/32 + 1)) {
freeRamFrames[i] = (uint32_t)0;
}
allocSize[i] = 0;
allocSize[i] = 0;
}
spinlock_acquire(&freemem_lock);
allocTableActive = 1;
@@ -110,8 +118,7 @@ vm_bootstrap(void)
* avoid the situation where syscall-layer code that works ok with
* dumbvm starts blowing up during the VM assignment.
*/
static
void
static void
dumbvm_can_sleep(void)
{
if (CURCPU_EXISTS()) {
@@ -123,16 +130,13 @@ dumbvm_can_sleep(void)
}
}
static paddr_t
static paddr_t
getfreeppages(unsigned long npages) {
paddr_t addr;
paddr_t addr;
long i, first, found, np = (long)npages;
if (!isTableActive()) return 0;
spinlock_acquire(&freemem_lock);
if (!allocTableActive) {
spinlock_release(&freemem_lock);
return 0;
}
for (i=0,first=found=-1; i<nRamFrames; i++) {
if (checkBit(freeRamFrames, i)) {
if (i==0 || !checkBit(freeRamFrames, i-1))
@@ -143,7 +147,7 @@ getfreeppages(unsigned long npages) {
}
}
}
if (found>=0) {
for (i=found; i<found+np; i++) {
resetBit(freeRamFrames, i);
@@ -160,28 +164,6 @@ getfreeppages(unsigned long npages) {
return addr;
}
static int
freeppages(paddr_t addr, unsigned long npages){
long i, first, np=(long)npages;
spinlock_acquire(&freemem_lock);
if (!allocTableActive) {
spinlock_release(&freemem_lock);
return 0;
}
first = addr/PAGE_SIZE;
KASSERT(allocSize!=NULL);
KASSERT(nRamFrames>first);
for (i=first; i<first+np; i++) {
setBit(freeRamFrames, i);
}
spinlock_release(&freemem_lock);
return 1;
}
static paddr_t
getppages(unsigned long npages)
{
@@ -195,17 +177,31 @@ getppages(unsigned long npages)
addr = ram_stealmem(npages);
spinlock_release(&stealmem_lock);
}
if (addr!=0) {
if (addr!=0 && isTableActive()) {
spinlock_acquire(&freemem_lock);
if (!allocTableActive) {
spinlock_release(&freemem_lock);
return addr;
}
allocSize[addr/PAGE_SIZE] = npages;
allocSize[addr/PAGE_SIZE] = npages;
spinlock_release(&freemem_lock);
}
}
return addr;
return addr;
}
static int
freeppages(paddr_t addr, unsigned long npages){
long i, first, np=(long)npages;
if (!isTableActive()) return 0;
first = addr/PAGE_SIZE;
KASSERT(allocSize!=NULL);
KASSERT(nRamFrames>first);
spinlock_acquire(&freemem_lock);
for (i=first; i<first+np; i++) {
setBit(freeRamFrames, i);
}
spinlock_release(&freemem_lock);
return 1;
}
/* Allocate/free some kernel-space virtual pages */
@@ -222,20 +218,15 @@ alloc_kpages(unsigned npages)
return PADDR_TO_KVADDR(pa);
}
void
free_kpages(vaddr_t addr)
{
spinlock_acquire(&freemem_lock);
if (!allocTableActive) {
spinlock_release(&freemem_lock);
return;
}
spinlock_release(&freemem_lock);
paddr_t paddr = addr - MIPS_KSEG0;
long first = paddr/PAGE_SIZE;
KASSERT(allocSize!=NULL);
KASSERT(nRamFrames>first);
freeppages(paddr, allocSize[first]);
void
free_kpages(vaddr_t addr){
if (isTableActive()) {
paddr_t paddr = addr - MIPS_KSEG0;
long first = paddr/PAGE_SIZE;
KASSERT(allocSize!=NULL);
KASSERT(nRamFrames>first);
freeppages(paddr, allocSize[first]);
}
}
void