lab 2 (probably working)
This commit is contained in:
parent
df7631de81
commit
404ae75cfa
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_ */
|
||||
|
||||
32
kern/syscall/file_syscalls.c
Normal file
32
kern/syscall/file_syscalls.c
Normal 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;
|
||||
}
|
||||
15
kern/syscall/proc_syscalls.c
Normal file
15
kern/syscall/proc_syscalls.c
Normal 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");
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user