This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / x86_64 / kernel / relocate_kernel.S
1 /*
2  * relocate_kernel.S - put the kernel image in place to boot
3  * Copyright (C) 2002-2004 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>
10
11         /*
12          * Must be relocatable PIC code callable as a C function, that once
13          * it starts can not use the previous processes stack.
14          */
15         .globl relocate_new_kernel
16         .code64
17 relocate_new_kernel:
18         /* %rdi indirection_page
19          * %rsi reboot_code_buffer
20          * %rdx start address
21          * %rcx page_table
22          * %r8  arg5
23          * %r9  arg6
24          */
25
26         /* zero out flags, and disable interrupts */
27         pushq $0
28         popfq
29
30         /* set a new stack at the bottom of our page... */
31         lea   4096(%rsi), %rsp
32
33         /* store the parameters back on the stack */
34         pushq   %rdx /* store the start address */
35
36         /* Set cr0 to a known state:
37          * 31 1 == Paging enabled
38          * 18 0 == Alignment check disabled
39          * 16 0 == Write protect disabled
40          * 3  0 == No task switch
41          * 2  0 == Don't do FP software emulation.
42          * 0  1 == Proctected mode enabled
43          */
44         movq    %cr0, %rax
45         andq    $~((1<<18)|(1<<16)|(1<<3)|(1<<2)), %rax
46         orl     $((1<<31)|(1<<0)), %eax
47         movq    %rax, %cr0
48
49         /* Set cr4 to a known state:
50          * 10 0 == xmm exceptions disabled
51          * 9  0 == xmm registers instructions disabled
52          * 8  0 == performance monitoring counter disabled
53          * 7  0 == page global disabled
54          * 6  0 == machine check exceptions disabled
55          * 5  1 == physical address extension enabled
56          * 4  0 == page size extensions disabled
57          * 3  0 == Debug extensions disabled
58          * 2  0 == Time stamp disable (disabled)
59          * 1  0 == Protected mode virtual interrupts disabled
60          * 0  0 == VME disabled
61          */
62
63         movq    $((1<<5)), %rax
64         movq    %rax, %cr4
65
66         jmp 1f
67 1:
68
69         /* Switch to the identity mapped page tables,
70          * and flush the TLB.
71         */
72         movq    %rcx, %cr3
73
74         /* Do the copies */
75         movq    %rdi, %rbx      /* Put the indirection page in %rbx */
76         xorq    %rdi, %rdi
77         xorq    %rsi, %rsi
78
79 0:      /* top, read another word for the indirection page */
80
81         movq    (%rbx), %rcx
82         addq    $8,     %rbx
83         testq   $0x1,   %rcx  /* is it a destination page? */
84         jz      1f
85         movq    %rcx,   %rdi
86         andq    $0xfffffffffffff000, %rdi
87         jmp     0b
88 1:
89         testq   $0x2,   %rcx  /* is it an indirection page? */
90         jz      1f
91         movq    %rcx,   %rbx
92         andq    $0xfffffffffffff000, %rbx
93         jmp     0b
94 1:
95         testq   $0x4,   %rcx  /* is it the done indicator? */
96         jz      1f
97         jmp     2f
98 1:
99         testq   $0x8,   %rcx  /* is it the source indicator? */
100         jz      0b            /* Ignore it otherwise */
101         movq    %rcx,   %rsi  /* For ever source page do a copy */
102         andq    $0xfffffffffffff000, %rsi
103
104         movq    $512,   %rcx
105         rep ; movsq
106         jmp     0b
107 2:
108
109         /* To be certain of avoiding problems with self-modifying code
110          * I need to execute a serializing instruction here.
111          * So I flush the TLB by reloading %cr3 here, it's handy,
112          * and not processor dependent.
113          */
114         movq    %cr3, %rax
115         movq    %rax, %cr3
116
117         /* set all of the registers to known values */
118         /* leave %rsp alone */
119
120         xorq    %rax, %rax
121         xorq    %rbx, %rbx
122         xorq    %rcx, %rcx
123         xorq    %rdx, %rdx
124         xorq    %rsi, %rsi
125         xorq    %rdi, %rdi
126         xorq    %rbp, %rbp
127         xorq    %r8,  %r8
128         xorq    %r9,  %r9
129         xorq    %r10, %r9
130         xorq    %r11, %r11
131         xorq    %r12, %r12
132         xorq    %r13, %r13
133         xorq    %r14, %r14
134         xorq    %r15, %r15
135
136         ret
137 relocate_new_kernel_end:
138
139         .globl relocate_new_kernel_size
140 relocate_new_kernel_size:
141         .quad relocate_new_kernel_end - relocate_new_kernel