123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703 |
- /*
- * 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 BY2PG 4096 /* bytes per page */
- #define WD2PG (BY2PG/BY2WD) /* words per page */
- #define PGSHIFT 12 /* log(BY2PG) */
- #define MAXMACH 4 /* max # cpus system can run */
- /*
- * Time
- */
- #define MS2HZ 50 /* millisec per clock tick */
- #define TK2SEC(t) ((t)/20) /* ticks to seconds */
- #define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */
- #define MS2TK(t) ((t)/MS2HZ) /* milliseconds to ticks */
- /*
- * CP0 registers
- */
- #define INDEX 0
- #define RANDOM 1
- #define TLBPHYS 2
- #define CONTEXT 4
- #define BADVADDR 8
- #define TLBVIRT 10
- #define STATUS 12
- #define CAUSE 13
- #define EPC 14
- #define PRID 15
- /*
- * M(STATUS) bits
- */
- #define IEC 0x00000001
- #define KUC 0x00000002
- #define IEP 0x00000004
- #define KUP 0x00000008
- #define INTMASK 0x0000ff00
- #define SW0 0x00000100
- #define SW1 0x00000200
- #define INTR0 0x00000400
- #define INTR1 0x00000800
- #define INTR2 0x00001000
- #define INTR3 0x00002000
- #define INTR4 0x00004000
- #define INTR5 0x00008000
- #define ISC 0x00010000
- #define SWC 0x00020000
- #define CU1 0x20000000
- /*
- * Traps
- */
- #define UTLBMISS (KSEG0+0x00)
- #define EXCEPTION (KSEG0+0x80)
- /*
- * Magic registers
- */
- #define MACH 25 /* R25 is m-> */
- #define USER 24 /* R24 is u-> */
- #define MPID 0xBF000000 /* long; low 3 bits identify mp bus slot */
- #define WBFLUSH 0xBC000000 /* D-CACHE data; used for write buffer flush */
- /*
- * Fundamental addresses
- */
- #define MACHADDR 0x80014000
- #define USERADDR 0xC0000000
- #define UREGADDR (USERADDR+BY2PG-4-0xA0)
- /*
- * MMU
- */
- #define KUSEG 0x00000000
- #define KSEG0 0x80000000
- #define KSEG1 0xA0000000
- #define KSEG2 0xC0000000
- #define KSEGM 0xE0000000 /* mask to check which seg */
- #define PTEGLOBL (1<<8)
- #define PTEVALID (1<<9)
- #define PTEWRITE (1<<10)
- #define PTEPID(n) ((n)<<6)
- #define NTLBPID 64 /* number of pids */
- #define NTLB 64 /* number of entries */
- #define TLBROFF 8 /* offset of first randomly indexed entry */
- /*
- * Address spaces
- */
- #define UZERO KUSEG /* base of user address space */
- #define UTZERO (UZERO+BY2PG) /* first address in user text */
- #define USTKTOP KZERO /* byte just beyond user stack */
- #define TSTKTOP (USERADDR+100*BY2PG) /* top of temporary stack */
- #define KZERO KSEG0 /* base of kernel address space */
- #define KTZERO (KSEG0+0x20000) /* first address in kernel text */
- #define USTACKSIZE (4*1024*1024) /* size of user stack */
- /*
- * Exception codes
- */
- #define CINT 0 /* external interrupt */
- #define CTLBM 1 /* TLB modification */
- #define CTLBL 2 /* TLB miss (load or fetch) */
- #define CTLBS 3 /* TLB miss (store) */
- #define CADREL 4 /* address error (load or fetch) */
- #define CADRES 5 /* address error (store) */
- #define CBUSI 6 /* bus error (fetch) */
- #define CBUSD 7 /* bus error (data load or store) */
- #define CSYS 8 /* system call */
- #define CBRK 9 /* breakpoint */
- #define CRES 10 /* reserved instruction */
- #define CCPU 11 /* coprocessor unusable */
- #define COVF 12 /* arithmetic overflow */
- #define CUNK13 13 /* undefined 13 */
- #define CUNK14 14 /* undefined 14 */
- #define CUNK15 15 /* undefined 15 */
- #define NSEG 5
- #define SP R29
- #define PROM (KSEG1+0x1FC00000)
- #define NOOP NOR R0,R0
- #define WAIT NOOP; NOOP
- /*
- * Boot first processor
- * - why is the processor number loaded from R0 ?????
- */
- TEXT start(SB), $-4
- MOVW $setR30(SB), R30
- MOVW $(CU1|INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1
- MOVW R1, M(STATUS)
- WAIT
- MOVW $(0x1C<<7), R1
- MOVW R1, FCR31 /* permit only inexact and underflow */
- NOOP
- MOVD $0.5, F26
- SUBD F26, F26, F24
- ADDD F26, F26, F28
- ADDD F28, F28, F30
- MOVD F24, F0
- MOVD F24, F2
- MOVD F24, F4
- MOVD F24, F6
- MOVD F24, F8
- MOVD F24, F10
- MOVD F24, F12
- MOVD F24, F14
- MOVD F24, F16
- MOVD F24, F18
- MOVD F24, F20
- MOVD F24, F22
- MOVW $MACHADDR, R(MACH)
- ADDU $(BY2PG-4), R(MACH), SP
- MOVW $0, R(USER)
- MOVW R0, 0(R(MACH))
- MOVW $edata(SB), R1
- MOVW $end(SB), R2
- clrbss:
- MOVB $0, (R1)
- ADDU $1, R1
- BNE R1, R2, clrbss
- MOVW R4, _argc(SB)
- MOVW R5, _argv(SB)
- MOVW R6, _env(SB)
- JAL main(SB)
- JMP (R0)
- /*
- * Take first processor into user mode
- * - argument is stack pointer to user
- */
- TEXT touser(SB), $-4
- MOVW M(STATUS), R1
- OR $(KUP|IEP), R1
- MOVW R1, M(STATUS)
- NOOP
- MOVW 0(FP), SP
- MOVW $(UTZERO+32), R26 /* header appears in text */
- RFE (R26)
- /*
- * Bring subsequent processors on line
- */
- TEXT newstart(SB), $0
- MOVW $setR30(SB), R30
- MOVW $(INTR5|INTR4|INTR3|INTR2|INTR1|SW1|SW0), R1
- MOVW R1, M(STATUS)
- NOOP
- MOVW $MACHADDR, R(MACH)
- MOVB (MPID+3), R1
- AND $7, R1
- SLL $PGSHIFT, R1, R2
- ADDU R2, R(MACH)
- ADDU $(BY2PG-4), R(MACH), SP
- MOVW $0, R(USER)
- MOVW R1, 0(R(MACH))
- JAL online(SB)
- JMP (R0)
- TEXT firmware(SB), $0
- MOVW $(PROM+0x18), R1 /**/
- /* MOVW $(PROM+0x00), R1 /**/
- JMP (R1)
- TEXT splhi(SB), $0
- MOVW M(STATUS), R1
- AND $~IEC, R1, R2
- MOVW R2, M(STATUS)
- NOOP
- RET
- TEXT spllo(SB), $0
- MOVW M(STATUS), R1
- OR $IEC, R1, R2
- MOVW R2, M(STATUS)
- NOOP
- RET
- TEXT splx(SB), $0
- MOVW 0(FP), R1
- MOVW M(STATUS), R2
- AND $IEC, R1
- AND $~IEC, R2
- OR R2, R1
- MOVW R1, M(STATUS)
- NOOP
- RET
- TEXT wbflush(SB), $-4
- MOVW $WBFLUSH, R1
- MOVW 0(R1), R1
- RET
- TEXT setlabel(SB), $0
- MOVW 0(FP), R2
- MOVW $0, R1
- MOVW R31, 0(R2)
- MOVW R29, 4(R2)
- RET
- TEXT gotolabel(SB), $0
- MOVW 0(FP), R2
- MOVW $1, R1
- MOVW 0(R2), R31
- MOVW 4(R2), R29
- RET
- TEXT gotopc(SB), $8
- MOVW 0(FP), R7 /* save arguments for later */
- MOVW _argc(SB), R4
- MOVW _argv(SB), R5
- MOVW _env(SB), R6
- MOVW R0, 4(SP)
- MOVW $(64*1024), R1
- MOVW R1, 8(SP)
- JAL icflush(SB)
- JMP (R7)
- TEXT puttlb(SB), $4
- JAL splhi(SB)
- MOVW 0(FP), R2
- MOVW 4(FP), R3
- MOVW R1, 4(SP)
- MOVW R2, M(TLBVIRT)
- MOVW R3, M(TLBPHYS)
- NOOP
- TLBP
- NOOP
- MOVW M(INDEX), R4
- BGEZ R4, index
- TLBWR
- NOOP
- JAL splx(SB)
- RET
- index:
- TLBWI
- NOOP
- JAL splx(SB)
- RET
- TEXT puttlbx(SB), $0
- MOVW 0(FP), R4
- MOVW 4(FP), R2
- MOVW 8(FP), R3
- SLL $8, R4
- MOVW R2, M(TLBVIRT)
- MOVW R3, M(TLBPHYS)
- MOVW R4, M(INDEX)
- NOOP
- TLBWI
- NOOP
- RET
- TEXT tlbp(SB), $0
- TLBP
- NOOP
- MOVW M(INDEX), R1
- RET
-
- TEXT tlbvirt(SB), $0
- TLBP
- NOOP
- MOVW M(TLBVIRT), R1
- RET
-
- TEXT gettlb(SB), $0
- MOVW 0(FP), R3
- MOVW 4(FP), R4
- SLL $8, R3
- MOVW R3, M(INDEX)
- NOOP
- TLBR
- NOOP
- MOVW M(TLBVIRT), R1
- MOVW M(TLBPHYS), R2
- NOOP
- MOVW R1, 0(R4)
- MOVW R2, 4(R4)
- RET
- TEXT gettlbvirt(SB), $0
- MOVW 0(FP), R3
- SLL $8, R3
- MOVW R3, M(INDEX)
- NOOP
- TLBR
- NOOP
- MOVW M(TLBVIRT), R1
- NOOP
- RET
- TEXT vector80(SB), $-4
- MOVW $exception(SB), R26
- JMP (R26)
- TEXT exception(SB), $-4
- MOVW M(STATUS), R26
- AND $KUP, R26
- BEQ R26, waskernel
- wasuser:
- MOVW SP, R26
- /*
- * set kernel sp: ureg - ureg* - pc
- * done in 2 steps because R30 is not set
- * and the loader will make a literal
- */
- MOVW $((UREGADDR-2*BY2WD) & 0xffff0000), SP
- OR $((UREGADDR-2*BY2WD) & 0xffff), SP
- MOVW R26, 0x10(SP) /* user SP */
- MOVW R31, 0x28(SP)
- MOVW R30, 0x2C(SP)
- MOVW M(CAUSE), R26
- MOVW R(MACH), 0x3C(SP)
- MOVW R(USER), 0x40(SP)
- AND $(0xF<<2), R26
- SUB $(CSYS<<2), R26
- JAL saveregs(SB)
- MOVW $setR30(SB), R30
- SUBU $(UREGADDR-2*BY2WD-USERADDR), SP, R(USER)
- MOVW $MPID, R1
- MOVB 3(R1), R1
- MOVW $MACHADDR, R(MACH) /* locn of mach 0 */
- AND $7, R1
- SLL $PGSHIFT, R1
- ADDU R1, R(MACH) /* add offset for mach # */
- BNE R26, notsys
- JAL syscall(SB)
- MOVW 0x28(SP), R31
- MOVW 0x08(SP), R26
- MOVW 0x2C(SP), R30
- MOVW R26, M(STATUS)
- NOOP
- MOVW 0x0C(SP), R26 /* old pc */
- MOVW 0x10(SP), SP
- RFE (R26)
- notsys:
- JAL trap(SB)
- restore:
- JAL restregs(SB)
- MOVW 0x28(SP), R31
- MOVW 0x2C(SP), R30
- MOVW 0x3C(SP), R(MACH)
- MOVW 0x40(SP), R(USER)
- MOVW 0x10(SP), SP
- RFE (R26)
- waskernel:
- MOVW $1, R26 /* not sys call */
- MOVW SP, -0x90(SP) /* drop this if possible */
- SUB $0xA0, SP
- MOVW R31, 0x28(SP)
- JAL saveregs(SB)
- JAL trap(SB)
- JAL restregs(SB)
- MOVW 0x28(SP), R31
- ADD $0xA0, SP
- RFE (R26)
- TEXT saveregs(SB), $-4
- MOVW R1, 0x9C(SP)
- MOVW R2, 0x98(SP)
- ADDU $8, SP, R1
- MOVW R1, 0x04(SP) /* arg to base of regs */
- MOVW M(STATUS), R1
- MOVW M(EPC), R2
- MOVW R1, 0x08(SP)
- MOVW R2, 0x0C(SP)
- BEQ R26, return /* sys call, don't save */
- MOVW M(CAUSE), R1
- MOVW M(BADVADDR), R2
- MOVW R1, 0x14(SP)
- MOVW M(TLBVIRT), R1
- MOVW R2, 0x18(SP)
- MOVW R1, 0x1C(SP)
- MOVW HI, R1
- MOVW LO, R2
- MOVW R1, 0x20(SP)
- MOVW R2, 0x24(SP)
- /* LINK,SB,SP missing */
- MOVW R28, 0x30(SP)
- /* R27, R26 not saved */
- /* R25, R24 missing */
- MOVW R23, 0x44(SP)
- MOVW R22, 0x48(SP)
- MOVW R21, 0x4C(SP)
- MOVW R20, 0x50(SP)
- MOVW R19, 0x54(SP)
- MOVW R18, 0x58(SP)
- MOVW R17, 0x5C(SP)
- MOVW R16, 0x60(SP)
- MOVW R15, 0x64(SP)
- MOVW R14, 0x68(SP)
- MOVW R13, 0x6C(SP)
- MOVW R12, 0x70(SP)
- MOVW R11, 0x74(SP)
- MOVW R10, 0x78(SP)
- MOVW R9, 0x7C(SP)
- MOVW R8, 0x80(SP)
- MOVW R7, 0x84(SP)
- MOVW R6, 0x88(SP)
- MOVW R5, 0x8C(SP)
- MOVW R4, 0x90(SP)
- MOVW R3, 0x94(SP)
- return:
- RET
- TEXT restregs(SB), $-4
- /* LINK,SB,SP missing */
- MOVW 0x30(SP), R28
- /* R27, R26 not saved */
- /* R25, R24 missing */
- MOVW 0x44(SP), R23
- MOVW 0x48(SP), R22
- MOVW 0x4C(SP), R21
- MOVW 0x50(SP), R20
- MOVW 0x54(SP), R19
- MOVW 0x58(SP), R18
- MOVW 0x5C(SP), R17
- MOVW 0x60(SP), R16
- MOVW 0x64(SP), R15
- MOVW 0x68(SP), R14
- MOVW 0x6C(SP), R13
- MOVW 0x70(SP), R12
- MOVW 0x74(SP), R11
- MOVW 0x78(SP), R10
- MOVW 0x7C(SP), R9
- MOVW 0x80(SP), R8
- MOVW 0x84(SP), R7
- MOVW 0x88(SP), R6
- MOVW 0x8C(SP), R5
- MOVW 0x90(SP), R4
- MOVW 0x94(SP), R3
- MOVW 0x24(SP), R2
- MOVW 0x20(SP), R1
- MOVW R2, LO
- MOVW R1, HI
- MOVW 0x08(SP), R1
- MOVW 0x98(SP), R2
- MOVW R1, M(STATUS)
- NOOP
- MOVW 0x9C(SP), R1
- MOVW 0x0C(SP), R26 /* old pc */
- RET
- TEXT rfnote(SB), $0
- MOVW 0(FP), R26 /* 1st arg is &uregpointer */
- SUBU $(BY2WD), R26, SP /* pc hole */
- BNE R26, restore
-
- TEXT clrfpintr(SB), $0
- MOVW FCR31, R1
- MOVW R1, R2
- AND $~(0x3F<<12), R2
- MOVW R2, FCR31
- RET
- TEXT savefpregs(SB), $0
- MOVW M(STATUS), R3
- MOVW 0(FP), R1
- MOVW FCR31, R2
- MOVD F0, 0x00(R1)
- MOVD F2, 0x08(R1)
- MOVD F4, 0x10(R1)
- MOVD F6, 0x18(R1)
- MOVD F8, 0x20(R1)
- MOVD F10, 0x28(R1)
- MOVD F12, 0x30(R1)
- MOVD F14, 0x38(R1)
- MOVD F16, 0x40(R1)
- MOVD F18, 0x48(R1)
- MOVD F20, 0x50(R1)
- MOVD F22, 0x58(R1)
- MOVD F24, 0x60(R1)
- MOVD F26, 0x68(R1)
- MOVD F28, 0x70(R1)
- MOVD F30, 0x78(R1)
- MOVW R2, 0x80(R1)
- AND $~CU1, R3
- MOVW R3, M(STATUS)
- RET
- TEXT restfpregs(SB), $0
- MOVW M(STATUS), R3
- MOVW 0(FP), R1
- OR $CU1, R3
- MOVW R3, M(STATUS)
- MOVW 0x80(R1), R2
- MOVD 0x00(R1), F0
- MOVD 0x08(R1), F2
- MOVD 0x10(R1), F4
- MOVD 0x18(R1), F6
- MOVD 0x20(R1), F8
- MOVD 0x28(R1), F10
- MOVD 0x30(R1), F12
- MOVD 0x38(R1), F14
- MOVD 0x40(R1), F16
- MOVD 0x48(R1), F18
- MOVD 0x50(R1), F20
- MOVD 0x58(R1), F22
- MOVD 0x60(R1), F24
- MOVD 0x68(R1), F26
- MOVD 0x70(R1), F28
- MOVD 0x78(R1), F30
- MOVW R2, FCR31
- AND $~CU1, R3
- MOVW R3, M(STATUS)
- RET
- /*
- * we avoid using R4, R5, R6, and R7 so gotopc can call us without saving them
- */
- TEXT icflush(SB), $-4 /* icflush(physaddr, nbytes) */
- MOVW M(STATUS), R10
- MOVW 0(FP), R8
- MOVW 4(FP), R9
- MOVW $KSEG0, R3
- OR R3, R8
- MOVW $0, M(STATUS)
- MOVW $WBFLUSH, R1 /* wbflush */
- MOVW 0(R1), R1
- NOOP
- MOVW $KSEG1, R3
- MOVW $icflush0(SB), R2 /* make sure PC is in uncached address space */
- MOVW $(SWC|ISC), R1
- OR R3, R2
- JMP (R2)
- TEXT icflush0(SB), $-4
- MOVW R1, M(STATUS) /* swap and isolate cache, splhi */
- MOVW $icflush1(SB), R2
- JMP (R2)
- TEXT icflush1(SB), $-4
- _icflush1:
- MOVBU R0, 0x00(R8)
- MOVBU R0, 0x04(R8)
- MOVBU R0, 0x08(R8)
- MOVBU R0, 0x0C(R8)
- MOVBU R0, 0x10(R8)
- MOVBU R0, 0x14(R8)
- MOVBU R0, 0x18(R8)
- MOVBU R0, 0x1C(R8)
- MOVBU R0, 0x20(R8)
- MOVBU R0, 0x24(R8)
- MOVBU R0, 0x28(R8)
- MOVBU R0, 0x2C(R8)
- MOVBU R0, 0x30(R8)
- MOVBU R0, 0x34(R8)
- MOVBU R0, 0x38(R8)
- MOVBU R0, 0x3C(R8)
- SUB $0x40, R9
- ADD $0x40, R8
- BGTZ R9, _icflush1
- MOVW $icflush2(SB), R2 /* make sure PC is in uncached address space */
- OR R3, R2
- JMP (R2)
- TEXT icflush2(SB), $-4
- MOVW $0, M(STATUS) /* swap back caches, de-isolate them, and stay splhi */
- NOOP /* +++ */
- MOVW R10, M(STATUS)
- RET
- TEXT dcflush(SB), $-4 /* dcflush(physaddr, nbytes) */
- MOVW M(STATUS), R6
- MOVW 0(FP), R4
- MOVW 4(FP), R5
- MOVW $KSEG0, R3
- OR R3, R4
- MOVW $0, M(STATUS)
- MOVW $WBFLUSH, R1
- MOVW 0(R1), R1
- NOOP
- MOVW $ISC, R1
- MOVW R1, M(STATUS)
- _dcflush0:
- MOVBU R0, 0x00(R4)
- MOVBU R0, 0x04(R4)
- MOVBU R0, 0x08(R4)
- MOVBU R0, 0x0C(R4)
- MOVBU R0, 0x10(R4)
- MOVBU R0, 0x14(R4)
- MOVBU R0, 0x18(R4)
- MOVBU R0, 0x1C(R4)
- MOVBU R0, 0x20(R4)
- MOVBU R0, 0x24(R4)
- MOVBU R0, 0x28(R4)
- MOVBU R0, 0x2C(R4)
- MOVBU R0, 0x30(R4)
- MOVBU R0, 0x34(R4)
- MOVBU R0, 0x38(R4)
- MOVBU R0, 0x3C(R4)
- SUB $0x40, R5
- ADD $0x40, R4
- BGTZ R5, _dcflush0
- MOVW $0, M(STATUS)
- NOOP /* +++ */
- MOVW R6, M(STATUS)
- RET
|