lab 2 (probably working)

This commit is contained in:
QcFe [PDS] 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

View File

@ -440,6 +440,10 @@ file test/fstest.c
optfile net test/nettest.c
# NEW PDS WORK
# NEW PDS WORK (lab1)
defoption hello
optfile hello main/hello.c
optfile hello main/hello.c
# LAB2
file syscall/file_syscalls.c
file syscall/proc_syscalls.c

View File

@ -30,7 +30,7 @@
#ifndef _SYSCALL_H_
#define _SYSCALL_H_
#include <types.h>
#include <cdefs.h> /* for __DEAD */
struct trapframe; /* from <machine/trapframe.h> */
@ -59,4 +59,9 @@ __DEAD void enter_new_process(int argc, userptr_t argv, userptr_t env,
int sys_reboot(int code);
int sys___time(userptr_t user_seconds, userptr_t user_nanoseconds);
size_t sys_read(int filehandle, userptr_t buf, size_t size);
size_t sys_write(int filehandle, const userptr_t buf, size_t size);
void sys__exit(int status);
#endif /* _SYSCALL_H_ */

View File

@ -0,0 +1,32 @@
#include <syscall.h>
#include <lib.h>
#include <kern/unistd.h>
size_t sys_read(int fh, userptr_t buf, size_t size) {
int i=0;
int * ary = (int*)buf;
if (fh!=STDIN_FILENO) {
kprintf("sys_read supported only to stdin\n");
return -1;
}
for (i=0;i<(int)size;i++) {
ary[i] = getch();
}
return i;
}
size_t sys_write(int fh, const userptr_t buf, size_t size) {
int i=0;
int * ary = (int*)buf;
if (fh!=STDOUT_FILENO && fh!=STDERR_FILENO) {
kprintf("sys_write supported only to stdout\n");
return -1;
}
for (i=0;i<(int)size;i++) {
putch(ary[i]);
}
return i;
}

View File

@ -0,0 +1,15 @@
#include <syscall.h>
#include <proc.h>
#include <thread.h>
#include <addrspace.h>
void sys__exit(int status) {
(void)status;
/* delete current process as */
struct addrspace *as = proc_getas();
as_destroy(as);
/* exit thread */
thread_exit();
panic("sys__exit end reached!!\n");
}