~kris/9p

9hist

390610134e0998653055d5501a608d5529e87ae0 — David du Colombier 32 years ago 3256d08
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.