Plan 9 from Bell Labs 1994-02-09
6 files changed, 325 insertions(+), 67 deletions(-) M carrera/l.s M carrera/mem.h A carrera/memmove.s M carrera/memset.s M carrera/trap.c M pc/ether509.c
M carrera/l.s => carrera/l.s +24 -9
@@ 1,10 1,10 @@ #include "mem.h" #define SP R29 #define SP R29 #define PROM (KSEG1+0x1C000000) #define PROM (KSEG1+0x1C000000) #define NOOP WORD $0x27 #define FCRNOOP NOOP; NOOP; NOOP #define FCRNOOP NOOP; NOOP; NOOP #define WAIT NOOP; NOOP #define NOOP4 NOOP; NOOP; NOOP; NOOP @@ 27,8 27,8 @@ /* * R4000 instructions */ #define LD(base, rt) WORD $((067<<26)|((base)<<21)|((rt)<<16)) #define STD(rt, base) WORD $((077<<26)|((base)<<21)|((rt)<<16)) #define LD(offset, base, rt) WORD $((067<<26)|((base)<<21)|((rt)<<16)|((offset)&0xFFFF)) #define STD(rt, offset, base) WORD $((077<<26)|((base)<<21)|((rt)<<16)|((offset)&0xFFFF)) #define DSLL(sa, rt, rd) WORD $(((rt)<<16)|((rd)<<11)|((sa)<<6)|070) #define DSRA(sa, rt, rd) WORD $(((rt)<<16)|((rd)<<11)|((sa)<<6)|073) #define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16)) @@ 491,6 491,12 @@ TEXT forkret(SB), $0 TEXT saveregs(SB), $-4 MOVW R1, 0x9C(SP) MOVW R2, 0x98(SP) /* save R5, R6 as 64 bits */ ADDU $(UREGSIZE-16), SP, R1 MOVW $~7, R2 /* don't let him use R28 */ AND R2, R1 STD (5, 0,(1)) STD (6, 8,(1)) ADDU $8, SP, R1 MOVW R1, 0x04(SP) /* arg to base of regs */ MOVW M(STATUS), R1 @@ 567,14 573,23 @@ TEXT restregs(SB), $-4 MOVW 0x7C(SP), R9 MOVW 0x80(SP), R8 MOVW 0x84(SP), R7 MOVW 0x88(SP), R6 MOVW 0x8C(SP), R5 /* * restored below * 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 /* restore 64-bit R5, R6 */ ADDU $(UREGSIZE-16), SP, R1 MOVW $~7, R2 /* don't let him use R28 */ AND R2, R1 LD (0,(1), 5) LD (8,(1), 6) MOVW 0x08(SP), R1 MOVW 0x98(SP), R2 MOVW R1, M(STATUS) @@ 842,7 857,7 @@ TEXT uvmove(SB), $-4 BNE R2, uvgetuna /* aligned load */ LD (1,2) LD (0,(1), 2) WAIT MOVW R2, R1 DSLL (16,1,1) @@ 854,7 869,7 @@ uvput: BNE R4, uvputuna /* aligned store */ STD (2,3) STD (2, 0,(3)) NOP RET
M carrera/mem.h => carrera/mem.h +33 -33
@@ 7,20 7,20 @@ */ #define BI2BY 8 /* bits per byte */ #define BI2WD 32 /* bits per word */ #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 PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) #define MAXMACH 1 /* max # cpus system can run */ #define KSTACK 4096 /* Size of kernel stack */ #define KSTACK 4096 /* Size of kernel stack */ /* * Time */ #define HZ 100 /* clock frequency */ #define HZ 100 /* clock frequency */ #define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ #define TK2MS(t) ((t)*MS2HZ) /* ticks to milliseconds */ @@ 96,53 96,53 @@ * Fundamental addresses */ #define MACHADDR (KTZERO-MAXMACH*BY2PG) /* warning: rdbg is near here */ #define UREGSIZE 0xA0 /* Sizeof(Ureg)+retpc & ur */ #define UREGSIZE 0xC0 /* Sizeof(Ureg)+R5,R6+16 bytes slop+retpc & ur */ #define MACHP(n) ((Mach *)(MACHADDR+(n)*BY2PG)) /* * MMU */ #define PGSZ4K (0x00<<13) #define PGSZ64K (0x0F<<13) #define PGSZ256K (0x3F<<13) #define PGSZ1M (0xFF<<13) #define PGSZ4K (0x00<<13) #define PGSZ64K (0x0F<<13) #define PGSZ256K (0x3F<<13) #define PGSZ1M (0xFF<<13) #define KUSEG 0x00000000 #define KSEG0 0x80000000 #define KSEG1 0xA0000000 #define KSEG0 0x80000000 #define KSEG1 0xA0000000 #define KSEG2 0xC0000000 #define KSEG3 0xE0000000 #define KSEGM 0xE0000000 /* mask to check which seg */ #define PIDXSHFT 12 #define PIDX (0x7<<PIDXSHFT) #define PIDXSHFT 12 #define PIDX (0x7<<PIDXSHFT) #define KMAPADDR 0xE2000000 #define KMAPMASK 0xFF000000 #define KMAPSHIFT 15 #define NCOLOR 8 #define getpgcolor(a) (((ulong)(a)>>PIDXSHFT)&7) #define KMAPMASK 0xFF000000 #define KMAPSHIFT 15 #define NCOLOR 8 #define getpgcolor(a) (((ulong)(a)>>PIDXSHFT)&7) #define PTEGLOBL (1<<0) #define PTEVALID (1<<1) #define PTEWRITE (1<<2) #define PTERONLY 0 #define PTEALGMASK (7<<3) #define PTEUNCACHED (2<<3) #define PTENONCOHER (3<<3) #define PTECOHERXCL (4<<3) #define PTECOHERXCLW (5<<3) #define PTECOHERUPDW (6<<3) #define IOPTE (PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED) #define PTERONLY 0 #define PTEALGMASK (7<<3) #define PTEUNCACHED (2<<3) #define PTENONCOHER (3<<3) #define PTECOHERXCL (4<<3) #define PTECOHERXCLW (5<<3) #define PTECOHERUPDW (6<<3) #define IOPTE (PTEGLOBL|PTEVALID|PTEWRITE|PTEUNCACHED) #define PTEPID(n) (n) #define TLBPID(n) ((n)&0xFF) #define PTEMAPMEM (1024*1024) #define TLBPID(n) ((n)&0xFF) #define PTEMAPMEM (1024*1024) #define PTEPERTAB (PTEMAPMEM/BY2PG) #define STLBLOG 13 #define STLBSIZE (1<<STLBLOG) #define KPTELOG 7 #define KPTESIZE (1<<KPTELOG) #define SEGMAPSIZE 512 #define STLBLOG 13 #define STLBSIZE (1<<STLBLOG) #define KPTELOG 7 #define KPTESIZE (1<<KPTELOG) #define SEGMAPSIZE 512 #define NTLBPID 256 /* number of pids */ #define NTLB 48 /* number of entries */ @@ 156,7 156,7 @@ #define UTZERO (UZERO+BY2PG) /* first address in user text */ #define USTKTOP (KZERO-BY2PG) /* byte just beyond user stack */ #define TSTKTOP (0xC0000000+USTKSIZE-BY2PG) /* top of temporary stack */ #define TSTKSIZ 100 #define TSTKSIZ 100 #define KZERO KSEG0 /* base of kernel address space */ #define KTZERO (KZERO+0x20000) /* first address in kernel text */ #define USTKSIZE (4*1024*1024) /* size of user stack */
A carrera/memmove.s => carrera/memmove.s +247 -0
@@ 0,0 1,247 @@ /* * R4000 double-word version. Only works in kernel mode. * Requires low-core support to save R5 and R6 in a 64-bit hole. */ /* * R4000 instructions */ #define LD(offset, base, rt) WORD $((067<<26)|((base)<<21)|((rt)<<16)|((offset)&0xFFFF)) #define STD(rt, offset, base) WORD $((077<<26)|((base)<<21)|((rt)<<16)|((offset)&0xFFFF)) TEXT memmove(SB), $0 JMP move TEXT memcpy(SB), $0 move: MOVW R1, s1+0(FP) MOVW n+8(FP), R3 /* R3 is count */ MOVW R1, R4 /* R4 is to-pointer */ SGT R0, R3, R10 BEQ R10, ok MOVW (R0), R0 /* abort if negative count */ ok: MOVW s2+4(FP), R10 /* R10 is from-pointer */ ADDU R3,R10, R7 /* R7 is end from-pointer */ ADDU R3,R4, R11 /* R11 is end to-pointer */ /* * easiest test is copy backwards if * destination string has higher mem address */ SGT $8,R3, R2 SGTU R4,R10, R1 BNE R1, back /* * if not at least 8 chars, * dont even mess around. * 7 chars to guarantee any * rounding up to a doubleword * boundary and 8 characters * to get at least maybe one * full doubleword store. */ BNE R2, fout /* * test if both pointers * are similarly word aligned */ XOR R4,R10, R1 AND $3, R1 BNE R1, fout /* * test if both pointers * are similarly double-word aligned */ XOR R4,R10, R1 AND $7, R1 BNE R1, f1 /* * double-word aligned; start by byte at a time until aligned */ fd1: AND $7,R4, R1 BEQ R1, fd2 MOVB 0(R10), R8 ADDU $1, R10 MOVB R8, 0(R4) ADDU $1, R4 JMP fd1 /* * turn R3 into to-end pointer-31 * copy 32 at a time while there's room. * R11 is smaller than R7 -- * there are problems if R7 is 0. */ fd2: ADDU $-31,R11, R3 fd3: SGTU R3,R4, R1 BEQ R1, f4 LD (0,(10), 5) /* MOVW 0(R10), R8 */ LD (8,(10), 6) /* MOVW 4(R10), R9 */ STD (5, 0,(4)) /* MOVW R8, 0(R4) */ LD (16,(10), 5) /* MOVW 8(R10), R8 */ STD (6, 8,(4)) /* MOVW R9, 4(R4) */ LD (24,(10), 6) /* MOVW 12(R10), R9 */ ADDU $32, R10 STD (5, 16,(4)) /* MOVW R8, 8(R4) */ STD (6, 24,(4)) /* MOVW R9, 12(R4) */ ADDU $32, R4 JMP fd3 /* * byte at a time to word align */ f1: AND $3,R4, R1 BEQ R1, f2 MOVB 0(R10), R8 ADDU $1, R10 MOVB R8, 0(R4) ADDU $1, R4 JMP f1 /* * turn R3 into to-end pointer-15 * copy 16 at a time while there's room. * R11 is smaller than R7 -- * there are problems if R7 is 0. */ f2: ADDU $-15,R11, R3 f3: SGTU R3,R4, R1 BEQ R1, f4 MOVW 0(R10), R8 MOVW 4(R10), R9 MOVW R8, 0(R4) MOVW 8(R10), R8 MOVW R9, 4(R4) MOVW 12(R10), R9 ADDU $16, R10 MOVW R8, 8(R4) MOVW R9, 12(R4) ADDU $16, R4 JMP f3 /* * turn R3 into to-end pointer-3 * copy 4 at a time while theres room */ f4: ADDU $-3,R11, R3 f5: SGTU R3,R4, R1 BEQ R1, fout MOVW 0(R10), R8 ADDU $4, R10 MOVW R8, 0(R4) ADDU $4, R4 JMP f5 /* * last loop, copy byte at a time */ fout: BEQ R7,R10, ret MOVB 0(R10), R8 ADDU $1, R10 MOVB R8, 0(R4) ADDU $1, R4 JMP fout /* * whole thing repeated for backwards */ back: BNE R2, bout XOR R11,R7, R1 AND $3, R1 BNE R1, bout XOR R11,R7, R1 AND $7, R1 BNE R1, b1 /* double words */ bd1: AND $7,R7, R1 BEQ R1, bd2 MOVB -1(R7), R8 ADDU $-1, R7 MOVB R8, -1(R11) ADDU $-1, R11 JMP bd1 bd2: ADDU $31,R10, R3 bd3: SGTU R7,R3, R1 BEQ R1, b4 LD (-8,(7), 5) /* MOVW -4(R7), R8 */ LD (-16,(7), 6) /* MOVW -8(R7), R9 */ STD (5, -8,(11)) /* MOVW R8, -4(R11) */ LD (-24,(7), 5) /* MOVW -12(R7), R8 */ STD (6, -16,(11)) /* MOVW R9, -8(R11) */ LD (-32,(7), 6) /* MOVW -16(R7), R9 */ ADDU $-32, R7 STD (5, -24,(11)) /* MOVW R8, -12(R11) */ STD (6, -32,(11)) /* MOVW R9, -16(R11) */ ADDU $-32, R11 JMP bd3 /* regular words */ b1: AND $3,R7, R1 BEQ R1, b2 MOVB -1(R7), R8 ADDU $-1, R7 MOVB R8, -1(R11) ADDU $-1, R11 JMP b1 b2: ADDU $15,R10, R3 b3: SGTU R7,R3, R1 BEQ R1, b4 MOVW -4(R7), R8 MOVW -8(R7), R9 MOVW R8, -4(R11) MOVW -12(R7), R8 MOVW R9, -8(R11) MOVW -16(R7), R9 ADDU $-16, R7 MOVW R8, -12(R11) MOVW R9, -16(R11) ADDU $-16, R11 JMP b3 b4: ADDU $3,R10, R3 b5: SGTU R7,R3, R1 BEQ R1, bout MOVW -4(R7), R8 ADDU $-4, R7 MOVW R8, -4(R11) ADDU $-4, R11 JMP b5 bout: BEQ R7,R10, ret MOVB -1(R7), R8 ADDU $-1, R7 MOVB R8, -1(R11) ADDU $-1, R11 JMP bout ret: MOVW s1+0(FP), R1 RET END
M carrera/memset.s => carrera/memset.s +1 -12
@@ 1,7 1,6 @@ /* * R4000 double-word version. Only works in kernel mode. * Must have interrupts disabled because we save and restore R5 in a 32-bit hole. * Here for reference... * Requires low-core support to save R5 in a 64-bit hole. */ /* @@ 9,20 8,10 @@ */ #define LD(base, rt) WORD $((067<<26)|((base)<<21)|((rt)<<16)) #define STD(rt, offset, base) WORD $((077<<26)|((base)<<21)|((rt)<<16)|((offset)&0xFFFF)) #define DSLL(sa, rt, rd) WORD $(((rt)<<16)|((rd)<<11)|((sa)<<6)|070) #define DSLL32(sa, rt, rd) WORD $(((rt)<<16)|((rd)<<11)|((sa)<<6)|070) #define DSRA(sa, rt, rd) WORD $(((rt)<<16)|((rd)<<11)|((sa)<<6)|074) #define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16)) #define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16)) TEXT memset(SB),$16 /* $16 for hole to build temporary */ MOVW R1, 0(FP) /* * performance: * about 1us/call and 28mb/sec (on what machine, ken? huh? -rob) */ MOVW n+8(FP), R3 /* R3 is count */ MOVW p+0(FP), R4 /* R4 is pointer */ MOVW c+4(FP), R5 /* R5 is char */
M carrera/trap.c => carrera/trap.c +1 -1
@@ 614,7 614,7 @@ forkchild(Proc *p, Ureg *ur) { Ureg *cur; p->sched.sp = (ulong)p->kstack+KSTACK-(sizeof(Ureg)+2*BY2WD); p->sched.sp = (ulong)p->kstack+KSTACK-UREGSIZE; p->sched.pc = (ulong)forkret; cur = (Ureg*)(p->sched.sp+2*BY2WD);
M pc/ether509.c => pc/ether509.c +19 -12
@@ 54,6 54,7 @@ enum { TxFreeBytes = 0x0C, /* window 1 */ TxStatus = 0x0B, Timer = 0x0A, RxStatus = 0x08, Fifo = 0x00, @@ 388,23 389,23 @@ activate(Ether *ether) idseq(); /* * 3. Read the Product ID from the EEPROM. * This is done by writing the IDPort with 0x83 (0x80 * is the 'read EEPROM command, 0x03 is the offset of * the Product ID field in the EEPROM). * 3. Read the Manufacturer ID from the EEPROM. * This is done by writing the IDPort with 0x87 (0x80 * is the 'read EEPROM command, 0x07 is the offset of * the Manufacturer ID field in the EEPROM). * The data comes back 1 bit at a time. * We seem to need a delay here between reading the bits. * * If the ID doesn't match the 3C509 ID code, the adapter * probably isn't there, so barf. */ outb(IDport, 0x83); outb(IDport, 0x87); for(x = 0, i = 0; i < 16; i++){ delay(5); x <<= 1; x |= inb(IDport) & 0x01; } if((x & 0xF0FF) != 0x9050) if((x & 0xF0FF) != 0x6D50) return -1; /* @@ 430,7 431,7 @@ activate(Ether *ether) ether->port = (acr & 0x1F)*0x10 + 0x200; outb(ether->port+ConfigControl, 0x01); return 0; return ether->port; } /* @@ 447,14 448,18 @@ reset(Ether *ether) /* * Switch out to 509 activation code if a port is supplied and is * not in the EISA slot space, otherwise check the EISA card is there. * Port is set to either the newly activated ISA card address or * the EISA slot configuration info where Window0 is always mapped. */ if(ether->port < 0x1000 && activate(ether) < 0) return -1; else if((ins(ether->port+ProductID) & 0xF0FF) != 0x9050) if(ether->port < 0x1000){ if((port = activate(ether)) < 0) return -1; } else if(ins(ether->port+ManufacturerID) == 0x6D50) port = ether->port+0xC80; else return -1; port = ether->port; /* * Read the IRQ from the Resource Configuration Register, * the ethernet address from the EEPROM, and the address configuration. @@ 474,6 479,8 @@ reset(Ether *ether) } acr = ins(port+AddressConfig); port = ether->port; /* * Finished with window 0. Now set the ethernet address * in window 2.