diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/boot/bitsy |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/boot/bitsy')
-rwxr-xr-x | sys/src/boot/bitsy/dat.h | 0 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/donprint.c | 332 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/fns.h | 7 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/il.s | 99 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/imain.c | 48 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/inflate.c | 208 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/io.h | 261 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/l.s | 454 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/lib.h | 143 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/map | 10 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/mem.h | 213 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/mkfile | 45 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/print.c | 56 | ||||
-rwxr-xr-x | sys/src/boot/bitsy/sinflate | bin | 0 -> 20696 bytes | |||
-rwxr-xr-x | sys/src/boot/bitsy/uart.c | 69 |
15 files changed, 1945 insertions, 0 deletions
diff --git a/sys/src/boot/bitsy/dat.h b/sys/src/boot/bitsy/dat.h new file mode 100755 index 000000000..e69de29bb --- /dev/null +++ b/sys/src/boot/bitsy/dat.h diff --git a/sys/src/boot/bitsy/donprint.c b/sys/src/boot/bitsy/donprint.c new file mode 100755 index 000000000..4125e6904 --- /dev/null +++ b/sys/src/boot/bitsy/donprint.c @@ -0,0 +1,332 @@ +#include "u.h" +#include "lib.h" + +#define PTR sizeof(char*) +#define SHORT sizeof(int) +#define INT sizeof(int) +#define LONG sizeof(long) +#define IDIGIT 30 +#define MAXCON 30 + +#define FLONG (1<<0) +#define FSHORT (1<<1) +#define FUNSIGN (1<<2) + +typedef struct Op Op; +struct Op +{ + char *p; + char *ep; + void *argp; + int f1; + int f2; + int f3; +}; + +static int noconv(Op*); +static int cconv(Op*); +static int dconv(Op*); +static int hconv(Op*); +static int lconv(Op*); +static int oconv(Op*); +static int sconv(Op*); +static int uconv(Op*); +static int xconv(Op*); +static int Xconv(Op*); +static int percent(Op*); + +static +int (*fmtconv[MAXCON])(Op*) = +{ + noconv, + cconv, dconv, hconv, lconv, + oconv, sconv, uconv, xconv, + Xconv, percent, +}; +static +char fmtindex[128] = +{ + ['c'] 1, + ['d'] 2, + ['h'] 3, + ['l'] 4, + ['o'] 5, + ['s'] 6, + ['u'] 7, + ['x'] 8, + ['X'] 9, + ['%'] 10, +}; + +static int convcount = { 11 }; +static int ucase; + +static void +PUT(Op *o, int c) +{ + static int pos; + int opos; + + if(c == '\t'){ + opos = pos; + pos = (opos+8) & ~7; + while(opos++ < pos && o->p < o->ep) + *o->p++ = ' '; + return; + } + if(o->p < o->ep){ + *o->p++ = c; + pos++; + } + if(c == '\n') + pos = 0; +} + +int +fmtinstall(char c, int (*f)(Op*)) +{ + + c &= 0177; + if(fmtindex[c] == 0) { + if(convcount >= MAXCON) + return 1; + fmtindex[c] = convcount++; + } + fmtconv[fmtindex[c]] = f; + return 0; +} + +char* +donprint(char *p, char *ep, char *fmt, void *argp) +{ + int sf1, c; + Op o; + + o.p = p; + o.ep = ep; + o.argp = argp; + +loop: + c = *fmt++; + if(c != '%') { + if(c == 0) { + if(o.p < o.ep) + *o.p = 0; + return o.p; + } + PUT(&o, c); + goto loop; + } + o.f1 = 0; + o.f2 = -1; + o.f3 = 0; + c = *fmt++; + sf1 = 0; + if(c == '-') { + sf1 = 1; + c = *fmt++; + } + while(c >= '0' && c <= '9') { + o.f1 = o.f1*10 + c-'0'; + c = *fmt++; + } + if(sf1) + o.f1 = -o.f1; + if(c != '.') + goto l1; + c = *fmt++; + while(c >= '0' && c <= '9') { + if(o.f2 < 0) + o.f2 = 0; + o.f2 = o.f2*10 + c-'0'; + c = *fmt++; + } +l1: + if(c == 0) + fmt--; + c = (*fmtconv[fmtindex[c&0177]])(&o); + if(c < 0) { + o.f3 |= -c; + c = *fmt++; + goto l1; + } + o.argp = (char*)o.argp + c; + goto loop; +} + +void +strconv(char *o, Op *op, int f1, int f2) +{ + int n, c; + char *p; + + n = strlen(o); + if(f1 >= 0) + while(n < f1) { + PUT(op, ' '); + n++; + } + for(p=o; c = *p++;) + if(f2 != 0) { + PUT(op, c); + f2--; + } + if(f1 < 0) { + f1 = -f1; + while(n < f1) { + PUT(op, ' '); + n++; + } + } +} + +int +numbconv(Op *op, int base) +{ + char b[IDIGIT]; + int i, f, n, r; + long v; + short h; + + f = 0; + switch(op->f3 & (FLONG|FSHORT|FUNSIGN)) { + case FLONG: + v = *(long*)op->argp; + r = LONG; + break; + + case FUNSIGN|FLONG: + v = *(ulong*)op->argp; + r = LONG; + break; + + case FSHORT: + h = *(int*)op->argp; + v = h; + r = SHORT; + break; + + case FUNSIGN|FSHORT: + h = *(int*)op->argp; + v = (ushort)h; + r = SHORT; + break; + + default: + v = *(int*)op->argp; + r = INT; + break; + + case FUNSIGN: + v = *(unsigned*)op->argp; + r = INT; + break; + } + if(!(op->f3 & FUNSIGN) && v < 0) { + v = -v; + f = 1; + } + b[IDIGIT-1] = 0; + for(i = IDIGIT-2;; i--) { + n = (ulong)v % base; + n += '0'; + if(n > '9'){ + n += 'a' - ('9'+1); + if(ucase) + n += 'A'-'a'; + } + b[i] = n; + if(i < 2) + break; + v = (ulong)v / base; + if(op->f2 >= 0 && i >= IDIGIT-op->f2) + continue; + if(v <= 0) + break; + } + if(f) + b[--i] = '-'; + strconv(b+i, op, op->f1, -1); + return r; +} + +static int +noconv(Op *op) +{ + + strconv("***", op, 0, -1); + return 0; +} + +static int +cconv(Op *op) +{ + char b[2]; + + b[0] = *(int*)op->argp; + b[1] = 0; + strconv(b, op, op->f1, -1); + return INT; +} + +static int +dconv(Op *op) +{ + return numbconv(op, 10); +} + +static int +hconv(Op*) +{ + return -FSHORT; +} + +static int +lconv(Op*) +{ + return -FLONG; +} + +static int +oconv(Op *op) +{ + return numbconv(op, 8); +} + +static int +sconv(Op *op) +{ + strconv(*(char**)op->argp, op, op->f1, op->f2); + return PTR; +} + +static int +uconv(Op*) +{ + return -FUNSIGN; +} + +static int +xconv(Op *op) +{ + return numbconv(op, 16); +} + +static int +Xconv(Op *op) +{ + int r; + + ucase = 1; + r = numbconv(op, 16); + ucase = 0; + return r; +} + +static int +percent(Op *op) +{ + + PUT(op, '%'); + return 0; +} diff --git a/sys/src/boot/bitsy/fns.h b/sys/src/boot/bitsy/fns.h new file mode 100755 index 000000000..53af19bf0 --- /dev/null +++ b/sys/src/boot/bitsy/fns.h @@ -0,0 +1,7 @@ +/* + * functions defined locally + */ +extern int gunzip(uchar *out, int outn, uchar *in, int inn); +extern void delay(int ms); +extern void serialputs(char *str, int n); +extern void draincache(void); diff --git a/sys/src/boot/bitsy/il.s b/sys/src/boot/bitsy/il.s new file mode 100755 index 000000000..c75ad987d --- /dev/null +++ b/sys/src/boot/bitsy/il.s @@ -0,0 +1,99 @@ +#include "mem.h" +/* + * Entered here from Compaq's bootldr. First relocate to + * the location we're linked for and then copy back the + * decompressed kernel. + * + * All + */ +TEXT _start(SB), $-4 + MOVW $setR12(SB), R12 /* load the SB */ + MOVW $1, R0 /* dance to make 5l think that the magic */ + MOVW $1, R1 /* numbers in WORDs below are being used */ + CMP.S R0, R1 /* and to align them to where bootldr wants */ + BEQ _start2 + WORD $0x016f2818 /* magic number to say we are a kernel */ + WORD $0xc0008000 /* entry point address */ + WORD $0 /* size?, or end of data? */ + +_start2: + + /* SVC mode, interrupts disabled */ + MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 + MOVW R1, CPSR + + /* disable the MMU */ + MOVW $0x130, R1 + MCR CpMMU, 0, R1, C(CpControl), C(0x0) + + /* enable caches */ + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + ORR $(CpCdcache|CpCicache|CpCwb), R0 + MCR CpMMU, 0, R0, C(CpControl), C(0x0) + + /* flush caches */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 + /* drain prefetch */ + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + + /* drain write buffer */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + + /* relocate to where we expect to be */ + MOVW $(512*1024),R3 + MOVW $0xC0008000,R1 + MOVW $0xC0200000,R2 + ADD R1,R3 +_relloop: + MOVW (R1),R0 + MOVW R0,(R2) + ADD $4,R1 + ADD $4,R2 + CMP.S R1,R3 + BNE _relloop + + MOVW $(MACHADDR+BY2PG), R13 /* stack */ + SUB $4, R13 /* link */ + + /* jump to where we've been relocated */ + MOVW $_relocated(SB),R15 + +TEXT _relocated(SB),$-4 + BL main(SB) + BL exit(SB) + /* we shouldn't get here */ +_mainloop: + B _mainloop + BL _div(SB) /* hack to get _div etc loaded */ + +TEXT mypc(SB),$-4 + MOVW R14,R0 + RET + +TEXT draincache(SB),$-4 + /* write back any dirty data */ + MOVW $0xe0000000,R0 + ADD $(8*1024),R0,R1 +_cfloop: + MOVW.P 32(R0),R2 + CMP.S R0,R1 + BNE _cfloop + + /* drain write buffer and invalidate i&d cache contents */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 + + /* drain prefetch */ + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + + /* disable caches */ + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + BIC $(CpCdcache|CpCicache|CpCwb), R0 + MCR CpMMU, 0, R0, C(CpControl), C(0x0) + RET diff --git a/sys/src/boot/bitsy/imain.c b/sys/src/boot/bitsy/imain.c new file mode 100755 index 000000000..4b8ef2ef2 --- /dev/null +++ b/sys/src/boot/bitsy/imain.c @@ -0,0 +1,48 @@ +#include "u.h" +#include "lib.h" +#include "fns.h" +#include "dat.h" +#include "mem.h" + +void +main(void) +{ + void (*f)(void); + ulong *kernel; + + print("inflating kernel\n"); + + kernel = (ulong*)(0xc0200000+20*1024); + if(gunzip((uchar*)0xc0008000, 2*1024*1024, (uchar*)kernel, 512*1024) > 0){ + f = (void (*)(void))0xc0008010; + draincache(); + } else { + print("inflation failed\n"); + f = nil; + } + (*f)(); +} + +void +exit(void) +{ + + void (*f)(void); + + delay(1000); + + print("it's a wonderful day to die\n"); + f = nil; + (*f)(); +} + +void +delay(int ms) +{ + int i; + + while(ms-- > 0){ + for(i = 0; i < 1000; i++) + ; + } +} diff --git a/sys/src/boot/bitsy/inflate.c b/sys/src/boot/bitsy/inflate.c new file mode 100755 index 000000000..abfed034e --- /dev/null +++ b/sys/src/boot/bitsy/inflate.c @@ -0,0 +1,208 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include <flate.h> + +typedef struct Biobuf Biobuf; + +struct Biobuf +{ + uchar *bp; + uchar *p; + uchar *ep; +}; + +static int header(Biobuf*); +static int trailer(Biobuf*, Biobuf*); +static int getc(void*); +static ulong offset(Biobuf*); +static int crcwrite(void *out, void *buf, int n); +static ulong get4(Biobuf *b); +static ulong Boffset(Biobuf *bp); + +/* GZIP flags */ +enum { + Ftext= (1<<0), + Fhcrc= (1<<1), + Fextra= (1<<2), + Fname= (1<<3), + Fcomment= (1<<4), + + GZCRCPOLY = 0xedb88320UL, +}; + +static ulong *crctab; +static ulong crc; + +int +gunzip(uchar *out, int outn, uchar *in, int inn) +{ + Biobuf bin, bout; + int err; + + crc = 0; + crctab = mkcrctab(GZCRCPOLY); + err = inflateinit(); + if(err != FlateOk) + print("inflateinit failed: %s\n", flateerr(err)); + + bin.bp = bin.p = in; + bin.ep = in+inn; + bout.bp = bout.p = out; + bout.ep = out+outn; + + err = header(&bin); + if(err != FlateOk) + return err; + + err = inflate(&bout, crcwrite, &bin, getc); + if(err != FlateOk) + print("inflate failed: %s\n", flateerr(err)); + + err = trailer(&bout, &bin); + if(err != FlateOk) + return err; + + return Boffset(&bout); +} + +static int +header(Biobuf *bin) +{ + int i, flag; + + if(getc(bin) != 0x1f || getc(bin) != 0x8b){ + print("bad magic\n"); + return FlateCorrupted; + } + if(getc(bin) != 8){ + print("unknown compression type\n"); + return FlateCorrupted; + } + + flag = getc(bin); + + /* mod time */ + get4(bin); + + /* extra flags */ + getc(bin); + + /* OS type */ + getc(bin); + + if(flag & Fextra) + for(i=getc(bin); i>0; i--) + getc(bin); + + /* name */ + if(flag&Fname) + while(getc(bin) != 0) + ; + + /* comment */ + if(flag&Fcomment) + while(getc(bin) != 0) + ; + + /* crc16 */ + if(flag&Fhcrc) { + getc(bin); + getc(bin); + } + + return FlateOk; +} + +static int +trailer(Biobuf *bout, Biobuf *bin) +{ + /* crc32 */ + ulong x; + + x = get4(bin); + if(crc != x){ + print("crc mismatch %lux %lux\n", crc, x); + return FlateCorrupted; + } + + /* length */ + if(get4(bin) != Boffset(bout)){ + print("bad output len\n"); + return FlateCorrupted; + } + return FlateOk; +} + +static ulong +get4(Biobuf *b) +{ + ulong v; + int i, c; + + v = 0; + for(i = 0; i < 4; i++){ + c = getc(b); + v |= c << (i * 8); + } + return v; +} + +static int +getc(void *in) +{ + Biobuf *bp = in; + + if((bp->p - bp->bp) % 10000 == 0) + print("."); + if(bp->p >= bp->ep) + return -1; + return *bp->p++; +} + +static ulong +Boffset(Biobuf *bp) +{ + return bp->p - bp->bp; +} + +static int +crcwrite(void *out, void *buf, int n) +{ + Biobuf *bp; + + crc = blockcrc(crctab, crc, buf, n); + bp = out; + if(n > bp->ep-bp->p) + n = bp->ep-bp->p; + memmove(bp->p, buf, n); + bp->p += n; + return n; +} + +#undef malloc +#undef free + +static ulong ibrkp = ~0; + +void * +malloc(ulong n) +{ + ulong rv; + + if(ibrkp == ~0) + ibrkp = ((ulong)end)+1024*1024; + n = (n+3)>>2; + n <<= 2; + rv = ibrkp; + ibrkp += n; + return (void*)rv; +} + +void +free(void *) +{ +} diff --git a/sys/src/boot/bitsy/io.h b/sys/src/boot/bitsy/io.h new file mode 100755 index 000000000..6791a6625 --- /dev/null +++ b/sys/src/boot/bitsy/io.h @@ -0,0 +1,261 @@ +/* + * Definitions for IO devices. Used only in C. + */ + +enum +{ + /* hardware counter frequency */ + ClockFreq= 3686400, +}; + +/* + * IRQ's defined by SA1100 + */ +enum +{ + IRQgpio0= 0, + IRQgpio1= 1, + IRQgpio2= 2, + IRQgpio3= 3, + IRQgpio4= 4, + IRQgpio5= 5, + IRQgpio6= 6, + IRQgpio7= 7, + IRQgpio8= 8, + IRQgpio9= 9, + IRQgpio10= 10, + IRQgpiohi= 11, + IRQlcd= 12, + IRQudc= 13, + IRQuart1b= 15, + IRQuart2= 16, + IRQuart3= 17, + IRQmcp= 18, + IRQssp= 19, + IRQdma0= 20, + IRQdma1= 21, + IRQdma2= 22, + IRQdma3= 23, + IRQdma4= 24, + IRQdma5= 25, + IRQtimer0= 26, + IRQtimer1= 27, + IRQtimer2= 28, + IRQtimer3= 29, + IRQsecond= 30, + IRQrtc= 31, +}; + +/* + * GPIO lines (signal names from compaq document). _i indicates input + * and _o output. + */ +enum +{ + GPIO_PWR_ON_i= 1<<0, /* power button */ + GPIO_UP_IRQ_i= 1<<1, /* microcontroller interrupts */ + GPIO_LDD8_o= 1<<2, /* LCD data 8-15 */ + GPIO_LDD9_o= 1<<3, + GPIO_LDD10_o= 1<<4, + GPIO_LDD11_o= 1<<5, + GPIO_LDD12_o= 1<<6, + GPIO_LDD13_o= 1<<7, + GPIO_LDD14_o= 1<<8, + GPIO_LDD15_o= 1<<9, + GPIO_CARD_IND1_i= 1<<10, /* card inserted in PCMCIA socket 1 */ + GPIO_CARD_IRQ1_i= 1<<11, /* PCMCIA socket 1 interrupt */ + GPIO_CLK_SET0_o= 1<<12, /* clock selects for audio codec */ + GPIO_CLK_SET1_o= 1<<13, + GPIO_L3_SDA_io= 1<<14, /* UDA1341 interface */ + GPIO_L3_MODE_o= 1<<15, + GPIO_L3_SCLK_o= 1<<16, + GPIO_CARD_IND0_i= 1<<17, /* card inserted in PCMCIA socket 0 */ + GPIO_KEY_ACT_i= 1<<18, /* hot key from cradle */ + GPIO_SYS_CLK_i= 1<<19, /* clock from codec */ + GPIO_BAT_FAULT_i= 1<<20, /* battery fault */ + GPIO_CARD_IRQ0_i= 1<<21, /* PCMCIA socket 0 interrupt */ + GPIO_LOCK_i= 1<<22, /* expansion pack lock/unlock */ + GPIO_COM_DCD_i= 1<<23, /* DCD from UART3 */ + GPIO_OPT_IRQ_i= 1<<24, /* expansion pack IRQ */ + GPIO_COM_CTS_i= 1<<25, /* CTS from UART3 */ + GPIO_COM_RTS_o= 1<<26, /* RTS to UART3 */ + GPIO_OPT_IND_i= 1<<27, /* expansion pack inserted */ + +/* Peripheral Unit GPIO pin assignments: alternate functions */ + GPIO_SSP_TXD_o= 1<<10, /* SSP Transmit Data */ + GPIO_SSP_RXD_i= 1<<11, /* SSP Receive Data */ + GPIO_SSP_SCLK_o= 1<<12, /* SSP Sample CLocK */ + GPIO_SSP_SFRM_o= 1<<13, /* SSP Sample FRaMe */ + /* ser. port 1: */ + GPIO_UART_TXD_o= 1<<14, /* UART Transmit Data */ + GPIO_UART_RXD_i= 1<<15, /* UART Receive Data */ + GPIO_SDLC_SCLK_io= 1<<16, /* SDLC Sample CLocK (I/O) */ + GPIO_SDLC_AAF_o= 1<<17, /* SDLC Abort After Frame */ + GPIO_UART_SCLK1_i= 1<<18, /* UART Sample CLocK 1 */ + /* ser. port 4: */ + GPIO_SSP_CLK_i= 1<<19, /* SSP external CLocK */ + /* ser. port 3: */ + GPIO_UART_SCLK3_i= 1<<20, /* UART Sample CLocK 3 */ + /* ser. port 4: */ + GPIO_MCP_CLK_i= 1<<21, /* MCP CLocK */ + /* test controller: */ + GPIO_TIC_ACK_o= 1<<21, /* TIC ACKnowledge */ + GPIO_MBGNT_o= 1<<21, /* Memory Bus GraNT */ + GPIO_TREQA_i= 1<<22, /* TIC REQuest A */ + GPIO_MBREQ_i= 1<<22, /* Memory Bus REQuest */ + GPIO_TREQB_i= 1<<23, /* TIC REQuest B */ + GPIO_1Hz_o= 1<<25, /* 1 Hz clock */ + GPIO_RCLK_o= 1<<26, /* internal (R) CLocK (O, fcpu/2) */ + GPIO_32_768kHz_o= 1<<27, /* 32.768 kHz clock (O, RTC) */ +}; + +/* + * types of interrupts + */ +enum +{ + GPIOrising, + GPIOfalling, + GPIOboth, + IRQ, +}; + +/* hardware registers */ +typedef struct Uartregs Uartregs; +struct Uartregs +{ + ulong ctl[4]; + ulong dummya; + ulong data; + ulong dummyb; + ulong status[2]; +}; +Uartregs *uart3regs; + +/* general purpose I/O lines control registers */ +typedef struct GPIOregs GPIOregs; +struct GPIOregs +{ + ulong level; /* 1 == high */ + ulong direction; /* 1 == output */ + ulong set; /* a 1 sets the bit, 0 leaves it alone */ + ulong clear; /* a 1 clears the bit, 0 leaves it alone */ + ulong rising; /* rising edge detect enable */ + ulong falling; /* falling edge detect enable */ + ulong edgestatus; /* writing a 1 bit clears */ + ulong altfunc; /* turn on alternate function for any set bits */ +}; + +extern GPIOregs *gpioregs; + +/* extra general purpose I/O bits, output only */ +enum +{ + EGPIO_prog_flash= 1<<0, + EGPIO_pcmcia_reset= 1<<1, + EGPIO_exppack_reset= 1<<2, + EGPIO_codec_reset= 1<<3, + EGPIO_exp_nvram_power= 1<<4, + EGPIO_exp_full_power= 1<<5, + EGPIO_lcd_3v= 1<<6, + EGPIO_rs232_power= 1<<7, + EGPIO_lcd_ic_power= 1<<8, + EGPIO_ir_power= 1<<9, + EGPIO_audio_power= 1<<10, + EGPIO_audio_ic_power= 1<<11, + EGPIO_audio_mute= 1<<12, + EGPIO_fir= 1<<13, /* not set is sir */ + EGPIO_lcd_5v= 1<<14, + EGPIO_lcd_9v= 1<<15, +}; +extern ulong *egpioreg; + +/* Peripheral pin controller registers */ +typedef struct PPCregs PPCregs; +struct PPCregs { + ulong direction; + ulong state; + ulong assignment; + ulong sleepdir; + ulong flags; +}; +extern PPCregs *ppcregs; + +/* Synchronous Serial Port controller registers */ +typedef struct SSPregs SSPregs; +struct SSPregs { + ulong control0; + ulong control1; + ulong dummy0; + ulong data; + ulong dummy1; + ulong status; +}; +extern SSPregs *sspregs; + +/* Multimedia Communications Port controller registers */ +typedef struct MCPregs MCPregs; +struct MCPregs { + ulong control0; + ulong reserved0; + ulong data0; + ulong data1; + ulong data2; + ulong reserved1; + ulong status; + ulong reserved[11]; + ulong control1; +}; +extern MCPregs *mcpregs; + +/* + * memory configuration + */ +enum +{ + /* bit shifts for pcmcia access time counters */ + MECR_io0= 0, + MECR_attr0= 5, + MECR_mem0= 10, + MECR_fast0= 11, + MECR_io1= MECR_io0+16, + MECR_attr1= MECR_attr0+16, + MECR_mem1= MECR_mem0+16, + MECR_fast1= MECR_fast0+16, +}; + +typedef struct MemConfRegs MemConfRegs; +struct MemConfRegs +{ + ulong mdcnfg; /* dram */ + ulong mdcas00; /* dram banks 0/1 */ + ulong mdcas01; + ulong mdcas02; + ulong msc0; /* static */ + ulong msc1; + ulong mecr; /* pcmcia */ + ulong mdrefr; /* dram refresh */ + ulong mdcas20; /* dram banks 2/3 */ + ulong mdcas21; + ulong mdcas22; + ulong msc2; /* static */ + ulong smcnfg; /* SMROM config */ +}; +extern MemConfRegs *memconfregs; + +/* + * power management + */ +typedef struct PowerRegs PowerRegs; +struct PowerRegs +{ + ulong pmcr; /* Power manager control register */ + ulong pssr; /* Power manager sleep status register */ + ulong pspr; /* Power manager scratch pad register */ + ulong pwer; /* Power manager wakeup enable register */ + ulong pcfr; /* Power manager general configuration register */ + ulong ppcr; /* Power manager PPL configuration register */ + ulong pgsr; /* Power manager GPIO sleep state register */ + ulong posr; /* Power manager oscillator status register */ +}; +extern PowerRegs *powerregs; diff --git a/sys/src/boot/bitsy/l.s b/sys/src/boot/bitsy/l.s new file mode 100755 index 000000000..0afdb8baf --- /dev/null +++ b/sys/src/boot/bitsy/l.s @@ -0,0 +1,454 @@ +#include "mem.h" + +/* + * Entered here from Compaq's bootldr with MMU disabled. + */ +TEXT _start(SB), $-4 + MOVW $setR12(SB), R12 /* load the SB */ +_main: + /* SVC mode, interrupts disabled */ + MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 + MOVW R1, CPSR + + /* 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 + MOVW R0,R0 + MOVW R0,R0 + + /* drain write buffer */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + + MOVW $(MACHADDR+BY2PG), R13 /* stack */ + SUB $4, R13 /* link */ + BL main(SB) + BL exit(SB) + /* we shouldn't get here */ +_mainloop: + B _mainloop + BL _div(SB) /* hack to get _div etc loaded */ + +/* flush tlb's */ +TEXT mmuinvalidate(SB), $-4 + MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7) + RET + +/* flush tlb's */ +TEXT mmuinvalidateaddr(SB), $-4 + MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x6), 1 + RET + +/* write back and invalidate i and d caches */ +TEXT cacheflush(SB), $-4 + /* write back any dirty data */ + MOVW $0xe0000000,R0 + ADD $(8*1024),R0,R1 +_cfloop: + MOVW.P 32(R0),R2 + CMP.S R0,R1 + BNE _cfloop + + /* drain write buffer and invalidate i&d cache contents */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 + + /* drain prefetch */ + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + RET + +/* write back d cache */ +TEXT cachewb(SB), $-4 + /* write back any dirty data */ +_cachewb: + MOVW $0xe0000000,R0 + ADD $(8*1024),R0,R1 +_cwbloop: + MOVW.P 32(R0),R2 + CMP.S R0,R1 + BNE _cwbloop + + /* drain write buffer */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + RET + +/* write back a single cache line */ +TEXT cachewbaddr(SB), $-4 + BIC $31,R0 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1 + B _wbflush + +/* write back a region of cache lines */ +TEXT cachewbregion(SB), $-4 + MOVW 4(FP),R1 + CMP.S $(4*1024),R1 + BGT _cachewb + ADD R0,R1 + BIC $31,R0 +_cwbrloop: + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1 + ADD $32,R0 + CMP.S R0,R1 + BGT _cwbrloop + B _wbflush + +/* invalidate the dcache */ +TEXT dcacheinvalidate(SB), $-4 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x6) + RET + +/* invalidate the icache */ +TEXT icacheinvalidate(SB), $-4 + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x9) + RET + +/* drain write buffer */ +TEXT wbflush(SB), $-4 +_wbflush: + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + RET + +/* return cpu id */ +TEXT getcpuid(SB), $-4 + MRC CpMMU, 0, R0, C(CpCPUID), C(0x0) + RET + +/* return fault status */ +TEXT getfsr(SB), $-4 + MRC CpMMU, 0, R0, C(CpFSR), C(0x0) + RET + +/* return fault address */ +TEXT getfar(SB), $-4 + MRC CpMMU, 0, R0, C(CpFAR), C(0x0) + RET + +/* return fault address */ +TEXT putfar(SB), $-4 + MRC CpMMU, 0, R0, C(CpFAR), C(0x0) + RET + +/* set the translation table base */ +TEXT putttb(SB), $-4 + MCR CpMMU, 0, R0, C(CpTTB), C(0x0) + RET + +/* + * enable mmu, i and d caches + */ +TEXT mmuenable(SB), $-4 + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + ORR $(CpCmmuena|CpCdcache|CpCicache|CpCwb), R0 + MCR CpMMU, 0, R0, C(CpControl), C(0x0) + RET + +TEXT mmudisable(SB), $-4 + MRC CpMMU, 0, R0, C(CpControl), C(0x0) + BIC $(CpCmmuena|CpCdcache|CpCicache|CpCwb|CpCvivec), R0 + 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) + RET + +/* set address translation pid */ +TEXT putpid(SB), $-4 + MCR CpMMU, 0, R0, C(CpPID), C(0x0) + RET + +/* + * set the stack value for the mode passed in R0 + */ +TEXT setr13(SB), $-4 + MOVW 4(FP), R1 + + MOVW CPSR, R2 + BIC $PsrMask, R2, R3 + ORR R0, R3 + MOVW R3, CPSR + + MOVW R13, R0 + MOVW R1, R13 + + MOVW R2, CPSR + RET + +/* + * exception vectors, copied by trapinit() to somewhere useful + */ + +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 $_vpabt(SB) /* prefetch abort, switch to svc mode */ + WORD $_vdabt(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 resettrap(SB) + +TEXT _vsvc(SB), $-4 /* SWI */ + MOVW.W R14, -4(R13) /* ureg->pc = interupted PC */ + MOVW SPSR, R14 /* ureg->psr = SPSR */ + MOVW.W R14, -4(R13) /* ... */ + MOVW $PsrMsvc, R14 /* ureg->type = PsrMsvc */ + MOVW.W R14, -4(R13) /* ... */ + MOVM.DB.W.S [R0-R14], (R13) /* save user level registers, at end r13 points to ureg */ + MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */ + MOVW R13, R0 /* first arg is pointer to ureg */ + SUB $8, R13 /* space for argument+link */ + + BL syscall(SB) + + ADD $(8+4*15), R13 /* make r13 point to ureg->type */ + MOVW 8(R13), R14 /* restore link */ + MOVW 4(R13), R0 /* restore SPSR */ + MOVW R0, SPSR /* ... */ + MOVM.DB.S (R13), [R0-R14] /* restore registers */ + ADD $8, R13 /* pop past ureg->{type+psr} */ + RFE /* MOVM.IA.S.W (R13), [R15] */ + +TEXT _vund(SB), $-4 /* undefined */ + MOVM.IA [R0-R4], (R13) /* free some working space */ + MOVW $PsrMund, R0 + B _vswitch + +TEXT _vpabt(SB), $-4 /* prefetch abort */ + MOVM.IA [R0-R4], (R13) /* free some working space */ + MOVW $PsrMabt, R0 /* r0 = type */ + B _vswitch + +TEXT _vdabt(SB), $-4 /* prefetch abort */ + MOVM.IA [R0-R4], (R13) /* free some working space */ + MOVW $(PsrMabt+1), R0 /* r0 = type */ + B _vswitch + +TEXT _virq(SB), $-4 /* IRQ */ + MOVM.IA [R0-R4], (R13) /* free some working space */ + MOVW $PsrMirq, R0 /* r0 = type */ + B _vswitch + + /* + * come here with type in R0 and R13 pointing above saved [r0-r4] + * and type in r0. we'll switch to SVC mode and then call trap. + */ +_vswitch: + MOVW SPSR, R1 /* save SPSR for ureg */ + MOVW R14, R2 /* save interrupted pc for ureg */ + MOVW R13, R3 /* save pointer to where the original [R0-R3] are */ + + /* switch to svc mode */ + MOVW CPSR, R14 + BIC $PsrMask, R14 + ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14 + MOVW R14, CPSR + + /* interupted code kernel or user? */ + AND.S $0xf, R1, R4 + BEQ _userexcep + + /* here for trap from SVC mode */ + MOVM.DB.W [R0-R2], (R13) /* set ureg->{type, psr, pc}; r13 points to ureg->type */ + MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */ + MOVM.DB.W [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */ + MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */ + MOVW R13, R0 /* first arg is pointer to ureg */ + SUB $8, R13 /* space for argument+link (for debugger) */ + MOVW $0xdeaddead,R11 /* marker */ + + BL trap(SB) + + ADD $(8+4*15), R13 /* make r13 point to ureg->type */ + MOVW 8(R13), R14 /* restore link */ + MOVW 4(R13), R0 /* restore SPSR */ + MOVW R0, SPSR /* ... */ + MOVM.DB (R13), [R0-R14] /* restore registers */ + ADD $8, R13 /* pop past ureg->{type+psr} */ + RFE /* MOVM.IA.S.W (R13), [R15] */ + + /* here for trap from USER mode */ +_userexcep: + MOVM.DB.W [R0-R2], (R13) /* set ureg->{type, psr, pc}; r13 points to ureg->type */ + MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */ + MOVM.DB.W.S [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */ + MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */ + MOVW R13, R0 /* first arg is pointer to ureg */ + SUB $8, R13 /* space for argument+link (for debugger) */ + + BL trap(SB) + + ADD $(8+4*15), R13 /* make r13 point to ureg->type */ + MOVW 8(R13), R14 /* restore link */ + MOVW 4(R13), R0 /* restore SPSR */ + MOVW R0, SPSR /* ... */ + MOVM.DB.S (R13), [R0-R14] /* restore registers */ + ADD $8, R13 /* pop past ureg->{type+psr} */ + RFE /* MOVM.IA.S.W (R13), [R15] */ + +TEXT _vfiq(SB), $-4 /* FIQ */ + RFE /* FIQ is special, ignore it for now */ + +/* + * This is the first jump from kernel to user mode. + * Fake a return from interrupt. + * + * Enter with R0 containing the user stack pointer. + * UTZERO + 0x20 is always the entry point. + * + */ +TEXT touser(SB),$-4 + /* store the user stack pointer into the USR_r13 */ + MOVM.DB.W [R0], (R13) + MOVM.S.IA.W (R13),[R13] + + /* set up a PSR for user level */ + MOVW $(PsrMusr), R0 + MOVW R0,SPSR + + /* save the PC on the stack */ + MOVW $(UTZERO+0x20), R0 + MOVM.DB.W [R0],(R13) + + /* return from interrupt */ + RFE /* MOVM.IA.S.W (R13), [R15] */ + +/* + * here to jump to a newly forked process + */ +TEXT forkret(SB),$-4 + ADD $(4*15), R13 /* make r13 point to ureg->type */ + MOVW 8(R13), R14 /* restore link */ + MOVW 4(R13), R0 /* restore SPSR */ + MOVW R0, SPSR /* ... */ + MOVM.DB.S (R13), [R0-R14] /* restore registers */ + ADD $8, R13 /* pop past ureg->{type+psr} */ + RFE /* MOVM.IA.S.W (R13), [R15] */ + +TEXT splhi(SB), $-4 + /* save caller pc in Mach */ + MOVW $(MACHADDR+0x04),R2 + MOVW R14,0(R2) + /* turn off interrupts */ + MOVW CPSR, R0 + ORR $(PsrDfiq|PsrDirq), R0, R1 + MOVW R1, CPSR + RET + +TEXT spllo(SB), $-4 + MOVW CPSR, R0 + BIC $(PsrDfiq|PsrDirq), R0, R1 + MOVW R1, CPSR + RET + +TEXT splx(SB), $-4 + /* save caller pc in Mach */ + MOVW $(MACHADDR+0x04),R2 + MOVW R14,0(R2) + /* reset interrupt level */ + MOVW R0, R1 + MOVW CPSR, R0 + MOVW R1, CPSR + RET + +TEXT splxpc(SB), $-4 /* for iunlock */ + MOVW R0, R1 + MOVW CPSR, R0 + MOVW R1, CPSR + RET + +TEXT spldone(SB), $0 + RET + +TEXT islo(SB), $-4 + MOVW CPSR, R0 + AND $(PsrDfiq|PsrDirq), R0 + EOR $(PsrDfiq|PsrDirq), R0 + RET + +TEXT cpsrr(SB), $-4 + MOVW CPSR, R0 + RET + +TEXT spsrr(SB), $-4 + MOVW SPSR, R0 + RET + +TEXT getcallerpc(SB), $-4 + MOVW 0(R13), R0 + RET + +TEXT tas(SB), $-4 + MOVW R0, R1 + MOVW $0xDEADDEAD, R2 + SWPW R2, (R1), R0 + RET + +TEXT setlabel(SB), $-4 + MOVW R13, 0(R0) /* sp */ + MOVW R14, 4(R0) /* pc */ + MOVW $0, R0 + RET + +TEXT gotolabel(SB), $-4 + MOVW 0(R0), R13 /* sp */ + MOVW 4(R0), R14 /* pc */ + MOVW $1, R0 + RET + + +/* The first MCR instruction of this function needs to be on a cache-line + * boundary; to make this happen, it will be copied (in trap.c). + * + * Doze puts the machine into idle mode. Any interrupt will get it out + * at the next instruction (the RET, to be precise). + */ +TEXT _doze(SB), $-4 + MOVW $UCDRAMZERO, R1 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2 + MOVW (R1), R0 + MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2 + RET diff --git a/sys/src/boot/bitsy/lib.h b/sys/src/boot/bitsy/lib.h new file mode 100755 index 000000000..5c99d1fe9 --- /dev/null +++ b/sys/src/boot/bitsy/lib.h @@ -0,0 +1,143 @@ +/* + * functions (possibly) linked in, complete, from libc. + */ + +/* + * mem routines + */ +extern void *memccpy(void*, void*, int, long); +extern void *memset(void*, int, long); +extern int memcmp(void*, void*, long); +extern void *memmove(void*, void*, long); +extern void *memchr(void*, int, long); + +/* + * string routines + */ +extern char *strcat(char*, char*); +extern char *strchr(char*, char); +extern char *strrchr(char*, char); +extern int strcmp(char*, char*); +extern char *strcpy(char*, char*); +extern char *strncat(char*, char*, long); +extern char *strncpy(char*, char*, long); +extern int strncmp(char*, char*, long); +extern long strlen(char*); +extern char* strstr(char*, char*); +extern int atoi(char*); + +enum +{ + UTFmax = 3, /* maximum bytes per rune */ + Runesync = 0x80, /* cannot represent part of a UTF sequence */ + Runeself = 0x80, /* rune and UTF sequences are the same (<) */ + Runeerror = 0x80, /* decoding error in UTF */ +}; + +/* + * rune routines + */ +extern int runetochar(char*, Rune*); +extern int chartorune(Rune*, char*); +extern char* utfrune(char*, long); +extern int utflen(char*); +extern int runelen(long); + +extern int abs(int); + +/* + * print routines + */ +typedef struct Cconv Fconv; +extern char* donprint(char*, char*, char*, void*); +extern int sprint(char*, char*, ...); +extern char* seprint(char*, char*, char*, ...); +extern int snprint(char*, int, char*, ...); +extern int print(char*, ...); + +/* + * one-of-a-kind + */ +extern char* cleanname(char*); +extern uintptr getcallerpc(void*); +extern long strtol(char*, char**, int); +extern ulong strtoul(char*, char**, int); +extern vlong strtoll(char*, char**, int); +extern uvlong strtoull(char*, char**, int); +extern char etext[]; +extern char edata[]; +extern char end[]; +extern int getfields(char*, char**, int, int, char*); + +/* + * Syscall data structures + */ +#define MORDER 0x0003 /* mask for bits defining order of mounting */ +#define MREPL 0x0000 /* mount replaces object */ +#define MBEFORE 0x0001 /* mount goes before others in union directory */ +#define MAFTER 0x0002 /* mount goes after others in union directory */ +#define MCREATE 0x0004 /* permit creation in mounted directory */ +#define MCACHE 0x0010 /* cache some data */ +#define MMASK 0x001F /* all bits on */ + +#define OREAD 0 /* open for read */ +#define OWRITE 1 /* write */ +#define ORDWR 2 /* read and write */ +#define OEXEC 3 /* execute, == read but check execute permission */ +#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ +#define OCEXEC 32 /* or'ed in, close on exec */ +#define ORCLOSE 64 /* or'ed in, remove on close */ + +#define NCONT 0 /* continue after note */ +#define NDFLT 1 /* terminate after note */ +#define NSAVE 2 /* clear note but hold state */ +#define NRSTR 3 /* restore saved state */ + +typedef struct Qid Qid; +typedef struct Dir Dir; +typedef struct Waitmsg Waitmsg; + +#define ERRLEN 64 +#define DIRLEN 116 +#define NAMELEN 28 + +struct Qid +{ + ulong path; + ulong vers; +}; + +struct Dir +{ + char name[NAMELEN]; + char uid[NAMELEN]; + char gid[NAMELEN]; + Qid qid; + ulong mode; + long atime; + long mtime; + vlong length; + short type; + short dev; +}; + +struct Waitmsg +{ + char pid[12]; /* of loved one */ + char time[3*12]; /* of loved one and descendants */ + char msg[ERRLEN]; +}; + +/* + * locks + */ +typedef +struct Lock { + int val; +} Lock; + +extern int _tas(int*); + +extern void lock(Lock*); +extern void unlock(Lock*); +extern int canlock(Lock*); diff --git a/sys/src/boot/bitsy/map b/sys/src/boot/bitsy/map new file mode 100755 index 000000000..87f67bece --- /dev/null +++ b/sys/src/boot/bitsy/map @@ -0,0 +1,10 @@ +defn acidmap() +{ + local dfoffset; + + dfoffset = map()[1][3]; + map({"text", _start, etext, 0x20}); + map({"data", etext+1, edata, dfoffset}); + print("Set map for plan 9 kernel image\n"); + print("btext ", _start, " etext ", etext, "\n"); +} diff --git a/sys/src/boot/bitsy/mem.h b/sys/src/boot/bitsy/mem.h new file mode 100755 index 000000000..2be6e705c --- /dev/null +++ b/sys/src/boot/bitsy/mem.h @@ -0,0 +1,213 @@ +/* + * Memory and machine-specific definitions. Used in C and assembler. + */ + +/* + * Sizes + */ +#define BI2BY 8 /* bits per byte */ +#define BI2WD 32 /* bits per word */ +#define BY2WD 4 /* bytes per word */ +#define BY2V 8 /* bytes per double word */ +#define BY2PG 4096 /* bytes per page */ +#define WD2PG (BY2PG/BY2WD) /* words per page */ +#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 */ + +/* + * Time + */ +#define HZ (20) /* clock frequency */ +#define MS2HZ (1000/HZ) /* millisec per clock tick */ +#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ +#define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ +#define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ + +/* + * Virtual addresses: + * + * We direct map all discovered DRAM and the area twixt 0xe0000000 and + * 0xe8000000 used to provide zeros for cache flushing. + * + * Flash is mapped to 0xb0000000 and special registers are mapped + * on demand to areas starting at 0xa0000000. + * + * The direct mapping is convenient but not necessary. It means + * that we don't have to turn on the MMU till well into the + * kernel. This can be changed by providing a mapping in l.s + * before calling main. + */ +#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 EMEMZERO 0x90000000 /* 256 meg for add on memory */ +#define EMEMTOP 0xA0000000 /* ... */ +#define REGZERO 0xA0000000 /* 128 meg for mapspecial regs */ +#define REGTOP 0xA8000000 /* ... */ +#define FLASHZERO 0xB0000000 /* 128 meg for flash */ +#define FLASHTOP 0xB8000000 /* ... */ +#define DRAMZERO 0xC0000000 /* 128 meg for dram */ +#define DRAMTOP 0xC8000000 /* ... */ +#define UCDRAMZERO 0xC8000000 /* 128 meg for dram (uncached/unbuffered) */ +#define UCDRAMTOP 0xD0000000 /* ... */ +#define NULLZERO 0xE0000000 /* 128 meg for cache flush zeroes */ +#define NULLTOP 0xE8000000 /* ... */ +#define USTKTOP 0x2000000 /* byte just beyond user stack */ +#define USTKSIZE (8*1024*1024) /* size of user stack */ +#define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */ +#define TSTKSIZ 100 +#define MACHADDR (KZERO+0x00001000) +#define EVECTORS 0xFFFF0000 /* virt base of exception vectors */ + +#define KSTACK (16*1024) /* Size of kernel stack */ + +/* + * Offsets into flash + */ +#define Flash_bootldr (FLASHZERO+0x0) /* boot loader */ +#define Flash_kernel (FLASHZERO+0x10000) /* boot kernel */ +#define Flash_tar (FLASHZERO+0x100000) /* tar file containing fs.sac */ + +/* + * virtual MMU + */ +#define PTEMAPMEM (1024*1024) +#define PTEPERTAB (PTEMAPMEM/BY2PG) +#define SEGMAPSIZE 1984 +#define SSEGMAPSIZE 16 +#define PPN(x) ((x)&~(BY2PG-1)) + +/* + * SA1110 definitions + */ + +/* + * memory physical addresses + */ +#define PHYSFLASH0 0x00000000 +#define PHYSDRAM0 0xC0000000 +#define PHYSNULL0 0xE0000000 + +/* + * peripheral control module physical addresses + */ +#define USBREGS 0x80000000 /* serial port 0 - USB */ +#define UART1REGS 0x80010000 /* serial port 1 - UART */ +#define GPCLKREGS 0x80020060 /* serial port 1 - general purpose clock */ +#define UART2REGS 0x80030000 /* serial port 2 - low speed IR */ +#define HSSPREGS 0x80040060 /* serial port 2 - high speed IR */ +#define UART3REGS 0x80050000 /* serial port 3 - RS232 UART */ +#define MCPREGS 0x80060000 /* serial port 4 - multimedia comm port */ +#define SSPREGS 0x80070060 /* serial port 4 - synchronous serial port */ +#define OSTIMERREGS 0x90000000 /* operating system timer registers */ +#define POWERREGS 0x90020000 /* power management */ +#define GPIOREGS 0x90040000 /* 28 general purpose IO pins */ +#define INTRREGS 0x90050000 /* interrupt registers */ +#define PPCREGS 0x90060000 /* peripheral pin controller */ +#define MEMCONFREGS 0xA0000000 /* memory configuration */ +#define LCDREGS 0xB0100000 /* display */ + +/* + * PCMCIA addresses + */ +#define PHYSPCM0REGS 0x20000000 +#define PYHSPCM0ATTR 0x28000000 +#define PYHSPCM0MEM 0x2C000000 +#define PHYSPCM1REGS 0x30000000 +#define PYHSPCM1ATTR 0x38000000 +#define PYHSPCM1MEM 0x3C000000 + +/* + * Program Status Registers + */ +#define PsrMusr 0x00000010 /* mode */ +#define PsrMfiq 0x00000011 +#define PsrMirq 0x00000012 +#define PsrMsvc 0x00000013 +#define PsrMabt 0x00000017 +#define PsrMund 0x0000001B +#define PsrMask 0x0000001F + +#define PsrDfiq 0x00000040 /* disable FIQ interrupts */ +#define PsrDirq 0x00000080 /* disable IRQ interrupts */ + +#define PsrV 0x10000000 /* overflow */ +#define PsrC 0x20000000 /* carry/borrow/extend */ +#define PsrZ 0x40000000 /* zero */ +#define PsrN 0x80000000 /* negative/less than */ + +/* + * Coprocessors + */ +#define CpMMU 15 +#define CpPWR 15 + +/* + * Internal MMU coprocessor registers + */ +#define CpCPUID 0 /* R: */ +#define CpControl 1 /* R: */ +#define CpTTB 2 /* RW: translation table base */ +#define CpDAC 3 /* RW: domain access control */ +#define CpFSR 5 /* RW: fault status */ +#define CpFAR 6 /* RW: fault address */ +#define CpCacheFlush 7 /* W: cache flushing, wb draining*/ +#define CpTLBFlush 8 /* W: TLB flushing */ +#define CpRBFlush 9 /* W: Read Buffer ops */ +#define CpPID 13 /* RW: PID for virtual mapping */ +#define CpBpt 14 /* W: Breakpoint register */ +#define CpTest 15 /* W: Test, Clock and Idle Control */ + +/* + * CpControl + */ +#define CpCmmuena 0x00000001 /* M: MMU enable */ +#define CpCalign 0x00000002 /* A: alignment fault enable */ +#define CpCdcache 0x00000004 /* C: data cache on */ +#define CpCwb 0x00000008 /* W: write buffer turned on */ +#define CpCi32 0x00000010 /* P: 32-bit program space */ +#define CpCd32 0x00000020 /* D: 32-bit data space */ +#define CpCbe 0x00000080 /* B: big-endian operation */ +#define CpCsystem 0x00000100 /* S: system permission */ +#define CpCrom 0x00000200 /* R: ROM permission */ +#define CpCicache 0x00001000 /* I: instruction cache on */ +#define CpCvivec 0x00002000 /* X: virtual interrupt vector adjust */ + +/* + * fault codes + */ +#define FCterm 0x2 /* terminal */ +#define FCvec 0x0 /* vector */ +#define FCalignf 0x1 /* unaligned full word data access */ +#define FCalignh 0x3 /* unaligned half word data access */ +#define FCl1abort 0xc /* level 1 external abort on translation */ +#define FCl2abort 0xe /* level 2 external abort on translation */ +#define FCtransSec 0x5 /* section translation */ +#define FCtransPage 0x7 /* page translation */ +#define FCdomainSec 0x9 /* section domain */ +#define FCdomainPage 0x11 /* page domain */ +#define FCpermSec 0x9 /* section permissions */ +#define FCpermPage 0x11 /* page permissions */ +#define FCabortLFSec 0x4 /* external abort on linefetch for section */ +#define FCabortLFPage 0x6 /* external abort on linefetch for page */ +#define FCabortNLFSec 0x8 /* external abort on non-linefetch for section */ +#define FCabortNLFPage 0xa /* external abort on non-linefetch for page */ + +/* + * PTE bits used by fault.h. mmu.c translates them to real values. + */ +#define PTEVALID (1<<0) +#define PTERONLY 0 /* this is implied by the absence of PTEWRITE */ +#define PTEWRITE (1<<1) +#define PTEUNCACHED (1<<2) +#define PTEKERNEL (1<<3) /* no user access */ + +/* + * H3650 specific definitions + */ +#define EGPIOREGS 0x49000000 /* Additional GPIO register */ diff --git a/sys/src/boot/bitsy/mkfile b/sys/src/boot/bitsy/mkfile new file mode 100755 index 000000000..fe32e6880 --- /dev/null +++ b/sys/src/boot/bitsy/mkfile @@ -0,0 +1,45 @@ +objtype=arm +</$objtype/mkfile +BIN=/arm + +TARG=\ + inflate\ + +INFLATE=\ + il.$O\ + imain.$O\ + +CORE=\ + uart.$O\ + inflate.$O\ + donprint.$O\ + print.$O\ + +HFILES=\ + mem.h\ + +CFLAGS=-w -I. + +all:V: $TARG + +install:V: $BIN/$TARG + +$BIN/%: % + cp $stem $BIN/$stem + +inflate: $INFLATE $CORE + $LD -o s$target -R4 -T0xC0200010 $prereq -lflate -lc + $LD -o _^$target -H5 -R4 -T0xC0200010 $prereq -lflate -lc + dd -conv sync -ibs 20k -if _^$target -of $target + +%.$O: %.s + $AS $stem.s + +%.$O: %.c + $CC $CFLAGS $stem.c + +%.$O: $HFILES + +clean: + rm -f *.[$OS] [$OS].out y.tab.? y.debug y.output $TARG _$TARG + diff --git a/sys/src/boot/bitsy/print.c b/sys/src/boot/bitsy/print.c new file mode 100755 index 000000000..f2b852878 --- /dev/null +++ b/sys/src/boot/bitsy/print.c @@ -0,0 +1,56 @@ +#include "u.h" +#include "lib.h" +#include "fns.h" +#include "dat.h" + + +#define SIZE 1024 + +int +print(char *fmt, ...) +{ + char buf[SIZE], *out; + va_list arg; + + va_start(arg, fmt); + out = donprint(buf, buf+SIZE, fmt, arg); + va_end(arg); + serialputs(buf, out-buf); + return out-buf; +} + +int +sprint(char *buf, char *fmt, ...) +{ + char *out; + va_list arg; + + va_start(arg, fmt); + out = donprint(buf, buf+SIZE, fmt, arg); + va_end(arg); + return out-buf; +} + +int +snprint(char *buf, int len, char *fmt, ...) +{ + char *out; + va_list arg; + + va_start(arg, fmt); + out = donprint(buf, buf+len, fmt, arg); + va_end(arg); + return out-buf; +} + +char* +seprint(char *buf, char *e, char *fmt, ...) +{ + char *out; + va_list arg; + + va_start(arg, fmt); + out = donprint(buf, e, fmt, arg); + va_end(arg); + return out; +} diff --git a/sys/src/boot/bitsy/sinflate b/sys/src/boot/bitsy/sinflate Binary files differnew file mode 100755 index 000000000..8f5a83924 --- /dev/null +++ b/sys/src/boot/bitsy/sinflate diff --git a/sys/src/boot/bitsy/uart.c b/sys/src/boot/bitsy/uart.c new file mode 100755 index 000000000..e060aa9d2 --- /dev/null +++ b/sys/src/boot/bitsy/uart.c @@ -0,0 +1,69 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +enum +{ + /* ctl[0] bits */ + Parity= 1<<0, + Even= 1<<1, + Stop2= 1<<2, + 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 */ + + /* status[0] 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 */ + + /* status[1] 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 = (Uartregs*)UART3REGS; + + +/* + * for iprint, just write it + */ +void +serialputs(char *str, int n) +{ + Uartregs *ur; + + ur = uart3regs; + while(n-- > 0){ + /* wait for output ready */ + while((ur->status[1] & Tnotfull) == 0) + ; + ur->data = *str++; + } + while((ur->status[1] & Tbusy)) + ; +} |