patch-2.1.16 linux/arch/ppc/kernel/head.S

Next file: linux/arch/ppc/kernel/include/elf/ChangeLog
Previous file: linux/arch/ppc/kernel/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.15/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
@@ -1,16 +1,15 @@
 #include "ppc_asm.tmpl"
 #include "ppc_defs.h"
 #include <linux/errno.h>
-#define NEWMM
+#include <linux/sys.h>
+#include <asm/ppc_machine.h>
+	
+#define NEWMM 1
 #define SYNC() \
 	isync; \
 	sync
 
-/* #define TLB_STATS */
-
-/* Keep track of low-level exceptions - rather crude, but informative */  
 #define STATS
-
 /*
  * Increment a [64 bit] statistic counter
  * Uses R2, R3
@@ -40,179 +39,9 @@
 	mtspr	XER,r0; \
 	stw	r3,0(r2)
 
-/* These macros can be used to generate very raw traces of low-level */
-/* operations (where printf, etc. can't help).  All they provide is */
-/* some after-the-fact documentation of what took place.  Since [in */
-/* most instances] they have no registers to work with, they use the */
-/* hardware "special" registers SPRx for storage.  Because of this, */
-/* defining more than one of them simultaneously will yield incorrect */
-/* results and a non-functional system.  Note: the trick here is to */
-/* gather some data without disturbing anything - Heisenberg are you watching? */
-
-/* CAUTION! Don't turn on more than one of these at once! */	
-/* #define DO_TRAP_TRACE   */ 
-/* #define DO_TLB_TRACE    */
-/* #define DO_RFI_TRACE    */
-
-#ifdef DO_RFI_TRACE
-#define DO_RFI_TRACE_UNMAPPED(mark) \
-	mtspr	SPR0,r1; \
-	mtspr	SPR1,r2; \
-	mtspr	SPR2,r3; \
-	mfcr	r3; \
-	mtspr	SPR3,r3; \
-	lis	r1,_RFI_ptr@h; \
-	ori	r1,r1,_RFI_ptr@l; \
-	lis	r3,0xF000; \
-	andc	r1,r1,r3; \
-	lwz	r1,0(r1); \
-	andc	r1,r1,r3; \
-	subi	r1,r1,4; \
-	lis	r2,(mark>>16); \
-	ori	r2,r2,(mark&0xFFFF); \
-	stwu	r2,4(r1); \
-	mfspr	r2,SRR0; \
-	stwu	r2,4(r1); \
-	mfspr	r2,SRR1; \
-	stwu	r2,4(r1); \
-	addi	r1,r1,4+4; \
-	lis	r2,_RFI_ptr@h; \
-	ori	r2,r2,_RFI_ptr@l; \
-	andc	r2,r2,r3; \
-	stw	r1,0(r2); \
-	mfspr	r3,SPR3; \
-	mtcrf	0xFF,r3; \
-	mfspr	r1,SPR0; \
-	mfspr	r2,SPR1; \
-	mfspr	r3,SPR2
-#define DO_RFI_TRACE_MAPPED(mark) \
-	mtspr	SPR0,r1; \
-	mtspr	SPR1,r2; \
-	mtspr	SPR2,r3; \
-	mfcr	r3; \
-	mtspr	SPR3,r3; \
-	lis	r1,_RFI_ptr@h; \
-	ori	r1,r1,_RFI_ptr@l; \
-	lwz	r1,0(r1); \
-	lis	r3,0x9000; \
-	or	r1,r1,r3; \
-	subi	r1,r1,4; \
-	lis	r2,(mark>>16); \
-	ori	r2,r2,(mark&0xFFFF); \
-	stwu	r2,4(r1); \
-	mfspr	r2,SRR0; \
-	stwu	r2,4(r1); \
-	mfspr	r2,SRR1; \
-	stwu	r2,4(r1); \
-	addi	r1,r1,4+4; \
-	lis	r2,_RFI_ptr@h; \
-	ori	r2,r2,_RFI_ptr@l; \
-	stw	r1,0(r2); \
-	mfspr	r3,SPR3; \
-	mtcrf	0xFF,r3; \
-	mfspr	r1,SPR0; \
-	mfspr	r2,SPR1; \
-	mfspr	r3,SPR2
-#else
 #define DO_RFI_TRACE_UNMAPPED(mark)
 #define DO_RFI_TRACE_MAPPED(mark)
-#endif
 
