1 /**
2  * \file
3  * \brief	Multiboot info structure as defined by GRUB
4  */
5 /*
6  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7  *               Frank Mehnert <fm3@os.inf.tu-dresden.de>
8  *     economic rights: Technische Universität Dresden (Germany)
9  * This file is part of TUD:OS and distributed under the terms of the
10  * GNU Lesser General Public License 2.1.
11  * Please see the COPYING-LGPL-2.1 file for details.
12  */
13 
14 #ifndef L4UTIL_MB_INFO_H
15 #define L4UTIL_MB_INFO_H
16 
17 /******************************************************************************
18  * Multiboot (v1)
19  *****************************************************************************/
20 
21 #ifndef __ASSEMBLY__
22 
23 #include <l4/sys/l4int.h>
24 
25 /*
26  * \defgroup l4util_mb_mod Multiboot v1
27  * \ingroup l4util_api
28  */
29 
30 /**
31  *  The structure type "mod_list" is used by the
32  *  \ref l4util_mb_info_t "multiboot_info" structure.
33  */
34 typedef struct
35 {
36   l4_uint32_t mod_start;	/**< Starting address of module in memory. */
37   l4_uint32_t mod_end;		/**< End address of module in memory. */
38   l4_uint32_t cmdline;		/**< Module command line */
39   l4_uint32_t pad;		/**< padding to take it to 16 bytes */
40 } l4util_mb_mod_t;
41 
42 
43 /**
44  *  INT-15, AX=E820 style "AddressRangeDescriptor"
45  *  ...with a "size" parameter on the front which is the structure size - 4,
46  *  pointing to the next one, up until the full buffer length of the memory
47  *  map has been reached.
48  */
49 typedef struct __attribute__((packed))
50 {
51   l4_uint32_t struct_size;	/**< Size of structure */
52   l4_uint64_t addr;		/**< Start address */
53   l4_uint64_t size;		/**< Size of memory range */
54   l4_uint32_t type;		/**< type of memory range */
55   /* unspecified optional padding... */
56 } l4util_mb_addr_range_t;
57 
58 /** usable memory "Type", all others are reserved.  */
59 #define MB_ARD_MEMORY		1
60 
61 /**
62  * Address Range Types (ART) from "Advanced Configuration and Power Interface
63  * Specification" Rev3.0a (p. 390). Other values are undefined.
64  */
65 #define MB_ART_MEMORY   1  /**< available, usable RAM */
66 #define MB_ART_RESERVED 2  /**< in use or reserved by system */
67 #define MB_ART_ACPI     3  /**< ACPI Reclaim Memory (RAM that contains
68 			        ACPI tables) */
69 #define MB_ART_NVS      4  /**< ACPI NVS Memory (must not be used by the OS */
70 #define MB_ART_UNUSABLE 5  /**< memory in which errors have been detected */
71 
72 
73 /** Drive Info structure.  */
74 typedef struct
75 {
76   l4_uint32_t size;		/** <The size of this structure.  */
77   l4_uint8_t drive_number;	/** <The BIOS drive number.  */
78   l4_uint8_t drive_mode;	/** <The access mode (see below).  */
79   l4_uint16_t drive_cylinders;	/** <number of cylinders  */
80   l4_uint8_t drive_heads;	/** <number of heads */
81   l4_uint8_t drive_sectors;	/** <number of sectors per track */
82   l4_uint16_t drive_ports[0];	/** <Array of I/O ports used for the drive. */
83 } l4util_mb_drive_t;
84 
85 /* Drive Mode.  */
86 #define MB_DI_CHS_MODE		0
87 #define MB_DI_LBA_MODE		1
88 
89 
90 /** APM BIOS info.  */
91 typedef struct
92 {
93   l4_uint16_t version;
94   l4_uint16_t cseg;
95   l4_uint32_t offset;
96   l4_uint16_t cseg_16;
97   l4_uint16_t dseg_16;
98   l4_uint16_t cseg_len;
99   l4_uint16_t cseg_16_len;
100   l4_uint16_t dseg_16_len;
101 } l4util_mb_apm_t;
102 
103 
104 /** VBE controller information. */
105 typedef struct
106 {
107   l4_uint8_t signature[4];
108   l4_uint16_t version;
109   l4_uint32_t oem_string;
110   l4_uint32_t capabilities;
111   l4_uint32_t video_mode;
112   l4_uint16_t total_memory;
113   l4_uint16_t oem_software_rev;
114   l4_uint32_t oem_vendor_name;
115   l4_uint32_t oem_product_name;
116   l4_uint32_t oem_product_rev;
117   l4_uint8_t reserved[222];
118   l4_uint8_t oem_data[256];
119 } __attribute__((packed)) l4util_mb_vbe_ctrl_t;
120 
121 
122 /** VBE mode information. */
123 typedef struct
124 {
125   /** @name all VESA versions
126   * @{ */
127   l4_uint16_t mode_attributes;
128   l4_uint8_t win_a_attributes;
129   l4_uint8_t win_b_attributes;
130   l4_uint16_t win_granularity;
131   l4_uint16_t win_size;
132   l4_uint16_t win_a_segment;
133   l4_uint16_t win_b_segment;
134   l4_uint32_t win_func;
135   l4_uint16_t bytes_per_scanline;
136   /** @} */
137 
138   /** @name >= VESA version 1.2
139    * @{ */
140   l4_uint16_t x_resolution;
141   l4_uint16_t y_resolution;
142   l4_uint8_t x_char_size;
143   l4_uint8_t y_char_size;
144   l4_uint8_t number_of_planes;
145   l4_uint8_t bits_per_pixel;
146   l4_uint8_t number_of_banks;
147   l4_uint8_t memory_model;
148   l4_uint8_t bank_size;
149   l4_uint8_t number_of_image_pages;
150   l4_uint8_t reserved0;
151   /** @} */
152 
153   /** @name direct color
154    * @{ */
155   l4_uint8_t red_mask_size;
156   l4_uint8_t red_field_position;
157   l4_uint8_t green_mask_size;
158   l4_uint8_t green_field_position;
159   l4_uint8_t blue_mask_size;
160   l4_uint8_t blue_field_position;
161   l4_uint8_t reserved_mask_size;
162   l4_uint8_t reserved_field_position;
163   l4_uint8_t direct_color_mode_info;
164   /** @} */
165 
166   /** @name >= VESA version 2.0
167    * @{*/
168   l4_uint32_t phys_base;
169   l4_uint32_t reserved1;
170   l4_uint16_t reversed2;
171   /** @} */
172 
173   /** @name >= VESA version 3.0
174    * @{*/
175   l4_uint16_t linear_bytes_per_scanline;
176   l4_uint8_t banked_number_of_image_pages;
177   l4_uint8_t linear_number_of_image_pages;
178   l4_uint8_t linear_red_mask_size;
179   l4_uint8_t linear_red_field_position;
180   l4_uint8_t linear_green_mask_size;
181   l4_uint8_t linear_green_field_position;
182   l4_uint8_t linear_blue_mask_size;
183   l4_uint8_t linear_blue_field_position;
184   l4_uint8_t linear_reserved_mask_size;
185   l4_uint8_t linear_reserved_field_position;
186   l4_uint32_t max_pixel_clock;
187 
188   /* The VBE spec says this structure should have a size of 256 bytes but
189    * the described structure layout is only 255 bytes... */
190   l4_uint8_t reserved3[189 + 1];
191   /** @} */
192 } __attribute__ ((packed)) l4util_mb_vbe_mode_t;
193 
194 
195 /**
196  * \brief MultiBoot Info description
197  *
198  * This is the struct passed to the boot image.  This is done by placing
199  * its address in the EAX register.
200  */
201 
202 typedef struct
203 {
204   l4_uint32_t flags;		/**< MultiBoot info version number */
205   l4_uint32_t mem_lower;	/**< available memory below 1MB */
206   l4_uint32_t mem_upper;	/**< available memory starting from 1MB [kB] */
207   l4_uint32_t boot_device;	/**< "root" partition */
208   l4_uint32_t cmdline;		/**< Kernel command line */
209   l4_uint32_t mods_count;	/**< number of modules */
210   l4_uint32_t mods_addr;	/**< module list */
211 
212   union
213   {
214     struct
215     {
216       /** (a.out) Kernel symbol table info */
217       l4_uint32_t tabsize;
218       l4_uint32_t strsize;
219       l4_uint32_t addr;
220       l4_uint32_t pad;
221     }
222     a;
223 
224     struct
225     {
226       /** (ELF) Kernel section header table */
227       l4_uint32_t num;
228       l4_uint32_t size;
229       l4_uint32_t addr;
230       l4_uint32_t shndx;
231     }
232     e;
233   }
234   syms;
235 
236   l4_uint32_t mmap_length;	/**< size of memory mapping buffer */
237   l4_uint32_t mmap_addr;	/**< address of memory mapping buffer */
238   l4_uint32_t drives_length;	/**< size of drive info buffer */
239   l4_uint32_t drives_addr;	/**< address of driver info buffer */
240   l4_uint32_t config_table;	/**< ROM configuration table */
241   l4_uint32_t boot_loader_name;	/**< Boot Loader Name */
242   l4_uint32_t apm_table;	/**< APM table */
243   l4_uint32_t vbe_ctrl_info;	/**< VESA video contoller info */
244   l4_uint32_t vbe_mode_info;	/**< VESA video mode info */
245   l4_uint16_t vbe_mode;		/**< VESA video mode number */
246   l4_uint16_t vbe_interface_seg; /**< VESA segment of prot BIOS interface */
247   l4_uint16_t vbe_interface_off; /**< VESA offset of prot BIOS interface */
248   l4_uint16_t vbe_interface_len; /**< VESA lenght of prot BIOS interface */
249 } l4util_mb_info_t;
250 
251 /**
252  * Get the first entry of the memory map provided through a multi boot
253  * information (MBI) structure.
254  *
255  * \return A pointer to the first entry of the memory map.
256  */
257 static inline l4util_mb_addr_range_t *
l4util_mb_first_mmap_entry(l4util_mb_info_t * mbi)258 l4util_mb_first_mmap_entry(l4util_mb_info_t *mbi)
259 {
260   return (l4util_mb_addr_range_t *)(l4_addr_t)mbi->mmap_addr;
261 }
262 
263 /**
264  * Advance to the next entry of a memory map provided through a multi boot
265  * information (MBI) structure.
266  *
267  * \return A pointer to the next entry of the memory map.
268  *
269  * \note   This function performs no checking. The user must ensure that the
270  *         returned pointer does not point beyond the end of the memory map.
271  */
272 static inline l4util_mb_addr_range_t *
l4util_mb_next_mmap_entry(l4util_mb_addr_range_t * e)273 l4util_mb_next_mmap_entry(l4util_mb_addr_range_t *e)
274 {
275   return (l4util_mb_addr_range_t *)((l4_addr_t)e + e->struct_size
276                                     + sizeof(e->struct_size));
277 }
278 
279 /**
280  * Iterate over a memory map provided in a Multiboot info.
281  *
282  * \param i   Name of a variable of type l4util_mb_addr_range_t * that is
283  *            consecutively assigned pointers to the entries of the memory map.
284  * \param mbi Pointer to the l4util_mb_info_t where the memory map can be found.
285  * */
286 #define l4util_mb_for_each_mmap_entry(i, mbi)                                  \
287   for (i = l4util_mb_first_mmap_entry(mbi);                                    \
288        (unsigned long)i < (unsigned long)mbi->mmap_addr + mbi->mmap_length;    \
289        i = l4util_mb_next_mmap_entry(i))
290 
291 #endif /* ! __ASSEMBLY__ */
292 
293 /**
294  *  Flags to be set in the 'flags' parameter above
295  */
296 
297 /** is there basic lower/upper memory information? */
298 #define L4UTIL_MB_MEMORY		0x00000001
299 
300 /** is there a boot device set? */
301 #define L4UTIL_MB_BOOTDEV		0x00000002
302 
303 /** is the command-line defined? */
304 #define L4UTIL_MB_CMDLINE		0x00000004
305 
306 /** are there modules to do something with? */
307 #define L4UTIL_MB_MODS			0x00000008
308 
309 /* These next two are mutually exclusive */
310 /** is there a symbol table loaded? */
311 #define L4UTIL_MB_AOUT_SYMS		0x00000010
312 
313 /** is there an ELF section header table? */
314 #define L4UTIL_MB_ELF_SHDR		0x00000020
315 
316 /** is there a full memory map? */
317 #define L4UTIL_MB_MEM_MAP		0x00000040
318 
319 /** Is there drive info?  */
320 #define L4UTIL_MB_DRIVE_INFO		0x00000080
321 
322 /** Is there a config table?  */
323 #define L4UTIL_MB_CONFIG_TABLE		0x00000100
324 
325 /** Is there a boot loader name?  */
326 #define L4UTIL_MB_BOOT_LOADER_NAME	0x00000200
327 
328 /** Is there a APM table?  */
329 #define L4UTIL_MB_APM_TABLE		0x00000400
330 
331 /** Is there video information?  */
332 #define L4UTIL_MB_VIDEO_INFO		0x00000800
333 
334 
335 /** If we are multiboot-compliant, this value is present in the eax register */
336 #define L4UTIL_MB_VALID			0x2BADB002UL
337 #define L4UTIL_MB_VALID_ASM		0x2BADB002
338 
339 
340 /******************************************************************************
341  * Multiboot2
342  *****************************************************************************/
343 
344 #ifndef __ASSEMBLY__
345 
346 typedef struct
347 {
348   l4_uint32_t total_size;
349   l4_uint32_t reserved;
350 }  __attribute__((packed)) l4util_mb2_info_t;
351 
352 typedef struct
353 {
354   char string[0];
355 }  __attribute__((packed)) l4util_mb2_cmdline_tag_t;
356 
357 typedef struct
358 {
359   l4_uint32_t mod_start;
360   l4_uint32_t mod_end;
361   char string[];
362 }  __attribute__((packed)) l4util_mb2_module_tag_t;
363 
364 typedef struct
365 {
366   l4_uint64_t base_addr;
367   l4_uint64_t length;
368   l4_uint32_t type;
369   l4_uint32_t reserved;
370 }  __attribute__((packed)) l4util_mb2_memmap_entry_t;
371 
372 typedef struct
373 {
374   l4_uint32_t entry_size;
375   l4_uint32_t entry_version;
376   l4util_mb2_memmap_entry_t entries[];
377 }  __attribute__((packed)) l4util_mb2_memmap_tag_t;
378 
379 typedef struct
380 {
381   char data[0];
382 } __attribute__((packed)) l4util_mb2_rsdp_tag_t;
383 
384 typedef struct
385 {
386   l4_uint32_t type;
387   l4_uint32_t size;
388 
389   union
390   {
391     l4util_mb2_cmdline_tag_t cmdline;
392     l4util_mb2_module_tag_t module;
393     l4util_mb2_memmap_tag_t memmap;
394     l4util_mb2_rsdp_tag_t rsdp;
395   };
396 }  __attribute__((packed)) l4util_mb2_tag_t;
397 
398 #endif  /* ! __ASSEMBLY__ */
399 
400 
401 #define L4UTIL_MB2_MAGIC		0xE85250D6
402 #define L4UTIL_MB2_ARCH_I386		0x0
403 
404 #define L4UTIL_MB2_TERMINATOR_HEADER_TAG	0
405 #define L4UTIL_MB2_INFO_REQUEST_HEADER_TAG	1
406 #define L4UTIL_MB2_ENTRY_ADDRESS_HEADER_TAG	3
407 #define L4UTIL_MB2_RELOCATABLE_HEADER_TAG	10
408 
409 #define L4UTIL_MB2_TAG_FLAG_REQUIRED		0
410 
411 #define L4UTIL_MB2_TAG_ALIGN_SHIFT		3
412 #define L4UTIL_MB2_TAG_ALIGN			8
413 
414 #define L4UTIL_MB2_TERMINATOR_INFO_TAG            0
415 #define L4UTIL_MB2_BOOT_CMDLINE_INFO_TAG          1
416 #define L4UTIL_MB2_MODULE_INFO_TAG                3
417 #define L4UTIL_MB2_MEMORY_MAP_INFO_TAG            6
418 #define L4UTIL_MB2_RSDP_OLD_INFO_TAG             14
419 #define L4UTIL_MB2_RSDP_NEW_INFO_TAG             15
420 #define L4UTIL_MB2_IMAGE_LOAD_BASE_PHYS_INFO_TAG 21
421 
422 #define L4UTIL_MB2_RELO_PREFERED_NONE 0
423 #define L4UTIL_MB2_RELO_PREFERED_MIN  1
424 #define L4UTIL_MB2_RELO_PREFERED_MAX  2
425 
426 #endif
427