2009-07-15 Pavel Roskin <proski@gnu.org>
[grub2/jjazz.git] / loader / i386 / xnu_helper.S
blob4250c58ad3563285918341e0b3bda31e3222234a
1 /*
2  *  GRUB  --  GRand Unified Bootloader
3  *  Copyright (C) 2009  Free Software Foundation, Inc.
4  *
5  *  GRUB is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  GRUB is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17  */
19 #include <grub/symbol.h>
22         .p2align        4       /* force 16-byte alignment */
24 VARIABLE(grub_xnu_launcher_start)
25 base:
26         cli
28 #ifndef __x86_64__
29         /* mov imm32, %eax */
30         .byte   0xb8
31 VARIABLE(grub_xnu_heap_will_be_at)
32         .long 0
33         mov %eax, %edi
35         /* mov imm32, %eax */
36         .byte   0xb8
37 VARIABLE(grub_xnu_heap_start)
38         .long 0
39         mov %eax, %esi
41         /* mov imm32, %ecx */
42         .byte   0xb9
43 VARIABLE(grub_xnu_heap_size)
44         .long 0
45         mov %edi, %eax
46         add %ecx, %eax
47         /* %rax now contains our starting position after relocation. */
48         /* One more page to copy: ourselves. */
49         add $0x403, %ecx
50         shr $2, %ecx
52         /* Forward copy.  */
53         cld
54         rep
55         movsl
57         mov %eax, %esi
58         add $(cont0-base), %eax
59         jmp *%eax
60 cont0:
61 #else
62         xorq %rax, %rax
64         /* mov imm32, %eax */
65         .byte   0xb8
66 VARIABLE(grub_xnu_heap_will_be_at)
67         .long 0
68         mov %rax, %rdi
70         /* mov imm32, %rax */
71         .byte   0x48
72         .byte   0xb8
73 VARIABLE(grub_xnu_heap_start)
74         .long 0
75         .long 0
76         mov %rax, %rsi
78         /* mov imm32, %rcx */
79         .byte   0x48
80         .byte   0xb9
81 VARIABLE(grub_xnu_heap_size)
82         .long 0
83         .long 0
84         mov %rdi, %rax
85         add %rcx, %rax
86         /* %rax now contains our starting position after relocation. */
87         /* One more page to copy: ourselves. */
88         add $0x403, %rcx
89         shr $2, %rcx
91         /* Forward copy.  */
92         cld
93         rep
94         movsl
96         mov %rax, %rsi
97 #ifdef APPLE_CC
98         add $(cont0-base), %eax
99 #else
100         add $(cont0-base), %rax
101 #endif
102         jmp *%rax
104 cont0:
105 #ifdef APPLE_CC
106         lea (cont1 - base) (%esi, 1), %eax
107         mov %eax, (jump_vector - base) (%esi, 1)
109         lea (gdt - base) (%esi, 1), %eax
110         mov %eax, (gdt_addr - base) (%esi, 1)
112         /* Switch to compatibility mode. */
114         lgdt (gdtdesc - base) (%esi, 1)
116         /* Update %cs. Thanks to David Miller for pointing this mistake out. */
117         ljmp *(jump_vector - base) (%esi,1)
118 #else
119         lea (cont1 - base) (%rsi, 1), %rax
120         mov %eax, (jump_vector - base) (%rsi, 1)
122         lea (gdt - base) (%rsi, 1), %rax
123         mov %rax, (gdt_addr - base) (%rsi, 1)
125         /* Switch to compatibility mode. */
127         lgdt (gdtdesc - base) (%rsi, 1)
129         /* Update %cs. Thanks to David Miller for pointing this mistake out. */
130         ljmp *(jump_vector - base) (%rsi, 1)
131 #endif
133 cont1:
134         .code32
136         /* Update other registers. */
137         mov $0x18, %eax
138         mov %eax, %ds
139         mov %eax, %es
140         mov %eax, %fs
141         mov %eax, %gs
142         mov %eax, %ss
144         /* Disable paging. */
145         mov %cr0, %eax
146         and $0x7fffffff, %eax
147         mov %eax, %cr0
149         /* Disable amd64. */
150         mov $0xc0000080, %ecx
151         rdmsr
152         and $0xfffffeff, %eax
153         wrmsr
155         /* Turn off PAE. */
156         movl %cr4, %eax
157         and $0xffffffcf, %eax
158         mov %eax, %cr4
160         jmp cont2
161 cont2:
162 #endif
163         .code32
165         /* Registers on XNU boot: eip, esp and eax. */
166         /* mov imm32, %ecx */
167         .byte   0xb9
168 VARIABLE (grub_xnu_entry_point)
169         .long 0
170         /* mov imm32, %eax */
171         .byte   0xb8
172 VARIABLE (grub_xnu_arg1)
173         .long 0
174         /* mov imm32, %ebx */
175         .byte   0xbb
176 VARIABLE (grub_xnu_stack)
177         .long 0
179         movl %ebx, %esp
181         jmp *%ecx
183 #ifdef __x86_64__
184         /* GDT. Copied from loader/i386/linux.c. */
185         .p2align 4
186 gdt:
187         /* NULL.  */
188         .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
190         /* Reserved.  */
191         .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
193         /* Code segment.  */
194         .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
196         /* Data segment.  */
197         .byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
199 gdtdesc:
200         .word 31
201 gdt_addr:
202         /* Filled by the code. */
203         .quad 0
205         .p2align 4
206 jump_vector:
207         /* Jump location. Is filled by the code */
208         .long 0
209         .long 0x10
210 #endif
211 VARIABLE(grub_xnu_launcher_end)