-#ifdef DO_TRAP_TRACE
-#define DEFAULT_TRAP(offset) \
-	mtspr	SPR0,r1; \
-	mtspr	SPR1,r2; \
-	mtspr	SPR2,r3; \
-	lis	r1,_TRAP_ptr@h; \
-	ori	r1,r1,_TRAP_ptr@l; \
-	lis	r3,0xF000; \
-	andc	r1,r1,r3; \
-	lwz	r1,0(r1); \
-	andc	r1,r1,r3; \
-	subi	r1,r1,4; \
-	lis	r2,0xCACA; \
-	ori	r2,r2,offset; \
-	stwu	r2,4(r1); \
-	mfspr	r2,SRR0; \
-	stwu	r2,4(r1); \
-	mfspr	r2,SRR1; \
-	stwu	r2,4(r1); \
-	mfspr	r2,SPR0; \
-	stwu	r2,4(r1); \
-	addi	r1,r1,4; \
-	lis	r2,_TRAP_ptr@h; \
-	ori	r2,r2,_TRAP_ptr@l; \
-	andc	r2,r2,r3; \
-	stw	r1,0(r2); \
-	mfspr	r1,SPR0; \
-	mfspr	r2,SPR1; \
-	mfspr	r3,SPR2; \
-	li	r13,0; \
-	ori	r13,r13,HID0_ICE; \
-	mtspr	HID0,r13; \
-	lis	r13,0xFFF00000>>16; \
-	ori	r13,r13,offset; \
-	mtlr	r13; \
-	b	hang
-#define TRACE_TRAP(offset) \
-	mtspr	SPR0,r1; \
-	mtspr	SPR1,r2; \
-	mtspr	SPR2,r3; \
-	mfcr	r3; \
-	mtspr	SPR3,r3; \
-	lis	r1,_TRAP_ptr@h; \
-	ori	r1,r1,_TRAP_ptr@l; \
-	lis	r3,0xF000; \
-	andc	r1,r1,r3; \
-	lwz	r1,0(r1); \
-	andc	r1,r1,r3; \
-	subi	r1,r1,4; \
-	lis	r2,0xCABB; \
-	ori	r2,r2,offset; \
-	stwu	r2,4(r1); \
-	dcbst	0,r1; \
-	mfspr	r2,SRR0; \
-	stwu	r2,4(r1); \
-	dcbst	0,r1; \
-	mfspr	r2,SRR1; \
-	stwu	r2,4(r1); \
-	dcbst	0,r1; \
-	li	r2,offset; \
-	cmpi	0,r2,0x0C00; \
-	beq	01f; \
-	cmpi	0,r2,0x0300; \
-	beq	00f; \
-	cmpi	0,r2,0x0400; \
-	beq	00f; \
-	mfspr	r2,SPR0; \
-	b	02f; \
-00:	mfspr	r2,DAR; \
-	b	02f; \
-01:	mr	r2,r0; \
-02:	stwu	r2,4(r1); \
-	dcbst	0,r1; \
-	addi	r1,r1,4; \
-	mflr	r2; \
-	stw	r2,0(r1); \
-	bl	check_trace; \
-	lwz	r2,0(r1); \
-	mtlr	r2; \
-02:	lis	r2,_TRAP_ptr@h; \
-	ori	r2,r2,_TRAP_ptr@l; \
-	oris	r1,r1,0x9000; \
-	cmp	0,r1,r2; \
-	bne	00f; \
-	lis	r1,_TRAP_TRACE@h; \
-	ori	r1,r1,_TRAP_TRACE@l; \
-00:	lis	r3,0xF000; \
-	andc	r2,r2,r3; \
-	stw	r1,0(r2); \
-	mfspr	r1,SPR0; \
-	mfspr	r2,SPR1; \
-	mfspr	r3,SPR3; \
-	mtcrf	0xFF,r3; \
-	mfspr	r3,SPR2
-#else
 #define DEFAULT_TRAP(offset) \
 	li	r13,0; \
 	ori	r13,r13,HID0_ICE; \
@@ -222,7 +51,6 @@
 	mtlr	r13; \
 	blr
 #define TRACE_TRAP(offset)	
-#endif
 
 #define DATA_CACHE_OFF() \
 	mfspr	r2,HID0; \
@@ -246,27 +74,147 @@
 	bdnz	0b
 
 /* Validate kernel stack - check for overflow */
-#define CHECK_STACK()
+/* all regs are considered scratch since the C function will stomp them */
+#define CHECK_STACK() \
+	/*lis	r3,current_set@ha; \
+	lwz	r3,current_set@l(r3); \
+	bl	_EXTERN(check_stack)*/
+#if 0
 #define _CHECK_STACK() \
 	mtspr	SPR0,r3; \
+	mtspr	SPR1,r4;    /* use r3,4 as scratch */ \
 	lis	r2,current_set@ha; \
 	lwz	r2,current_set@l(r2); \
 	lwz	r2,KERNEL_STACK_PAGE(r2); \
-	lis	r3,sys_stack@h; \
+	/* if kernel stack is sys_stack skip check */ \
+	/*lis	r3,sys_stack@h; \
 	ori	r3,r3,sys_stack@l; \
-	cmpl	0,r1,r3; \
-	ble	02f; \
-	li	r3,0x0FFF; \
+	cmpl	0,r1,r3;*/ \
+	/* check for STACK_MAGIC on kernel stack page */ \
+	lis	r3, 0xdead; /* STACK_MAGIC */ \
+	ori	r3,r3,0xbeef; \
+	lwz	r4,0(r2);      /* get *kernel_stack_page */ \
+	cmpl	0,r4,r3; \
+	bne	01f; \
+	/* check that ksp is > kernel page */ \
+	/*li	r3,0x0FFF; \
 	andc	r2,r2,r3; \
 	andc	r3,r1,r3; \
 	cmp	0,r3,r2; \
-	beq	02f; \
-	mr	r3,r1; \
+	beq	02f;*/ \
+	/* check that ksp and kernel stack page are on same page */ \
+	cmp	0,r1,r2; \
+	bge	02f; \
+01:	mr	r6,r1; /* setup info for call to bad_stack() */ \
+	mr	r5,r2; \
 	bl	_EXTERN(bad_stack); \
