Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/sh64-2.6
[deliverable/linux.git] / arch / ppc / kernel / relocate_kernel.S
CommitLineData
70765aa4
EB
1/*
2 * relocate_kernel.S - put the kernel image in place to boot
3 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
4 *
5 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
6 *
7 * This source code is licensed under the GNU General Public License,
8 * Version 2. See the file COPYING for more details.
9 */
10
11#include <asm/reg.h>
12#include <asm/ppc_asm.h>
13#include <asm/processor.h>
14
15#include <asm/kexec.h>
16
17#define PAGE_SIZE 4096 /* must be same value as in <asm/page.h> */
18
19 /*
20 * Must be relocatable PIC code callable as a C function.
21 */
22 .globl relocate_new_kernel
23relocate_new_kernel:
24 /* r3 = page_list */
25 /* r4 = reboot_code_buffer */
26 /* r5 = start_address */
27
28 li r0, 0
29
30 /*
31 * Set Machine Status Register to a known status,
32 * switch the MMU off and jump to 1: in a single step.
33 */
34
35 mr r8, r0
36 ori r8, r8, MSR_RI|MSR_ME
ee93b43a 37 mtspr SPRN_SRR1, r8
70765aa4 38 addi r8, r4, 1f - relocate_new_kernel
ee93b43a 39 mtspr SPRN_SRR0, r8
70765aa4
EB
40 sync
41 rfi
42
431:
44 /* from this point address translation is turned off */
45 /* and interrupts are disabled */
46
47 /* set a new stack at the bottom of our page... */
48 /* (not really needed now) */
49 addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */
50 stw r0, 0(r1)
51
52 /* Do the copies */
53 li r6, 0 /* checksum */
54 mr r0, r3
55 b 1f
56
570: /* top, read another word for the indirection page */
58 lwzu r0, 4(r3)
59
601:
61 /* is it a destination page? (r8) */
62 rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */
63 beq 2f
64
65 rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */
66 b 0b
67
682: /* is it an indirection page? (r3) */
69 rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */
70 beq 2f
71
72 rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */
73 subi r3, r3, 4
74 b 0b
75
762: /* are we done? */
77 rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */
78 beq 2f
79 b 3f
80
812: /* is it a source page? (r9) */
82 rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */
83 beq 0b
84
85 rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */
86
87 li r7, PAGE_SIZE / 4
88 mtctr r7
89 subi r9, r9, 4
90 subi r8, r8, 4
919:
92 lwzu r0, 4(r9) /* do the copy */
93 xor r6, r6, r0
94 stwu r0, 4(r8)
95 dcbst 0, r8
96 sync
97 icbi 0, r8
98 bdnz 9b
99
100 addi r9, r9, 4
101 addi r8, r8, 4
102 b 0b
103
1043:
105
106 /* To be certain of avoiding problems with self-modifying code
107 * execute a serializing instruction here.
108 */
109 isync
110 sync
111
112 /* jump to the entry point, usually the setup routine */
113 mtlr r5
114 blrl
115
1161: b 1b
117
118relocate_new_kernel_end:
119
120 .globl relocate_new_kernel_size
121relocate_new_kernel_size:
122 .long relocate_new_kernel_end - relocate_new_kernel
123
This page took 0.214665 seconds and 5 git commands to generate.