From d2a38bfd2e8dedc6bfb69153bc5f7d6f39acf746 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 7 Oct 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-10-07 --- bitsy/clock.c | 20 +-- bitsy/dat.h | 8 ++ bitsy/devuart.c | 325 ++++++++---------------------------------------- bitsy/fns.h | 14 ++- bitsy/io.h | 87 +++++++++++++ bitsy/l.s | 79 +++++++----- bitsy/main.c | 14 ++- bitsy/mem.h | 2 +- bitsy/mmu.c | 21 ++-- bitsy/trap.c | 44 +++++-- pc/devi82365.c | 5 +- 11 files changed, 271 insertions(+), 348 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index c84b8f6b26e2d5d7387a55002f0eabab5579eb25..caf4957c9575009f4002836e91e8b8cd20ab5bdc 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -18,12 +18,6 @@ typedef struct OSTimer static OSTimer *timerregs = (OSTimer*)OSTIMERREGS; -enum -{ - /* hardware counter frequency */ - ClockFreq= 3686400, -}; - static void clockintr(Ureg*, void*); typedef struct Clock0link Clock0link; @@ -58,8 +52,9 @@ clockinit(void) timerregs = mapspecial(OSTIMERREGS, 32); /* enable interrupts on match register 0, turn off all others */ - timerregs->oier = 1<<0; + timerregs->ossr |= 1<<0; intrenable(IRQtimer0, clockintr, nil, "clock"); + timerregs->oier = 1<<0; /* post interrupt 1/HZ secs from now */ timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ; @@ -91,15 +86,10 @@ clockintr(Ureg*, void*) void delay(int ms) { - ulong cnt, old; + ulong start; while(ms-- > 0){ - cnt = ClockFreq/1000; - while(cnt-- > 0){ - old = timerregs->oscr; - while(old == timerregs->oscr) - ; - } + start = timerregs->oscr; + while(timerregs->oscr-start < ClockFreq/1000); } - } diff --git a/bitsy/dat.h b/bitsy/dat.h index 9699990855754788b1d7ec0dbd4c49b126786443..1283184bfe313f8eddae1e076d1abe22779dbfe1 100644 --- a/bitsy/dat.h +++ b/bitsy/dat.h @@ -10,6 +10,8 @@ typedef struct PMMU PMMU; typedef struct Proc Proc; typedef struct Ureg Ureg; typedef struct Vctl Vctl; +typedef struct PhysUart PhysUart; +typedef struct Uart Uart; /* * parameters for sysproc.c @@ -134,6 +136,12 @@ struct Mach vlong mtrrfix[11]; vlong mtrrvar[32]; /* 256 max. */ + /* save areas for exceptions */ + ulong sfiq[5]; + ulong sirq[5]; + ulong sund[5]; + ulong sabt[5]; + int stack[1]; }; diff --git a/bitsy/devuart.c b/bitsy/devuart.c index b353ec96dc922b5ef33d4ba5a8a9315f0f3bee00..5b2a275f8248de45c2196e08f65b6055e8ddcf6a 100644 --- a/bitsy/devuart.c +++ b/bitsy/devuart.c @@ -8,119 +8,7 @@ #include "../port/netif.h" -enum -{ - Nuart = 1, - Stagesize= 1024, -}; - -/* hardware registers */ -struct Uartregs -{ - ulong ctl[4]; - ulong dummya; - ulong data; - ulong dummyb; - ulong status0; - ulong status1; -}; - -enum -{ - /* ctl[0] bits */ - Parity= 1<<0, - Even= 1<<1, - Stop1= 0<<2, - Stop2= 1<<2, - Bits7= 0<<3, - Bits8= 1<<3, - SCE= 1<<4, /* synchronous clock enable */ - RCE= 1<<5, /* rx on falling edge of clock */ - TCE= 1<<6, /* tx on falling edge of clock */ - - /* ctl[3] bits */ - Rena= 1<<0, /* receiver enable */ - Tena= 1<<1, /* transmitter enable */ - Break= 1<<2, /* force TXD3 low */ - Rintena= 1<<3, /* enable receive interrupt */ - Tintena= 1<<4, /* enable transmitter interrupt */ - Loopback= 1<<5, /* loop back data */ - - /* data bits */ - DEparity= 1<<8, /* parity error */ - DEframe= 1<<9, /* framing error */ - DEoverrun= 1<<10, /* overrun error */ - - /* status0 bits */ - Tint= 1<<0, /* transmit fifo half full interrupt */ - Rint0= 1<<1, /* receiver fifo 1/3-2/3 full */ - Rint1= 1<<2, /* receiver fifo not empty and receiver idle */ - Breakstart= 1<<3, - Breakend= 1<<4, - Fifoerror= 1<<5, /* fifo error */ - - /* status1 bits */ - Tbusy= 1<<0, /* transmitting */ - Rnotempty= 1<<1, /* receive fifo not empty */ - Tnotfull= 1<<2, /* transmit fifo not full */ - ParityError= 1<<3, - FrameError= 1<<4, - Overrun= 1<<5, -}; - -Uartregs *uart3regs = UART3REGS; -/* software representation */ -typedef struct Uart Uart; -struct Uart -{ - QLock; - int dev; - int opens; - Uartregs *regs; - - int enabled; - Uart *elist; /* next enabled interface */ - char name[NAMELEN]; - - uchar sticky[4]; /* sticky write register values */ - ulong freq; /* clock frequency */ - uchar mask; /* bits/char */ - int baud; /* baud rate */ - - int parity; /* parity errors */ - int frame; /* framing errors */ - int overrun; /* rcvr overruns */ - - /* buffers */ - int (*putc)(Queue*, int); - Queue *iq; - Queue *oq; - - Lock rlock; /* receive */ - uchar istage[Stagesize]; - uchar *ip; - uchar *ie; - - int haveinput; - - Lock tlock; /* transmit */ - uchar ostage[Stagesize]; - uchar *op; - uchar *oe; - - int modem; /* hardware flow control on */ - int xonoff; /* software flow control on */ - int blocked; - int cts, dsr, dcd, dcdts; /* keep track of modem status */ - int ctsbackoff; - int hup_dsr, hup_dcd; /* send hangup upstream? */ - int dohup; - - int kinuse; /* device in use by kernel */ - - Rendez r; -}; static Uart* uart[Nuart]; static int nuart; @@ -132,23 +20,20 @@ static int uartndir; */ static char Ekinuse[] = "device in use by kernel"; -static void uartsetbaud(Uart *p, int rate); -static void uartflow(void *v); -static void uartkick0(void *v); -static void uartkick(void *v); -static void uartrts(Uart *p, int on); -static void uartintr(Ureg*, void*); +static void uartdcdhup(Uart*, int); +static void uartdcdts(Uart*, int); +static void uartdsrhup(Uart*, int); /* - * define a Uart. + * define a Uart */ -static void -uartsetup0(Uartregs *regs, ulong freq, char *name) +Uart* +uartsetup(PhysUart *phys, void *regs, ulong freq, char *name) { Uart *p; if(nuart >= Nuart) - return; + return nil; p = xalloc(sizeof(Uart)); uart[nuart] = p; @@ -156,23 +41,21 @@ uartsetup0(Uartregs *regs, ulong freq, char *name) p->dev = nuart++; p->freq = freq; p->regs = regs; - - memset(p->sticky, 0, sizeof(p->sticky)); + p->phys = phys; /* * set rate to 115200 baud. * 8 bits/character. * 1 stop bit. - * interrupts disabled. + * enabled with interrupts disabled. */ - p->sticky[0] = Bits8; - p->regs->ctl[0] = p->sticky[0]; - p->sticky[3] = Rena|Tena; - p->regs->ctl[3] = p->sticky[3]; - uartsetbaud(p, 115200); - - p->iq = qopen(4*1024, 0, uartflow, p); - p->oq = qopen(4*1024, 0, uartkick, p); + (*p->phys->bits)(p, 8); + (*p->phys->stop)(p, 1); + (*p->phys->baud)(p, 115200); + (*p->phys->enable)(p, 0); + + p->iq = qopen(4*1024, 0, p->phys->flow, p); + p->oq = qopen(4*1024, 0, p->phys->kick, p); if(p->iq == nil || p->oq == nil) panic("uartsetup"); @@ -180,47 +63,7 @@ uartsetup0(Uartregs *regs, ulong freq, char *name) p->ie = &p->istage[Stagesize]; p->op = p->ostage; p->oe = p->ostage; -} - -/* - * setup all uarts (called early by main() to allow debugging output to - * a serial port) - */ -void -uartsetup(void) -{ - uart3regs = mapspecial(UART3REGS, 64); - uartsetup0(uart3regs, 36864000, "serialport3"); -} - -/* - * enable a port's interrupts. set DTR and RTS - */ -static void -uartenable(Uart *p) -{ - p->sticky[3] |= Rintena|Tintena; - p->regs->ctl[3] = p->sticky[3]; - intrenable(IRQuart3, uartintr, p, p->name); -} - -/* - * disable interrupts. clear DTR, and RTS - */ -static void -uartdisable(Uart *p) -{ - p->sticky[3] &= ~(Rintena|Tintena); - p->regs->ctl[3] = p->sticky[3]; -} - -static long -uartstatus(Chan*, Uart *p, void *buf, long n, long offset) -{ - USED(p); -// "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n" -// "dev(%d) type(%d) framing(%d) overruns(%d)%s%s%s%s\n", - return readstr(offset, buf, n, ""); + return p; } static void @@ -304,7 +147,7 @@ uartopen(Chan *c, int omode) error(Ekinuse); qlock(p); if(p->opens++ == 0){ - uartenable(p); + (*p->phys->enable)(p, 1); qreopen(p->iq); qreopen(p->oq); } @@ -332,7 +175,7 @@ uartclose(Chan *c) error(Ekinuse); qlock(p); if(--(p->opens) == 0){ - uartdisable(p); + (*p->phys->disable)(p); qclose(p->iq); qclose(p->oq); p->ip = p->istage; @@ -363,7 +206,7 @@ uartread(Chan *c, void *buf, long n, vlong off) case Nctlqid: return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE); case Nstatqid: - return uartstatus(c, p, buf, n, offset); + return (*p->phys->status)(p, buf, n, offset); } return 0; @@ -385,7 +228,7 @@ uartctl(Uart *p, char *cmd) for(i = 0; i < nf; i++){ if(strncmp(f[i], "break", 5) == 0){ -// uartbreak(p, 0); + (*p->phys->dobreak)(p, 0); continue; } @@ -393,19 +236,19 @@ uartctl(Uart *p, char *cmd) switch(*f[i]){ case 'B': case 'b': -// uartsetbaud(p, n); + (*p->phys->baud)(p, n); break; case 'C': case 'c': -// uartdcdhup(p, n); + uartdcdhup(p, n); break; case 'D': case 'd': -// uartdtr(p, n); + (*p->phys->dtr)(p, n); break; case 'E': case 'e': -// uartdsrhup(p, n); + uartdsrhup(p, n); break; case 'f': case 'F': @@ -418,17 +261,14 @@ uartctl(Uart *p, char *cmd) break; case 'i': case 'I': -// lock(&p->flock); -// uartfifo(p, n); -// unlock(&p->flock); break; case 'L': case 'l': -// uartbits(p, n); + (*p->phys->bits)(p, n); break; case 'm': case 'M': -// uartmflow(p, n); + (*p->phys->modemctl)(p, n); break; case 'n': case 'N': @@ -436,15 +276,15 @@ uartctl(Uart *p, char *cmd) break; case 'P': case 'p': -// uartparity(p, *(cmd+1)); + (*p->phys->parity)(p, *(cmd+1)); break; case 'K': case 'k': -// uartbreak(p, n); + (*p->phys->dobreak)(p, n); break; case 'R': case 'r': -// uartrts(p, n); + (*p->phys->rts)(p, n); break; case 'Q': case 'q': @@ -453,7 +293,7 @@ uartctl(Uart *p, char *cmd) break; case 'T': case 't': -// uartdcdts(p, n); + uartdcdts(p, n); break; case 'W': case 'w': @@ -536,107 +376,42 @@ Dev uartdevtab = { }; /* - * set the buad rate + * decide if we should hangup when dsr or dcd drops. */ static void -uartsetbaud(Uart *p, int rate) +uartdsrhup(Uart *p, int n) { - ulong brconst; - - if(rate <= 0) - return; - - brconst = (p->freq+8*rate-1)/(16*rate) - 1; - p->regs->ctl[1] = (brconst>>8) & 0xf; - p->regs->ctl[2] = brconst; - - p->baud = rate; + p->hup_dsr = n; } -/* - * turn on/off rts - */ static void -uartrts(Uart*, int) +uartdcdhup(Uart *p, int n) { + p->hup_dcd = n; } /* - * restart input if it's off + * save dcd timestamps for gps clock */ static void -uartflow(void *v) +uartdcdts(Uart *p, int n) { - Uart *p; - - p = v; - if(p->modem){ - uartrts(p, 1); - ilock(&p->rlock); - p->haveinput = 1; - iunlock(&p->rlock); - } + p->dcdts = n; } /* - * restart output if not blocked and OK to send + * put some bytes into the local queue to avoid calling + * qconsume for every character */ -static void -uartkick0(void *v) +int +uartstageoutput(Uart *p) { - int i; - Uart *p; + int n; - p = v; - if(p->cts == 0 || p->blocked) - return; - - /* - * 128 here is an arbitrary limit to make sure - * we don't stay in this loop too long. If the - * chips output queue is longer than 128, too - * bad -- presotto - */ - for(i = 0; i < 128; i++){ -// if(!(uartrdreg(p, Lstat) & Outready)) -// break; -// if(p->op >= p->oe && stageoutput(p) == 0) -// break; -// outb(p->port + Data, *(p->op++)); - } -} - -static void -uartkick(void *v) -{ - Uart *p; - - p = v; - ilock(&p->tlock); - uartkick0(p); - iunlock(&p->tlock); -} - -static void -uartintr(Ureg*, void *x) -{ - Uart *p; - - p = x; -} - -void -serialputs(char *str, int n) -{ - Uartregs *ur; - - ur = uart3regs; - while(n-- > 0){ - /* wait for output ready */ - while((ur->status1 & Tnotfull) == 0) - ; - ur->data = *str++; - } - while((ur->status1 & Tbusy)) - ; + n = qconsume(p->oq, p->ostage, Stagesize); + if(n <= 0) + return 0; + p->op = p->ostage; + p->oe = p->ostage + n; + return n; } diff --git a/bitsy/fns.h b/bitsy/fns.h index 99e1a2e317d047b8c4f537a2bac8a57e3431f780..88c5483e5aaaff2deaabe576f208b8ae1b9dd3ed 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -7,14 +7,18 @@ void clockinit(void); #define coherence() void delay(int); void evenaddr(ulong); -void exceptionvectors(void); +void flushcache(void); +void flushmmu(void); ulong getfar(void); ulong getfsr(void); #define getpgcolor(a) 0 +void h3650uartsetup(void); void idle(void); #define idlehands() /* nothing to do in the runproc */ void intrenable(int, void (*)(Ureg*, void*), void*, char*); int iprint(char*, ...); +void mappedIvecEnable(void); +void mappedIvecDisable(void); void* mapspecial(ulong, int); void meminit(void); void mmuinit(void); @@ -29,13 +33,19 @@ void putdac(ulong); void putttb(ulong); void putpid(ulong); void reset(void); +Uart* uartsetup(PhysUart*, void*, ulong, char*); +void sa1100_uartsetup(void); void screeninit(void); int screenprint(char*, ...); /* debugging */ void (*screenputs)(char*, int); +void setr13(int, ulong*); void touser(void*); +void trapdump(char *tag); void trapinit(void); int tas(void*); -void uartsetup(void); +int uartstageoutput(Uart*); +void vectors(void); +void vtable(void); void wbflush(void); #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) diff --git a/bitsy/io.h b/bitsy/io.h index a86877ea95e72d9eb1492e6deccb6ab65f852f69..4f29a58a23531d6273ed2d2cfdfc8388ba4801e1 100644 --- a/bitsy/io.h +++ b/bitsy/io.h @@ -77,3 +77,90 @@ enum COM_RTS_oi= 1<<26, /* RTS to UART3 */ OPT_IND_i= 1<<27, /* expansion pack inserted */ }; + +enum +{ + /* hardware counter frequency */ + ClockFreq= 3686400, + Stagesize= 1024, + Nuart = 4, + + /* soft flow control chars */ + CTLS= 023, + CTLQ= 021, +}; + +typedef struct PhysUart PhysUart; +typedef struct Uart Uart; + +/* link twixt hardware and software */ +struct PhysUart +{ + void (*enable)(Uart*, int); + void (*disable)(Uart*); + void (*kick)(void*); + void (*flow)(void*); + void (*intr)(Ureg*, void*); + void (*dobreak)(Uart*, int); + void (*baud)(Uart*, int); + void (*bits)(Uart*, int); + void (*stop)(Uart*, int); + void (*parity)(Uart*, int); + void (*modemctl)(Uart*, int); + void (*rts)(Uart*, int); + void (*dtr)(Uart*, int); + long (*status)(Uart*, void*, long, long); +}; + +/* software representation */ +struct Uart +{ + QLock; + int type; + int dev; + int opens; + void *regs; + PhysUart *phys; + + int enabled; + Uart *elist; /* next enabled interface */ + char name[NAMELEN]; + + uchar sticky[4]; /* sticky write register values */ + ulong freq; /* clock frequency */ + uchar mask; /* bits/char */ + int baud; /* baud rate */ + + int parity; /* parity errors */ + int frame; /* framing errors */ + int overrun; /* rcvr overruns */ + + /* buffers */ + int (*putc)(Queue*, int); + Queue *iq; + Queue *oq; + + Lock rlock; /* receive */ + uchar istage[Stagesize]; + uchar *ip; + uchar *ie; + + int haveinput; + + Lock tlock; /* transmit */ + uchar ostage[Stagesize]; + uchar *op; + uchar *oe; + + int modem; /* hardware flow control on */ + int xonoff; /* software flow control on */ + int blocked; + int cts, dsr, dcd, dcdts; /* keep track of modem status */ + int ctsbackoff; + int hup_dsr, hup_dcd; /* send hangup upstream? */ + int dohup; + + int kinuse; /* device in use by kernel */ + + Rendez r; +}; diff --git a/bitsy/l.s b/bitsy/l.s index 71ef71f4531d012a780d5030f145c30bf2c0b80f..bfdc4e6d1dc996f3b9b68a1f25139bb92ca58825 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -10,8 +10,12 @@ _main: MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 MOVW R1, CPSR - /* flush TLB's */ - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0) + /* disable the MMU */ + MOVW $0x130, R1 + MCR CpMMU, 0, R1, C(CpControl), C(0x0) + + /* flush caches */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 /* drain prefetch */ MOVW R0,R0 MOVW R0,R0 @@ -19,11 +23,7 @@ _main: MOVW R0,R0 /* drain write buffer */ - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0), 4 - - /* disable the MMU */ - MOVW $0x130, R1 - MCR CpMMU, 0, R1, C(CpControl), C(0x0) + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 MOVW $(MACHADDR+BY2PG), R13 /* stack */ SUB $4, R13 /* link */ @@ -36,12 +36,12 @@ _mainloop: /* flush tlb's */ TEXT flushmmu(SB), $-4 - MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x0) + MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7) RET /* flush instruction cache */ TEXT flushicache(SB), $-4 - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0) + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0 /* drain prefetch */ MOVW R0,R0 MOVW R0,R0 @@ -51,12 +51,12 @@ TEXT flushicache(SB), $-4 /* flush data cache */ TEXT flushdcache(SB), $-4 - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0) + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x6), 0 RET /* flush i and d caches */ TEXT flushcache(SB), $-4 - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0) + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 /* drain prefetch */ MOVW R0,R0 MOVW R0,R0 @@ -66,7 +66,7 @@ TEXT flushcache(SB), $-4 /* drain write buffer */ TEXT wbflush(SB), $-4 - MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x0), 4 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 RET /* return cpu id */ @@ -90,11 +90,11 @@ TEXT putttb(SB), $-4 RET /* - * enable mmu, i and d caches, and exception vectors at 0xffff0000 + * enable mmu, i and d caches */ TEXT mmuenable(SB), $-4 MRC CpMMU, 0, R0, C(CpControl), C(0x0) - ORR $(CpCmmuena|CpCdcache|CpCicache|CpCvivec), R0 + ORR $(CpCmmuena|CpCdcache|CpCicache), R0 MCR CpMMU, 0, R0, C(CpControl), C(0x0) RET @@ -104,6 +104,20 @@ TEXT mmudisable(SB), $-4 MCR CpMMU, 0, R0, C(CpControl), C(0x0) RET +/* + * use exception vectors at 0xffff0000 + */ +TEXT mappedIvecEnable(SB), $-4 + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + ORR $(CpCvivec), R0 + MCR CpMMU, 0, R0, C(CpControl), C(0x0) + RET +TEXT mappedIvecDisable(SB), $-4 + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + BIC $(CpCvivec), R0 + MCR CpMMU, 0, R0, C(CpControl), C(0x0) + RET + /* set the translation table base */ TEXT putdac(SB), $-4 MCR CpMMU, 0, R0, C(CpDAC), C(0x0) @@ -134,23 +148,26 @@ TEXT setr13(SB), $-4 /* * exception vectors, copied by trapinit() to somewhere useful */ -TEXT exceptionvectors(SB), $-4 - MOVW 0x18(R15), R15 /* reset */ - MOVW 0x18(R15), R15 /* undefined */ - MOVW 0x18(R15), R15 /* SWI */ - MOVW 0x18(R15), R15 /* prefetch abort */ - MOVW 0x18(R15), R15 /* data abort */ - MOVW 0x18(R15), R15 /* reserved */ - MOVW 0x18(R15), R15 /* IRQ */ - MOVW 0x18(R15), R15 /* FIQ */ - WORD $_vrst(SB) /* reset, in svc mode already */ - WORD $_vund(SB) /* undefined, switch to svc mode */ - WORD $_vsvc(SB) /* swi, in svc mode already */ - WORD $_vabt(SB) /* prefetch abort, switch to svc mode */ - WORD $_vabt(SB) /* data abort, switch to svc mode */ - WORD $_vrst(SB) /* reserved, shouldn't happen */ - WORD $_virq(SB) /* IRQ, switch to svc mode */ - WORD $_vfiq(SB) /* FIQ, switch to svc mode */ + +TEXT vectors(SB), $-4 + MOVW 0x18(R15), R15 /* reset */ + MOVW 0x18(R15), R15 /* undefined */ + MOVW 0x18(R15), R15 /* SWI */ + MOVW 0x18(R15), R15 /* prefetch abort */ + MOVW 0x18(R15), R15 /* data abort */ + MOVW 0x18(R15), R15 /* reserved */ + MOVW 0x18(R15), R15 /* IRQ */ + MOVW 0x18(R15), R15 /* FIQ */ + +TEXT vtable(SB), $-4 + WORD $_vsvc(SB) /* reset, in svc mode already */ + WORD $_vund(SB) /* undefined, switch to svc mode */ + WORD $_vsvc(SB) /* swi, in svc mode already */ + WORD $_vabt(SB) /* prefetch abort, switch to svc mode */ + WORD $_vabt(SB) /* data abort, switch to svc mode */ + WORD $_vsvc(SB) /* reserved */ + WORD $_virq(SB) /* IRQ, switch to svc mode */ + WORD $_vfiq(SB) /* FIQ, switch to svc mode */ TEXT _vrst(SB), $-4 BL reset(SB) diff --git a/bitsy/main.c b/bitsy/main.c index c0f235eda05095293de91b5155710a5c458be778..1fcc23ac9747d1f61f2b044f7ffe4ff06dd3bdf6 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -17,6 +17,9 @@ main(void) /* zero out bss */ memset(edata, 0, end-edata); + /* point to Mach structure */ + m = (Mach*)MACHADDR; + iprint("bitsy kernel\n"); confinit(); iprint("%d pages %lux(%lud) %lux(%lud)\n", conf.npage, conf.base0, conf.npage0, conf.base1, conf.npage1); @@ -26,15 +29,17 @@ main(void) delay(2000); iprint("done\n"); mmuinit(); - uartsetup(); + sa1100_uartsetup(); iprint("after mmuinit\n"); - clockinit(); - iprint("after clockinit\n"); trapinit(); iprint("after trapinit\n"); + clockinit(); + iprint("after clockinit\n"); +trapdump("before spllo"); spllo(); iprint("after spllo\n"); - delay(1000000); + delay(10000); +trapdump("after delay"); exit(1); } @@ -181,3 +186,4 @@ confinit(void) conf.copymode = 0; /* copy on write */ } + diff --git a/bitsy/mem.h b/bitsy/mem.h index a61aa7760e69c710c9fd3997e2832875775ecd76..0a6108807d5bec0c47e22ba9df9db22bef27eb45 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -53,7 +53,7 @@ #define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */ #define TSTKSIZ 100 #define MACHADDR (KZERO+0x00001000) -#define EVECTORS 0xFFFF0000 /* base of exception vectors (also mapped to KZERO) */ +#define EVECTORS 0xFFFF0000 /* virt base of exception vectors */ #define KSTACK (16*1024) /* Size of kernel stack */ diff --git a/bitsy/mmu.c b/bitsy/mmu.c index 7ebc84513f19844fd8c85afc0d55099a1af46b1b..cffe10a9bb6afd989fb5e82d1ca37acd7869b6bc 100644 --- a/bitsy/mmu.c +++ b/bitsy/mmu.c @@ -54,6 +54,7 @@ static ulong phystrans[16] = ulong *l1table; + /* * We map all of memory, flash, and the zeros area with sections. * Special use space is mapped on the fly with regmap. @@ -65,8 +66,8 @@ mmuinit(void) ulong *t; /* get a prototype level 1 page */ - l1table = xspanalloc(BY2PG, 16*1024, 0); - memset(l1table, 0, BY2PG); + l1table = xspanalloc(16*1024, 16*1024, 0); + memset(l1table, 0, 16*1024); /* direct map DRAM */ e = conf.base1 + BY2PG*conf.npage1; @@ -83,11 +84,14 @@ mmuinit(void) l1table[a>>20] = L1Section | L1KernelRW | (a&L1SectBaseMask) | L1Cached | L1Buffered; - /* map first page of DRAM also into 0xFFFF0000 for the interrupt vectors */ - t = xspanalloc(BY2PG, 16*1024, 0); + /* + * double map start of ram to exception vectors + */ + a = EVECTORS; + t = xspanalloc(BY2PG, 1024, 0); memset(t, 0, BY2PG); - l1table[0xFFFF0000>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask); - t[0xF0000>>PGSHIFT] = L2SmallPage | L2KernelRW | PHYSDRAM0; + l1table[a>>20] = L1PageTable | L1Domain0 | (((ulong)t) & L1PTBaseMask); + t[(a&0xfffff)>>PGSHIFT] = L2SmallPage | L2KernelRW | (PHYSDRAM0 & L2PageBaseMask); /* set up the domain register to cause all domains to obey pte access bits */ iprint("setting up domain access\n"); @@ -97,7 +101,10 @@ mmuinit(void) iprint("setting tlb map %lux\n", (ulong)l1table); putttb((ulong)l1table); - /* enable mmu, and make 0xFFFF0000 the virtual address of the exception vecs */ + /* enable mmu */ + wbflush(); + flushcache(); + flushmmu(); mmuenable(); } diff --git a/bitsy/trap.c b/bitsy/trap.c index 58c983b9e289861615ed46adc10191eb30939897..944220b1654ffd9a7b6be5f8503a72dca1fce025 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -34,23 +34,40 @@ typedef struct Vctl { static Lock vctllock; static Vctl *vctl[32]; + +/* + * Layout at virtual address 0. + */ +typedef struct Vpage0 { + void (*vectors[8])(void); + ulong vtable[8]; + + ulong hole[16]; +} Vpage0; +Vpage0 *vpage0; + /* * set up for exceptioons */ void trapinit(void) { - /* - * exceptionvectors points to a prototype in l.s of the - * exception vectors that save the regs and then call - * trap(). The actual vectorrs are double mapped - * to 0xffff0000 and to KZERO. We write them via - * KZERO since a data access to them will cause an - * exception. - */ - memmove((void*)KZERO, exceptionvectors, 2*4*8); + /* set up the exception vectors */ + vpage0 = (Vpage0*)EVECTORS; + memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors)); + memmove(vpage0->vtable, vtable, sizeof(vpage0->vtable)); + memset(vpage0->hole, 0, sizeof(vpage0->hole)); wbflush(); + /* use exception vectors at 0xFFFF0000 */ + mappedIvecEnable(); + + /* set up the stacks for the interrupt modes */ + setr13(PsrMfiq, m->sfiq); + setr13(PsrMirq, m->sirq); + setr13(PsrMabt, m->sabt); + setr13(PsrMund, m->sund); + /* map in interrupt registers */ intrregs = mapspecial(INTRREGS, sizeof(*intrregs)); @@ -59,6 +76,15 @@ trapinit(void) intrregs->icmr = 0; } +void +trapdump(char *tag) +{ + iprint("%s: icip %lux icmr %lux iclr %lux iccr %lux icfp %lux\n", + tag, intrregs->icip, intrregs->icmr, intrregs->iclr, + intrregs->iccr, intrregs->icfp); +} + + /* * enable an interrupt and attach a function to it */ diff --git a/pc/devi82365.c b/pc/devi82365.c index da3463701f31aa5e5a5845c239ad84edd50e0f7d..4a7b24aa2c114092b9b6b12cdefc254ab5849679 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -440,10 +440,7 @@ pcmspecial(char *idstr, ISAConf *isa) extern char *strstr(char*, char*); static int resetdone; - if (! resetdone) { - i82365reset(); - resetdone++; - } + i82365reset(); for(pp = slot; pp < lastslot; pp++){ if(pp->special) continue; /* already taken */