Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/book3e: support CONFIG_RELOCATABLE

book3e is different with book3s since 3s includes the exception
vectors code in head_64.S as it relies on absolute addressing
which is only possible within this compilation unit. So we have
to get that label address with got.

And when boot a relocated kernel, we should reset ipvr properly again
after .relocate.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood: cleanup and ifdef removal]
Signed-off-by: Scott Wood <scottwood@freescale.com>

authored by

Tiejun Chen and committed by
Scott Wood
1cb6e064 835c031c

+28 -7
+2 -2
arch/powerpc/include/asm/exception-64e.h
··· 204 204 #endif 205 205 206 206 #define SET_IVOR(vector_number, vector_offset) \ 207 - li r3,vector_offset@l; \ 208 - ori r3,r3,interrupt_base_book3e@l; \ 207 + LOAD_REG_ADDR(r3,interrupt_base_book3e);\ 208 + ori r3,r3,vector_offset@l; \ 209 209 mtspr SPRN_IVOR##vector_number,r3; 210 210 211 211 #endif /* _ASM_POWERPC_EXCEPTION_64E_H */
+7 -2
arch/powerpc/kernel/exceptions-64e.S
··· 1351 1351 * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping 1352 1352 */ 1353 1353 /* Now we branch the new virtual address mapped by this entry */ 1354 - LOAD_REG_IMMEDIATE(r6,2f) 1354 + bl 1f /* Find our address */ 1355 + 1: mflr r6 1356 + addi r6,r6,(2f - 1b) 1357 + tovirt(r6,r6) 1355 1358 lis r7,MSR_KERNEL@h 1356 1359 ori r7,r7,MSR_KERNEL@l 1357 1360 mtspr SPRN_SRR0,r6 ··· 1586 1583 mflr r28 1587 1584 b 3b 1588 1585 1586 + .globl init_core_book3e 1589 1587 init_core_book3e: 1590 1588 /* Establish the interrupt vector base */ 1591 - LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e) 1589 + tovirt(r2,r2) 1590 + LOAD_REG_ADDR(r3, interrupt_base_book3e) 1592 1591 mtspr SPRN_IVPR,r3 1593 1592 sync 1594 1593 blr
+19 -3
arch/powerpc/kernel/head_64.S
··· 457 457 /* process relocations for the final address of the kernel */ 458 458 lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ 459 459 sldi r25,r25,32 460 + #if defined(CONFIG_PPC_BOOK3E) 461 + tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */ 462 + #endif 460 463 lwz r7,__run_at_load-_stext(r26) 464 + #if defined(CONFIG_PPC_BOOK3E) 465 + tophys(r26,r26) 466 + #endif 461 467 cmplwi cr0,r7,1 /* flagged to stay where we are ? */ 462 468 bne 1f 463 469 add r25,r25,r26 464 470 1: mr r3,r25 465 471 bl relocate 472 + #if defined(CONFIG_PPC_BOOK3E) 473 + /* IVPR needs to be set after relocation. */ 474 + bl init_core_book3e 475 + #endif 466 476 #endif 467 477 468 478 /* ··· 500 490 * variable __run_at_load, if it is set the kernel is treated as relocatable 501 491 * kernel, otherwise it will be moved to PHYSICAL_START 502 492 */ 493 + #if defined(CONFIG_PPC_BOOK3E) 494 + tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */ 495 + #endif 503 496 lwz r7,__run_at_load-_stext(r26) 504 497 cmplwi cr0,r7,1 505 498 bne 3f 506 499 500 + #ifdef CONFIG_PPC_BOOK3E 501 + LOAD_REG_ADDR(r5, __end_interrupts) 502 + LOAD_REG_ADDR(r11, _stext) 503 + sub r5,r5,r11 504 + #else 507 505 /* just copy interrupts */ 508 506 LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext) 507 + #endif 509 508 b 5f 510 509 3: 511 510 #endif ··· 533 514 p_end: .llong _end - _stext 534 515 535 516 4: /* Now copy the rest of the kernel up to _end */ 536 - #if defined(CONFIG_PPC_BOOK3E) 537 - tovirt(r26,r26) 538 - #endif 539 517 addis r5,r26,(p_end - _stext)@ha 540 518 ld r5,(p_end - _stext)@l(r5) /* get _end */ 541 519 5: bl copy_and_flush /* copy the rest */