* relocate_kernel.S - put the kernel image in place to boot
* Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
*
- * 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.
#define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */
-/* 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 */
/* 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
addi r8, r8, 4
b 0b
-2:
+3:
/* To be certain of avoiding problems with self-modifying code
* execute a serializing instruction here.