diff options
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64e.S')
-rw-r--r-- | arch/powerpc/kernel/exceptions-64e.S | 86 |
1 files changed, 65 insertions, 21 deletions
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 645170a..4add11d 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -445,6 +445,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) fixed_interval, .unknown_exception, ACK_FIT) /* Watchdog Timer Interrupt */ +#ifdef CONFIG_FSL_ERRATUM_A_006184 + START_EXCEPTION(watchdog) + mtspr SPRN_SPRG_CRIT_SCRATCH, r3 + lis r3, TSR_WIS@h + mtspr SPRN_TSR, r3 + mfspr r3, SPRN_SPRG_CRIT_SCRATCH + rfci +#else START_EXCEPTION(watchdog); CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, PROLOG_ADDITION_NONE) @@ -455,6 +463,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) // bl .unknown_exception // b ret_from_crit_except b . +#endif /* System Call Interrupt */ START_EXCEPTION(system_call) @@ -695,6 +704,7 @@ kernel_dbg_exc: mtcr r11 ld r10,PACA_EXGEN+EX_R10(r13) ld r11,PACA_EXGEN+EX_R11(r13) + fsl_erratum_a006198_restore_srr r13 mfspr r13,SPRN_SPRG_GEN_SCRATCH rfi b . @@ -799,7 +809,7 @@ _GLOBAL(exception_return_book3e) */ .globl fast_exception_return fast_exception_return: - wrteei 0 + fsl_erratum_a006198_wrteei0 r0 r10 1: mr r0,r13 ld r10,_MSR(r1) REST_4GPRS(2, r1) @@ -835,6 +845,7 @@ fast_exception_return: mtspr SPRN_SRR1,r11 ld r10,PACA_EXGEN+EX_R10(r13) ld r11,PACA_EXGEN+EX_R11(r13) + fsl_erratum_a006198_restore_srr r13 mfspr r13,SPRN_SPRG_GEN_SCRATCH rfi @@ -1053,12 +1064,9 @@ skpinv: addi r6,r6,1 /* Increment */ mtspr SPRN_MAS0,r3 tlbre mfspr r6,SPRN_MAS1 - rlwinm r6,r6,0,2,0 /* clear IPROT */ + rlwinm r6,r6,0,2,31 /* clear IPROT and VALID */ mtspr SPRN_MAS1,r6 tlbwe - - /* Invalidate TLB1 */ - PPC_TLBILX_ALL(0,R0) sync isync @@ -1112,12 +1120,9 @@ skpinv: addi r6,r6,1 /* Increment */ mtspr SPRN_MAS0,r4 tlbre mfspr r5,SPRN_MAS1 - rlwinm r5,r5,0,2,0 /* clear IPROT */ + rlwinm r5,r5,0,2,31 /* clear IPROT and VALID */ mtspr SPRN_MAS1,r5 tlbwe - - /* Invalidate TLB1 */ - PPC_TLBILX_ALL(0,R0) sync isync @@ -1320,6 +1325,11 @@ _GLOBAL(book3e_secondary_core_init) /* Init global core bits */ 2: bl .init_core_book3e +BEGIN_FTR_SECTION + /* Start threads */ + bl .fsl_enable_threads +END_FTR_SECTION_IFSET(CPU_FTR_SMT) + /* Init per-thread bits */ 3: bl .init_thread_book3e @@ -1355,12 +1365,46 @@ _STATIC(init_core_book3e) sync blr +_GLOBAL(fsl_enable_threads) +BEGIN_FTR_SECTION + MFTMR(TMRN_TMCFG0, 3) + andi. r3,r3,0x3f + cmpi 0,r3,2 + blt 2f + + /* Disable the other thread */ + li r3,2 + mtspr SPRN_TENC,r3 + +1: mfspr r3,SPRN_TENSR + andi. r3,r3,2 + bne 1b + +#ifndef CONFIG_PPC_DISABLE_THREADS + /* Configure the MSR per the default */ + LOAD_REG_IMMEDIATE(r3, MSR_KERNEL); + MTTMR(TMRN_IMSR1, 3); + + /* + * Set the NIA for the secondary thread to + * generic_secondary_thread_init + */ + LOAD_REG_IMMEDIATE(r3, .fsl_secondary_thread_init); + MTTMR(TMRN_INIA1, 3); + + /* Release the other thread. It will spin until kick_cpu is called */ + li r3, 2 + mtspr SPRN_TENS, r3 +#endif +END_FTR_SECTION_IFSET(CPU_FTR_SMT) +2: blr + _STATIC(init_thread_book3e) lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h mtspr SPRN_EPCR,r3 /* Make sure interrupts are off */ - wrteei 0 + fsl_erratum_a006198_wrteei0 r3 r4 /* disable all timers and clear out status */ li r3,0 @@ -1373,18 +1417,18 @@ _STATIC(init_thread_book3e) _GLOBAL(__setup_base_ivors) SET_IVOR(0, 0x020) /* Critical Input */ SET_IVOR(1, 0x000) /* Machine Check */ - SET_IVOR(2, 0x060) /* Data Storage */ + SET_IVOR(2, 0x060) /* Data Storage */ SET_IVOR(3, 0x080) /* Instruction Storage */ - SET_IVOR(4, 0x0a0) /* External Input */ - SET_IVOR(5, 0x0c0) /* Alignment */ - SET_IVOR(6, 0x0e0) /* Program */ - SET_IVOR(7, 0x100) /* FP Unavailable */ - SET_IVOR(8, 0x120) /* System Call */ - SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ - SET_IVOR(10, 0x160) /* Decrementer */ - SET_IVOR(11, 0x180) /* Fixed Interval Timer */ - SET_IVOR(12, 0x1a0) /* Watchdog Timer */ - SET_IVOR(13, 0x1c0) /* Data TLB Error */ + SET_IVOR(4, 0x0a0) /* External Input */ + SET_IVOR(5, 0x0c0) /* Alignment */ + SET_IVOR(6, 0x0e0) /* Program */ + SET_IVOR(7, 0x100) /* FP Unavailable */ + SET_IVOR(8, 0x120) /* System Call */ + SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ + SET_IVOR(10, 0x160) /* Decrementer */ + SET_IVOR(11, 0x180) /* Fixed Interval Timer */ + SET_IVOR(12, 0x1a0) /* Watchdog Timer */ + SET_IVOR(13, 0x1c0) /* Data TLB Error */ SET_IVOR(14, 0x1e0) /* Instruction TLB Error */ SET_IVOR(15, 0x040) /* Debug */ |