Imported Upstream version 3.4
[debian/elilo] / ia32 / sysdeps.h
1 /*
2  *  Copyright (C) 2001-2003 Hewlett-Packard Co.
3  *      Contributed by Stephane Eranian <eranian@hpl.hp.com>
4  *      Contributed by Mike Johnston <johnston@intel.com>
5  *      Contributed by Chris Ahna <christopher.j.ahna@intel.com>
6  *
7  * This file is part of the ELILO, the EFI Linux boot loader.
8  *
9  *  ELILO is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2, or (at your option)
12  *  any later version.
13  *
14  *  ELILO is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with ELILO; see the file COPYING.  If not, write to the Free
21  *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22  *  02111-1307, USA.
23  *
24  * Please check out the elilo.txt for complete documentation on how
25  * to use this program.
26  */
27
28 /*
29  * This file is used to define all the IA32-specific data structures
30  * and constant used by the generic ELILO
31  */
32 #ifndef __ELILO_SYSDEPS_IA32_H__
33 #define __ELILO_SYSDEPS_IA32_H__
34
35 #define ELILO_ARCH      "IA-32" /* ASCII string */
36
37 /* for now use library versions */
38 #define Memset(a,v,n)   SetMem((a),(n),(v))
39 #define Memcpy(a,b,n)   CopyMem((a),(b),(n))
40
41 /*
42  * This version must match the one in the kernel.
43  *
44  * This table was put together using information from the
45  * following Linux kernel source files:
46  *   linux/include/tty.h
47  *   linux/arch/i386/kernel/setup.c
48  *   linux/arch/i386/boot/bootsect.S
49  *   linux/arch/i386/boot/setup.S
50  *   linux/arch/i386/boot/video.S
51  *
52  * New fields in this structure for EFI and ELILO are:
53  *   efi_loader_sig
54  *   efi_st_addr
55  *
56  * A new bit, LDRFLAG_BOOT_PARAM_RELOC, in the loader_flags
57  * field is also defined in this file.
58  */
59 typedef struct efi_ia32_boot_params {
60         UINT32 size;
61         UINT32 command_line;
62         UINT32 efi_sys_tbl;
63         UINT32 efi_mem_map;
64         UINT32 efi_mem_map_size;
65         UINT32 efi_mem_desc_size;
66         UINT32 efi_mem_desc_version;
67         UINT32 initrd_start;
68         UINT32 initrd_size;
69         UINT32 loader_start; 
70         UINT32 loader_size;
71         UINT32 kernel_start;
72         UINT32 kernel_size;
73         UINT16 num_cols;        
74         UINT16 num_rows;
75         UINT16 orig_x;
76         UINT16 orig_y;  
77 } efi_ia32_boot_params_t;
78
79 extern efi_ia32_boot_params_t efi_ia32_bp;
80  
81 #pragma pack(1)
82 typedef union ia32_boot_params {
83         UINT8 raw[0x2000];
84         struct {
85 /* Cursor position before passing control to kernel. */
86 /* 0x00 */      UINT8 orig_cursor_col;          /* LDR */
87 /* 0x01 */      UINT8 orig_cursor_row;          /* LDR */
88
89 /* Available contiguous extended memory in KB. */
90 /* 0x02 */      UINT16 ext_mem_k;               /* LDR */
91
92 /* Video page, mode and screen width before passing control to kernel. */
93 /* 0x04 */      UINT16 orig_video_page;         /* LDR */
94 /* 0x06 */      UINT8 orig_video_mode;          /* LDR */
95 /* 0x07 */      UINT8 orig_video_cols;          /* LDR */
96
97 /* 0x08 */      UINT16 unused_1;                /* unused */
98
99 /* %%TBD */
100 /* 0x0A */      UINT16 orig_ega_bx;             /* LDR */
101
102 /* 0x0C */      UINT16 unused_2;                /* unused */
103
104 /* Screen height before passing control to kernel. */
105 /* 0x0E */      UINT8 orig_video_rows;          /* LDR */
106
107 /* %%TBD */
108 /* 0x0F */      UINT8 is_vga;                   /* LDR */
109 /* 0x10 */      UINT16 orig_video_points;       /* LDR */
110
111 /* %%TBD */
112 /* 0x12 */      UINT16 lfb_width;               /* LDR */
113 /* 0x14 */      UINT16 lfb_height;              /* LDR */
114 /* 0x16 */      UINT16 lfb_depth;               /* LDR */
115 /* 0x18 */      UINT32 lfb_base;                /* LDR */
116 /* 0x1C */      UINT32 lfb_size;                /* LDR */
117
118 /* Offset of command line (from start of ia32_boot_param struct). */
119 /* The command line magik number must be set for the kernel setup */
120 /* code to use the command line offset. */
121 /* 0x20 */      UINT16 cmdline_magik;           /* LDR */
122 #define CMDLINE_MAGIK           0xA33F
123 /* 0x22 */      UINT16 cmdline_offset;          /* LDR */
124
125 /* %%TBD */
126 /* 0x24 */      UINT16 lfb_line_len;            /* LDR */
127
128 /* %%TBD */
129 /* 0x26 */      UINT8 lfb_red_size;             /* LDR */
130 /* 0x27 */      UINT8 lfb_red_pos;              /* LDR */
131 /* 0x28 */      UINT8 lfb_green_size;           /* LDR */
132 /* 0x29 */      UINT8 lfb_green_pos;            /* LDR */
133 /* 0x2A */      UINT8 lfb_blue_size;            /* LDR */
134 /* 0x2B */      UINT8 lfb_blue_pos;             /* LDR */
135 /* 0x2C */      UINT8 lfb_rsvd_size;            /* LDR */
136 /* 0x2D */      UINT8 lfb_rsvd_pos;             /* LDR */
137
138 /* %%TBD */
139 /* 0x2E */      UINT16 vesa_seg;                /* LDR */
140 /* 0x30 */      UINT16 vesa_off;                /* LDR */
141
142 /* %%TBD */
143 /* 0x32 */      UINT16 lfb_pages;               /* LDR */
144 /* 0x34 */      UINT8 lfb_reserved[0x0C];       /* reserved */
145
146 /* %%TBD */
147 /* 0x40 */      UINT16 apm_bios_ver;            /* LDR */
148 #define NO_APM_BIOS             0x0000
149
150 /* %%TBD */
151 /* 0x42 */      UINT16 bios_code_seg;           /* LDR */
152 /* 0x44 */      UINT32 bios_entry_point;        /* LDR */
153 /* 0x48 */      UINT16 bios_code_seg16;         /* LDR */
154 /* 0x4A */      UINT16 bios_data_seg;           /* LDR */
155
156 /* %%TBD */
157 /* 0x4C */      UINT16 apm_bios_flags;          /* LDR */
158 #define NO_32BIT_APM_MASK       0xFFFD
159
160 /* %%TBD */
161 /* 0x4E */      UINT32 bios_code_len;           /* LDR */
162 /* 0x52 */      UINT16 bios_data_len;           /* LDR */
163
164 /* 0x54 */      UINT8 unused_3[0x2C];           /* unused */
165
166 /* %%TBD */
167 /* 0x80 */      UINT8 hd0_info[0x10];           /* LDR */
168 /* 0x90 */      UINT8 hd1_info[0x10];           /* LDR */
169
170 /* %%TBD */
171 /* 0xA0 */      UINT16 mca_info_len;            /* LDR */
172 /* 0xA2 */      UINT8 mca_info_buf[0x10];       /* LDR */
173
174 /* 0xB2 */      UINT8 unused_4[0x10E];          /* unused */
175
176 /* EFI boot loader signature. */
177 /* 0x1C0 */     UINT8 efi_loader_sig[4];        /* LDR */
178 #define EFI_LOADER_SIG          "EFIL"
179
180 /* Address of the EFI system table. */
181 /* 0x1C4 */     UINT32 efi_sys_tbl;             /* LDR */
182
183 /* EFI memory descriptor size. */
184 /* 0x1C8 */     UINT32 efi_mem_desc_size;       /* LDR */
185
186 /* EFI memory descriptor version. */
187 /* 0x1CC */     UINT32 efi_mem_desc_ver;        /* LDR */
188
189 /* Address & size of EFI memory map. */
190 /* 0x1D0 */     UINT32 efi_mem_map;             /* LDR */
191 /* 0x1D4 */     UINT32 efi_mem_map_size;        /* LDR */
192
193 /* Address & size of loader. */
194 /* 0x1D8 */     UINT32 loader_start;            /* LDR */
195 /* 0x1DC */     UINT32 loader_size;             /* LDR */
196
197 /* Available contiguous extended memory in KB. */
198 /* 0x1E0 */     UINT32 alt_mem_k;               /* LDR */
199
200 /* 0x1E4 */     UINT8 unused_5[0x0D];           /* unused */
201
202 /* Size of setup code in sectors (1 sector == 512 bytes). */
203 /* 0x1F1 */     UINT8 setup_sectors;            /* BLD */
204
205 /* %%TBD */
206 /* 0x1F2 */     UINT16 mount_root_rdonly;       /* BLD */
207
208 /* %%TBD */
209 /* 0x1F4 */     UINT16 sys_size;                /* BLD */
210
211 /* %%TBD */
212 /* 0x1F6 */     UINT16 swap_dev;                /* BLD */
213
214 /* %%TBD */
215 /* 0x1F8 */     UINT16 ramdisk_flags;           /* BLD */
216 #define RAMDISK_PROMPT          0x8000
217 #define RAMDISK_LOAD            0x4000
218
219 /* %%TBD */
220 /* 0x1FA */     UINT16 video_mode_flag;         /* BLD */
221
222 /* %%TBD */
223 /* 0x1FC */     UINT16 orig_root_dev;           /* BLD */
224
225 /* 0x1FE */     UINT8 unused_6;                 /* unused */
226
227 /* %%TBD */
228 /* 0x1FF */     UINT8 aux_dev_info;             /* LDR */
229 #define NO_MOUSE                0x00
230 #define FOUND_MOUSE             0xAA
231
232 /* Jump past setup data (not used in EFI). */
233 /* 0x200 */     UINT16 jump;                    /* BLD */
234
235 /* Setup data signature. */
236 /* 0x202 */     UINT8 setup_sig[4];             /* BLD */
237 #define SETUP_SIG               "HdrS"
238
239 /* %%TBD */
240 /* 0x206 */     UINT8 hdr_minor;                /* BLD */
241 /* 0x207 */     UINT8 hdr_major;                /* BLD */
242
243 /* %%TBD */
244 /* 0x208 */     UINT32 rm_switch;               /* LDD */
245
246 /* %%TBD */
247 /* 0x20C */     UINT16 start_sys_seg;           /* BLD */
248
249 /* %%TBD */
250 /* 0x20E */     UINT16 kernel_verstr_offset;    /* BLD */
251
252 /* Loader type & version. */
253 /* 0x210 */     UINT8 loader_type;              /* LDR */
254 #define LDRTYPE_ELILO                   0x50    /* 5?h == elilo */
255                                                 /* ?0h == revision */
256
257 /* 0x211 */     UINT8 loader_flags;             /* BLD and LDR */
258 #define LDRFLAG_CAN_USE_HEAP            0x80
259 #define LDRFLAG_BOOT_PARAM_RELOC        0x40
260
261 /* %%TBD */
262 /* 0x212 */     UINT16 setup_move_size;         /* BLD */
263
264 /* %%TBD */
265 /* 0x214 */     UINT32 kernel_start;            /* LDR */
266
267 /* %%TBD */
268 /* 0x218 */     UINT32 initrd_start;            /* LDR */
269 /* 0x21C */     UINT32 initrd_size;             /* LDR */
270
271 /* %%TBD */
272 /* 0x220 */     UINT32 bootsect_helper;         /* BLD */
273
274 /* %%TBD */
275 /* 0x224 */     UINT16 heap_end_ptr;            /* LDR */
276
277 /* %%TBD */
278 /* 0x226 */     UINT32 base_mem_size;           /* LDR */
279         } s;
280 } boot_params_t;
281 #pragma pack()
282
283 /*
284  * The stuff below here is for jumping to the kernel.
285  */
286
287 /*
288  * Some macros to copy and set memory after EFI has been
289  * stopped.
290  */
291
292 #define MEMCPY(to, from, cnt) { \
293         UINT8 *t = (UINT8 *)(to); \
294         UINT8 *f = (UINT8 *)(from); \
295         UINTN n = cnt; \
296         if (t && f && n) { \
297                 while (n--) { \
298                         *t++ = *f++; \
299                 } \
300         } \
301 }
302
303 #define MEMSET(ptr, size, val) { \
304         UINT8 *p = (UINT8 *)(ptr); \
305         UINTN n = (UINTN)(size); \
306         UINT8 v = (UINT8)(val); \
307         if (p && n) { \
308                 while (n--) { \
309                         *p++ = v; \
310                 } \
311         } \
312 }
313
314 /*
315  * Descriptor table pointer format.
316  */
317 #pragma pack(1)
318 typedef struct {
319         UINT16 limit;
320         UINT32 base;
321 } dt_addr_t;
322 #pragma pack()
323
324 extern UINTN high_base_mem;
325 extern UINTN high_ext_mem;
326
327 extern boot_params_t *param_start;
328 extern UINTN param_size;
329
330 extern VOID *kernel_start;
331 extern UINTN kernel_size;
332
333 extern VOID *initrd_start;
334 extern UINTN initrd_size;
335
336 extern dt_addr_t gdt_addr;
337 extern dt_addr_t idt_addr;
338
339 extern UINT16 init_gdt[];
340 extern UINTN sizeof_init_gdt;
341
342 extern UINT8 rmswitch_image[];
343 extern UINTN rmswitch_size;
344
345 extern INTN ia32_use_legacy_free_boot();
346
347 /*
348  * How to jump to kernel code
349  */
350
351 static inline void
352 start_kernel(VOID *kentry, boot_params_t *bp)
353 {
354         /*
355          * Disable interrupts.
356          */
357
358         asm volatile ( "cli" : : );
359
360         /*
361          * Relocate initrd, if present.
362          */
363
364         if (bp->s.initrd_start) {
365                 /* %%TBD */
366                 MEMCPY(15 * 1024 * 1024, bp->s.initrd_start, bp->s.initrd_size);
367                 bp->s.initrd_start = 15 * 1024 * 1024;
368         }
369
370         /*
371          * Copy boot sector, setup data and command line
372          * to final resting place.  We need to copy
373          * BOOT_PARAM_MEMSIZE bytes.
374          */
375
376         MEMCPY(high_base_mem, bp, 0x4000);
377
378         /* 
379          * initialize efi ia32 boot params and place them at 1kb up from
380          * the start of the boot command line param.  This results in the 
381          * efi ia32 boot params to be copied to 0x00104c00.  See bootparams.c
382          * for details on how this is arranged.  EFI enabled 
383          * kernels will look for the efi boot params here to know if the
384          * kernel is booting on an EFI platform or legacy BIOS based platfrom
385          */
386
387         efi_ia32_bp.initrd_start = bp->s.initrd_start;
388         efi_ia32_bp.initrd_size = bp->s.initrd_size;
389
390         MEMCPY(high_base_mem + 0x4000 - 0x0400, &efi_ia32_bp, sizeof(efi_ia32_bp));
391  
392         /*
393          * Initialize Linux GDT.
394          */
395
396         MEMSET(gdt_addr.base, gdt_addr.limit, 0);
397         MEMCPY(gdt_addr.base, init_gdt, sizeof_init_gdt);
398
399         if (! ia32_use_legacy_free_boot()) {
400
401                 /*
402                  * Copy our real mode transition code to 0x7C00.
403                  */
404
405                 MEMCPY(0x7C00, rmswitch_image, rmswitch_size);
406
407                 asm volatile ( "movl $0x7C00, %%ebx" : : );
408                 asm volatile ( "jmp *%%ebx" : : );
409         }
410
411         /*
412          * Load descriptor table pointers.
413          */
414
415         asm volatile ( "lidt %0" : : "m" (idt_addr) );
416         asm volatile ( "lgdt %0" : : "m" (gdt_addr) );
417
418         /*
419          * ebx := 0  (%%TBD - do not know why, yet)
420          * ecx := kernel entry point
421          * esi := address of boot sector and setup data
422          */
423
424         asm volatile ( "movl %0, %%esi" : : "m" (high_base_mem) );
425         asm volatile ( "movl %0, %%ecx" : : "m" (kentry) );
426         asm volatile ( "xorl %%ebx, %%ebx" : : );
427
428         /*
429          * Jump to kernel entry point.
430          */
431
432
433         asm volatile ( "jmp *%%ecx" : : );
434 }
435
436 typedef struct sys_img_options {
437         UINT8 nothing_yet;
438 } sys_img_options_t;
439
440 #endif /* __ELILO_SYSDEPS_IA32_H__ */