diff options
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r-- | arch/powerpc/kernel/head_64.S | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 6cdfd44d8efe..84856bee33a5 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -1360,6 +1360,12 @@ _INIT_STATIC(__boot_from_prom) | |||
1360 | */ | 1360 | */ |
1361 | rldicr r1,r1,0,59 | 1361 | rldicr r1,r1,0,59 |
1362 | 1362 | ||
1363 | #ifdef CONFIG_RELOCATABLE | ||
1364 | /* Relocate code for where we are now */ | ||
1365 | mr r3,r26 | ||
1366 | bl .relocate | ||
1367 | #endif | ||
1368 | |||
1363 | /* Restore parameters */ | 1369 | /* Restore parameters */ |
1364 | mr r3,r31 | 1370 | mr r3,r31 |
1365 | mr r4,r30 | 1371 | mr r4,r30 |
@@ -1368,11 +1374,19 @@ _INIT_STATIC(__boot_from_prom) | |||
1368 | mr r7,r27 | 1374 | mr r7,r27 |
1369 | 1375 | ||
1370 | /* Do all of the interaction with OF client interface */ | 1376 | /* Do all of the interaction with OF client interface */ |
1377 | mr r8,r26 | ||
1371 | bl .prom_init | 1378 | bl .prom_init |
1372 | /* We never return */ | 1379 | /* We never return */ |
1373 | trap | 1380 | trap |
1374 | 1381 | ||
1375 | _STATIC(__after_prom_start) | 1382 | _STATIC(__after_prom_start) |
1383 | #ifdef CONFIG_RELOCATABLE | ||
1384 | /* process relocations for the final address of the kernel */ | ||
1385 | lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ | ||
1386 | sldi r25,r25,32 | ||
1387 | mr r3,r25 | ||
1388 | bl .relocate | ||
1389 | #endif | ||
1376 | 1390 | ||
1377 | /* | 1391 | /* |
1378 | * We need to run with _stext at physical address PHYSICAL_START. | 1392 | * We need to run with _stext at physical address PHYSICAL_START. |
@@ -1381,10 +1395,9 @@ _STATIC(__after_prom_start) | |||
1381 | * | 1395 | * |
1382 | * Note: This process overwrites the OF exception vectors. | 1396 | * Note: This process overwrites the OF exception vectors. |
1383 | */ | 1397 | */ |
1384 | LOAD_REG_IMMEDIATE(r3, PHYSICAL_START) /* target addr */ | 1398 | li r3,0 /* target addr */ |
1385 | cmpd r3,r26 /* In some cases the loader may */ | 1399 | mr. r4,r26 /* In some cases the loader may */ |
1386 | beq 9f /* have already put us at zero */ | 1400 | beq 9f /* have already put us at zero */ |
1387 | mr r4,r26 /* source address */ | ||
1388 | lis r5,(copy_to_here - _stext)@ha | 1401 | lis r5,(copy_to_here - _stext)@ha |
1389 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ | 1402 | addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ |
1390 | li r6,0x100 /* Start offset, the first 0x100 */ | 1403 | li r6,0x100 /* Start offset, the first 0x100 */ |
@@ -1617,6 +1630,13 @@ _INIT_STATIC(start_here_multiplatform) | |||
1617 | ori r6,r6,MSR_RI | 1630 | ori r6,r6,MSR_RI |
1618 | mtmsrd r6 /* RI on */ | 1631 | mtmsrd r6 /* RI on */ |
1619 | 1632 | ||
1633 | #ifdef CONFIG_RELOCATABLE | ||
1634 | /* Save the physical address we're running at in kernstart_addr */ | ||
1635 | LOAD_REG_ADDR(r4, kernstart_addr) | ||
1636 | clrldi r0,r25,2 | ||
1637 | std r0,0(r4) | ||
1638 | #endif | ||
1639 | |||
1620 | /* The following gets the stack set up with the regs */ | 1640 | /* The following gets the stack set up with the regs */ |
1621 | /* pointing to the real addr of the kernel stack. This is */ | 1641 | /* pointing to the real addr of the kernel stack. This is */ |
1622 | /* all done to support the C function call below which sets */ | 1642 | /* all done to support the C function call below which sets */ |