-02:	mfspr	r3,SPR0
+02:	mfspr	r4,SPR1; \
+	mfspr	r3,SPR0
+#endif
+	
+/* save fp regs if fp is used */
+/* assumes that r1 contains ptr to regs of task and r2 is scratch 
+	  -- Cort  */
+#define SAVE_FP_REGS() \
+       	/* check if fp has been used by checking msr_fp bit */ \
+	lwz	r2,_MSR(r1);  \
+	andi.	r2,r2,MSR_FP; \
+	bne	00f; \
+	/* floating point has been used -- save fp regs */ \
+	lis	r2,current_set@h; \
+	ori	r2,r2,current_set@l; \
+	addi	r2,r2,TSS; \
+	/*mr	r2,r1;*/ \
+	stfd	fr0,TSS_FPR0(r2); \
+	stfd	fr1,TSS_FPR1(r2); \
+	stfd	fr2,TSS_FPR2(r2); \
+	stfd	fr3,TSS_FPR3(r2); \
+	stfd	fr4,TSS_FPR4(r2); \
+	stfd	fr5,TSS_FPR5(r2); \
+	stfd	fr6,TSS_FPR6(r2); \
+	stfd	fr7,TSS_FPR7(r2); \
+	stfd	fr8,TSS_FPR8(r2); \
+	stfd	fr9,TSS_FPR9(r2); \
+	stfd	fr10,TSS_FPR10(r2); \
+	stfd	fr11,TSS_FPR11(r2); \
+	stfd	fr12,TSS_FPR12(r2); \
+	stfd	fr13,TSS_FPR13(r2); \
+	stfd	fr14,TSS_FPR14(r2); \
+	stfd	fr15,TSS_FPR15(r2); \
+	stfd	fr16,TSS_FPR16(r2); \
+	stfd	fr17,TSS_FPR17(r2); \
+	stfd	fr18,TSS_FPR18(r2); \
+	stfd	fr19,TSS_FPR19(r2); \
+	stfd	fr20,TSS_FPR20(r2); \
+	stfd	fr21,TSS_FPR21(r2); \
+	stfd	fr22,TSS_FPR22(r2); \
+	stfd	fr23,TSS_FPR23(r2); \
+	stfd	fr24,TSS_FPR24(r2); \
+	stfd	fr25,TSS_FPR25(r2); \
+	stfd	fr26,TSS_FPR26(r2); \
+	stfd	fr27,TSS_FPR27(r2); \
+	stfd	fr28,TSS_FPR28(r2); \
+	stfd	fr29,TSS_FPR29(r2); \
+	stfd	fr30,TSS_FPR30(r2); \
+	stfd	fr31,TSS_FPR31(r2); \
+00:
+
 
-/* Save all registers on kernel stack during an exception */	
-#define SAVE_REGS(mark) \
+/* restores fp regs if fp has been used -- always restores fpscr */
+/* assumes that r1 contains ptr to regs, r2 is scratch and srr1 holds
+   what will become the msr when this process executes 	-- Cort*/
+#define RESTORE_FP_REGS(mark) \
+	/* check if restoring from _switch() */ \
+	li	r2, mark; \
+	cmpi	0,r2,0x0f0f; \
+	bne	00f; /* only need to save if called from _switch() with 0x0f0f */\
+       	/* check if fp has been used by checking msr_fp bit */ \
+	/* srr1 contains msr */ \
+	mfspr	r2,SRR1; \
+	andi.	r2,r2,MSR_FP; \
+	bne	00f; \
+	/* floating point has been used -- restore fp regs */ \
+	/* Hey, Rocky!  Watch me pull fp regs from my stack! */ \
+	lis	r2,current_set@h; \
+	ori	r2,r2,current_set@l; \
+	addi	r2,r2,TSS; \
+	/*mr	r2,r1;*/\
+	lfd	fr0,TSS_FPR0(r2); \
+	lfd	fr1,TSS_FPR1(r2); \
+	lfd	fr2,TSS_FPR2(r2); \
+	lfd	fr3,TSS_FPR3(r2); \
+	lfd	fr4,TSS_FPR4(r2); \
+	lfd	fr5,TSS_FPR5(r2); \
+	lfd	fr6,TSS_FPR6(r2); \
+	lfd	fr7,TSS_FPR7(r2); \
+	lfd	fr8,TSS_FPR8(r2); \
+	lfd	fr9,TSS_FPR9(r2); \
+	lfd	fr10,TSS_FPR10(r2); \
+	lfd	fr11,TSS_FPR11(r2); \
+	lfd	fr12,TSS_FPR12(r2); \
+	lfd	fr13,TSS_FPR13(r2); \
+	lfd	fr14,TSS_FPR14(r2); \
+	lfd	fr15,TSS_FPR15(r2); \
+	lfd	fr16,TSS_FPR16(r2); \
+	lfd	fr17,TSS_FPR17(r2); \
+	lfd	fr18,TSS_FPR18(r2); \
+	lfd	fr19,TSS_FPR19(r2); \
+	lfd	fr20,TSS_FPR20(r2); \
+	lfd	fr21,TSS_FPR21(r2); \
+	lfd	fr22,TSS_FPR22(r2); \
+	lfd	fr23,TSS_FPR23(r2); \
+	lfd	fr24,TSS_FPR24(r2); \
+	lfd	fr25,TSS_FPR25(r2); \
+	lfd	fr26,TSS_FPR26(r2); \
+	lfd	fr27,TSS_FPR27(r2); \
+	lfd	fr28,TSS_FPR28(r2); \
+	lfd	fr29,TSS_FPR29(r2); \
+	lfd	fr30,TSS_FPR30(r2); \
+	lfd	fr31,TSS_FPR31(r2); \
+00:
+
+/* save all registers */
+#define SAVE_ALL_REGS(mark) \
 	subi	r1,r1,INT_FRAME_SIZE;	/* Make room for frame */ \
 	stmw	r3,GPR3(r1);	/* Save R3..R31 */ \
 	stw	r3,ORIG_GPR3(r1); \
@@ -287,10 +235,6 @@
 	stw	r2,_CCR(r1); \
 	mfspr	r2,XER; \
 	stw	r2,_XER(r1); \
-	stfd	fr0,FPR0(r1); \
-	stfd	fr1,FPR1(r1); \
-	stfd	fr2,FPR2(r1); \
-	stfd	fr3,FPR3(r1); \
 	mffs	fr0; \
 	stfd	fr0,FPCSR(r1); \
 	lis	r2,_break_lwarx@h; \
@@ -304,9 +248,11 @@
 	li	r2,0; \
 	stw	r2,RESULT(r1)
 
