X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fkernel%2Frelocate_kernel.S;fp=arch%2Fppc%2Fkernel%2Frelocate_kernel.S;h=9b2ad48e988c45bc3e18c5dee7834788aa299e03;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=837e5965adef8f645eb4550fb6ab81488da0a927;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S index 837e5965a..9b2ad48e9 100644 --- a/arch/ppc/kernel/relocate_kernel.S +++ b/arch/ppc/kernel/relocate_kernel.S @@ -2,7 +2,7 @@ * relocate_kernel.S - put the kernel image in place to boot * Copyright (C) 2002-2003 Eric Biederman * - * GAMECUBE/PPC32 port Copyright (C) 2004 Albert Herranz + * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz * * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. @@ -16,37 +16,31 @@ #define PAGE_SIZE 4096 /* must be same value as in */ -/* returns r3 = relocated address of sym */ -/* modifies r0 */ -#define RELOC_SYM(sym) \ - mflr r3; \ - bl 1f; \ -1: mflr r0; \ - mtlr r3; \ - lis r3, 1b@ha; \ - ori r3, r3, 1b@l; \ - subf r0, r3, r0; \ - lis r3, sym@ha; \ - ori r3, r3, sym@l; \ - add r3, r3, r0 - /* * Must be relocatable PIC code callable as a C function. */ .globl relocate_new_kernel relocate_new_kernel: - /* r3 = indirection_page */ + /* r3 = page_list */ /* r4 = reboot_code_buffer */ /* r5 = start_address */ li r0, 0 - /* Set Machine Status Register to a known status */ + /* + * Set Machine Status Register to a known status, + * switch the MMU off and jump to 1: in a single step. + */ + mr r8, r0 ori r8, r8, MSR_RI|MSR_ME - mtmsr r8 - isync + mtspr SPRN_SRR1, r8 + addi r8, r4, 1f - relocate_new_kernel + mtspr SPRN_SRR0, r8 + sync + rfi +1: /* from this point address translation is turned off */ /* and interrupts are disabled */ @@ -57,32 +51,34 @@ relocate_new_kernel: /* Do the copies */ li r6, 0 /* checksum */ - subi r3, r3, 4 + mr r0, r3 + b 1f 0: /* top, read another word for the indirection page */ lwzu r0, 4(r3) +1: /* is it a destination page? (r8) */ rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */ - beq 1f + beq 2f rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */ b 0b -1: /* is it an indirection page? (r3) */ +2: /* is it an indirection page? (r3) */ rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */ - beq 1f + beq 2f rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */ subi r3, r3, 4 b 0b -1: /* are we done? */ +2: /* are we done? */ rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */ - beq 1f - b 2f + beq 2f + b 3f -1: /* is it a source page? (r9) */ +2: /* is it a source page? (r9) */ rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */ beq 0b @@ -105,7 +101,7 @@ relocate_new_kernel: addi r8, r8, 4 b 0b -2: +3: /* To be certain of avoiding problems with self-modifying code * execute a serializing instruction here.