Trust uboot's device list only if it does not look suspicious.
[AROS.git] / arch / all-pc / bootstrap / multiboot1.c
blob12ecd8439c3b051b9c8fb66913f41b65b1f0f202
1 #define DEBUG
3 #include <aros/kernel.h>
5 #include <bootconsole.h>
6 #include <elfloader.h>
7 #include <runtime.h>
8 #include <string.h>
10 #include "bootstrap.h"
11 #include "support.h"
13 unsigned long mb1_parse(struct multiboot *mb, struct mb_mmap **mmap_addr, unsigned long *mmap_len)
15 const char *cmdline = NULL;
16 struct mb_mmap *mmap = NULL;
17 unsigned long len = 0;
18 unsigned long usable = (unsigned long)&_end;
20 con_InitMultiboot(mb);
21 Hello();
22 D(kprintf("[Multiboot] Multiboot v1 structure @ %p\n", mb));
25 * Now allocate our mirror buffer.
26 * The buffer is used only by graphical console.
28 AllocFB();
30 if (mb->flags & MB_FLAGS_CMDLINE)
32 cmdline = (const char *)mb->cmdline;
33 D(kprintf("[Multiboot] Command line @ %p : '%s'\n", mb->cmdline, cmdline));
35 usable = STR_TOP_ADDR(usable, cmdline);
38 if ((mb->flags & MB_FLAGS_MMAP))
40 mmap = (struct mb_mmap *)mb->mmap_addr;
41 len = mb->mmap_length;
43 D(kprintf("[Multiboot] Memory map at 0x%p, length %u\n", mmap, len));
44 usable = TOP_ADDR(usable, (void *)mmap + len);
47 if (mb->flags & MB_FLAGS_MEM)
49 D(kprintf("[Multiboot] Low memory %u KB, upper memory %u KB\n", mb->mem_lower, mb->mem_upper));
51 if (!mmap)
54 * To simplify things down, memory map is mandatory for our kickstart.
55 * So we create an implicit one if the bootloader didn't supply it.
57 mmap = mmap_make(&len, mb->mem_lower << 10, (unsigned long long)mb->mem_upper << 10);
60 /* Kickstart wants size in bytes */
61 tag->ti_Tag = KRN_MEMLower;
62 tag->ti_Data = mb->mem_lower << 10;
63 tag++;
65 tag->ti_Tag = KRN_MEMUpper;
66 tag->ti_Data = (unsigned long long)mb->mem_upper << 10;
67 tag++;
70 if (mb->flags & MB_FLAGS_LDRNAME)
72 tag->ti_Tag = KRN_BootLoader;
73 tag->ti_Data = mb->loader_name;
74 tag++;
76 usable = STR_TOP_ADDR(usable, (const char *)mb->loader_name);
79 if (!mmap)
80 panic("No memory information provided by the bootloader");
82 if (ParseCmdLine(cmdline))
84 /* No VESA mode was set by command line arguments, supply what we already have */
85 if (mb->flags & MB_FLAGS_GFX)
87 /* We prefer complete VBE data if present */
88 kprintf("[Multiboot] Got VESA display mode 0x%x from the bootstrap\n", mb->vbe_mode);
90 D(kprintf("[Multiboot] Mode info 0x%p, controller into 0x%p\n", mb->vbe_mode_info, mb->vbe_control_info));
91 D(kprintf("[Multiboot] VBE version 0x%04X\n", ((struct vbe_controller *)mb->vbe_control_info)->version));
92 D(kprintf("[Multiboot] Resolution %d x %d\n", ((struct vbe_mode *)mb->vbe_mode_info)->x_resolution, ((struct vbe_mode *)mb->vbe_mode_info)->y_resolution));
93 D(kprintf("[Multiboot] Mode flags 0x%04X, framebuffer 0x%p\n", ((struct vbe_mode *)mb->vbe_mode_info)->mode_attributes, ((struct vbe_mode *)mb->vbe_mode_info)->phys_base));
94 D(kprintf("[Multiboot] Windows A 0x%04X B 0x%04X\n", ((struct vbe_mode *)mb->vbe_mode_info)->win_a_segment, ((struct vbe_mode *)mb->vbe_mode_info)->win_b_segment));
97 * We are already running in VESA mode set by the bootloader.
98 * Pass on the mode information to AROS.
100 tag->ti_Tag = KRN_VBEModeInfo;
101 tag->ti_Data = mb->vbe_mode_info;
102 tag++;
104 tag->ti_Tag = KRN_VBEControllerInfo;
105 tag->ti_Data = mb->vbe_control_info;
106 tag++;
108 tag->ti_Tag = KRN_VBEMode;
109 tag->ti_Data = mb->vbe_mode;
110 tag++;
112 usable = TOP_ADDR(usable, mb->vbe_mode_info + sizeof(struct vbe_mode));
113 usable = TOP_ADDR(usable, mb->vbe_control_info + sizeof(struct vbe_controller));
115 else if (mb->flags & MB_FLAGS_FB)
118 * We have a framebuffer but no VBE information.
119 * Looks like we are running on EFI machine with no VBE support (Mac).
120 * Convert framebuffer data to VBEModeInfo and hand it to AROS.
122 kprintf("[Multiboot] Got framebuffer display %dx%dx%d from the bootstrap\n", mb->framebuffer_width, mb->framebuffer_height, mb->framebuffer_bpp);
123 D(kprintf("[Multiboot] Address 0x%016llX, type %d, %d bytes per line\n", mb->framebuffer_addr, mb->framebuffer_type, mb->framebuffer_pitch));
126 * AROS VESA driver supports only RGB framebuffer because we are
127 * unlikely to have VGA palette registers for other cases.
128 * FIXME: we have some pointer to palette registers. We just need to
129 * pass it to the bootstrap and handle it there (how? Is it I/O port
130 * address or memory-mapped I/O address?)
132 if (mb->framebuffer_type == MB_FRAMEBUFFER_RGB)
134 VBEModeInfo.mode_attributes = VM_SUPPORTED|VM_COLOR|VM_GRAPHICS|VM_NO_VGA_HW|VM_NO_VGA_MEM|VM_LINEAR_FB;
135 VBEModeInfo.bytes_per_scanline = mb->framebuffer_pitch;
136 VBEModeInfo.x_resolution = mb->framebuffer_width;
137 VBEModeInfo.y_resolution = mb->framebuffer_height;
138 VBEModeInfo.bits_per_pixel = mb->framebuffer_bpp;
139 VBEModeInfo.memory_model = VMEM_RGB;
140 VBEModeInfo.red_mask_size = mb->framebuffer_red_mask_size;
141 VBEModeInfo.red_field_position = mb->framebuffer_red_field_position;
142 VBEModeInfo.green_mask_size = mb->framebuffer_green_mask_size;
143 VBEModeInfo.green_field_position = mb->framebuffer_green_field_position;
144 VBEModeInfo.blue_mask_size = mb->framebuffer_blue_mask_size;
145 VBEModeInfo.blue_field_position = mb->framebuffer_blue_field_position;
146 VBEModeInfo.phys_base = mb->framebuffer_addr;
147 VBEModeInfo.linear_bytes_per_scanline = mb->framebuffer_pitch;
148 VBEModeInfo.linear_red_mask_size = mb->framebuffer_red_mask_size;
149 VBEModeInfo.linear_red_field_position = mb->framebuffer_red_field_position;
150 VBEModeInfo.linear_green_mask_size = mb->framebuffer_green_mask_size;
151 VBEModeInfo.linear_green_field_position = mb->framebuffer_green_field_position;
152 VBEModeInfo.linear_blue_mask_size = mb->framebuffer_blue_mask_size;
153 VBEModeInfo.linear_blue_field_position = mb->framebuffer_blue_field_position;
155 tag->ti_Tag = KRN_VBEModeInfo;
156 tag->ti_Data = KERNEL_OFFSET | (unsigned long)&VBEModeInfo;
157 tag++;
162 *mmap_addr = mmap;
163 *mmap_len = len;
165 /* Search for external modules loaded by GRUB */
166 /* Are there any modules at all? */
167 if (mb->flags && MB_FLAGS_MODS)
169 struct mb_module *mod = (struct mb_module *)mb->mods_addr;
170 int i;
172 D(kprintf("[Multiboot] GRUB has loaded %d files\n", mb->mods_count));
174 /* Go through the list of modules loaded by GRUB */
175 for (i=0; i < mb->mods_count; i++)
177 usable = AddModule(mod->mod_start, mod->mod_end, usable);
178 mod++;
182 /* We return the lowest address suitable for loading kickstart into */
183 return usable;