+
+/* save registers clobbered by a page fault handler */
 #define SAVE_PAGE_FAULT_REGS(offset) \
 	mfspr	r2,DAR; \
-	stw	r2,_DAR(r1); \
+ 	stw	r2,_DAR(r1); \
 	mfspr	r2,DSISR; \
 	stw	r2,_DSISR(r1); \
 	mfspr	r2,PVR;			/* Check for 603/603e */ \
@@ -328,7 +274,7 @@
 	mfspr	r2,DCMP; \
 	stw	r2,_DCMP(r1); \
 24:	
-	
+
 #define SAVE_INT_REGS(mark) \
 	mtspr	SPR0,r1;	/* Save current stack pointer */ \
 	mtspr	SPR1,r2;	/* Scratch */ \
@@ -375,7 +321,7 @@
 	mtspr	SRR1,r2; \
 	SYNC(); \
 	rfi; \
-20:	SAVE_REGS(mark); \
+20:	SAVE_ALL_REGS(mark); \
 	CHECK_STACK()
 
 #define RETURN_FROM_INT(mark) \
@@ -412,7 +358,10 @@
 	bl	_EXTERN(flush_instruction_cache); */ \
 05:	lis	r3,current_set@ha;	/* need to save kernel stack pointer */ \
 	lwz	r3,current_set@l(r3); \
-	addi	r4,r1,INT_FRAME_SIZE;	/* size of frame */ \
+	/*addi	r4,r1,INT_FRAME_SIZE*/;	/* size of frame */ \
+	lwz	r4, KERNEL_STACK_PAGE(r3); \
+	addi	r4,r4,KERNEL_STACK_SIZE; /* reset stack pointer to top of stack page */ \
+	/* stack isn't 0'd so show_task():sched.c shows highwater of stack */ \
 	stw	r4,TSS+KSP(r3); \
 	lwz	r4,STATE(r3);	/* If state != 0, can't run */ \
 	cmpi	0,r4,0; \
@@ -442,20 +391,18 @@
 	mtlr	r2; \
 	lwz	r2,_XER(r1); \
 	mtspr	XER,r2; \
-	lwz	r2,_CCR(r1); \
-	mtcrf	0xFF,r2; \
 	lfd	fr0,FPCSR(r1); \
 	mtfsf	0xFF,fr0; \
-	lfd	fr0,FPR0(r1); \
-	lfd	fr1,FPR1(r1); \
-	lfd	fr2,FPR2(r1); \
-	lfd	fr3,FPR3(r1); \
+	RESTORE_FP_REGS(mark) ; \
+	lwz	r2,_CCR(r1); \
+	mtcrf	0xFF,r2; \
 	lwz	r0,GPR0(r1); \
 	lwz	r2,GPR2(r1); \
 	lwz	r1,GPR1(r1); \
 	SYNC(); \
 	rfi
 
+	
 _TEXT()
 /*
  * This code may be executed by a bootstrap process.  If so, the
@@ -578,35 +525,6 @@
 /* Note: It is *unsafe* to use the TRACE TRAP macro here since there */
 /* could be a 'trace' in progress when the TLB miss occurs.          */
 /* TRACE_TRAP(0x1000) */
-#ifdef TLB_STATS
-	lis	r2,DataLoadTLB_trace_ptr@h
-	ori	r2,r2,DataLoadTLB_trace_ptr@l
-	lis	r3,0xF000
-	andc	r2,r2,r3
-	lwz	r1,0(r2)
-	andc	r1,r1,r3
-	li	r0,0x1000
-	stw	r0,0(r1)
-	mftbu	r0
-	stw	r0,4(r1)
-	mftb	r0
-	stw	r0,8(r1)
-	mfspr	r0,IMISS
-	mfspr	r3,SRR1
-	extrwi	r3,r3,1,14
-	or	r0,r0,r3
-	stw	r0,12(r1)
-	addi	r1,r1,16
-	mfcr	r0
-	cmpl	0,r1,r2
-	blt	00f
-	lis	r1,DataLoadTLB_trace_buf@h
-	ori	r1,r1,DataLoadTLB_trace_buf@l
-	lis	r3,0xF000
-	andc	r1,r1,r3
-00:	mtcrf	0xFF,r0
-	stw	r1,0(r2)
-#endif	
 	b	InstructionTLBMiss
 
 /*
@@ -614,41 +532,6 @@
  */
 _ORG(0x1100)
 /* TRACE_TRAP(0x1100) */
-#ifdef TLB_STATS
-	lis	r2,DataLoadTLB_trace_ptr@h
-	ori	r2,r2,DataLoadTLB_trace_ptr@l
-	lis	r3,0xF000
-	andc	r2,r2,r3
-	lwz	r1,0(r2)
-	andc	r1,r1,r3
-	li	r0,0x1100
-	stw	r0,0(r1)
-	mftbu	r0
-	stw	r0,4(r1)
-	mftb	r0
-	stw	r0,8(r1)
-	mfspr	r0,DMISS
-	mfspr	r3,SRR1
-	extrwi	r3,r3,1,14
-	or	r0,r0,r3
-	stw	r0,12(r1)
-	addi	r1,r1,16
-	mfcr	r0
-	cmpl	0,r1,r2
-	blt	00f
-	lis	r1,DataLoadTLB_trace_buf@h
-	ori	r1,r1,DataLoadTLB_trace_buf@l
-	lis	r3,0xF000
-	andc	r1,r1,r3
-00:	mtcrf	0xFF,r0
-	stw	r1,0(r2)
-	.data
-DataLoadTLB_trace_buf:
-	.space	64*1024*4
-DataLoadTLB_trace_ptr:
-	.long	DataLoadTLB_trace_buf
-	.text
-#endif	
 	b	DataLoadTLBMiss
 
 /*
@@ -656,35 +539,6 @@
  */
 _ORG(0x1200)
 /* TRACE_TRAP(0x1200) */
