diff options
author | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-08-18 18:24:55 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-08-18 18:24:55 -0700 |
commit | 29cc0dc9854c66f12bd65e12516f68ccd9a741da (patch) | |
tree | 23bd8147007d3d0fbb005f578f395e71f7d7d18d /pk/pk.c | |
parent | e97220c9bf519b8e0f0b131a4f868331c4d526fb (diff) | |
download | pk-29cc0dc9854c66f12bd65e12516f68ccd9a741da.zip pk-29cc0dc9854c66f12bd65e12516f68ccd9a741da.tar.gz pk-29cc0dc9854c66f12bd65e12516f68ccd9a741da.tar.bz2 |
[pk,fesvr] improved proxykernel build system
Now uses a modified MCPPBS. Add --host=riscv to configure path.
Front-end server now just searches PATH for riscv-pk, so just install the pk
to somewhere in your path.
Diffstat (limited to 'pk/pk.c')
-rw-r--r-- | pk/pk.c | 158 |
1 files changed, 158 insertions, 0 deletions
@@ -0,0 +1,158 @@ +#include "pcr.h" +#include "pk.h" +#include "file.h" +#include "frontend.h" +#include <stdarg.h> +#include <stdbool.h> +#include <string.h> + +static void vsprintk(char* out, const char* s, va_list vl) +{ + bool format = false; + bool longarg = false; + for( ; *s; s++) + { + if(format) + { + switch(*s) + { + case 'l': + longarg = true; + break; + case 'x': + { + long n = longarg ? va_arg(vl,long) : va_arg(vl,int); + for(int i = 2*(longarg ? sizeof(long) : sizeof(int))-1; i >= 0; i--) + { + int d = (n >> (4*i)) & 0xF; + *out++ = (d < 10 ? '0'+d : 'A'+d-10); + } + longarg = false; + format = false; + break; + } + case 'd': + { + long n = longarg ? va_arg(vl,long) : va_arg(vl,int); + if(n < 0) + { + n = -n; + *out++ = '-'; + } + long digits = 1; + for(long nn = n ; nn /= 10; digits++); + for(int i = digits-1; i >= 0; i--) + { + out[i] = '0' + n%10; + n /= 10; + } + out += digits; + longarg = false; + format = false; + break; + } + case 's': + { + const char* s2 = va_arg(vl,const char*); + while(*s2) + *out++ = *s2++; + longarg = false; + format = false; + break; + } + case 'c': + { + *out++ = (char)va_arg(vl,int); + longarg = false; + format = false; + break; + } + default: + panic("bad fmt"); + } + } + else if(*s == '%') + format = true; + else + *out++ = *s; + } + *out++ = '\0'; +} + +void printk(const char* s, ...) +{ + va_list vl; + va_start(vl,s); + + char out[1024]; // XXX + vsprintk(out,s,vl); + cons_write(out,strlen(out)); + + va_end(vl); +} + +void sprintk(char* out, const char* s, ...) +{ + va_list vl; + va_start(vl,s); + + vsprintk(out,s,vl); + + va_end(vl); +} + +void dump_tf(trapframe_t* tf) +{ + static const char* regnames[] = { + "z ", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" + }; + + tf->gpr[0] = 0; + + for(int i = 0; i < 32; i+=4) + { + for(int j = 0; j < 4; j++) + printk("%s %lx%c",regnames[i+j],tf->gpr[i+j],j < 3 ? ' ' : '\n'); + } + printk("sr %lx pc %lx va %lx\n",tf->sr,tf->epc,tf->badvaddr); +} + +void init_tf(trapframe_t* tf, long pc, long sp) +{ + memset(tf,0,sizeof(*tf)); + tf->sr = SR_S | SR_KX | SR_UX; // SR_PS=0 (usermode); SR_ET=0 + tf->gpr[29] = USER_MEM_SIZE-USER_MAINVARS_SIZE; + tf->epc = USER_START; +} + +void bss_init() +{ + extern char edata,end; + memset(&edata,0,&end-&edata); +} + +void mainvars_init() +{ + sysret_t r = frontend_syscall(SYS_getmainvars, + USER_MEM_SIZE-USER_MAINVARS_SIZE, USER_MAINVARS_SIZE, 0, 0); + + kassert(r.result == 0); +} + +void jump_usrstart() +{ + trapframe_t tf; + init_tf(&tf, USER_START, USER_MEM_SIZE-USER_MAINVARS_SIZE); + pop_tf(&tf); +} + +void boot() +{ + bss_init(); + file_init(); + mainvars_init(); + jump_usrstart(); +} |