A bitsy/clock.c => bitsy/clock.c +53 -0
@@ 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);
+}
M bitsy/dat.h => bitsy/dat.h +9 -0
@@ 34,6 34,15 @@ struct Label
/*
* no floating point, hence nothing to save
*/
+
+/*
+ * FPsave.status
+ */
+enum
+{
+ FPinit,
+ FPinactive,
+};
struct FPsave
{
int dummy;
M bitsy/fns.h => bitsy/fns.h +3 -0
@@ 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*);
M bitsy/l.s => bitsy/l.s +14 -3
@@ 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
M bitsy/main.c => bitsy/main.c +39 -1
@@ 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)
{
}
M bitsy/mem.h => bitsy/mem.h +19 -2
@@ 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
+
A bitsy/mmu.c => bitsy/mmu.c +26 -0
@@ 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);
+}
A bitsy/random.c => bitsy/random.c +138 -0
@@ 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;
+}
A bitsy/screen.c => bitsy/screen.c +44 -0
@@ 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 <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#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);
+}
A bitsy/screen.h => bitsy/screen.h +2 -0
@@ 0,0 1,2 @@
+extern void blankscreen(int);
+extern void flushmemscreen(Rectangle);
A bitsy/segment.h => bitsy/segment.h +8 -0
@@ 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 },
+};
A bitsy/trap.c => bitsy/trap.c +123 -0
@@ 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;
+}
M pc/trap.c => pc/trap.c +3 -0
@@ 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)
{