-#ifdef TLB_STATS
-	lis	r2,DataLoadTLB_trace_ptr@h
-	ori	r2,r2,DataLoadTLB_trace_ptr@l
-	lis	r3,0xF000
-	andc	r2,r2,r3
-	lwz	r1,0(r2)
-	andc	r1,r1,r3
-	li	r0,0x1200
-	stw	r0,0(r1)
-	mftbu	r0
-	stw	r0,4(r1)
-	mftb	r0
-	stw	r0,8(r1)
-	mfspr	r0,DMISS
-	mfspr	r3,SRR1
-	extrwi	r3,r3,1,14
-	or	r0,r0,r3
-	stw	r0,12(r1)
-	addi	r1,r1,16
-	mfcr	r0
-	cmpl	0,r1,r2
-	blt	00f
-	lis	r1,DataLoadTLB_trace_buf@h
-	ori	r1,r1,DataLoadTLB_trace_buf@l
-	lis	r3,0xF000
-	andc	r1,r1,r3
-00:	mtcrf	0xFF,r0
-	stw	r1,0(r2)
-#endif	
 	b	DataStoreTLBMiss
 
 _ORG(0x1300)
@@ -718,16 +572,40 @@
 #endif
 
 
+/* changed to use r3 as residual pointer (as firmware does), that's all -- Cort */
 /*
  * Hardware reset [actually from bootstrap]
  * Initialize memory management & call secondary init
  * Registers initialized by bootstrap:
  *   R11: Start of command line string
  *   R12: End of command line string
+ *   R28: Residual data
+ *   R29: Total Memory Size
  *   R30: 'BeBx' if this is a BeBox
  */	
 Reset:
 	lis	r7,0xF000		/* To mask upper 4 bits */
+/* set pointer to residual data */
+	lis	r1,resptr@h
+	ori	r1,r1,resptr@l
+	andc	r1,r1,r7
+/* changed to use r3 as residual pointer (as firmware does) -- Cort */
+/* this is only a ptr, the actual data is copied in mmu_init */
+	stw	r3,0(r1)
+	
+/* Copy argument string */
+	li	r0,0		/* Null terminate string */
+	stb	r0,0(r12)
+	lis	r1,cmd_line@h
+	ori	r1,r1,cmd_line@l
+	andc	r1,r1,r7	/* No MMU yet - need unmapped address */
+	subi	r1,r1,1
+	subi	r11,r11,1
+00:	lbzu	r0,1(r11)
+	cmpi	0,r0,0
+	stbu	r0,1(r1)
+	bne	00b
+
 #define IS_BE_BOX	0x42654278	/* 'BeBx' */
 	lis	r1,isBeBox@h
 	ori	r1,r1,isBeBox@l
@@ -751,21 +629,19 @@
 	andc	r5,r5,r7		/* Tell CPU #1 where to go */
 00:	stw	r2,0(r1)
 	stw	r30,4(r1)
-/* Copy argument string */
-	li	r0,0		/* Null terminate string */
-	stb	r0,0(r12)
-	lis	r1,cmd_line@h
-	ori	r1,r1,cmd_line@l
-	andc	r1,r1,r7	/* No MMU yet - need unmapped address */
-	subi	r1,r1,1
-	subi	r11,r11,1
-00:	lbzu	r0,1(r11)
-	cmpi	0,r0,0
-	stbu	r0,1(r1)
-	bne	00b	
+	
+
+#if 0	
 	lis	r1,sys_stack@h
 	ori	r1,r1,sys_stack@l
+#else
+	lis	r1,init_kernel_stack@h
+	ori	r1,r1,init_kernel_stack@l
+#endif
+	addi	r1,r1,0x1000	/* top of stack */
+#if 0	
 	li	r2,0x0FFF	/* Mask stack address down to page boundary */
+#endif
 	andc	r1,r1,r2
 	subi	r1,r1,INT_FRAME_SIZE	/* Padding for first frame */
 	li	r2,0		/* TOC pointer for nanokernel */
@@ -782,6 +658,13 @@
 00:	stwu	r0,4(r3)
 	cmp	0,r3,r4
 	blt	00b
+#if 0	
+/* Save total memory size (passed from bootstrap) */
+	lis	r3,_TotalMemory@h
+	ori	r3,r3,_TotalMemory@l
+	andc	r3,r3,r7	/* make unmapped address */
+	stw	r29,0(r3)
+#endif	
 /* Initialize BAT registers */
 	lis	r3,BAT0@h
 	ori	r3,r3,BAT0@l
@@ -816,7 +699,7 @@
 	lwz	r0,4(r3)
 	mtspr	IBAT2L,r0
 	mtspr	DBAT2L,r0
-#if 0	
+#if 1
 	lis	r3,BAT3@h
 	ori	r3,r3,BAT3@l
 	andc	r3,r3,r7	/* make unmapped address */
@@ -837,7 +720,7 @@
 DO_RFI_TRACE_UNMAPPED(0xDEAD0000)	
 	SYNC
 	rfi				/* enables MMU */
-10:	bl	_EXTERN(MMU_init)	/* initialize MMU environment */
+10:    	bl	_EXTERN(MMU_init)	/* initialize MMU environment */
 DO_RFI_TRACE_MAPPED(0xDEAD0100)	
 /* Withdraw BAT2->RAM mapping */
 	lis	r7,0xF000		/* To mask upper 4 bits */
@@ -1017,14 +900,17 @@
  * Data Access exception
  */
 DataAccess:
-/*	TRACE_TRAP(0x0300) */
 	SAVE_INT_REGS(0x0300)
