Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / common / boot / grub2 / kern / i386 / loader.S
blob8f146d92e8f89e4d0934aefdaf7f90f52427520e
1 /*
2  *  GRUB  --  GRand Unified Bootloader
3  *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 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  */
21  * Note: These functions defined in this file may be called from C.
22  *       Be careful of that you must not modify some registers. Quote
23  *       from gcc-2.95.2/gcc/config/i386/i386.h:
25    1 for registers not available across function calls.
26    These must include the FIXED_REGISTERS and also any
27    registers that can be used without being saved.
28    The latter must include the registers where values are returned
29    and the register where structure-value addresses are passed.
30    Aside from that, you can include as many other registers as you like.
32   ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
33 {  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
34  */
37  * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
38  *       So the first three arguments are passed in %eax, %edx, and %ecx,
39  *       respectively, and if a function has a fixed number of arguments
40  *       and the number if greater than three, the function must return
41  *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
42  */
45  *  This is the area for all of the special variables.
46  */
48         .p2align        2       /* force 4-byte alignment */
51  * void grub_linux_boot_zimage (void)
52  */
53 VARIABLE(grub_linux_prot_size)
54         .long   0
55 VARIABLE(grub_linux_tmp_addr)
56         .long   0
57 VARIABLE(grub_linux_real_addr)
58         .long   0
59 VARIABLE(grub_linux_is_bzimage)
60         .long   0
62 FUNCTION(grub_linux_boot)
63         /* Must be done before zImage copy.  */
64         call    EXT_C(grub_dl_unload_all)
66         movl    EXT_C(grub_linux_is_bzimage), %ebx
67         test    %ebx, %ebx
68         jne bzimage
70         /* copy the kernel */
71         movl    EXT_C(grub_linux_prot_size), %ecx
72         addl    $3, %ecx
73         shrl    $2, %ecx
74         movl    $GRUB_LINUX_BZIMAGE_ADDR, %esi
75         movl    $GRUB_LINUX_ZIMAGE_ADDR, %edi
76         cld
77         rep
78         movsl
80 bzimage:
81         movl    EXT_C(grub_linux_real_addr), %ebx
83         /* copy the real mode code */
84         movl    EXT_C(grub_linux_tmp_addr), %esi
85         movl    %ebx, %edi
86         movl    $GRUB_LINUX_SETUP_MOVE_SIZE, %ecx
87         cld
88         rep
89         movsb
91         /* change %ebx to the segment address */
92         shrl    $4, %ebx
93         movl    %ebx, %eax
94         addl    $0x20, %eax
95         movw    %ax, linux_setup_seg
97         /* XXX new stack pointer in safe area for calling functions */
98         movl    $0x4000, %esp
99         call    EXT_C(grub_stop_floppy)
101         /* final setup for linux boot */
102         call    prot_to_real
103         .code16
105         cli
106         movw    %bx, %ss
107         movw    $GRUB_LINUX_SETUP_STACK, %sp
109         movw    %bx, %ds
110         movw    %bx, %es
111         movw    %bx, %fs
112         movw    %bx, %gs
114         /* ljmp */
115         .byte   0xea
116         .word   0
117 linux_setup_seg:
118         .word   0
119         .code32
123  * This starts the multiboot kernel.
124  */
126 VARIABLE(grub_multiboot_payload_size)
127         .long   0
128 VARIABLE(grub_multiboot_payload_orig)
129         .long   0
130 VARIABLE(grub_multiboot_payload_dest)
131         .long   0
132 VARIABLE(grub_multiboot_payload_entry_offset)
133         .long   0
136  * The relocators below understand the following parameters:
137  * ecx: Size of the block to be copied.
138  * esi: Where to copy from (always lowest address, even if we're relocating
139  *      backwards).
140  * edi: Where to copy to (likewise).
141  * edx: Offset of the entry point (relative to the beginning of the block).
142  */
143 VARIABLE(grub_multiboot_forward_relocator)
144         cld
145         addl    %edi, %edx
146         rep
147         movsb
148         jmp     *%edx
149 VARIABLE(grub_multiboot_forward_relocator_end)
151 VARIABLE(grub_multiboot_backward_relocator)
152         std
153         addl    %ecx, %esi
154         addl    %ecx, %edi
155         /* backward movsb is implicitly off-by-one.  compensate that. */
156         incl    %ecx
157         rep
158         movsb
159         /* same problem again. */
160         incl    %edi
161         addl    %edi, %edx
162         jmp     *%edx
163 VARIABLE(grub_multiboot_backward_relocator_end)
165 FUNCTION(grub_multiboot_real_boot)
166         /* Push the entry address on the stack.  */
167         pushl   %eax
168         /* Move the address of the multiboot information structure to ebx.  */
169         movl    %edx,%ebx
171         /* Unload all modules and stop the floppy driver.  */
172         call    EXT_C(grub_dl_unload_all)
173         call    EXT_C(grub_stop_floppy)
175         /* Interrupts should be disabled.  */
176         cli
178         /* Where do we copy what from.  */
179         movl    EXT_C(grub_multiboot_payload_size), %ecx
180         movl    EXT_C(grub_multiboot_payload_orig), %esi
181         movl    EXT_C(grub_multiboot_payload_dest), %edi
182         movl    EXT_C(grub_multiboot_payload_entry_offset), %edx
184         /* Move the magic value into eax.  */
185         movl    $MULTIBOOT_MAGIC2, %eax
186                                 
187         /* Jump to the relocator.  */
188         popl    %ebp
189         jmp     *%ebp
190         
192  * This starts the multiboot 2 kernel.
193  */
195 FUNCTION(grub_multiboot2_real_boot)
196         /* Push the entry address on the stack.  */
197         pushl   %eax
198         /* Move the address of the multiboot information structure to ebx.  */
199         movl    %edx,%ebx
201         /* Unload all modules and stop the floppy driver.  */
202         call    EXT_C(grub_dl_unload_all)
203         call    EXT_C(grub_stop_floppy)
205         /* Interrupts should be disabled.  */
206         cli
208         /* Move the magic value into eax and jump to the kernel.  */
209         movl    $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
210         popl    %ecx
211         jmp     *%ecx
214  * Use cdecl calling convention for *BSD kernels.
215  */
217 FUNCTION(grub_unix_real_boot)
219         call    EXT_C(grub_dl_unload_all)
220         call    EXT_C(grub_stop_floppy)
222         /* Interrupts should be disabled.  */
223         cli
225         /* Discard `grub_unix_real_boot' return address.  */
226         popl    %eax
228         /* Fetch `entry' address ...  */
229         popl    %eax
231         /*
232          * ... and put our return address in its place. The kernel will
233          * ignore it, but it expects %esp to point to it.
234          */
235         call    *%eax