123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696 |
- /*
- * 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 PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1))
- #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 */
- /*
- * PSR bits
- */
- #define PSREC 0x00002000
- #define PSREF 0x00001000
- #define PSRSUPER 0x00000080
- #define PSRPSUPER 0x00000040
- #define PSRET 0x00000020
- #define SPL(n) (n<<8)
- /*
- * Magic registers
- */
- #define MACH 6 /* R6 is m-> */
- #define USER 5 /* R5 is u-> */
- /*
- * Fundamental addresses
- */
- #define USERADDR 0xE0000000
- #define UREGADDR (USERADDR+BY2PG-((32+6)*BY2WD))
- #define BOOTSTACK (KTZERO-0*BY2PG)
- #define TRAPS (KTZERO-2*BY2PG)
- /*
- * MMU
- */
- #define VAMASK 0x3FFFFFFF
- #define NPMEG (1<<12)
- #define BY2SEGM (1<<18)
- #define PG2SEGM (1<<6)
- #define NTLBPID (1+NCONTEXT) /* TLBPID 0 is unallocated */
- #define NCONTEXT 8
- #define CONTEXT 0x30000000 /* in ASI 2 */
- /*
- * MMU regions
- */
- #define INVALIDSEGM 0xFFFC0000 /* highest seg of VA reserved as invalid */
- #define INVALIDPMEG 0x7F
- #define SCREENSEGM 0xFFF80000
- #define SCREENPMEG 0x7E
- #define ROMSEGM 0xFFE80000
- #define ROMEND 0xFFEA0000
- #define PG2ROM ((ROMEND-ROMSEGM)/BY2PG)
- #define IOSEGM0 ROMSEGM /* see mmuinit() */
- #define NIOSEGM ((SCREENSEGM-ROMSEGM)/BY2SEGM)
- #define IOPMEG0 (SCREENPMEG-NIOSEGM)
- #define IOSEGM ROMEND
- #define IOEND SCREENSEGM
- #define TOPPMEG IOPMEG0
- /*
- * MMU entries
- */
- #define PTEVALID (1<<31)
- #define PTERONLY (0<<30)
- #define PTEWRITE (1<<30)
- #define PTEKERNEL (1<<29)
- #define PTENOCACHE (1<<28)
- #define PTEMAINMEM (0<<26)
- #define PTEIO (1<<26)
- #define PTEACCESS (1<<25)
- #define PTEMODIFY (1<<24)
- #define PTEUNCACHED 0
- #define PTEMAPMEM (1024*1024)
- #define PTEPERTAB (PTEMAPMEM/BY2PG)
- #define SEGMAPSIZE 16
- #define INVALIDPTE 0
- #define PPN(pa) ((pa>>12)&0xFFFF)
- /*
- * Weird addresses in various ASI's
- */
- #define CACHETAGS 0x80000000 /* ASI 2 */
- #define CACHEDATA 0x90000000 /* ASI 2 */
- #define SER 0x60000000 /* ASI 2 */
- #define SEVAR 0x60000004 /* ASI 2 */
- #define ASER 0x60000008 /* ASI 2 */
- #define ASEVAR 0x6000000C /* ASI 2 */
- #define ENAB 0x40000000 /* ASI 2 */
- #define ENABCACHE 0x10
- #define ENABRESET 0x04
- /*
- * Virtual addresses
- */
- #define VTAG(va) ((va>>22)&0x03F)
- #define VPN(va) ((va>>13)&0x1FF)
- #define PARAM ((char*)0x40500000)
- #define TLBFLUSH_ 0x01
- /*
- * Address spaces
- */
- #define UZERO 0x00000000 /* base of user address space */
- #define UTZERO (UZERO+BY2PG) /* first address in user text */
- #define TSTKTOP 0x10000000 /* end of new stack in sysexec */
- #define TSTKSIZ 32
- #define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */
- #define KZERO 0xE0000000 /* base of kernel address space */
- #define KTZERO (KZERO+4*BY2PG) /* first address in kernel text */
- #define USTKSIZE (4*1024*1024) /* size of user stack */
- #define MACHSIZE 4096
- #define isphys(x) (((ulong)(x)&0xF0000000) == KZERO)
- #define SYSPSR (SPL(0x0)|PSREF|PSRSUPER|0)
- #define NOOP OR R0, R0; OR R0, R0; OR R0, R0
- TEXT start(SB), $-4
- /* get virtual, fast */
- /* we are executing in segment 0, mapped to pmeg 0. stack is there too */
- /* get virtual by mapping segment(KZERO) to pmeg 0., and next to 1 */
- MOVW $KZERO, R7
- MOVB R0, (R7, 3)
- MOVW $(KZERO+BY2SEGM), R7
- MOVW $1, R8
- MOVB R8, (R7, 3)
- /* now mapped correctly. jmpl to where we want to be */
- MOVW $setSB(SB), R2
- MOVW $startvirt(SB), R7
- JMPL (R7)
- MOVW $_mul(SB), R0 /* touch _mul etc.; doesn't need to execute */
- RETURN /* can't get here */
- TEXT startvirt(SB), $-4
- MOVW $BOOTSTACK, R1
- MOVW $(SPL(0xF)|PSREF|PSRSUPER), R7
- MOVW R7, PSR
- MOVW $(0x35<<22), R7 /* NVM OFM DZM AU */
- MOVW R7, fsr+0(SB)
- MOVW fsr+0(SB), FSR
- FMOVD $0.5, F26 /* 0.5 -> F26 */
- FSUBD F26, F26, F24 /* 0.0 -> F24 */
- FADDD F26, F26, F28 /* 1.0 -> F28 */
- FADDD F28, F28, F30 /* 2.0 -> F30 */
- FMOVD F24, F0
- FMOVD F24, F2
- FMOVD F24, F4
- FMOVD F24, F6
- FMOVD F24, F8
- FMOVD F24, F10
- FMOVD F24, F12
- FMOVD F24, F14
- FMOVD F24, F16
- FMOVD F24, F18
- FMOVD F24, F20
- FMOVD F24, F22
- MOVW $mach0(SB), R(MACH)
- /* MOVW $0x8, R7 /**/
- MOVW R0, WIM
- JMPL main(SB)
- MOVW (R0), R0
- RETURN
- TEXT swap1(SB), $0
- TAS (R7), R7 /* LDSTUB, thank you ken */
- RETURN
- TEXT swap1_should_work(SB), $0
- MOVW R7, R8
- MOVW $1, R7
- SWAP (R8), R7
- RETURN
- TEXT swap1x(SB), $0
- MOVW PSR, R9
- MOVW R9, R10
- AND $~PSRET, R10 /* BUG: book says this is buggy */
- MOVW R10, PSR
- NOOP
- MOVW (R7), R7
- CMP R7, R0
- BNE was1
- MOVW $1, R10
- MOVW R10, (R8)
- was1:
- MOVW R9, PSR
- RETURN
- TEXT spllo(SB), $0
- MOVW PSR, R7
- MOVW R7, R10
- OR $PSRET, R10
- MOVW R10, PSR
- NOOP
- RETURN
- TEXT splhi(SB), $0
- MOVW R15, 4(R(MACH)) /* save PC in m->splpc */
- MOVW PSR, R7
- MOVW R7, R10
- AND $~PSRET, R10 /* BUG: book says this is buggy */
- MOVW R10, PSR
- NOOP
- RETURN
- TEXT splx(SB), $0
- MOVW R15, 4(R(MACH)) /* save PC in m->splpc */
- MOVW R7, PSR /* BUG: book says this is buggy */
- NOOP
- RETURN
- TEXT spldone(SB), $0
- RETURN
- TEXT touser(SB), $0
- MOVW $(SYSPSR&~PSREF), R8
- MOVW R8, PSR
- NOOP
- MOVW R7, R1
- SAVE R0, R0 /* RETT is implicit RESTORE */
- MOVW $(UTZERO+32), R7 /* PC; header appears in text */
- MOVW $(UTZERO+32+4), R8 /* nPC */
- RETT R7, R8
- TEXT rfnote(SB), $0
- MOVW R7, R1 /* 1st arg is &uregpointer */
- ADD $4, R1 /* point at ureg */
- JMP restore
- TEXT traplink(SB), $-4
- /* R8 to R23 are free to play with */
- /* R17 contains PC, R18 contains nPC */
- /* R19 has PSR loaded from vector code */
- ANDCC $PSRPSUPER, R19, R0
- BE usertrap
- kerneltrap:
- /*
- * Interrupt or fault from kernel
- */
- ANDN $7, R1, R20 /* dbl aligned */
- MOVW R1, (0-(4*(32+6))+(4*1))(R20) /* save R1=SP */
- /* really clumsy: store these in Ureg so can be restored below */
- MOVW R2, (0-(4*(32+6))+(4*2))(R20) /* SB */
- MOVW R5, (0-(4*(32+6))+(4*5))(R20) /* USER */
- MOVW R6, (0-(4*(32+6))+(4*6))(R20) /* MACH */
- SUB $(4*(32+6)), R20, R1
- trap1:
- MOVW Y, R20
- MOVW R20, (4*(32+0))(R1) /* Y */
- MOVW TBR, R20
- MOVW R20, (4*(32+1))(R1) /* TBR */
- AND $~0x1F, R19 /* force CWP=0 */
- MOVW R19, (4*(32+2))(R1) /* PSR */
- MOVW R18, (4*(32+3))(R1) /* nPC */
- MOVW R17, (4*(32+4))(R1) /* PC */
- MOVW R0, (4*0)(R1)
- MOVW R3, (4*3)(R1)
- MOVW R4, (4*4)(R1)
- MOVW R7, (4*7)(R1)
- RESTORE R0, R0
- /* now our registers R8-R31 are same as before trap */
- /* save registers two at a time */
- MOVD R8, (4*8)(R1)
- MOVD R10, (4*10)(R1)
- MOVD R12, (4*12)(R1)
- MOVD R14, (4*14)(R1)
- MOVD R16, (4*16)(R1)
- MOVD R18, (4*18)(R1)
- MOVD R20, (4*20)(R1)
- MOVD R22, (4*22)(R1)
- MOVD R24, (4*24)(R1)
- MOVD R26, (4*26)(R1)
- MOVD R28, (4*28)(R1)
- MOVD R30, (4*30)(R1)
- /* SP and SB and u and m are already set; away we go */
- MOVW R1, R7 /* pointer to Ureg */
- SUB $8, R1
- MOVW $SYSPSR, R8
- MOVW R8, PSR
- NOOP
- JMPL trap(SB)
- ADD $8, R1
- restore:
- MOVW (4*(32+2))(R1), R8 /* PSR */
- MOVW R8, PSR
- NOOP
- MOVD (4*30)(R1), R30
- MOVD (4*28)(R1), R28
- MOVD (4*26)(R1), R26
- MOVD (4*24)(R1), R24
- MOVD (4*22)(R1), R22
- MOVD (4*20)(R1), R20
- MOVD (4*18)(R1), R18
- MOVD (4*16)(R1), R16
- MOVD (4*14)(R1), R14
- MOVD (4*12)(R1), R12
- MOVD (4*10)(R1), R10
- MOVD (4*8)(R1), R8
- SAVE R0, R0
- MOVD (4*6)(R1), R6
- MOVD (4*4)(R1), R4
- MOVD (4*2)(R1), R2
- MOVW (4*(32+0))(R1), R20 /* Y */
- MOVW R20, Y
- MOVW (4*(32+4))(R1), R17 /* PC */
- MOVW (4*(32+3))(R1), R18 /* nPC */
- MOVW (4*1)(R1), R1 /* restore R1=SP */
- RETT R17, R18
-
- usertrap:
- /*
- * Interrupt or fault from user
- */
- MOVW R1, R8
- MOVW R2, R9
- MOVW $setSB(SB), R2
- MOVW $(USERADDR+BY2PG), R1
- MOVW R8, (0-(4*(32+6))+(4*1))(R1) /* save R1=SP */
- MOVW R9, (0-(4*(32+6))+(4*2))(R1) /* save R2=SB */
- MOVW R5, (0-(4*(32+6))+(4*5))(R1) /* save R5=USER */
- MOVW R6, (0-(4*(32+6))+(4*6))(R1) /* save R6=MACH */
- MOVW $USERADDR, R(USER)
- MOVW $mach0(SB), R(MACH)
- SUB $(4*(32+6)), R1
- JMP trap1
- TEXT syslink(SB), $-4
- /* R8 to R23 are free to play with */
- /* R17 contains PC, R18 contains nPC */
- /* R19 has PSR loaded from vector code */
- /* assume user did it; syscall checks */
- MOVW R1, R8
- MOVW R2, R9
- MOVW $setSB(SB), R2
- MOVW $(USERADDR+BY2PG), R1
- MOVW R8, (0-(4*(32+6))+4)(R1) /* save R1=SP */
- SUB $(4*(32+6)), R1
- MOVW R9, (4*2)(R1) /* save R2=SB */
- MOVW R3, (4*3)(R1) /* global register */
- MOVD R4, (4*4)(R1) /* global register, R5=USER */
- MOVD R6, (4*6)(R1) /* save R6=MACH, R7=syscall# */
- MOVW $USERADDR, R(USER)
- MOVW $mach0(SB), R(MACH)
- MOVW TBR, R20
- MOVW R20, (4*(32+1))(R1) /* TBR */
- AND $~0x1F, R19
- MOVW R19, (4*(32+2))(R1) /* PSR */
- MOVW R18, (4*(32+3))(R1) /* nPC */
- MOVW R17, (4*(32+4))(R1) /* PC */
- RESTORE R0, R0
- /* now our registers R8-R31 are same as before trap */
- MOVW R15, (4*15)(R1)
- /* SP and SB and u and m are already set; away we go */
- MOVW R1, R7 /* pointer to Ureg */
- SUB $8, R1
- MOVW $SYSPSR, R8
- MOVW R8, PSR
- JMPL syscall(SB)
- /* R7 contains return value from syscall */
- ADD $8, R1
- MOVW (4*(32+2))(R1), R8 /* PSR */
- MOVW R8, PSR
- NOOP
- MOVW (4*15)(R1), R15
- SAVE R0, R0
- MOVW (4*6)(R1), R6
- MOVD (4*4)(R1), R4
- MOVD (4*2)(R1), R2
- MOVW (4*(32+4))(R1), R17 /* PC */
- MOVW (4*(32+3))(R1), R18 /* nPC */
- MOVW (4*1)(R1), R1 /* restore R1=SP */
- RETT R17, R18
- TEXT puttbr(SB), $0
- MOVW R7, TBR
- NOOP
- RETURN
- TEXT gettbr(SB), $0
- MOVW TBR, R7
- RETURN
- TEXT r1(SB), $0
- MOVW R1, R7
- RETURN
- TEXT getwim(SB), $0
- MOVW WIM, R7
- RETURN
- TEXT setlabel(SB), $0
- MOVW R1, (R7)
- MOVW R15, 4(R7)
- MOVW $0, R7
- RETURN
- TEXT gotolabel(SB), $0
- MOVW (R7), R1
- MOVW 4(R7), R15
- MOVW $1, R7
- RETURN
- TEXT putcxsegm(SB), $0
- MOVW R7, R8 /* context */
- MOVW 4(FP), R9 /* segment addr */
- MOVW 8(FP), R10 /* segment value */
- MOVW $0xFFE80118, R7
- JMPL (R7)
- RETURN
- TEXT getpsr(SB), $0
- MOVW PSR, R7
- RETURN
- TEXT putcxreg(SB), $0
- MOVW $CONTEXT, R8
- MOVB R7, (R8, 2)
- RETURN
- TEXT putb2(SB), $0
- MOVW 4(FP), R8
- MOVB R8, (R7, 2)
- RETURN
- TEXT getb2(SB), $0
- MOVB (R7, 2), R7
- RETURN
- TEXT getw2(SB), $0
- MOVW (R7, 2), R7
- RETURN
- TEXT putw2(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 2)
- RETURN
- TEXT putw4(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 4)
- RETURN
- TEXT getw4(SB), $0
- MOVW (R7, 4), R7
- RETURN
- TEXT putwC(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xC)
- RETURN
- TEXT putwD(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xD)
- RETURN
- TEXT putwD16(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xD)
- RETURN
- TEXT putwE(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xE)
- RETURN
- TEXT putwE16(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- ADD $(1<<4), R7
- MOVW R8, (R7, 0xE)
- RETURN
- TEXT putsegm(SB), $0
- MOVW 4(FP), R8
- MOVW R8, (R7, 3)
- RETURN
- /*
- * in savefpregs and restfpregs, incoming R7 points to doubleword
- * below where F0 will go; doubleword align in and backfill FSR
- */
- TEXT savefpregs(SB), $0
- ADD $8, R7
- ANDN $7, R7 /* now MOVD-aligned */
- MOVW FSR, -4(R7)
- MOVD F0, (0*4)(R7)
- MOVD F2, (2*4)(R7)
- MOVD F4, (4*4)(R7)
- MOVD F6, (6*4)(R7)
- MOVD F8, (8*4)(R7)
- MOVD F10, (10*4)(R7)
- MOVD F12, (12*4)(R7)
- MOVD F14, (14*4)(R7)
- MOVD F16, (16*4)(R7)
- MOVD F18, (18*4)(R7)
- MOVD F20, (20*4)(R7)
- MOVD F22, (22*4)(R7)
- MOVD F24, (24*4)(R7)
- MOVD F26, (26*4)(R7)
- MOVD F28, (28*4)(R7)
- MOVD F30, (30*4)(R7)
- MOVW PSR, R8
- ANDN $PSREF, R8
- MOVW R8, PSR
- RETURN
- TEXT restfpregs(SB), $0
- MOVW PSR, R8
- OR $PSREF, R8
- MOVW R8, PSR
- ADD $8, R7
- ANDN $7, R7 /* now MOVD-aligned */
- OR R0, R0
- MOVW -4(R7), FSR
- MOVD (0*4)(R7), F0
- MOVD (2*4)(R7), F2
- MOVD (4*4)(R7), F4
- MOVD (6*4)(R7), F6
- MOVD (8*4)(R7), F8
- MOVD (10*4)(R7), F10
- MOVD (12*4)(R7), F12
- MOVD (14*4)(R7), F14
- MOVD (16*4)(R7), F16
- MOVD (18*4)(R7), F18
- MOVD (20*4)(R7), F20
- MOVD (22*4)(R7), F22
- MOVD (24*4)(R7), F24
- MOVD (26*4)(R7), F26
- MOVD (28*4)(R7), F28
- MOVD (30*4)(R7), F30
- ANDN $PSREF, R8
- MOVW R8, PSR
- RETURN
- TEXT clearfpintr(SB), $0
- MOVW $fpq+BY2WD(SB), R7
- ANDN $0x7, R7 /* must be D aligned */
- MOVW $fsr+0(SB), R9
- clrq:
- MOVD FQ, (R7)
- MOVW FSR, (R9)
- MOVW (R9), R8
- AND $(1<<13), R8 /* queue not empty? */
- BNE clrq
- RETURN
- TEXT getfsr(SB), $0
- MOVW $fsr+0(SB), R7
- MOVW FSR, (R7)
- MOVW (R7), R7
- RETURN
- GLOBL mach0+0(SB), $MACHSIZE
- GLOBL fpq+0(SB), $(3*BY2WD)
- GLOBL fsr+0(SB), $BY2WD
|