-	SAVE_PAGE_FAULT_REGS(0x0300)
-	BUMP(__Data_Page_Faults)
-	mr	r3,r1		/* Set pointer to saved regs */
+#if 1
+	mfspr	r3, DAR
+	mfspr	r4, DSISR
+	li	r5, 0		/* not a text fault */
+	mr	r6, r1
+	bl	_EXTERN(new_page_fault)
+#else
+	SAVE_PAGE_FAULT_REGS(0x0D00)	
+	mr	r3,r1
 	bl	_EXTERN(DataAccessException)
-#if 0
-	bl	_EXTERN(flush_instruction_cache)
 #endif	
 	RETURN_FROM_INT(0x0300)
 
@@ -1032,14 +918,17 @@
  * Instruction Access Exception
  */
 InstructionAccess:
-/*	TRACE_TRAP(0x0400) */
 	SAVE_INT_REGS(0x0400)
-	SAVE_PAGE_FAULT_REGS(0x0400)
-	BUMP(__Instruction_Page_Faults)
-	mr	r3,r1		/* Set pointer to saved regs */
+#if 1
+	mfspr	r3, SPR2 /* srr0 was saved here */
+	mfspr	r4, SPR3 /* srr1 was saved here */
+	li	r5, 1	 /* a text fault */
+	mr	r6, r1
+	bl	_EXTERN(new_page_fault)
+#else
+	SAVE_PAGE_FAULT_REGS(0x0D00)	
+	mr	r3,r1
 	bl	_EXTERN(InstructionAccessException)
-#if 0
-	bl	_EXTERN(flush_instruction_cache)
 #endif	
 	RETURN_FROM_INT(0x0400)
 
@@ -1090,17 +979,18 @@
  * Floating point [not available, etc]
  */
 FloatingPointCheck:	
-	TRACE_TRAP(0x0800)
 	SAVE_INT_REGS(0x0800)
 	mr	r3,r1		/* Set pointer to saved regs */
 	bl	_EXTERN(FloatingPointCheckException)
-	RETURN_FROM_INT(0x0200)
+	cmpi	0,r3,MSR_FP    /* check if fp was turned on by handler */
+	bne	00f
+	RETURN_FROM_INT(0x0f0f) /* 0xf0f tells to restore fp regs */
+00:	RETURN_FROM_INT(0x0200)
 
 /*
  * System Call exception
  */
 SystemCall:
-/*	TRACE_TRAP(0x0C00) */
 	SAVE_INT_REGS(0x0C00)
 	lwz	r2,_CCR(r1)	/* Clear SO bit in CR */
 	lis	r9,0x1000
@@ -1118,13 +1008,21 @@
 	lwz	r2,TASK_FLAGS(r2)
 	andi.	r2,r2,PF_TRACESYS
 	bne	50f
+	
 	lis	r2,sys_call_table@h
 	ori	r2,r2,sys_call_table@l
 	slwi	r0,r0,2
 	lwzx	r2,r2,r0	/* Fetch system call handler [ptr] */
+#if 1
+	cmpi	0,r2,0		/* make sure syscall handler not 0 */
+	beq	99f
+	cmpi	0,r0,NR_syscalls<<2 /* make sure syscallnum in bounds */
+	bgt	99f
+#endif	
 	mtlr	r2
 	mr	r9,r1
 	blrl			/* Call handler */
+	
 20:	stw	r3,RESULT(r1)	/* Save result */	
 	cmpi	0,r3,0
 	bge	30f
@@ -1136,10 +1034,6 @@
 	oris	r2,r2,0x1000
 	stw	r2,_CCR(r1)
 30:	stw	r3,GPR3(r1)	/* Update return value */
-#if 0
-	mr	r3,r1
-	bl	_EXTERN(trace_syscall)
-#endif
 	b	99f
 /* Traced system call support */
 50:	bl	_EXTERN(syscall_trace)
@@ -1171,14 +1065,6 @@
 60:	stw	r3,GPR3(r1)	/* Update return value */
 	bl	_EXTERN(syscall_trace)
 99:
-#if 0 /* This isn't needed here - already in RETURN_FROM_INT */
-	lis	r2,kernel_pages_are_copyback@ha
-	lwz	r2,kernel_pages_are_copyback@l(r2)
-	cmpi	0,r2,0
-	beq	00f
-	bl	_EXTERN(flush_instruction_cache)	/* Ensure cache coherency */
-00:
-#endif
 	RETURN_FROM_INT(0x0C00)
 
 /*
@@ -1186,36 +1072,6 @@
  */
 InstructionTLBMiss:
 	BUMP_UNMAPPED(__Instruction_TLB_Misses)
-#ifdef DO_TLB_TRACE
-	lis	r1,_TLB_ptr@h
-	ori	r1,r1,_TLB_ptr@l
-	lis	r2,0xF000
-	andc	r1,r1,r2
-	lwz	r1,0(r1)
-	andc	r1,r1,r2
-	subi	r1,r1,4
-	lis	r2,0xBEBE
-	ori	r2,r2,0x0100
-	stwu	r2,4(r1)
-	mfspr	r2,SRR0
-	stwu	r2,4(r1)
-	mfspr	r2,SRR1
-	stwu	r2,4(r1)
-	mfspr	r2,HASH1
-	stwu	r2,4(r1)
-	mfspr	r2,HASH2
-	stwu	r2,4(r1)
-	mfspr	r2,ICMP
-	stwu	r2,4(r1)
-	mfspr	r2,IMISS
-	stwu	r2,4(r1)
-	addi	r1,r1,4+(1*4)
-	lis	r3,_TLB_ptr@h
-	ori	r3,r3,_TLB_ptr@l
-	lis	r2,0xF000
-	andc	r3,r3,r2
-	stw	r1,0(r3)
-#endif	
 	mfctr	r0		/* Need to save this - CTR can't be touched! */
 	mfspr	r2,HASH1	/* Get PTE pointer */
 	mfspr	r3,ICMP		/* Partial item compare value */
