forsyth20121205-174063a80cc13 years agoHistory
704 lines · 12.3 KB · Assembly
RawDownload
/* * 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 */ /* * Fundamental addresses */ /* *  Address spaces * *  User is at 0-2GB *  Kernel is at 2GB-4GB * *  To avoid an extra page map, both the user stack (USTKTOP) and *  the temporary user stack (TSTKTOP) should be in the the same *  4 meg. */#define	UZERO		0			/* base of user address space */#define	UTZERO		(UZERO+BY2PG)		/* first address in user text */#define	KZERO		0x80000000		/* base of kernel address space */#define	KTZERO		KZERO			/* first address in kernel text */#define	USERADDR	0xC0000000		/* struct User */#define	UREGADDR	(USERADDR+BY2PG-4*19)	#define	TSTKTOP		USERADDR		/* end of new stack in sysexec */#define TSTKSIZ 10#define	USTKTOP		(TSTKTOP-TSTKSIZ*BY2PG)	/* byte just beyond user stack */#define	USTKSIZE	(16*1024*1024 - TSTKSIZ*BY2PG)	/* size of user stack */#define ROMBIOS		(KZERO|0xF0000) #define	MACHSIZE	4096 #define isphys(x) (((ulong)x)&KZERO) /* *  known 80386 segments (in GDT) and their selectors */#define	NULLSEG	0	/* null segment */#define	KDSEG	1	/* kernel data/stack */#define	KESEG	2	/* kernel executable */	#define	UDSEG	3	/* user data/stack */#define	UESEG	4	/* user executable */#define TSSSEG	5	/* task segment */ #define SELGDT	(0<<3)	/* selector is in gdt */#define	SELLDT	(1<<3)	/* selector is in ldt */ #define SELECTOR(i, t, p)	(((i)<<3) | (t) | (p)) #define NULLSEL	SELECTOR(NULLSEG, SELGDT, 0)#define KESEL	SELECTOR(KESEG, SELGDT, 0)#define KDSEL	SELECTOR(KDSEG, SELGDT, 0)#define UESEL	SELECTOR(UESEG, SELGDT, 3)#define UDSEL	SELECTOR(UDSEG, SELGDT, 3)#define TSSSEL	SELECTOR(TSSSEG, SELGDT, 0) /* *  fields in segment descriptors */#define SEGDATA	(0x10<<8)	/* data/stack segment */#define SEGEXEC	(0x18<<8)	/* executable segment */#define	SEGTSS	(0x9<<8)	/* TSS segment */#define SEGCG	(0x0C<<8)	/* call gate */#define	SEGIG	(0x0E<<8)	/* interrupt gate */#define SEGTG	(0x0F<<8)	/* task gate */#define SEGTYPE	(0x1F<<8) #define SEGP	(1<<15)		/* segment present */#define SEGPL(x) ((x)<<13)	/* priority level */#define SEGB	(1<<22)		/* granularity 1==4k (for expand-down) */#define SEGG	(1<<23)		/* granularity 1==4k (for other) */#define SEGE	(1<<10)		/* expand down */#define SEGW	(1<<9)		/* writable (for data/stack) */#define	SEGR	(1<<9)		/* readable (for code) */#define SEGD	(1<<22)		/* default 1==32bit (for code) */ /* *  virtual MMU */#define PTEMAPMEM	(1024*1024)	/* ??? */	#define SEGMAPSIZE	16		/* ??? */#define	PTEPERTAB	(PTEMAPMEM/BY2PG)	/* ??? */#define PPN(x)		((x)&~(BY2PG-1)) /* *  physical MMU */#define	PTEVALID	(1<<0)#define	PTEUNCACHED	0		/* everything is uncached */#define PTEWRITE	(1<<1)#define	PTERONLY	(0<<1)#define	PTEKERNEL	(0<<2)#define	PTEUSER		(1<<2) /* *  flag register bits that we care about */#define IFLAG	0x200 #define OP16	BYTE	$0x66 /* *	about to walk all over ms/dos - turn off interrupts */TEXT	origin(SB),$0 	CLI #ifdef BOOT/* *	This part of l.s is used only in the boot kernel. *	It assumes that we are in real address mode, i.e., *	that we look like an 8086. *//* *	relocate everything to a half meg and jump there *	- looks wierd because it is being assembled by a 32 bit *	  assembler for a 16 bit world */	MOVL	$0,BX	INCL	BX	SHLL	$15,BX	MOVL	BX,CX	MOVW	BX,ES	MOVL	$0,SI	MOVL	SI,DI	CLD; REP; MOVSL/*	JMPFAR	0X8000:$lowcore(SB) /**/	 BYTE	$0xEA	 WORD	$lowcore(SB)	 WORD	$0X8000 TEXT	lowcore(SB),$0 /* *	now that we're in low core, update the DS */ 	MOVW	BX,DS /* * 	goto protected mode *//*	MOVL	tgdtptr(SB),GDTR /**/	 BYTE	$0x0f	 BYTE	$0x01	 BYTE	$0x16	 WORD	$tgdtptr(SB)	MOVL	CR0,AX	ORL	$1,AX	MOVL	AX,CR0 /* *	clear prefetch queue (wierd code to avoid optimizations) */	CLC	JCC	flush	MOVL	AX,AXflush: /* *	set all segs *//*	MOVW	$SELECTOR(1, SELGDT, 0),AX	/**/	 BYTE	$0xc7	 BYTE	$0xc0	 WORD	$SELECTOR(1, SELGDT, 0)	MOVW	AX,DS	MOVW	AX,SS	MOVW	AX,ES	MOVW	AX,FS	MOVW	AX,GS /*	JMPFAR	SELECTOR(2, SELGDT, 0):$mode32bit(SB) /**/	 BYTE	$0x66	 BYTE	$0xEA	 LONG	$mode32bit-KZERO(SB)	 WORD	$SELECTOR(2, SELGDT, 0) TEXT	mode32bit(SB),$0 #endif BOOT 	/*	 * Clear BSS	 */	LEAL	edata-KZERO(SB),SI	MOVL	SI,DI	ADDL	$4,DI	MOVL	$0,AX	MOVL	AX,(SI)	LEAL	end-KZERO(SB),CX	SUBL	DI,CX	SHRL	$2,CX	CLD; REP; MOVSL 	/*	 *  make a bottom level page table page that maps the first	 *  16 meg of physical memory	 */	LEAL	tpt-KZERO(SB),AX	/* get phys addr of temporary page table */	ADDL	$(BY2PG-1),AX		/* must be page alligned */	ANDL	$(~(BY2PG-1)),AX	/* ... */	MOVL	$(4*1024),CX		/* pte's per page */	MOVL	$((((4*1024)-1)<<PGSHIFT)|PTEVALID|PTEKERNEL|PTEWRITE),BXsetpte:	MOVL	BX,-4(AX)(CX*4)	SUBL	$(1<<PGSHIFT),BX	LOOP	setpte 	/*	 *  make a top level page table page that maps the first	 *  16 meg of memory to 0 thru 16meg and to KZERO thru KZERO+16meg	 */	MOVL	AX,BX	ADDL	$(4*BY2PG),AX	ADDL	$(PTEVALID|PTEKERNEL|PTEWRITE),BX	MOVL	BX,0(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+0)(AX)	ADDL	$BY2PG,BX	MOVL	BX,4(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+4)(AX)	ADDL	$BY2PG,BX	MOVL	BX,8(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+8)(AX)	ADDL	$BY2PG,BX	MOVL	BX,12(AX)	MOVL	BX,((((KZERO>>1)&0x7FFFFFFF)>>(2*PGSHIFT-1-4))+12)(AX) 	/*	 *  point processor to top level page & turn on paging	 */	MOVL	AX,CR3	MOVL	CR0,AX	ORL	$0X80000000,AX	ANDL	$~(0x8|0x2),AX	/* TS=0, MP=0 */	MOVL	AX,CR0 	/*	 *  use a jump to an absolute location to get the PC into	 *  KZERO.	 */	LEAL	tokzero(SB),AX	JMP*	AX TEXT	tokzero(SB),$0 	/*	 *  stack and mach	 */	MOVL	$mach0(SB),SP	MOVL	SP,m(SB)	MOVL	$0,0(SP)	ADDL	$(MACHSIZE-4),SP	/* start stack under machine struct */	MOVL	$0, u(SB) 	/*	 *  clear flags	 */	MOVL	$0,AX	PUSHL	AX	POPFL 	CALL	main(SB) loop:	JMP	loop GLOBL	mach0+0(SB), $MACHSIZEGLOBL	u(SB), $4GLOBL	m(SB), $4GLOBL	tpt(SB), $(BY2PG*6) /* *  gdt to get us to 32-bit/segmented/unpaged mode */TEXT	tgdt(SB),$0 	/* null descriptor */	LONG	$0	LONG	$0 	/* data segment descriptor for 4 gigabytes (PL 0) */	LONG	$(0xFFFF)	LONG	$(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW) 	/* exec segment descriptor for 4 gigabytes (PL 0) */	LONG	$(0xFFFF)	LONG	$(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR) /* *  pointer to initial gdt */TEXT	tgdtptr(SB),$0 	WORD	$(3*8)	LONG	$tgdt-KZERO(SB) /* *  input a byte */TEXT	inb(SB),$0 	MOVL	p+0(FP),DX	XORL	AX,AX	INB	RET /* *  output a byte */TEXT	outb(SB),$0 	MOVL	p+0(FP),DX	MOVL	b+4(FP),AX	OUTB	RET /* *  input a string of shorts from a port */TEXT	inss(SB),$0	MOVL	p+0(FP),DX	MOVL	a+4(FP),DI	MOVL	c+8(FP),CX	CLD; REP; OP16; INSL	RET /* *  output a string of shorts to a port */TEXT	outss(SB),$0	MOVL	p+0(FP),DX	MOVL	a+4(FP),SI	MOVL	c+8(FP),CX	CLD; REP; OP16; OUTSL	RET /* *  test and set */TEXT	tas(SB),$0	MOVL	$0xdeadead,AX	MOVL	l+0(FP),BX	XCHGL	AX,(BX)	RET /* *  routines to load/read various system registers */GLOBL	idtptr(SB),$6TEXT	putidt(SB),$0		/* interrupt descriptor table */	MOVL	t+0(FP),AX	MOVL	AX,idtptr+2(SB)	MOVL	l+4(FP),AX	MOVW	AX,idtptr(SB)	MOVL	idtptr(SB),IDTR	RET GLOBL	gdtptr(SB),$6TEXT	putgdt(SB),$0		/* global descriptor table */	MOVL	t+0(FP),AX	MOVL	AX,gdtptr+2(SB)	MOVL	l+4(FP),AX	MOVW	AX,gdtptr(SB)	MOVL	gdtptr(SB),GDTR	RET TEXT	putcr3(SB),$0		/* top level page table pointer */	MOVL	t+0(FP),AX	MOVL	AX,CR3	RET TEXT	puttr(SB),$0		/* task register */	MOVL	t+0(FP),AX	MOVW	AX,TASK	RET TEXT	getcr0(SB),$0		/* coprocessor bits */	MOVL	CR0,AX	RET TEXT	getcr2(SB),$0		/* fault address */	MOVL	CR2,AX	RET #define	FPOFF\	WAIT;\	MOVL	CR0,AX;\	ORL	$0x4,AX		/* EM=1 */;\	MOVL	AX,CR0 #define	FPON\	MOVL	CR0,AX;\	ANDL	$~0x4,AX	/* EM=0 */;\	MOVL	AX,CR0	TEXT	fpoff(SB),$0		/* turn off floating point */	FPOFF	RET TEXT	fpinit(SB),$0		/* turn on & init the floating point */	FPON	FINIT	WAIT	PUSHW	$0x0330	FLDCW	0(SP)		/* ignore underflow/precision, signal others */	POPW	AX	WAIT	RET TEXT	fpsave(SB),$0		/* save floating point state and turn off */	MOVL	p+0(FP),AX	WAIT	FSAVE	0(AX)	FPOFF	RET TEXT	fprestore(SB),$0	/* turn on floating point and restore regs */	FPON	MOVL	p+0(FP),AX	FRSTOR	0(AX)	WAIT	RET TEXT	fpstatus(SB),$0		/* get floating point status */	FSTSW	AX	RET /* *  special traps */TEXT	intr0(SB),$0	PUSHL	$0	PUSHL	$0	JMP	intrcommonTEXT	intr1(SB),$0	PUSHL	$0	PUSHL	$1	JMP	intrcommonTEXT	intr2(SB),$0	PUSHL	$0	PUSHL	$2	JMP	intrcommonTEXT	intr3(SB),$0	PUSHL	$0	PUSHL	$3	JMP	intrcommonTEXT	intr4(SB),$0	PUSHL	$0	PUSHL	$4	JMP	intrcommonTEXT	intr5(SB),$0	PUSHL	$0	PUSHL	$5	JMP	intrcommonTEXT	intr6(SB),$0	PUSHL	$0	PUSHL	$6	JMP	intrcommonTEXT	intr7(SB),$0	PUSHL	$0	PUSHL	$7	JMP	intrcommonTEXT	intr8(SB),$0	PUSHL	$8	JMP	intrscommonTEXT	intr9(SB),$0	PUSHL	$0	PUSHL	$9	JMP	intrcommonTEXT	intr10(SB),$0	PUSHL	$10	JMP	intrscommonTEXT	intr11(SB),$0	PUSHL	$11	JMP	intrscommonTEXT	intr12(SB),$0

Lines 1–500 of 704.