diff options
author | Paul Mackerras <paulus@samba.org> | 2008-08-29 21:41:12 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-09-15 14:08:35 -0400 |
commit | e31aa453bbc4886a7bd33e5c2afa526d6f55bd7a (patch) | |
tree | fefa13c13d7b1803fdaeb92143f83b1971f0ec8d /arch | |
parent | 1f6a93e4c35e75d547b51f56ba8139ab1a91628c (diff) |
powerpc: Use LOAD_REG_IMMEDIATE only for constants on 64-bit
Using LOAD_REG_IMMEDIATE to get the address of kernel symbols
generates 5 instructions where LOAD_REG_ADDR can do it in one,
and will generate R_PPC64_ADDR16_* relocations in the output when
we get to making the kernel as a position-independent executable,
which we'd rather not have to handle. This changes various bits
of assembly code to use LOAD_REG_ADDR when we need to get the
address of a symbol, or to use suitable position-independent code
for cases where we can't access the TOC for various reasons, or
if we're not running at the address we were linked at.
It also cleans up a few minor things; there's no reason to save and
restore SRR0/1 around RTAS calls, __mmu_off can get the return
address from LR more conveniently than the caller can supply it in
R4 (and we already assume elsewhere that EA == RA if the MMU is on
in early boot), and enable_64b_mode was using 5 instructions where
2 would do.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/include/asm/ppc_asm.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/cpu_setup_ppc970.S | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/entry_64.S | 16 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 181 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc.S | 10 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/exception.S | 23 |
6 files changed, 110 insertions, 126 deletions
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 0966899d974b..c4a029ccb4d3 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h | |||
@@ -268,7 +268,7 @@ n: | |||
268 | * Loads the value of the constant expression 'expr' into register 'rn' | 268 | * Loads the value of the constant expression 'expr' into register 'rn' |
269 | * using immediate instructions only. Use this when it's important not | 269 | * using immediate instructions only. Use this when it's important not |
270 | * to reference other data (i.e. on ppc64 when the TOC pointer is not | 270 | * to reference other data (i.e. on ppc64 when the TOC pointer is not |
271 | * valid). | 271 | * valid) and when 'expr' is a constant or absolute address. |
272 | * | 272 | * |
273 | * LOAD_REG_ADDR(rn, name) | 273 | * LOAD_REG_ADDR(rn, name) |
274 | * Loads the address of label 'name' into register 'rn'. Use this when | 274 | * Loads the address of label 'name' into register 'rn'. Use this when |
diff --git a/arch/powerpc/kernel/cpu_setup_ppc970.S b/arch/powerpc/kernel/cpu_setup_ppc970.S index bf118c385752..27f2507279d8 100644 --- a/arch/powerpc/kernel/cpu_setup_ppc970.S +++ b/arch/powerpc/kernel/cpu_setup_ppc970.S | |||
@@ -110,7 +110,7 @@ load_hids: | |||
110 | isync | 110 | isync |
111 | 111 | ||
112 | /* Save away cpu state */ | 112 | /* Save away cpu state */ |
113 | LOAD_REG_IMMEDIATE(r5,cpu_state_storage) | 113 | LOAD_REG_ADDR(r5,cpu_state_storage) |
114 | 114 | ||
115 | /* Save HID0,1,4 and 5 */ | 115 | /* Save HID0,1,4 and 5 */ |
116 | mfspr r3,SPRN_HID0 | 116 | mfspr r3,SPRN_HID0 |
@@ -134,7 +134,7 @@ _GLOBAL(__restore_cpu_ppc970) | |||
134 | rldicl. r0,r0,4,63 | 134 | rldicl. r0,r0,4,63 |
135 | beqlr | 135 | beqlr |
136 | 136 | ||
137 | LOAD_REG_IMMEDIATE(r5,cpu_state_storage) | 137 | LOAD_REG_ADDR(r5,cpu_state_storage) |
138 | /* Before accessing memory, we make sure rm_ci is clear */ | 138 | /* Before accessing memory, we make sure rm_ci is clear */ |
139 | li r0,0 | 139 | li r0,0 |
140 | mfspr r3,SPRN_HID4 | 140 | mfspr r3,SPRN_HID4 |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 55445f1dba8a..fd8b4bae9b04 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -690,10 +690,6 @@ _GLOBAL(enter_rtas) | |||
690 | std r7,_DAR(r1) | 690 | std r7,_DAR(r1) |
691 | mfdsisr r8 | 691 | mfdsisr r8 |
692 | std r8,_DSISR(r1) | 692 | std r8,_DSISR(r1) |
693 | mfsrr0 r9 | ||
694 | std r9,_SRR0(r1) | ||
695 | mfsrr1 r10 | ||
696 | std r10,_SRR1(r1) | ||
697 | 693 | ||
698 | /* Temporary workaround to clear CR until RTAS can be modified to | 694 | /* Temporary workaround to clear CR until RTAS can be modified to |
699 | * ignore all bits. | 695 | * ignore all bits. |
@@ -754,6 +750,10 @@ _STATIC(rtas_return_loc) | |||
754 | mfspr r4,SPRN_SPRG3 /* Get PACA */ | 750 | mfspr r4,SPRN_SPRG3 /* Get PACA */ |
755 | clrldi r4,r4,2 /* convert to realmode address */ | 751 | clrldi r4,r4,2 /* convert to realmode address */ |
756 | 752 | ||
753 | bcl 20,31,$+4 | ||
754 | 0: mflr r3 | ||
755 | ld r3,(1f-0b)(r3) /* get &.rtas_restore_regs */ | ||
756 | |||
757 | mfmsr r6 | 757 | mfmsr r6 |
758 | li r0,MSR_RI | 758 | li r0,MSR_RI |
759 | andc r6,r6,r0 | 759 | andc r6,r6,r0 |
@@ -761,7 +761,6 @@ _STATIC(rtas_return_loc) | |||
761 | mtmsrd r6 | 761 | mtmsrd r6 |
762 | 762 | ||
763 | ld r1,PACAR1(r4) /* Restore our SP */ | 763 | ld r1,PACAR1(r4) /* Restore our SP */ |
764 | LOAD_REG_IMMEDIATE(r3,.rtas_restore_regs) | ||
765 | ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ | 764 | ld r4,PACASAVEDMSR(r4) /* Restore our MSR */ |
766 | 765 | ||
767 | mtspr SPRN_SRR0,r3 | 766 | mtspr SPRN_SRR0,r3 |
@@ -769,6 +768,9 @@ _STATIC(rtas_return_loc) | |||
769 | rfid | 768 | rfid |
770 | b . /* prevent speculative execution */ | 769 | b . /* prevent speculative execution */ |
771 | 770 | ||
771 | .align 3 | ||
772 | 1: .llong .rtas_restore_regs | ||
773 | |||
772 | _STATIC(rtas_restore_regs) | 774 | _STATIC(rtas_restore_regs) |
773 | /* relocation is on at this point */ | 775 | /* relocation is on at this point */ |
774 | REST_GPR(2, r1) /* Restore the TOC */ | 776 | REST_GPR(2, r1) /* Restore the TOC */ |
@@ -788,10 +790,6 @@ _STATIC(rtas_restore_regs) | |||
788 | mtdar r7 | 790 | mtdar r7 |
789 | ld r8,_DSISR(r1) | 791 | ld r8,_DSISR(r1) |
790 | mtdsisr r8 | 792 | mtdsisr r8 |
791 | ld r9,_SRR0(r1) | ||
792 | mtsrr0 r9 | ||
793 | ld r10,_SRR1(r1) | ||
794 | mtsrr1 r10 | ||
795 | 793 | ||
796 | addi r1,r1,RTAS_FRAME_SIZE /* Unstack our frame */ | 794 | addi r1,r1,RTAS_FRAME_SIZE /* Unstack our frame */ |
797 | ld r0,16(r1) /* get return address */ | 795 | ld r0,16(r1) /* get return address */ |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 97bb6e6f67b1..6cdfd44d8efe 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -128,11 +128,11 @@ __secondary_hold: | |||
128 | /* Tell the master cpu we're here */ | 128 | /* Tell the master cpu we're here */ |
129 | /* Relocation is off & we are located at an address less */ | 129 | /* Relocation is off & we are located at an address less */ |
130 | /* than 0x100, so only need to grab low order offset. */ | 130 | /* than 0x100, so only need to grab low order offset. */ |
131 | std r24,__secondary_hold_acknowledge@l(0) | 131 | std r24,__secondary_hold_acknowledge-_stext(0) |
132 | sync | 132 | sync |
133 | 133 | ||
134 | /* All secondary cpus wait here until told to start. */ | 134 | /* All secondary cpus wait here until told to start. */ |
135 | 100: ld r4,__secondary_hold_spinloop@l(0) | 135 | 100: ld r4,__secondary_hold_spinloop-_stext(0) |
136 | cmpdi 0,r4,0 | 136 | cmpdi 0,r4,0 |
137 | beq 100b | 137 | beq 100b |
138 | 138 | ||
@@ -1223,11 +1223,14 @@ _GLOBAL(generic_secondary_smp_init) | |||
1223 | /* turn on 64-bit mode */ | 1223 | /* turn on 64-bit mode */ |
1224 | bl .enable_64b_mode | 1224 | bl .enable_64b_mode |
1225 | 1225 | ||
1226 | /* get the TOC pointer (real address) */ | ||
1227 | bl .relative_toc | ||
1228 | |||
1226 | /* Set up a paca value for this processor. Since we have the | 1229 | /* Set up a paca value for this processor. Since we have the |
1227 | * physical cpu id in r24, we need to search the pacas to find | 1230 | * physical cpu id in r24, we need to search the pacas to find |
1228 | * which logical id maps to our physical one. | 1231 | * which logical id maps to our physical one. |
1229 | */ | 1232 | */ |
1230 | LOAD_REG_IMMEDIATE(r13, paca) /* Get base vaddr of paca array */ | 1233 | LOAD_REG_ADDR(r13, paca) /* Get base vaddr of paca array */ |
1231 | li r5,0 /* logical cpu id */ | 1234 | li r5,0 /* logical cpu id */ |
1232 | 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ | 1235 | 1: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ |
1233 | cmpw r6,r24 /* Compare to our id */ | 1236 | cmpw r6,r24 /* Compare to our id */ |
@@ -1256,7 +1259,7 @@ _GLOBAL(generic_secondary_smp_init) | |||
1256 | sync /* order paca.run and cur_cpu_spec */ | 1259 | sync /* order paca.run and cur_cpu_spec */ |
1257 | 1260 | ||
1258 | /* See if we need to call a cpu state restore handler */ | 1261 | /* See if we need to call a cpu state restore handler */ |
1259 | LOAD_REG_IMMEDIATE(r23, cur_cpu_spec) | 1262 | LOAD_REG_ADDR(r23, cur_cpu_spec) |
1260 | ld r23,0(r23) | 1263 | ld r23,0(r23) |
1261 | ld r23,CPU_SPEC_RESTORE(r23) | 1264 | ld r23,CPU_SPEC_RESTORE(r23) |
1262 | cmpdi 0,r23,0 | 1265 | cmpdi 0,r23,0 |
@@ -1272,10 +1275,15 @@ _GLOBAL(generic_secondary_smp_init) | |||
1272 | b __secondary_start | 1275 | b __secondary_start |
1273 | #endif | 1276 | #endif |
1274 | 1277 | ||
1278 | /* | ||
1279 | * Turn the MMU off. | ||
1280 | * Assumes we're mapped EA == RA if the MMU is on. | ||
1281 | */ | ||
1275 | _STATIC(__mmu_off) | 1282 | _STATIC(__mmu_off) |
1276 | mfmsr r3 | 1283 | mfmsr r3 |
1277 | andi. r0,r3,MSR_IR|MSR_DR | 1284 | andi. r0,r3,MSR_IR|MSR_DR |
1278 | beqlr | 1285 | beqlr |
1286 | mflr r4 | ||
1279 | andc r3,r3,r0 | 1287 | andc r3,r3,r0 |
1280 | mtspr SPRN_SRR0,r4 | 1288 | mtspr SPRN_SRR0,r4 |
1281 | mtspr SPRN_SRR1,r3 | 1289 | mtspr SPRN_SRR1,r3 |
@@ -1296,6 +1304,18 @@ _STATIC(__mmu_off) | |||
1296 | * | 1304 | * |
1297 | */ | 1305 | */ |
1298 | _GLOBAL(__start_initialization_multiplatform) | 1306 | _GLOBAL(__start_initialization_multiplatform) |
1307 | /* Make sure we are running in 64 bits mode */ | ||
1308 | bl .enable_64b_mode | ||
1309 | |||
1310 | /* Get TOC pointer (current runtime address) */ | ||
1311 | bl .relative_toc | ||
1312 | |||
1313 | /* find out where we are now */ | ||
1314 | bcl 20,31,$+4 | ||
1315 | 0: mflr r26 /* r26 = runtime addr here */ | ||
1316 | addis r26,r26,(_stext - 0b)@ha | ||
1317 | addi r26,r26,(_stext - 0b)@l /* current runtime base addr */ | ||
1318 | |||
1299 | /* | 1319 | /* |
1300 | * Are we booted from a PROM Of-type client-interface ? | 1320 | * Are we booted from a PROM Of-type client-interface ? |
1301 | */ | 1321 | */ |
@@ -1307,9 +1327,6 @@ _GLOBAL(__start_initialization_multiplatform) | |||
1307 | mr r31,r3 | 1327 | mr r31,r3 |
1308 | mr r30,r4 | 1328 | mr r30,r4 |
1309 | 1329 | ||
1310 | /* Make sure we are running in 64 bits mode */ | ||
1311 | bl .enable_64b_mode | ||
1312 | |||
1313 | /* Setup some critical 970 SPRs before switching MMU off */ | 1330 | /* Setup some critical 970 SPRs before switching MMU off */ |
1314 | mfspr r0,SPRN_PVR | 1331 | mfspr r0,SPRN_PVR |
1315 | srwi r0,r0,16 | 1332 | srwi r0,r0,16 |
@@ -1324,9 +1341,7 @@ _GLOBAL(__start_initialization_multiplatform) | |||
1324 | 1: bl .__cpu_preinit_ppc970 | 1341 | 1: bl .__cpu_preinit_ppc970 |
1325 | 2: | 1342 | 2: |
1326 | 1343 | ||
1327 | /* Switch off MMU if not already */ | 1344 | /* Switch off MMU if not already off */ |
1328 | LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) | ||
1329 | add r4,r4,r30 | ||
1330 | bl .__mmu_off | 1345 | bl .__mmu_off |
1331 | b .__after_prom_start | 1346 | b .__after_prom_start |
1332 | 1347 | ||
@@ -1341,23 +1356,10 @@ _INIT_STATIC(__boot_from_prom) | |||
1341 | /* | 1356 | /* |
1342 | * Align the stack to 16-byte boundary | 1357 | * Align the stack to 16-byte boundary |
1343 | * Depending on the size and layout of the ELF sections in the initial | 1358 | * Depending on the size and layout of the ELF sections in the initial |
1344 | * boot binary, the stack pointer will be unalignet on PowerMac | 1359 | * boot binary, the stack pointer may be unaligned on PowerMac |
1345 | */ | 1360 | */ |
1346 | rldicr r1,r1,0,59 | 1361 | rldicr r1,r1,0,59 |
1347 | 1362 | ||
1348 | /* Make sure we are running in 64 bits mode */ | ||
1349 | bl .enable_64b_mode | ||
1350 | |||
1351 | /* put a relocation offset into r3 */ | ||
1352 | bl .reloc_offset | ||
1353 | |||
1354 | LOAD_REG_IMMEDIATE(r2,__toc_start) | ||
1355 | addi r2,r2,0x4000 | ||
1356 | addi r2,r2,0x4000 | ||
1357 | |||
1358 | /* Relocate the TOC from a virt addr to a real addr */ | ||
1359 | add r2,r2,r3 | ||
1360 | |||
1361 | /* Restore parameters */ | 1363 | /* Restore parameters */ |
1362 | mr r3,r31 | 1364 | mr r3,r31 |
1363 | mr r4,r30 | 1365 | mr r4,r30 |
@@ -1373,53 +1375,37 @@ _INIT_STATIC(__boot_from_prom) | |||
1373 | _STATIC(__after_prom_start) | 1375 | _STATIC(__after_prom_start) |
1374 | 1376 | ||
1375 | /* | 1377 | /* |
1376 | * We need to run with __start at physical address PHYSICAL_START. | 1378 | * We need to run with _stext at physical address PHYSICAL_START. |
1377 | * This will leave some code in the first 256B of | 1379 | * This will leave some code in the first 256B of |
1378 | * real memory, which are reserved for software use. | 1380 | * real memory, which are reserved for software use. |
1379 | * The remainder of the first page is loaded with the fixed | ||
1380 | * interrupt vectors. The next two pages are filled with | ||
1381 | * unknown exception placeholders. | ||
1382 | * | 1381 | * |
1383 | * Note: This process overwrites the OF exception vectors. | 1382 | * Note: This process overwrites the OF exception vectors. |
1384 | * r26 == relocation offset | ||
1385 | * r27 == KERNELBASE | ||
1386 | */ | 1383 | */ |
1387 | bl .reloc_offset | ||
1388 | mr r26,r3 | ||
1389 | LOAD_REG_IMMEDIATE(r27, KERNELBASE) | ||
1390 | |||
1391 | LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */ | 1384 | LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */ |
1392 | 1385 | cmpd r3,r26 /* In some cases the loader may */ | |
1393 | // XXX FIXME: Use phys returned by OF (r30) | 1386 | beq 9f /* have already put us at zero */ |
1394 | add r4,r27,r26 /* source addr */ | 1387 | mr r4,r26 /* source address */ |
1395 | /* current address of _start */ | 1388 | lis r5,(copy_to_here - _stext)@ha |
1396 | /* i.e. where we are running */ | 1389 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ |
1397 | /* the source addr */ | ||
1398 | |||
1399 | cmpdi r4,0 /* In some cases the loader may */ | ||
1400 | bne 1f | ||
1401 | b .start_here_multiplatform /* have already put us at zero */ | ||
1402 | /* so we can skip the copy. */ | ||
1403 | 1: LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ | ||
1404 | sub r5,r5,r27 | ||
1405 | |||
1406 | li r6,0x100 /* Start offset, the first 0x100 */ | 1390 | li r6,0x100 /* Start offset, the first 0x100 */ |
1407 | /* bytes were copied earlier. */ | 1391 | /* bytes were copied earlier. */ |
1408 | 1392 | ||
1409 | bl .copy_and_flush /* copy the first n bytes */ | 1393 | bl .copy_and_flush /* copy the first n bytes */ |
1410 | /* this includes the code being */ | 1394 | /* this includes the code being */ |
1411 | /* executed here. */ | 1395 | /* executed here. */ |
1412 | 1396 | addis r8,r3,(4f - _stext)@ha /* Jump to the copy of this code */ | |
1413 | LOAD_REG_IMMEDIATE(r0, 4f) /* Jump to the copy of this code */ | 1397 | addi r8,r8,(4f - _stext)@l /* that we just made */ |
1414 | mtctr r0 /* that we just made/relocated */ | 1398 | mtctr r8 |
1415 | bctr | 1399 | bctr |
1416 | 1400 | ||
1417 | 4: LOAD_REG_IMMEDIATE(r5,klimit) | 1401 | 4: /* Now copy the rest of the kernel up to _end */ |
1418 | add r5,r5,r26 | 1402 | addis r5,r26,(p_end - _stext)@ha |
1419 | ld r5,0(r5) /* get the value of klimit */ | 1403 | ld r5,(p_end - _stext)@l(r5) /* get _end */ |
1420 | sub r5,r5,r27 | ||
1421 | bl .copy_and_flush /* copy the rest */ | 1404 | bl .copy_and_flush /* copy the rest */ |
1422 | b .start_here_multiplatform | 1405 | |
1406 | 9: b .start_here_multiplatform | ||
1407 | |||
1408 | p_end: .llong _end - _stext | ||
1423 | 1409 | ||
1424 | /* | 1410 | /* |
1425 | * Copy routine used to copy the kernel to start at physical address 0 | 1411 | * Copy routine used to copy the kernel to start at physical address 0 |
@@ -1484,6 +1470,9 @@ _GLOBAL(pmac_secondary_start) | |||
1484 | /* turn on 64-bit mode */ | 1470 | /* turn on 64-bit mode */ |
1485 | bl .enable_64b_mode | 1471 | bl .enable_64b_mode |
1486 | 1472 | ||
1473 | /* get TOC pointer (real address) */ | ||
1474 | bl .relative_toc | ||
1475 | |||
1487 | /* Copy some CPU settings from CPU 0 */ | 1476 | /* Copy some CPU settings from CPU 0 */ |
1488 | bl .__restore_cpu_ppc970 | 1477 | bl .__restore_cpu_ppc970 |
1489 | 1478 | ||
@@ -1493,10 +1482,10 @@ _GLOBAL(pmac_secondary_start) | |||
1493 | mtmsrd r3 /* RI on */ | 1482 | mtmsrd r3 /* RI on */ |
1494 | 1483 | ||
1495 | /* Set up a paca value for this processor. */ | 1484 | /* Set up a paca value for this processor. */ |
1496 | LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ | 1485 | LOAD_REG_ADDR(r4,paca) /* Get base vaddr of paca array */ |
1497 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ | 1486 | mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */ |
1498 | add r13,r13,r4 /* for this processor. */ | 1487 | add r13,r13,r4 /* for this processor. */ |
1499 | mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ | 1488 | mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */ |
1500 | 1489 | ||
1501 | /* Create a temp kernel stack for use before relocation is on. */ | 1490 | /* Create a temp kernel stack for use before relocation is on. */ |
1502 | ld r1,PACAEMERGSP(r13) | 1491 | ld r1,PACAEMERGSP(r13) |
@@ -1524,9 +1513,6 @@ __secondary_start: | |||
1524 | /* Set thread priority to MEDIUM */ | 1513 | /* Set thread priority to MEDIUM */ |
1525 | HMT_MEDIUM | 1514 | HMT_MEDIUM |
1526 | 1515 | ||
1527 | /* Load TOC */ | ||
1528 | ld r2,PACATOC(r13) | ||
1529 | |||
1530 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ | 1516 | /* Do early setup for that CPU (stab, slb, hash table pointer) */ |
1531 | bl .early_setup_secondary | 1517 | bl .early_setup_secondary |
1532 | 1518 | ||
@@ -1563,9 +1549,11 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) | |||
1563 | 1549 | ||
1564 | /* | 1550 | /* |
1565 | * Running with relocation on at this point. All we want to do is | 1551 | * Running with relocation on at this point. All we want to do is |
1566 | * zero the stack back-chain pointer before going into C code. | 1552 | * zero the stack back-chain pointer and get the TOC virtual address |
1553 | * before going into C code. | ||
1567 | */ | 1554 | */ |
1568 | _GLOBAL(start_secondary_prolog) | 1555 | _GLOBAL(start_secondary_prolog) |
1556 | ld r2,PACATOC(r13) | ||
1569 | li r3,0 | 1557 | li r3,0 |
1570 | std r3,0(r1) /* Zero the stack frame pointer */ | 1558 | std r3,0(r1) /* Zero the stack frame pointer */ |
1571 | bl .start_secondary | 1559 | bl .start_secondary |
@@ -1577,34 +1565,46 @@ _GLOBAL(start_secondary_prolog) | |||
1577 | */ | 1565 | */ |
1578 | _GLOBAL(enable_64b_mode) | 1566 | _GLOBAL(enable_64b_mode) |
1579 | mfmsr r11 /* grab the current MSR */ | 1567 | mfmsr r11 /* grab the current MSR */ |
1580 | li r12,1 | 1568 | li r12,(MSR_SF | MSR_ISF)@highest |
1581 | rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) | 1569 | sldi r12,r12,48 |
1582 | or r11,r11,r12 | ||
1583 | li r12,1 | ||
1584 | rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) | ||
1585 | or r11,r11,r12 | 1570 | or r11,r11,r12 |
1586 | mtmsrd r11 | 1571 | mtmsrd r11 |
1587 | isync | 1572 | isync |
1588 | blr | 1573 | blr |
1589 | 1574 | ||
1590 | /* | 1575 | /* |
1576 | * This puts the TOC pointer into r2, offset by 0x8000 (as expected | ||
1577 | * by the toolchain). It computes the correct value for wherever we | ||
1578 | * are running at the moment, using position-independent code. | ||
1579 | */ | ||
1580 | _GLOBAL(relative_toc) | ||
1581 | mflr r0 | ||
1582 | bcl 20,31,$+4 | ||
1583 | 0: mflr r9 | ||
1584 | ld r2,(p_toc - 0b)(r9) | ||
1585 | add r2,r2,r9 | ||
1586 | mtlr r0 | ||
1587 | blr | ||
1588 | |||
1589 | p_toc: .llong __toc_start + 0x8000 - 0b | ||
1590 | |||
1591 | /* | ||
1591 | * This is where the main kernel code starts. | 1592 | * This is where the main kernel code starts. |
1592 | */ | 1593 | */ |
1593 | _INIT_STATIC(start_here_multiplatform) | 1594 | _INIT_STATIC(start_here_multiplatform) |
1594 | /* get a new offset, now that the kernel has moved. */ | 1595 | /* set up the TOC (real address) */ |
1595 | bl .reloc_offset | 1596 | bl .relative_toc |
1596 | mr r26,r3 | ||
1597 | 1597 | ||
1598 | /* Clear out the BSS. It may have been done in prom_init, | 1598 | /* Clear out the BSS. It may have been done in prom_init, |
1599 | * already but that's irrelevant since prom_init will soon | 1599 | * already but that's irrelevant since prom_init will soon |
1600 | * be detached from the kernel completely. Besides, we need | 1600 | * be detached from the kernel completely. Besides, we need |
1601 | * to clear it now for kexec-style entry. | 1601 | * to clear it now for kexec-style entry. |
1602 | */ | 1602 | */ |
1603 | LOAD_REG_IMMEDIATE(r11,__bss_stop) | 1603 | LOAD_REG_ADDR(r11,__bss_stop) |
1604 | LOAD_REG_IMMEDIATE(r8,__bss_start) | 1604 | LOAD_REG_ADDR(r8,__bss_start) |
1605 | sub r11,r11,r8 /* bss size */ | 1605 | sub r11,r11,r8 /* bss size */ |
1606 | addi r11,r11,7 /* round up to an even double word */ | 1606 | addi r11,r11,7 /* round up to an even double word */ |
1607 | rldicl. r11,r11,61,3 /* shift right by 3 */ | 1607 | srdi. r11,r11,3 /* shift right by 3 */ |
1608 | beq 4f | 1608 | beq 4f |
1609 | addi r8,r8,-8 | 1609 | addi r8,r8,-8 |
1610 | li r0,0 | 1610 | li r0,0 |
@@ -1617,35 +1617,28 @@ _INIT_STATIC(start_here_multiplatform) | |||
1617 | ori r6,r6,MSR_RI | 1617 | ori r6,r6,MSR_RI |
1618 | mtmsrd r6 /* RI on */ | 1618 | mtmsrd r6 /* RI on */ |
1619 | 1619 | ||
1620 | /* The following gets the stack and TOC set up with the regs */ | 1620 | /* The following gets the stack set up with the regs */ |
1621 | /* pointing to the real addr of the kernel stack. This is */ | 1621 | /* pointing to the real addr of the kernel stack. This is */ |
1622 | /* all done to support the C function call below which sets */ | 1622 | /* all done to support the C function call below which sets */ |
1623 | /* up the htab. This is done because we have relocated the */ | 1623 | /* up the htab. This is done because we have relocated the */ |
1624 | /* kernel but are still running in real mode. */ | 1624 | /* kernel but are still running in real mode. */ |
1625 | 1625 | ||
1626 | LOAD_REG_IMMEDIATE(r3,init_thread_union) | 1626 | LOAD_REG_ADDR(r3,init_thread_union) |
1627 | add r3,r3,r26 | ||
1628 | 1627 | ||
1629 | /* set up a stack pointer (physical address) */ | 1628 | /* set up a stack pointer */ |
1630 | addi r1,r3,THREAD_SIZE | 1629 | addi r1,r3,THREAD_SIZE |
1631 | li r0,0 | 1630 | li r0,0 |
1632 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | 1631 | stdu r0,-STACK_FRAME_OVERHEAD(r1) |
1633 | 1632 | ||
1634 | /* set up the TOC (physical address) */ | ||
1635 | LOAD_REG_IMMEDIATE(r2,__toc_start) | ||
1636 | addi r2,r2,0x4000 | ||
1637 | addi r2,r2,0x4000 | ||
1638 | add r2,r2,r26 | ||
1639 | |||
1640 | /* Do very early kernel initializations, including initial hash table, | 1633 | /* Do very early kernel initializations, including initial hash table, |
1641 | * stab and slb setup before we turn on relocation. */ | 1634 | * stab and slb setup before we turn on relocation. */ |
1642 | 1635 | ||
1643 | /* Restore parameters passed from prom_init/kexec */ | 1636 | /* Restore parameters passed from prom_init/kexec */ |
1644 | mr r3,r31 | 1637 | mr r3,r31 |
1645 | bl .early_setup | 1638 | bl .early_setup /* also sets r13 and SPRG3 */ |
1646 | 1639 | ||
1647 | LOAD_REG_IMMEDIATE(r3, .start_here_common) | 1640 | LOAD_REG_ADDR(r3, .start_here_common) |
1648 | LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) | 1641 | ld r4,PACAKMSR(r13) |
1649 | mtspr SPRN_SRR0,r3 | 1642 | mtspr SPRN_SRR0,r3 |
1650 | mtspr SPRN_SRR1,r4 | 1643 | mtspr SPRN_SRR1,r4 |
1651 | rfid | 1644 | rfid |
@@ -1654,20 +1647,10 @@ _INIT_STATIC(start_here_multiplatform) | |||
1654 | /* This is where all platforms converge execution */ | 1647 | /* This is where all platforms converge execution */ |
1655 | _INIT_GLOBAL(start_here_common) | 1648 | _INIT_GLOBAL(start_here_common) |
1656 | /* relocation is on at this point */ | 1649 | /* relocation is on at this point */ |
1650 | std r1,PACAKSAVE(r13) | ||
1657 | 1651 | ||
1658 | /* The following code sets up the SP and TOC now that we are */ | 1652 | /* Load the TOC (virtual address) */ |
1659 | /* running with translation enabled. */ | ||
1660 | |||
1661 | LOAD_REG_IMMEDIATE(r3,init_thread_union) | ||
1662 | |||
1663 | /* set up the stack */ | ||
1664 | addi r1,r3,THREAD_SIZE | ||
1665 | li r0,0 | ||
1666 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | ||
1667 | |||
1668 | /* Load the TOC */ | ||
1669 | ld r2,PACATOC(r13) | 1653 | ld r2,PACATOC(r13) |
1670 | std r1,PACAKSAVE(r13) | ||
1671 | 1654 | ||
1672 | bl .setup_system | 1655 | bl .setup_system |
1673 | 1656 | ||
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S index 85cb6f340846..2d29752cbe16 100644 --- a/arch/powerpc/kernel/misc.S +++ b/arch/powerpc/kernel/misc.S | |||
@@ -31,11 +31,14 @@ _GLOBAL(reloc_offset) | |||
31 | mflr r0 | 31 | mflr r0 |
32 | bl 1f | 32 | bl 1f |
33 | 1: mflr r3 | 33 | 1: mflr r3 |
34 | LOAD_REG_IMMEDIATE(r4,1b) | 34 | PPC_LL r4,(2f-1b)(r3) |
35 | subf r3,r4,r3 | 35 | subf r3,r4,r3 |
36 | mtlr r0 | 36 | mtlr r0 |
37 | blr | 37 | blr |
38 | 38 | ||
39 | .align 3 | ||
40 | 2: PPC_LONG 1b | ||
41 | |||
39 | /* | 42 | /* |
40 | * add_reloc_offset(x) returns x + reloc_offset(). | 43 | * add_reloc_offset(x) returns x + reloc_offset(). |
41 | */ | 44 | */ |
@@ -43,12 +46,15 @@ _GLOBAL(add_reloc_offset) | |||
43 | mflr r0 | 46 | mflr r0 |
44 | bl 1f | 47 | bl 1f |
45 | 1: mflr r5 | 48 | 1: mflr r5 |
46 | LOAD_REG_IMMEDIATE(r4,1b) | 49 | PPC_LL r4,(2f-1b)(r5) |
47 | subf r5,r4,r5 | 50 | subf r5,r4,r5 |
48 | add r3,r3,r5 | 51 | add r3,r3,r5 |
49 | mtlr r0 | 52 | mtlr r0 |
50 | blr | 53 | blr |
51 | 54 | ||
55 | .align 3 | ||
56 | 2: PPC_LONG 1b | ||
57 | |||
52 | _GLOBAL(kernel_execve) | 58 | _GLOBAL(kernel_execve) |
53 | li r0,__NR_execve | 59 | li r0,__NR_execve |
54 | sc | 60 | sc |
diff --git a/arch/powerpc/platforms/iseries/exception.S b/arch/powerpc/platforms/iseries/exception.S index 8ff330d026ca..2f581521eb9b 100644 --- a/arch/powerpc/platforms/iseries/exception.S +++ b/arch/powerpc/platforms/iseries/exception.S | |||
@@ -38,12 +38,13 @@ | |||
38 | 38 | ||
39 | .globl system_reset_iSeries | 39 | .globl system_reset_iSeries |
40 | system_reset_iSeries: | 40 | system_reset_iSeries: |
41 | bl .relative_toc | ||
41 | mfspr r13,SPRN_SPRG3 /* Get alpaca address */ | 42 | mfspr r13,SPRN_SPRG3 /* Get alpaca address */ |
42 | LOAD_REG_IMMEDIATE(r23, alpaca) | 43 | LOAD_REG_ADDR(r23, alpaca) |
43 | li r0,ALPACA_SIZE | 44 | li r0,ALPACA_SIZE |
44 | sub r23,r13,r23 | 45 | sub r23,r13,r23 |
45 | divdu r23,r23,r0 /* r23 has cpu number */ | 46 | divdu r23,r23,r0 /* r23 has cpu number */ |
46 | LOAD_REG_IMMEDIATE(r13, paca) | 47 | LOAD_REG_ADDR(r13, paca) |
47 | mulli r0,r23,PACA_SIZE | 48 | mulli r0,r23,PACA_SIZE |
48 | add r13,r13,r0 | 49 | add r13,r13,r0 |
49 | mtspr SPRN_SPRG3,r13 /* Save it away for the future */ | 50 | mtspr SPRN_SPRG3,r13 /* Save it away for the future */ |
@@ -60,14 +61,14 @@ system_reset_iSeries: | |||
60 | mtspr SPRN_CTRLT,r4 | 61 | mtspr SPRN_CTRLT,r4 |
61 | 62 | ||
62 | /* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */ | 63 | /* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */ |
63 | /* In the UP case we'll yeild() later, and we will not access the paca anyway */ | 64 | /* In the UP case we'll yield() later, and we will not access the paca anyway */ |
64 | #ifdef CONFIG_SMP | 65 | #ifdef CONFIG_SMP |
65 | 1: | 66 | 1: |
66 | HMT_LOW | 67 | HMT_LOW |
67 | LOAD_REG_IMMEDIATE(r23, __secondary_hold_spinloop) | 68 | LOAD_REG_ADDR(r23, __secondary_hold_spinloop) |
68 | ld r23,0(r23) | 69 | ld r23,0(r23) |
69 | sync | 70 | sync |
70 | LOAD_REG_IMMEDIATE(r3,current_set) | 71 | LOAD_REG_ADDR(r3,current_set) |
71 | sldi r28,r24,3 /* get current_set[cpu#] */ | 72 | sldi r28,r24,3 /* get current_set[cpu#] */ |
72 | ldx r3,r3,r28 | 73 | ldx r3,r3,r28 |
73 | addi r1,r3,THREAD_SIZE | 74 | addi r1,r3,THREAD_SIZE |
@@ -90,7 +91,7 @@ system_reset_iSeries: | |||
90 | lbz r23,PACAPROCSTART(r13) /* Test if this processor | 91 | lbz r23,PACAPROCSTART(r13) /* Test if this processor |
91 | * should start */ | 92 | * should start */ |
92 | sync | 93 | sync |
93 | LOAD_REG_IMMEDIATE(r3,current_set) | 94 | LOAD_REG_ADDR(r3,current_set) |
94 | sldi r28,r24,3 /* get current_set[cpu#] */ | 95 | sldi r28,r24,3 /* get current_set[cpu#] */ |
95 | ldx r3,r3,r28 | 96 | ldx r3,r3,r28 |
96 | addi r1,r3,THREAD_SIZE | 97 | addi r1,r3,THREAD_SIZE |
@@ -255,8 +256,8 @@ hardware_interrupt_iSeries_masked: | |||
255 | 256 | ||
256 | _INIT_STATIC(__start_initialization_iSeries) | 257 | _INIT_STATIC(__start_initialization_iSeries) |
257 | /* Clear out the BSS */ | 258 | /* Clear out the BSS */ |
258 | LOAD_REG_IMMEDIATE(r11,__bss_stop) | 259 | LOAD_REG_ADDR(r11,__bss_stop) |
259 | LOAD_REG_IMMEDIATE(r8,__bss_start) | 260 | LOAD_REG_ADDR(r8,__bss_start) |
260 | sub r11,r11,r8 /* bss size */ | 261 | sub r11,r11,r8 /* bss size */ |
261 | addi r11,r11,7 /* round up to an even double word */ | 262 | addi r11,r11,7 /* round up to an even double word */ |
262 | rldicl. r11,r11,61,3 /* shift right by 3 */ | 263 | rldicl. r11,r11,61,3 /* shift right by 3 */ |
@@ -267,15 +268,11 @@ _INIT_STATIC(__start_initialization_iSeries) | |||
267 | 3: stdu r0,8(r8) | 268 | 3: stdu r0,8(r8) |
268 | bdnz 3b | 269 | bdnz 3b |
269 | 4: | 270 | 4: |
270 | LOAD_REG_IMMEDIATE(r1,init_thread_union) | 271 | LOAD_REG_ADDR(r1,init_thread_union) |
271 | addi r1,r1,THREAD_SIZE | 272 | addi r1,r1,THREAD_SIZE |
272 | li r0,0 | 273 | li r0,0 |
273 | stdu r0,-STACK_FRAME_OVERHEAD(r1) | 274 | stdu r0,-STACK_FRAME_OVERHEAD(r1) |
274 | 275 | ||
275 | LOAD_REG_IMMEDIATE(r2,__toc_start) | ||
276 | addi r2,r2,0x4000 | ||
277 | addi r2,r2,0x4000 | ||
278 | |||
279 | bl .iSeries_early_setup | 276 | bl .iSeries_early_setup |
280 | bl .early_setup | 277 | bl .early_setup |
281 | 278 | ||