@@ -1256,37 +1112,6 @@
  * Handle TLB miss for DATA Load operation
  */	
 DataLoadTLBMiss:
-	BUMP_UNMAPPED(__DataLoad_TLB_Misses)
-#ifdef DO_TLB_TRACE
-	lis	r1,_TLB_ptr@h
-	ori	r1,r1,_TLB_ptr@l
-	lis	r2,0xF000
-	andc	r1,r1,r2
-	lwz	r1,0(r1)
-	andc	r1,r1,r2
-	subi	r1,r1,4
-	lis	r2,0xBEBE
-	ori	r2,r2,0x0200
-	stwu	r2,4(r1)
-	mfspr	r2,SRR0
-	stwu	r2,4(r1)
-	mfspr	r2,SRR1
-	stwu	r2,4(r1)
-	mfspr	r2,HASH1
-	stwu	r2,4(r1)
-	mfspr	r2,HASH2
-	stwu	r2,4(r1)
-	mfspr	r2,DCMP
-	stwu	r2,4(r1)
-	mfspr	r2,DMISS
-	stwu	r2,4(r1)
-	addi	r1,r1,4+(1*4)
-	lis	r3,_TLB_ptr@h
-	ori	r3,r3,_TLB_ptr@l
-	lis	r2,0xF000
-	andc	r3,r3,r2
-	stw	r1,0(r3)
-#endif	
 	mfctr	r0		/* Need to save this - CTR can't be touched! */
 	mfspr	r2,HASH1	/* Get PTE pointer */
 	mfspr	r3,DCMP		/* Partial item compare value */
@@ -1325,36 +1150,6 @@
  */
 DataStoreTLBMiss:
 	BUMP_UNMAPPED(__DataStore_TLB_Misses)
-#ifdef DO_TLB_TRACE
-	lis	r1,_TLB_ptr@h
-	ori	r1,r1,_TLB_ptr@l
-	lis	r2,0xF000
-	andc	r1,r1,r2
-	lwz	r1,0(r1)
-	andc	r1,r1,r2
-	subi	r1,r1,4
-	lis	r2,0xBEBE
-	ori	r2,r2,0x0300
-	stwu	r2,4(r1)
-	mfspr	r2,SRR0
-	stwu	r2,4(r1)
-	mfspr	r2,SRR1
-	stwu	r2,4(r1)
-	mfspr	r2,HASH1
-	stwu	r2,4(r1)
-	mfspr	r2,HASH2
-	stwu	r2,4(r1)
-	mfspr	r2,DCMP
-	stwu	r2,4(r1)
-	mfspr	r2,DMISS
-	stwu	r2,4(r1)
-	addi	r1,r1,4+(1*4)
-	lis	r3,_TLB_ptr@h
-	ori	r3,r3,_TLB_ptr@l
-	lis	r2,0xF000
-	andc	r3,r3,r2
-	stw	r1,0(r3)
-#endif	
 	mfctr	r0		/* Need to save this - CTR can't be touched! */
 	mfspr	r2,HASH1	/* Get PTE pointer */
 	mfspr	r3,DCMP		/* Partial item compare value */
@@ -1531,7 +1326,7 @@
 	addi	r3,r3,CACHE_LINE_SIZE
 	bdnz	00b
 	blr
-	
+
 /*
  * This routine switches between two different tasks.  The process
  * state of one is saved on its kernel stack.  Then the state
@@ -1543,24 +1338,25 @@
  * of this code; either by coming in via the entry (_switch)
  * or via "fork" which must set up an environment equivalent
  * to the "_switch" path.  If you change this (or in particular, the
- * SAVE_REGS macro), you'll have to change the fork code also.
+ * SAVE_ALL_REGS macro), you'll have to change the fork code also.
  *
  * The code which creates the new task context is in 'copy_thread'
  * in arch/ppc/kernel/process.c
  */	
 _GLOBAL(_switch)
-	mtspr	SPR0,r1		/* SAVE_REGS prologue */
+	mtspr	SPR0,r1		/* SAVE_ALL_REGS prologue */
 	mtspr	SPR1,r2
 	mflr	r2		/* Return to switch caller */
 	mtspr	SPR2,r2
 	mfmsr	r2
 	mtspr	SPR3,r2
-	SAVE_REGS(0x0FF0)
+	SAVE_ALL_REGS(0x0FF0)
+	SAVE_FP_REGS()
+	CHECK_STACK()
 	SYNC()
 	stw	r1,KSP(r3)	/* Set old stack pointer */
 	BUMP(__Context_Switches)
 	lwz	r1,KSP(r4)	/* Load new stack pointer */
-	CHECK_STACK()
 	lwz	r0,MMU_SEG0(r4)
 	mtsr	SR0,r0
 	lwz	r0,MMU_SEG1(r4)
@@ -1577,6 +1373,8 @@
 	mtsr	SR6,r0
 	lwz	r0,MMU_SEG7(r4)
 	mtsr	SR7,r0
+#if 0
+	/* segs 8-15 are shared by everyone -- don't need to be changed */
 	lwz	r0,MMU_SEG8(r4)
 	mtsr	SR8,r0
 	lwz	r0,MMU_SEG9(r4)
@@ -1593,34 +1391,22 @@
 	mtsr	SR14,r0
 	lwz	r0,MMU_SEG15(r4)
 	mtsr	SR15,r0
+#endif
+	/* no need to invalidate tlb since each process has a distinct
+	   set of vsid's.	 -- Cort */
+#if 0	  
 	tlbia				/* Invalidate entire TLB */
 	BUMP(__TLBIAs)
