From a53ddff3f0482baaacc14a7500bba281c167c99e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 2 Sep 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-09-02 --- bitsy/clock.c | 53 +++++++++++++++++++ bitsy/dat.h | 9 ++++ bitsy/fns.h | 3 ++ bitsy/l.s | 17 ++++-- bitsy/main.c | 40 +++++++++++++- bitsy/mem.h | 21 +++++++- bitsy/mmu.c | 26 +++++++++ bitsy/random.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++ bitsy/screen.c | 44 +++++++++++++++ bitsy/screen.h | 2 + bitsy/segment.h | 8 +++ bitsy/trap.c | 123 ++++++++++++++++++++++++++++++++++++++++++ pc/trap.c | 3 ++ 13 files changed, 481 insertions(+), 6 deletions(-) create mode 100644 bitsy/clock.c create mode 100644 bitsy/mmu.c create mode 100644 bitsy/random.c create mode 100644 bitsy/screen.c create mode 100644 bitsy/screen.h create mode 100644 bitsy/segment.h create mode 100644 bitsy/trap.c diff --git a/bitsy/clock.c b/bitsy/clock.c new file mode 100644 index 0000000000000000000000000000000000000000..87ffe715924cad950e0704c28f2ce90d14456e94 --- /dev/null +++ b/bitsy/clock.c @@ -0,0 +1,53 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" +#include "../port/error.h" + +typedef struct Clock0link Clock0link; +typedef struct Clock0link { + void (*clock)(void); + Clock0link* link; +} Clock0link; + +static Clock0link *clock0link; +static Lock clock0lock; + +void +addclock0link(void (*clock)(void)) +{ + Clock0link *lp; + + if((lp = malloc(sizeof(Clock0link))) == 0){ + print("addclock0link: too many links\n"); + return; + } + ilock(&clock0lock); + lp->clock = clock; + lp->link = clock0link; + clock0link = lp; + iunlock(&clock0lock); +} + + +vlong +fastticks(uvlong *hz) +{ + USED(hz); + + return m->ticks; +} + +void +clockintr(Ureg*, void*) +{ +} + +void +delay(int ms) +{ + USED(ms); +} diff --git a/bitsy/dat.h b/bitsy/dat.h index a311ab3bca29c829a36f24bb4db68034da9bbf85..e0ff4eaf4738b26891393fc822a8f76a627b3b3a 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -34,6 +34,15 @@ struct Label /* * no floating point, hence nothing to save */ + +/* + * FPsave.status + */ +enum +{ + FPinit, + FPinactive, +}; struct FPsave { int dummy; diff --git a/bitsy/fns.h b/bitsy/fns.h index dbc70addf6c8b6d66f8872d4ba393a64a406d1af..672769b76ae2dbc06ce8cba7664a331eacd7581a 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -7,8 +7,11 @@ void clockintr(Ureg*, void*); void clockintrsched(void); void (*coherence)(void); void delay(int); +void evenaddr(ulong); +#define getpgcolor(a) 0 void idle(void); #define idlehands() /* nothing to do in the runproc */ +int iprint(char*, ...); #define procrestore(p) void procsave(Proc*); void procsetup(Proc*); diff --git a/bitsy/l.s b/bitsy/l.s index 3d9e0f9a11ea9ea151d2ba444d33e3ca28e21141..865955a7ed735166b13f5170538c4b388f58915c 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -17,11 +17,15 @@ _main: ORR $(CpCdcache|CpCwb), R1 MCR CpMMU, 0, R1, C(CpControl), C(0x0) + /* turn off interrupts */ + BL splhi(SB) + MOVW $(MACHADDR+BY2PG), R13 /* stack */ SUB $4, R13 /* link */ BL main(SB) BL exit(SB) /* we shouldn't get here */ + BL _div(SB) /* hack to get _div etc loaded */ _mainloop: B _mainloop @@ -162,12 +166,13 @@ _vswitch: /* switch to svc, type in R0 */ MOVM.IA (R3), [R0-R3] /* restore [R0-R3] */ B _vsaveu + /* push the registers as in ureg */ _vsaveu: SUB $4, R13 /* save link */ MOVW R14, (R13) - MOVM.DB.W [R0-R14], (R13) /* save svc registers */ + MOVM.DB.W.S [R0-R14], (R13) /* save svc registers */ - MOVW $setR12(SB), R12 /* safety */ + MOVW $setR12(SB), R12 /* the SB from user mode is different */ MOVW R13, R0 /* argument is &ureg */ SUB $8, R13 /* space for argument+link */ BL exception(SB) @@ -177,7 +182,7 @@ _vrfe: MOVW (R13), R14 /* restore link */ MOVW 8(R13), R0 /* restore SPSR */ MOVW R0, SPSR - MOVM.DB (R13), [R0-R14] /* restore registers */ + MOVM.DB.S (R13), [R0-R14] /* restore registers */ ADD $12, R13 /* skip saved link+type+SPSR */ RFE /* MOVM.IA.S.W (R13), [R15] */ @@ -199,6 +204,12 @@ TEXT splx(SB), $-4 MOVW R1, CPSR RET +TEXT splxpc(SB), $0 /* for iunlock */ + MOVW R0, R1 + MOVW CPSR, R0 + MOVW R1, CPSR + RET + TEXT islo(SB), $-4 MOVW CPSR, R0 AND $(PsrDfiq|PsrDirq), R0 diff --git a/bitsy/main.c b/bitsy/main.c index 107466dc2d1e77e1a6b8d4d5e9a5cd1b69647b30..f10e2c85a57e9d2bc121a6f11852899561d748ce 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -9,13 +9,51 @@ #include "pool.h" Mach *m; +Conf conf; void main(void) { + +} + +/* + * exit kernel either on a panic or user request + */ +void +exit(int ispanic) +{ + USED(ispanic); +} + +/* + * set mach dependent process state for a new process + */ +void +procsetup(Proc *p) +{ + p->fpstate = FPinit; +} + +/* + * Save the mach dependent part of the process state. + */ +void +procsave(Proc *p) +{ + USED(p); +} + +/* place holder */ +void +serialputs(char*, int) +{ } +/* + * dummy since rdb is not included + */ void -exit(int) +rdb(void) { } diff --git a/bitsy/mem.h b/bitsy/mem.h index 26323cca26ea4c7be02119bb9199285151f17b19..cdfd8e0e630f4c2040ccccb678f3705e7423ff08 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -14,6 +14,7 @@ #define PGSHIFT 12 /* log(BY2PG) */ #define ROUND(s, sz) (((s)+(sz-1))&~(sz-1)) #define PGROUND(s) ROUND(s, BY2PG) +#define BLOCKALIGN 8 #define MAXMACH 1 /* max # cpus system can run */ @@ -27,11 +28,22 @@ #define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ /* - * Address spaces + * Fundamental addresses */ -#define KZERO 0xC0000000 #define MACHADDR (KZERO+0x00001000) +/* + * Address spaces + */ +#define UZERO 0 /* base of user address space */ +#define UTZERO (UZERO+BY2PG) /* first address in user text */ +#define KZERO 0xC0000000 /* base of kernel address space */ +#define KTZERO 0xC0008000 /* first address in kernel text */ +#define USTKTOP (KZERO-BY2PG) /* byte just beyond user stack */ +#define USTKSIZE (16*1024*1024) /* size of user stack */ +#define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */ +#define TSTKSIZ 100 + #define KSTACK (16*1024) /* Size of kernel stack */ /* @@ -46,3 +58,8 @@ /* * physical MMU */ +#define PTEVALID 0 +#define PTERONLY 0 +#define PTEWRITE 0 +#define PTEUNCACHED 0 + diff --git a/bitsy/mmu.c b/bitsy/mmu.c new file mode 100644 index 0000000000000000000000000000000000000000..2d9e8b37d1937c0c34adb7154ee271247fc1825c --- /dev/null +++ b/bitsy/mmu.c @@ -0,0 +1,26 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" +#include "../port/error.h" + +void +putmmu(ulong va, ulong pa, Page*) +{ + USED(va, pa); +} + +void +mmurelease(Proc* proc) +{ + USED(proc); +} + +void +mmuswitch(Proc* proc) +{ + USED(proc); +} diff --git a/bitsy/random.c b/bitsy/random.c new file mode 100644 index 0000000000000000000000000000000000000000..282e8c99a29b625dc7be4b2b37f564c2ed8bf11b --- /dev/null +++ b/bitsy/random.c @@ -0,0 +1,138 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + + +struct Rb +{ + QLock; + Rendez producer; + Rendez consumer; + ulong randomcount; + uchar buf[1024]; + uchar *ep; + uchar *rp; + uchar *wp; + uchar next; + uchar wakeme; + ushort bits; + ulong randn; +} rb; + +static int +rbnotfull(void*) +{ + int i; + + i = rb.rp - rb.wp; + return i != 1 && i != (1 - sizeof(rb.buf)); +} + +static int +rbnotempty(void*) +{ + return rb.wp != rb.rp; +} + +static void +genrandom(void*) +{ + up->basepri = PriNormal; + up->priority = up->basepri; + + for(;;){ + for(;;) + if(++rb.randomcount > 100000) + break; + if(anyhigher()) + sched(); + if(!rbnotfull(0)) + sleep(&rb.producer, rbnotfull, 0); + } +} + +/* + * produce random bits in a circular buffer + */ +static void +randomclock(void) +{ + if(rb.randomcount == 0 || !rbnotfull(0)) + return; + + rb.bits = (rb.bits<<2) ^ rb.randomcount; + rb.randomcount = 0; + + rb.next++; + if(rb.next != 8/2) + return; + rb.next = 0; + + *rb.wp ^= rb.bits; + if(rb.wp+1 == rb.ep) + rb.wp = rb.buf; + else + rb.wp = rb.wp+1; + + if(rb.wakeme) + wakeup(&rb.consumer); +} + +void +randominit(void) +{ + addclock0link(randomclock); + rb.ep = rb.buf + sizeof(rb.buf); + rb.rp = rb.wp = rb.buf; + kproc("genrandom", genrandom, 0); +} + +/* + * consume random bytes from a circular buffer + */ +ulong +randomread(void *xp, ulong n) +{ + uchar *e, *p; + ulong x; + + p = xp; + + if(waserror()){ + qunlock(&rb); + nexterror(); + } + + qlock(&rb); + for(e = p + n; p < e; ){ + if(rb.wp == rb.rp){ + rb.wakeme = 1; + wakeup(&rb.producer); + sleep(&rb.consumer, rbnotempty, 0); + rb.wakeme = 0; + continue; + } + + /* + * beating clocks will be precictable if + * they are synchronized. Use a cheap pseudo + * random number generator to obscure any cycles. + */ + x = rb.randn*1103515245 ^ *rb.rp; + *p++ = rb.randn = x; + + if(rb.rp+1 == rb.ep) + rb.rp = rb.buf; + else + rb.rp = rb.rp+1; + } + qunlock(&rb); + poperror(); + + wakeup(&rb.producer); + + return n; +} diff --git a/bitsy/screen.c b/bitsy/screen.c new file mode 100644 index 0000000000000000000000000000000000000000..b9bcd00f89618bb2489dd8cc01044fe91c448289 --- /dev/null +++ b/bitsy/screen.c @@ -0,0 +1,44 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" +#include "../port/error.h" + +#define Image IMAGE +#include +#include +#include +#include "screen.h" + +void +flushmemscreen(Rectangle) +{ +} + +uchar* +attachscreen(Rectangle*, ulong*, int*, int*, int*) +{ + return nil; +} + +void +getcolor(ulong p, ulong* pr, ulong* pg, ulong* pb) +{ + USED(p, pr, pg, pb); +} + +int +setcolor(ulong p, ulong r, ulong g, ulong b) +{ + USED(p,r,g,b); + return 0; +} + +void +blankscreen(int blank) +{ + USED(blank); +} diff --git a/bitsy/screen.h b/bitsy/screen.h new file mode 100644 index 0000000000000000000000000000000000000000..76f6cbb977ccb685b1c5523a043387e3f8804331 --- /dev/null +++ b/bitsy/screen.h @@ -0,0 +1,2 @@ +extern void blankscreen(int); +extern void flushmemscreen(Rectangle); diff --git a/bitsy/segment.h b/bitsy/segment.h new file mode 100644 index 0000000000000000000000000000000000000000..3f6e9542bee2c5956771b00436fa8bbb8f17f350 --- /dev/null +++ b/bitsy/segment.h @@ -0,0 +1,8 @@ +/* + * Attach segment types + */ +static Physseg physseg[10] = { + { SG_SHARED, "shared", 0, SEGMAXSIZE, 0, 0 }, + { SG_BSS, "memory", 0, SEGMAXSIZE, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, +}; diff --git a/bitsy/trap.c b/bitsy/trap.c new file mode 100644 index 0000000000000000000000000000000000000000..cf2cf967a18f80a0bbf1c64f3d2256a9ab54585d --- /dev/null +++ b/bitsy/trap.c @@ -0,0 +1,123 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "ureg.h" +#include "../port/error.h" + +/* + * called in sysfile.c + */ +void +evenaddr(ulong addr) +{ + if(addr & 3){ + postnote(up, 1, "sys: odd address", NDebug); + error(Ebadarg); + } +} + +void +exception(void) +{ +} + +/* Give enough context in the ureg to produce a kernel stack for + * a sleeping process + */ +void +setkernur(Ureg *ureg, Proc *p) +{ + USED(ureg, p); +} + +/* + * return the userpc the last exception happened at + */ +ulong +userpc(void) +{ + return 0; +} + +/* This routine must save the values of registers the user is not permitted + * to write from devproc and then restore the saved values before returning. + */ +void +setregisters(Ureg* ureg, char* pureg, char* uva, int n) +{ + USED(ureg, pureg, uva, n); +} + +/* + * this is the body for all kproc's + */ +static +void +linkproc(void) +{ + spllo(); + up->kpfun(up->kparg); +} + +/* + * setup stack and initial PC for a new kernel proc. This is architecture + * dependent because of the starting stack location + */ +void +kprocchild(Proc *p, void (*func)(void*), void *arg) +{ + p->sched.pc = (ulong)linkproc; + p->sched.sp = (ulong)p->kstack+KSTACK; + + p->kpfun = func; + p->kparg = arg; +} + + +/* + * Craft a return frame which will cause the child to pop out of + * the scheduler in user mode with the return register zero. Set + * pc to point to a l.s return function. + */ +void +forkchild(Proc *p, Ureg *ureg) +{ + USED(p, ureg); +} + +/* + * setup stack, initial PC, and any arch dependent regs for an execing user proc. + */ +long +execregs(ulong entry, ulong ssize, ulong nargs) +{ + ulong *sp; + Ureg *ureg; + + sp = (ulong*)(USTKTOP - ssize); + *--sp = nargs; + + ureg = up->dbgreg; + ureg->r13 = (ulong)sp; + ureg->pc = entry; + return USTKTOP-BY2WD; /* address of user-level clock */ +} + +/* + * dump the processor stack for this process + */ +void +dumpstack(void) +{ +} + + +ulong +dbgpc(Proc *p) +{ + USED(p); + return 0; +} diff --git a/pc/trap.c b/pc/trap.c index 07050fff83737dab78ac3dff0b1d118d9739797e..3928680ae6a1d560de5f84bf436db301da09da54 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -712,6 +712,9 @@ execregs(ulong entry, ulong ssize, ulong nargs) return USTKTOP-BY2WD; /* address of user-level clock */ } +/* + * return the userpc the last exception happened at + */ ulong userpc(void) {