summaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/exceptions-64e.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64e.S')
-rw-r--r--arch/powerpc/kernel/exceptions-64e.S86
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 */