-	bl	_EXTERN(flush_instruction_cache)
-#ifdef TLB_STATS
-/* TEMP */
-	lis	r2,DataLoadTLB_trace_ptr@h
-	ori	r2,r2,DataLoadTLB_trace_ptr@l
-	lis	r3,0x9000
-	lwz	r4,0(r2)
-	or	r4,r4,r3
-	li	r0,0
-	stw	r0,0(r4)
-	stw	r0,4(r4)
-	stw	r0,8(r4)
-	stw	r0,12(r4)
-	addi	r4,r4,4
-	cmpl	0,r4,r2
-	blt	00f
-	lis	r4,DataLoadTLB_trace_buf@h
-	ori	r4,r4,DataLoadTLB_trace_buf@l
-00:	stw	r4,0(r2)
-/* TEMP */	
-#endif
-#if 0
-	lwz	r2,_NIP(r1)	/* Force TLB/MMU hit */
-	lwz	r2,0(r2)
 #endif	
-	RETURN_FROM_INT(0xF000)
+	/* p5.2 603 users manual - with addr transl. enabled, 
+	   the memory access is performed under the control of 
+	   the page table entry.  I interpret this to mean that
+	   it is tagged with the vsid -- so no need to flush here
+	   since each process has a distinct set of vsid's.
+	   Of course, my intepretation may be wrong.
+	              -- Cort */
+	/*bl	_EXTERN(flush_instruction_cache)*/
+	RETURN_FROM_INT(0x0f0f)
 	
 
 /*
@@ -1629,50 +1415,16 @@
 _GLOBAL(__main)
 	blr
 
-#ifdef DO_TRAP_TRACE
-check_trace:
-	sync				/* Force all writes out */
-	lwz	r2,-8(r1)
-	andi.	r2,r2,MSR_PR
-	bne	99f
-	lwz	r2,-32(r1)
-	lwz	r3,-16(r1)
-	cmp	0,r2,r3
-	bne	99f
-	andi.	r2,r2,0x7FFF
-	cmpi	0,r2,0x0C00
-	bge	99f
-	lwz	r2,-32+4(r1)
-	lwz	r3,-16+4(r1)
-	cmp	0,r2,r3
-	bne	99f
-	lwz	r2,-32+8(r1)
-	lwz	r3,-16+8(r1)
-	cmp	0,r2,r3
-	bne	99f
-	lwz	r2,-32(r1)
-	lwz	r3,-16(r1)
-	cmp	0,r2,r3
-	bne	99f
-	andi.	r2,r2,0x7FFF
-	cmpi	0,r2,0x0600
-	beq	00f
-	lwz	r2,-32+12(r1)
-	lwz	r3,-16+12(r1)
-	cmp	0,r2,r3
-	bne	99f
-00:	li	r2,0x7653
-	stw	r2,0(r1)
-	b	00b
-99:	blr
-#endif	
-
 	.data
 	.globl	sdata
 sdata:
 	.space	2*4096
+
+#if 0
+_GLOBAL(sys_stack)
 sys_stack:
-	.space	2*4096
+	.space	4096
+#endif
 CPU1_stack:	
 
 	.globl	empty_zero_page
@@ -1689,32 +1441,40 @@
  */	
 	.globl	cmd_line
 cmd_line:
-	.space	512	
-
+	.space	512
+	
 #ifdef STATS	
 /*
  * Miscellaneous statistics - gathered just for performance info
  */
-
  	.globl	_INTR_stats
 _INTR_stats:
+	.globl __Instruction_TLB_Misses
 __Instruction_TLB_Misses:
 	.long	0,0	/* Instruction TLB misses */
+	.globl __DataLoad_TLB_Misses
 __DataLoad_TLB_Misses:
 	.long	0,0	/* Data [load] TLB misses */
+	.globl __DataStore_TLB_Misses
 __DataStore_TLB_Misses:
 	.long	0,0	/* Data [store] TLB misses */
+	.globl __Instruction_Page_Faults
 __Instruction_Page_Faults:	
 	.long	0,0	/* Instruction page faults */
+	.globl __Data_Page_Faults
 __Data_Page_Faults:	
 	.long	0,0	/* Data page faults */
+	.globl __Cache_Flushes
 __Cache_Flushes:	
 	.long	0,0	/* Explicit cache flushes */
+	.globl __Context_Switches
 __Context_Switches:	
 	.long	0,0	/* Context switches */
+	.globl __Hardware_Interrupts
 __Hardware_Interrupts:	
 	.long	0,0	/* I/O interrupts (disk, timer, etc) */
 	.globl	__TLBIAs
+	.globl __TLBIAs
 __TLBIAs:
 	.long	0,0	/* TLB cache forceably flushed */
 	.globl	__TLBIEs
@@ -1722,33 +1482,14 @@
 	.long	0,0	/* Specific TLB entry flushed */	
 #endif
 
+	.globl	_TotalMemory
+_TotalMemory:
+	.long	0,0	
+	
 /*
  * This location is used to break any outstanding "lock"s when
  * changing contexts.
  */
 _break_lwarx:	.long	0
-
-/*
- * Various trace buffers
- */	
-#ifdef DO_TRAP_TRACE
-	.data
-_TRAP_TRACE: .space	32*1024
-_TRAP_ptr:   .long	_TRAP_TRACE
-	.text
-#endif
-
-#ifdef DO_TLB_TRACE
-	.data
-_TLB_TRACE: .space	128*1024
-_TLB_ptr:   .long	_TLB_TRACE
-	.text
-#endif
-
-#ifdef DO_RFI_TRACE
-	.data
-_RFI_DATA: .space	128*1024
-_RFI_ptr:  .long	_RFI_DATA
-	.text	
-#endif
+	
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov