diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-10-05 01:18:40 +0000 |
commit | 012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch) | |
tree | 87efc733f9b164e8c85c0336f92c8fb7eff6d183 /arch/ppc/kernel/head.S | |
parent | 625a1589d3d6464b5d90b8a0918789e3afffd220 (diff) |
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found
that this kernel will only boot SMP on Origin; the UP kernel freeze
soon after bootup with SCSI timeout messages. I commit this anyway
since I found that the last CVS versions had the same problem.
Diffstat (limited to 'arch/ppc/kernel/head.S')
-rw-r--r-- | arch/ppc/kernel/head.S | 180 |
1 files changed, 113 insertions, 67 deletions
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 067581f5d..5d26e2917 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -31,6 +31,7 @@ #include <asm/page.h> #include <linux/config.h> #include <asm/mmu.h> +#include "mol.h" #ifdef CONFIG_APUS #include <asm/amigappc.h> @@ -78,7 +79,7 @@ CACHELINE_WORDS = 32 mtspr DBAT##n##L,RB; \ 1: #endif /* CONFIG_PPC64BRIDGE */ - + .text .globl _stext _stext: @@ -162,8 +163,8 @@ __start: /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by prom_init() */ -__after_prom_start: bl mmu_off +__after_mmu_off: bl clear_bats bl flush_tlbs #endif @@ -202,15 +203,7 @@ __after_prom_start: mr r26,r3 addis r4,r3,KERNELBASE@h /* current address of _start */ cmpwi 0,r4,0 /* are we already running at 0? */ - beq 2f /* assume it's OK if so */ - li r3,0 - mfmsr r0 - andi. r0,r0,MSR_DR /* MMU enabled? */ - beq relocate_kernel - lis r3,KERNELBASE@h /* if so, are we */ - cmpw 0,r4,r3 /* already running at KERNELBASE? */ bne relocate_kernel -2: #endif /* CONFIG_APUS */ /* * we now have the 1st 16M of ram mapped with the bats. @@ -300,6 +293,17 @@ label: \ .long hdlr; \ .long ret_from_except +#define STD_MOL_EXCEPTION(n, label, hdlr, hook) \ + . = n; \ +label: \ + EXCEPTION_PROLOG; \ + MOL_HOOK(hook); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r20,MSR_KERNEL; \ + bl transfer_to_handler; \ + .long hdlr; \ + .long ret_from_except + /* System reset */ #ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */ #ifdef CONFIG_GEMINI @@ -324,6 +328,7 @@ DataAccessCont: DataAccess: EXCEPTION_PROLOG #endif /* CONFIG_PPC64BRIDGE */ + MOL_HOOK(0) mfspr r20,DSISR andis. r0,r20,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ @@ -366,6 +371,7 @@ InstructionAccessCont: InstructionAccess: EXCEPTION_PROLOG #endif /* CONFIG_PPC64BRIDGE */ + MOL_HOOK(1) andis. r0,r23,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ mr r3,r22 /* into the hash table */ @@ -430,6 +436,7 @@ Alignment: . = 0x700 ProgramCheck: EXCEPTION_PROLOG + MOL_HOOK(2) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ @@ -441,6 +448,7 @@ ProgramCheck: . = 0x800 FPUnavailable: EXCEPTION_PROLOG + MOL_HOOK_RESTORE(3) bne load_up_fpu /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ @@ -450,6 +458,7 @@ FPUnavailable: . = 0x900 Decrementer: EXCEPTION_PROLOG + MOL_HOOK(4) addi r3,r1,STACK_FRAME_OVERHEAD li r20,MSR_KERNEL bl transfer_to_handler @@ -473,12 +482,9 @@ SystemCall: .long ret_from_except /* Single step - not used on 601 */ - STD_EXCEPTION(0xd00, SingleStep, SingleStepException) - + STD_MOL_EXCEPTION(0xd00, SingleStep, SingleStepException, 5) STD_EXCEPTION(0xe00, Trap_0e, UnknownException) -#ifndef CONFIG_ALTIVEC - STD_EXCEPTION(0xf00, Trap_0f, UnknownException) -#else + /* * The Altivec unavailable trap is at 0x0f20. Foo. * We effectively remap it to 0x3000. @@ -493,15 +499,20 @@ trap_0f_cont: .long ret_from_except . = 0xf20 +#ifdef CONFIG_ALTIVEC b AltiVecUnavailable -#endif /* CONFIG_ALTIVEC */ - +#endif +Trap_0f: + EXCEPTION_PROLOG + b trap_0f_cont + /* * Handle TLB miss for instruction on 603/603e. * Note: we get an alternate set of r0 - r3 to use automatically. */ . = 0x1000 InstructionTLBMiss: + MOL_HOOK_TLBMISS( 14 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -568,6 +579,7 @@ InstructionAddressInvalid: */ . = 0x1100 DataLoadTLBMiss: + MOL_HOOK_TLBMISS( 15 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -633,6 +645,7 @@ DataAddressInvalid: */ . = 0x1200 DataStoreTLBMiss: + MOL_HOOK_TLBMISS( 16 ) /* * r0: stored ctr * r1: linux style pte ( later becomes ppc hardware pte ) @@ -674,7 +687,7 @@ DataStoreTLBMiss: mtcrf 0x80,r3 rfi - STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint) + STD_MOL_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, 11) STD_EXCEPTION(0x1400, SMI, SMIException) STD_EXCEPTION(0x1500, Trap_15, UnknownException) STD_EXCEPTION(0x1600, Trap_16, UnknownException) @@ -687,7 +700,7 @@ DataStoreTLBMiss: STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) - STD_EXCEPTION(0x2000, RunMode, RunModeException) + STD_MOL_EXCEPTION(0x2000, RunMode, RunModeException, 5) STD_EXCEPTION(0x2100, Trap_21, UnknownException) STD_EXCEPTION(0x2200, Trap_22, UnknownException) STD_EXCEPTION(0x2300, Trap_23, UnknownException) @@ -709,16 +722,12 @@ DataStoreTLBMiss: #ifdef CONFIG_ALTIVEC AltiVecUnavailable: EXCEPTION_PROLOG + MOL_HOOK_RESTORE(12) bne load_up_altivec /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ .long KernelAltiVec .long ret_from_except - -/* here are the bits of trap 0xf00 which got displaced */ -Trap_0f: - EXCEPTION_PROLOG - b trap_0f_cont #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_PPC64BRIDGE @@ -753,6 +762,14 @@ transfer_to_handler: beq 2f addi r24,r1,STACK_FRAME_OVERHEAD stw r24,PT_REGS(r23) +#ifdef CONFIG_ALTIVEC + mfpvr r24 /* check if we are on a G4 */ + srwi r24,r24,16 + cmpwi r24,PVR_7400@h + bne 2f + mfspr r22,SPRN_VRSAVE /* if so, save vrsave register value */ + stw r22,THREAD_VRSAVE(r23) +#endif /* CONFIG_ALTIVEC */ 2: addi r2,r23,-THREAD /* set r2 to current */ tovirt(r2,r2) mflr r23 @@ -771,6 +788,7 @@ transfer_to_handler: lwz r24,0(r23) /* virtual address of handler */ lwz r23,4(r23) /* where to go when done */ FIX_SRR1(r20,r22) + MOL_HOOK(6) mtspr SRR0,r24 mtspr SRR1,r20 mtlr r23 @@ -981,6 +999,11 @@ KernelAltiVec: .globl giveup_altivec giveup_altivec: +#ifdef CONFIG_MOL + mflr r4 + MOL_HOOK_MMU(13, r5) + mtlr r4 +#endif mfmsr r5 oris r5,r5,MSR_VEC@h SYNC @@ -1017,6 +1040,11 @@ giveup_altivec: */ .globl giveup_fpu giveup_fpu: +#ifdef CONFIG_MOL + mflr r4 + MOL_HOOK_MMU(7, r5) + mtlr r4 +#endif mfmsr r5 ori r5,r5,MSR_FP SYNC @@ -1048,19 +1076,10 @@ giveup_fpu: * the kernel image to physical address 0. */ relocate_kernel: -#if 0 /* Is this still needed ? I don't think so. It breaks new - * boot-with-mmu-off stuff - */ - lis r9,0x426f /* if booted from BootX, don't */ - addi r9,r9,0x6f58 /* translate source addr */ - cmpw r31,r9 /* (we have to on chrp) */ - beq 7f - rlwinm r4,r4,0,8,31 /* translate source address */ - add r4,r4,r3 /* to region mapped with BATs */ -#endif -7: addis r9,r26,klimit@ha /* fetch klimit */ + addis r9,r26,klimit@ha /* fetch klimit */ lwz r25,klimit@l(r9) addis r25,r25,-KERNELBASE@h + li r3,0 /* Destination base address */ li r6,0 /* Destination offset */ li r5,0x4000 /* # bytes of memory to copy */ bl copy_and_flush /* copy the first 0x4000 bytes */ @@ -1307,7 +1326,7 @@ enable_caches: mfspr r9,PVR rlwinm r9,r9,16,16,31 cmpi 0,r9,1 - beq 4f /* not needed for 601 */ + beq 6f /* not needed for 601 */ mfspr r11,HID0 andi. r0,r11,HID0_DCE ori r11,r11,HID0_ICE|HID0_DCE @@ -1323,26 +1342,33 @@ enable_caches: isync cmpi 0,r9,4 /* check for 604 */ cmpi 1,r9,9 /* or 604e */ - cmpi 2,r9,10 /* or mach5 */ + cmpi 2,r9,10 /* or mach5 / 604r */ cmpi 3,r9,8 /* check for 750 (G3) */ cmpi 4,r9,12 /* or 7400 (G4) */ cror 2,2,6 cror 2,2,10 bne 4f - ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */ + ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e|r], enable */ bne 2,5f - ori r11,r11,HID0_BTCD + ori r11,r11,HID0_BTCD /* superscalar exec & br history tbl */ b 5f 4: cror 14,14,18 bne 3,6f - /* We should add ABE here if we want to use Store Gathering - * and other nifty bridge features + /* for G3/G4: + * enable Store Gathering (SGE), Address Brodcast (ABE), + * Branch History Table (BHTE), Branch Target ICache (BTIC) */ - ori r11,r11,HID0_SGE|HID0_BHTE|HID0_BTIC /* for g3/g4, enable */ + ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC + oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */ + li r3,HID0_SPD + andc r11,r11,r3 /* clear SPD: enable speculative */ li r3,0 - mtspr ICTC,r3 -5: mtspr HID0,r11 /* superscalar exec & br history tbl */ + mtspr ICTC,r3 /* Instruction Cache Throttling off */ +5: isync + mtspr HID0,r11 + sync + isync 6: blr /* @@ -1548,12 +1574,11 @@ flush_tlbs: blr mmu_off: - addi r4, r3, __after_prom_start - _start + addi r4, r3, __after_mmu_off - _start mfmsr r3 andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */ beqlr - ori r3,r3,MSR_DR|MSR_IR - xori r3,r3,MSR_DR|MSR_IR + andc r3,r3,r0 mtspr SRR0,r4 mtspr SRR1,r3 sync @@ -1617,23 +1642,19 @@ setup_disp_bat: mflr r8 bl reloc_offset mtlr r8 - lis r8, disp_BATL@h - ori r8, r8, disp_BATL@l - add r8, r3, r8 - lwz r8, 0(r8) - lis r11, disp_BATU@h - ori r11, r11, disp_BATU@l - add r11, r3, r11 - lwz r11, 0(r11) - mtspr IBAT3L,r8 - mtspr IBAT3U,r11 + addis r8,r3,disp_BAT@ha + addi r8,r8,disp_BAT@l + lwz r11,0(r8) + lwz r8,4(r8) mfspr r9,PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ cmpi 0,r9,1 beq 1f mtspr DBAT3L,r8 mtspr DBAT3U,r11 -1: + blr +1: mtspr IBAT3L,r8 + mtspr IBAT3U,r11 blr #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ @@ -1649,18 +1670,43 @@ setup_disp_bat: */ .globl m8260_gorom m8260_gorom: - li r5,MSR_KERNEL & ~(MSR_IR|MSR_DR) - lis r6,2f@h - addis r6,r6,-KERNELBASE@h - ori r6,r6,2f@l - mtspr SRR0,r6 - mtspr SRR1,r5 - rfi + mfmsr r0 + rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ + sync + mtmsr r0 + sync + mfspr r11, HID0 + lis r10, 0 + ori r10,r10,HID0_ICE|HID0_DCE + andc r11, r11, r10 + mtspr HID0, r11 + isync + li r5, MSR_ + lis r6,2f@h + addis r6,r6,-KERNELBASE@h + ori r6,r6,2f@l + mtspr SRR0,r6 + mtspr SRR1,r5 + isync + sync + rfi 2: - mtlr r4 - blr + mtlr r4 + blr +#endif + +#ifdef CONFIG_MOL +/* + * Mac-on-linux hook_table. Don't put this in the data section - + * the base address must be within the first 32KB of RAM. + */ + .globl mol_interface +mol_interface: + .long MOL_INTERFACE_VERSION + .fill 24,4,0 /* space for 24 hooks */ #endif + /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the data segment, |