x86, kexec: x86_64: add identity map for pages at image->start
[linux-2.6-block.git] / arch / x86 / kernel / relocate_kernel_64.S
CommitLineData
5234f5eb
EB
1/*
2 * relocate_kernel.S - put the kernel image in place to boot
3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
4 *
5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details.
7 */
8
9#include <linux/linkage.h>
0341c14d 10#include <asm/page_types.h>
4bfaaef0 11#include <asm/kexec.h>
fd3af531 12#include <asm/processor-flags.h>
0341c14d 13#include <asm/pgtable_types.h>
5234f5eb 14
4bfaaef0
MD
15/*
16 * Must be relocatable PIC code callable as a C function
17 */
18
19#define PTR(x) (x << 3)
366932de 20#define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
4bfaaef0
MD
21
22 .text
288621e3 23 .align PAGE_SIZE
5234f5eb 24 .code64
4bfaaef0
MD
25 .globl relocate_kernel
26relocate_kernel:
fef3a7a1
HY
27 /*
28 * %rdi indirection_page
4bfaaef0
MD
29 * %rsi page_list
30 * %rdx start address
31 */
32
5234f5eb
EB
33 /* zero out flags, and disable interrupts */
34 pushq $0
35 popfq
36
fef3a7a1
HY
37 /*
38 * get physical address of control page now
39 * this is impossible after page table switch
40 */
4bfaaef0
MD
41 movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
42
43 /* get physical address of page table now too */
44 movq PTR(PA_TABLE_PAGE)(%rsi), %rcx
5234f5eb 45
f5deb796
HY
46 /* Switch to the identity mapped page tables */
47 movq %rcx, %cr3
4bfaaef0
MD
48
49 /* setup a new stack at the end of the physical control page */
a7bba17b 50 lea PAGE_SIZE(%r8), %rsp
4bfaaef0
MD
51
52 /* jump to identity mapped page */
53 addq $(identity_mapped - relocate_kernel), %r8
54 pushq %r8
55 ret
56
57identity_mapped:
58 /* store the start address on the stack */
59 pushq %rdx
5234f5eb 60
fef3a7a1
HY
61 /*
62 * Set cr0 to a known state:
fd3af531 63 * - Paging enabled
64 * - Alignment check disabled
65 * - Write protect disabled
66 * - No task switch
67 * - Don't do FP software emulation.
68 * - Proctected mode enabled
5234f5eb
EB
69 */
70 movq %cr0, %rax
fd3af531 71 andq $~(X86_CR0_AM | X86_CR0_WP | X86_CR0_TS | X86_CR0_EM), %rax
72 orl $(X86_CR0_PG | X86_CR0_PE), %eax
5234f5eb
EB
73 movq %rax, %cr0
74
fef3a7a1
HY
75 /*
76 * Set cr4 to a known state:
fd3af531 77 * - physical address extension enabled
5234f5eb 78 */
fd3af531 79 movq $X86_CR4_PAE, %rax
5234f5eb
EB
80 movq %rax, %cr4
81
82 jmp 1f
831:
84
f5deb796 85 /* Flush the TLB (needed?) */
5234f5eb
EB
86 movq %rcx, %cr3
87
88 /* Do the copies */
89 movq %rdi, %rcx /* Put the page_list in %rcx */
90 xorq %rdi, %rdi
91 xorq %rsi, %rsi
92 jmp 1f
93
940: /* top, read another word for the indirection page */
95
96 movq (%rbx), %rcx
97 addq $8, %rbx
981:
99 testq $0x1, %rcx /* is it a destination page? */
100 jz 2f
101 movq %rcx, %rdi
102 andq $0xfffffffffffff000, %rdi
103 jmp 0b
1042:
105 testq $0x2, %rcx /* is it an indirection page? */
106 jz 2f
107 movq %rcx, %rbx
108 andq $0xfffffffffffff000, %rbx
109 jmp 0b
1102:
111 testq $0x4, %rcx /* is it the done indicator? */
112 jz 2f
113 jmp 3f
1142:
115 testq $0x8, %rcx /* is it the source indicator? */
116 jz 0b /* Ignore it otherwise */
117 movq %rcx, %rsi /* For ever source page do a copy */
118 andq $0xfffffffffffff000, %rsi
119
120 movq $512, %rcx
121 rep ; movsq
122 jmp 0b
1233:
124
fef3a7a1
HY
125 /*
126 * To be certain of avoiding problems with self-modifying code
5234f5eb
EB
127 * I need to execute a serializing instruction here.
128 * So I flush the TLB by reloading %cr3 here, it's handy,
129 * and not processor dependent.
130 */
131 movq %cr3, %rax
132 movq %rax, %cr3
133
fef3a7a1
HY
134 /*
135 * set all of the registers to known values
136 * leave %rsp alone
137 */
5234f5eb
EB
138
139 xorq %rax, %rax
140 xorq %rbx, %rbx
141 xorq %rcx, %rcx
142 xorq %rdx, %rdx
143 xorq %rsi, %rsi
144 xorq %rdi, %rdi
145 xorq %rbp, %rbp
146 xorq %r8, %r8
147 xorq %r9, %r9
148 xorq %r10, %r9
149 xorq %r11, %r11
150 xorq %r12, %r12
151 xorq %r13, %r13
152 xorq %r14, %r14
153 xorq %r15, %r15
154
155 ret