lab 2 (probably working)

This commit is contained in:
2020-05-25 18:00:42 +02:00
parent df7631de81
commit 404ae75cfa
6 changed files with 201 additions and 14 deletions

View File

@@ -110,6 +110,25 @@ syscall(struct trapframe *tf)
break;
/* Add stuff here */
case SYS_read:
err = sys_read(
(int)tf->tf_a0,
(userptr_t)tf->tf_a1,
(size_t)tf->tf_a2
);
break;
case SYS_write:
err = sys_write(
(int)tf->tf_a0,
(userptr_t)tf->tf_a1,
(size_t)tf->tf_a2
);
break;
case SYS__exit:
sys__exit((int)tf->tf_a0);
break;
default:
kprintf("Unknown syscall %d\n", callno);

View File

@@ -55,6 +55,15 @@
* it's cutting (there are many) and why, and more importantly, how.
*/
/*
* Bitmap utils
*/
#define setBit(A,k) ( A[(k/32)] |= (1 << (k%32)) )
#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
@@ -63,11 +72,35 @@
* Wrap ram_stealmem in a spinlock.
*/
static struct spinlock stealmem_lock = SPINLOCK_INITIALIZER;
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;
void
vm_bootstrap(void)
{
/* Do nothing. */
int i;
nRamFrames = ((int)ram_getsize())/PAGE_SIZE;
/* alloc freeRamFrame and allocSize */
freeRamFrames = kmalloc(sizeof(uint32_t)*(nRamFrames/32 + 1));
if (freeRamFrames==NULL) return;
allocSize = kmalloc(sizeof(unsigned long)*nRamFrames);
if (allocSize==NULL) {
/* reset to disable this vm management */
freeRamFrames = NULL; return;
}
for (i=0; i<nRamFrames; i++) {
if (i<(nRamFrames/32 + 1)) {
freeRamFrames[i] = (uint32_t)0;
}
allocSize[i] = 0;
}
spinlock_acquire(&freemem_lock);
allocTableActive = 1;
spinlock_release(&freemem_lock);
}
/*
@@ -90,17 +123,88 @@ dumbvm_can_sleep(void)
}
}
static
paddr_t
static paddr_t
getfreeppages(unsigned long npages) {
paddr_t addr;
long i, first, found, np = (long)npages;
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))
first = i; /* set first free in an interval */
if (i-first+1 >= np) {
found = first;
break;
}
}
}
if (found>=0) {
for (i=found; i<found+np; i++) {
resetBit(freeRamFrames, i);
}
allocSize[found] = np;
addr = (paddr_t) found*PAGE_SIZE;
}
else {
addr = 0;
}
spinlock_release(&freemem_lock);
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)
{
paddr_t addr;
paddr_t addr;
spinlock_acquire(&stealmem_lock);
/* try freed pages first */
addr = getfreeppages(npages);
if (addr == 0) {
/* call stealmem */
spinlock_acquire(&stealmem_lock);
addr = ram_stealmem(npages);
spinlock_release(&stealmem_lock);
}
if (addr!=0) {
spinlock_acquire(&freemem_lock);
if (!allocTableActive) {
spinlock_release(&freemem_lock);
return addr;
}
allocSize[addr/PAGE_SIZE] = npages;
spinlock_release(&freemem_lock);
}
addr = ram_stealmem(npages);
spinlock_release(&stealmem_lock);
return addr;
}
@@ -121,9 +225,17 @@ alloc_kpages(unsigned npages)
void
free_kpages(vaddr_t addr)
{
/* nothing - leak the memory. */
(void)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