diff options
Diffstat (limited to 'arch/ppc/kernel/head.S')
-rw-r--r-- | arch/ppc/kernel/head.S | 783 |
1 files changed, 262 insertions, 521 deletions
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index bd6819c34..648c7bccf 100644 --- a/arch/ppc/kernel/head.S +++ b/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 @@ _ORG(0x1000) /* 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(0x1000) */ _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 @@ DataLoadTLB_trace_ptr: */ _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 @@ _ORG(0x4000) #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 @@ Reset: 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 @@ Reset: 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 @@ Reset: 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 @@ Reset: 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 @@ MachineCheck: * 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 @@ DataAccess: * 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 @@ SingleStep: * 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 @@ SystemCall: 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 @@ SystemCall: 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 @@ SystemCall: 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 @@ SystemCall: */ 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 @@ InstructionTLBMiss: * 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 @@ DataLoadTLBMiss: */ 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 @@ _GLOBAL(flush_page) 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 @@ _GLOBAL(flush_page) * 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 @@ _GLOBAL(_switch) 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 @@ _GLOBAL(_switch) 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(_switch) _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 @@ swapper_pg_dir: */ .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 @@ __TLBIEs: .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 + |