aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-08-29 21:41:12 -0400
committerPaul Mackerras <paulus@samba.org>2008-09-15 14:08:35 -0400
commite31aa453bbc4886a7bd33e5c2afa526d6f55bd7a (patch)
treefefa13c13d7b1803fdaeb92143f83b1971f0ec8d
parent1f6a93e4c35e75d547b51f56ba8139ab1a91628c (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>
-rw-r--r--arch/powerpc/include/asm/ppc_asm.h2
-rw-r--r--arch/powerpc/kernel/cpu_setup_ppc970.S4
-rw-r--r--arch/powerpc/kernel/entry_64.S16
-rw-r--r--arch/powerpc/kernel/head_64.S181
-rw-r--r--arch/powerpc/kernel/misc.S10
-rw-r--r--arch/powerpc/platforms/iseries/exception.S23
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 0966899d974..c4a029ccb4d 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 bf118c38575..27f2507279d 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 55445f1dba8..fd8b4bae9b0 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
7540: 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
7721: .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 97bb6e6f67b..6cdfd44d8ef 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. */
135100: ld r4,__secondary_hold_spinloop@l(0) 135100: 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 */
12321: lhz r6,PACAHWCPUID(r13) /* Load HW procid from paca */ 12351: 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
13150: 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)
13241: bl .__cpu_preinit_ppc970 13411: bl .__cpu_preinit_ppc970
13252: 13422:
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. */
14031: 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
14174: LOAD_REG_IMMEDIATE(r5,klimit) 14014: /* 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
14069: b .start_here_multiplatform
1407
1408p_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
15830: mflr r9
1584 ld r2,(p_toc - 0b)(r9)
1585 add r2,r2,r9
1586 mtlr r0
1587 blr
1588
1589p_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 85cb6f34084..2d29752cbe1 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
331: mflr r3 331: 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
402: 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
451: mflr r5 481: 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
562: 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 8ff330d026c..2f581521eb9 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
40system_reset_iSeries: 40system_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
651: 661:
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)
2673: stdu r0,8(r8) 2683: stdu r0,8(r8)
268 bdnz 3b 269 bdnz 3b
2694: 2704:
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