aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/exceptions-64s.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/exceptions-64s.S')
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S178
1 files changed, 97 insertions, 81 deletions
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 87ef8f5ee5bc..56bd92362ce1 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -1066,78 +1066,6 @@ unrecov_user_slb:
1066#endif /* __DISABLED__ */ 1066#endif /* __DISABLED__ */
1067 1067
1068 1068
1069/*
1070 * r13 points to the PACA, r9 contains the saved CR,
1071 * r12 contain the saved SRR1, SRR0 is still ready for return
1072 * r3 has the faulting address
1073 * r9 - r13 are saved in paca->exslb.
1074 * r3 is saved in paca->slb_r3
1075 * We assume we aren't going to take any exceptions during this procedure.
1076 */
1077_GLOBAL(slb_miss_realmode)
1078 mflr r10
1079#ifdef CONFIG_RELOCATABLE
1080 mtctr r11
1081#endif
1082
1083 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
1084 std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
1085
1086 bl .slb_allocate_realmode
1087
1088 /* All done -- return from exception. */
1089
1090 ld r10,PACA_EXSLB+EX_LR(r13)
1091 ld r3,PACA_EXSLB+EX_R3(r13)
1092 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
1093
1094 mtlr r10
1095
1096 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
1097 beq- 2f
1098
1099.machine push
1100.machine "power4"
1101 mtcrf 0x80,r9
1102 mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
1103.machine pop
1104
1105 RESTORE_PPR_PACA(PACA_EXSLB, r9)
1106 ld r9,PACA_EXSLB+EX_R9(r13)
1107 ld r10,PACA_EXSLB+EX_R10(r13)
1108 ld r11,PACA_EXSLB+EX_R11(r13)
1109 ld r12,PACA_EXSLB+EX_R12(r13)
1110 ld r13,PACA_EXSLB+EX_R13(r13)
1111 rfid
1112 b . /* prevent speculative execution */
1113
11142: mfspr r11,SPRN_SRR0
1115 ld r10,PACAKBASE(r13)
1116 LOAD_HANDLER(r10,unrecov_slb)
1117 mtspr SPRN_SRR0,r10
1118 ld r10,PACAKMSR(r13)
1119 mtspr SPRN_SRR1,r10
1120 rfid
1121 b .
1122
1123unrecov_slb:
1124 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
1125 DISABLE_INTS
1126 bl .save_nvgprs
11271: addi r3,r1,STACK_FRAME_OVERHEAD
1128 bl .unrecoverable_exception
1129 b 1b
1130
1131
1132#ifdef CONFIG_PPC_970_NAP
1133power4_fixup_nap:
1134 andc r9,r9,r10
1135 std r9,TI_LOCAL_FLAGS(r11)
1136 ld r10,_LINK(r1) /* make idle task do the */
1137 std r10,_NIP(r1) /* equivalent of a blr */
1138 blr
1139#endif
1140
1141 .align 7 1069 .align 7
1142 .globl alignment_common 1070 .globl alignment_common
1143alignment_common: 1071alignment_common:
@@ -1336,6 +1264,78 @@ _GLOBAL(opal_mc_secondary_handler)
1336 1264
1337 1265
1338/* 1266/*
1267 * r13 points to the PACA, r9 contains the saved CR,
1268 * r12 contain the saved SRR1, SRR0 is still ready for return
1269 * r3 has the faulting address
1270 * r9 - r13 are saved in paca->exslb.
1271 * r3 is saved in paca->slb_r3
1272 * We assume we aren't going to take any exceptions during this procedure.
1273 */
1274_GLOBAL(slb_miss_realmode)
1275 mflr r10
1276#ifdef CONFIG_RELOCATABLE
1277 mtctr r11
1278#endif
1279
1280 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
1281 std r10,PACA_EXSLB+EX_LR(r13) /* save LR */
1282
1283 bl .slb_allocate_realmode
1284
1285 /* All done -- return from exception. */
1286
1287 ld r10,PACA_EXSLB+EX_LR(r13)
1288 ld r3,PACA_EXSLB+EX_R3(r13)
1289 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
1290
1291 mtlr r10
1292
1293 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
1294 beq- 2f
1295
1296.machine push
1297.machine "power4"
1298 mtcrf 0x80,r9
1299 mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */
1300.machine pop
1301
1302 RESTORE_PPR_PACA(PACA_EXSLB, r9)
1303 ld r9,PACA_EXSLB+EX_R9(r13)
1304 ld r10,PACA_EXSLB+EX_R10(r13)
1305 ld r11,PACA_EXSLB+EX_R11(r13)
1306 ld r12,PACA_EXSLB+EX_R12(r13)
1307 ld r13,PACA_EXSLB+EX_R13(r13)
1308 rfid
1309 b . /* prevent speculative execution */
1310
13112: mfspr r11,SPRN_SRR0
1312 ld r10,PACAKBASE(r13)
1313 LOAD_HANDLER(r10,unrecov_slb)
1314 mtspr SPRN_SRR0,r10
1315 ld r10,PACAKMSR(r13)
1316 mtspr SPRN_SRR1,r10
1317 rfid
1318 b .
1319
1320unrecov_slb:
1321 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
1322 DISABLE_INTS
1323 bl .save_nvgprs
13241: addi r3,r1,STACK_FRAME_OVERHEAD
1325 bl .unrecoverable_exception
1326 b 1b
1327
1328
1329#ifdef CONFIG_PPC_970_NAP
1330power4_fixup_nap:
1331 andc r9,r9,r10
1332 std r9,TI_LOCAL_FLAGS(r11)
1333 ld r10,_LINK(r1) /* make idle task do the */
1334 std r10,_NIP(r1) /* equivalent of a blr */
1335 blr
1336#endif
1337
1338/*
1339 * Hash table stuff 1339 * Hash table stuff
1340 */ 1340 */
1341 .align 7 1341 .align 7
@@ -1452,20 +1452,36 @@ do_ste_alloc:
1452_GLOBAL(do_stab_bolted) 1452_GLOBAL(do_stab_bolted)
1453 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ 1453 stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */
1454 std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */ 1454 std r11,PACA_EXSLB+EX_SRR0(r13) /* save SRR0 in exc. frame */
1455 mfspr r11,SPRN_DAR /* ea */
1455 1456
1457 /*
1458 * check for bad kernel/user address
1459 * (ea & ~REGION_MASK) >= PGTABLE_RANGE
1460 */
1461 rldicr. r9,r11,4,(63 - 46 - 4)
1462 li r9,0 /* VSID = 0 for bad address */
1463 bne- 0f
1464
1465 /*
1466 * Calculate VSID:
1467 * This is the kernel vsid, we take the top for context from
1468 * the range. context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1
1469 * Here we know that (ea >> 60) == 0xc
1470 */
1471 lis r9,(MAX_USER_CONTEXT + 1)@ha
1472 addi r9,r9,(MAX_USER_CONTEXT + 1)@l
1473
1474 srdi r10,r11,SID_SHIFT
1475 rldimi r10,r9,ESID_BITS,0 /* proto vsid */
1476 ASM_VSID_SCRAMBLE(r10, r9, 256M)
1477 rldic r9,r10,12,16 /* r9 = vsid << 12 */
1478
14790:
1456 /* Hash to the primary group */ 1480 /* Hash to the primary group */
1457 ld r10,PACASTABVIRT(r13) 1481 ld r10,PACASTABVIRT(r13)
1458 mfspr r11,SPRN_DAR 1482 srdi r11,r11,SID_SHIFT
1459 srdi r11,r11,28
1460 rldimi r10,r11,7,52 /* r10 = first ste of the group */ 1483 rldimi r10,r11,7,52 /* r10 = first ste of the group */
1461 1484
1462 /* Calculate VSID */
1463 /* This is a kernel address, so protovsid = ESID | 1 << 37 */
1464 li r9,0x1
1465 rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0
1466 ASM_VSID_SCRAMBLE(r11, r9, 256M)
1467 rldic r9,r11,12,16 /* r9 = vsid << 12 */
1468
1469 /* Search the primary group for a free entry */ 1485 /* Search the primary group for a free entry */
14701: ld r11,0(r10) /* Test valid bit of the current ste */ 14861: ld r11,0(r10) /* Test valid bit of the current ste */
1471 andi. r11,r11,0x80 1487 andi. r11,r11,0x80