19 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ |
20 |
|
|
21 |
#include <alloca.h> |
#include <alloca.h> |
22 |
|
#include <stdint.h> |
23 |
|
|
24 |
#include "laden.h" |
#include "laden.h" |
25 |
|
|
45 |
/* Setup the argument vector and pass control over to the main |
/* Setup the argument vector and pass control over to the main |
46 |
function. */ |
function. */ |
47 |
void |
void |
48 |
cmain (unsigned long magic, multiboot_info_t *mbi) |
cmain (uint32_t magic, multiboot_info_t *mbi) |
49 |
{ |
{ |
50 |
int argc = 0; |
int argc = 0; |
51 |
char **argv = 0; |
char **argv = 0; |
52 |
|
|
53 |
/* Verify that we are booted by a Multiboot-compliant boot loader. */ |
/* Verify that we are booted by a Multiboot-compliant boot loader. */ |
54 |
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) |
if (magic != MULTIBOOT_BOOTLOADER_MAGIC) |
55 |
panic ("Error: Invalid magic number: 0x%x", magic); |
panic ("Invalid magic number: 0x%x", magic); |
56 |
|
|
57 |
if (!CHECK_FLAG (mbi->flags, 0) && !CHECK_FLAG (mbi->flags, 6)) |
if (!CHECK_FLAG (mbi->flags, 0) && !CHECK_FLAG (mbi->flags, 6)) |
58 |
panic ("Error: Bootloader did not provide a memory map"); |
panic ("Bootloader did not provide a memory map"); |
59 |
|
|
60 |
if (CHECK_FLAG (mbi->flags, 2)) |
if (CHECK_FLAG (mbi->flags, 2)) |
61 |
{ |
{ |
112 |
/* The boot info is set to the multiboot info on ia32. We use this |
/* The boot info is set to the multiboot info on ia32. We use this |
113 |
also to get at the multiboot info from other functions called at |
also to get at the multiboot info from other functions called at |
114 |
a later time. */ |
a later time. */ |
115 |
boot_info = (unsigned long) mbi; |
boot_info = (uint32_t) mbi; |
116 |
|
|
117 |
/* Now invoke the main function. */ |
/* Now invoke the main function. */ |
118 |
main (argc, argv); |
main (argc, argv); |
149 |
int nr = 1; |
int nr = 1; |
150 |
|
|
151 |
for (mmap = (memory_map_t *) mbi->mmap_addr; |
for (mmap = (memory_map_t *) mbi->mmap_addr; |
152 |
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; |
(uint32_t) mmap < mbi->mmap_addr + mbi->mmap_length; |
153 |
mmap = (memory_map_t *) ((unsigned long) mmap |
mmap = (memory_map_t *) ((uint32_t) mmap |
154 |
+ mmap->size + sizeof (mmap->size))) |
+ mmap->size + sizeof (mmap->size))) |
155 |
debug ("Memory Map %i: Type %i, Base 0x%x%x, Length 0x%x%x\n", |
debug ("Memory Map %i: Type %i, Base 0x%x%x, Length 0x%x%x\n", |
156 |
nr++, mmap->type, mmap->base_addr_high, mmap->base_addr_low, |
nr++, mmap->type, mmap->base_addr >> 32, |
157 |
mmap->length_high, mmap->length_low); |
mmap->base_addr & ((1ULL << 32) - 1), |
158 |
|
mmap->length >> 32, mmap->length & ((1ULL << 32) - 1)); |
159 |
} |
} |
160 |
} |
} |
161 |
|
|
198 |
memory_map_t *mmap; |
memory_map_t *mmap; |
199 |
|
|
200 |
for (mmap = (memory_map_t *) mbi->mmap_addr; |
for (mmap = (memory_map_t *) mbi->mmap_addr; |
201 |
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; |
(uint32_t) mmap < mbi->mmap_addr + mbi->mmap_length; |
202 |
mmap = (memory_map_t *) ((unsigned long) mmap |
mmap = (memory_map_t *) ((uint32_t) mmap |
203 |
+ mmap->size + sizeof (mmap->size))) |
+ mmap->size + sizeof (mmap->size))) |
204 |
{ |
{ |
205 |
unsigned long long end; |
uint64_t end; |
206 |
|
|
207 |
if (mmap->base_addr_high) |
if (mmap->base_addr >> 32) |
208 |
panic ("Error: L4 does not support more than 4 GB on ia32"); |
panic ("L4 does not support more than 4 GB on ia32"); |
209 |
|
|
210 |
end = (((unsigned long long) mmap->base_addr_high) << 32) |
end = mmap->base_addr + mmap->length; |
|
| mmap->base_addr_low; |
|
|
end += (((unsigned long long) mmap->length_high) << 32) |
|
|
| mmap->length_low; |
|
211 |
|
|
212 |
if (end >> 32) |
if (end == (1ULL << 32)) |
213 |
panic ("Error: L4 does not support more than 4 GB on ia32"); |
{ |
214 |
|
#if 0 |
215 |
if ((end + (1 << 10) - 1) >> 32) |
panic ("L4 does not support exactly 4 GB on ia32"); |
216 |
panic ("Error: L4 does not support exactly 4 GB on ia32"); |
#elif 1 |
217 |
|
/* The L4 specification does not seem to allow this |
218 |
|
configuration. Truncate the region by dropping the |
219 |
|
last page. FIXME: kickstart overflows and sets the |
220 |
|
high address to 0. This is unambiguous, but needs to |
221 |
|
be supported by sigma0 and the operating system. |
222 |
|
Clarification of the specification is required. */ |
223 |
|
end = (1ULL << 32) - (1 << 10); |
224 |
|
#else |
225 |
|
/* This is effectively what kickstart does. */ |
226 |
|
end = 0; |
227 |
|
#endif |
228 |
|
} |
229 |
|
else if (end >> 32) |
230 |
|
panic ("L4 does not support more than 4 GB on ia32"); |
231 |
|
|
232 |
if (mmap->base_addr_low & 0x2ff || mmap->length_low & 0x2ff) |
if (mmap->base_addr & ((1 << 10) - 1) |
233 |
panic ("Error: Memory region (0x%x - 0x%x) is unaligned", |
|| mmap->length & ((1 << 10) - 1)) |
234 |
mmap->base_addr_low, (unsigned long) end); |
panic ("Memory region (0x%x - 0x%x) is unaligned", |
235 |
|
(uint32_t) mmap->base_addr, (uint32_t) end); |
236 |
|
|
237 |
add_memory_map (mmap->base_addr_low, (unsigned long) end, |
add_memory_map ((uint32_t) mmap->base_addr, (uint32_t) end, |
238 |
mmap->type == 1 |
mmap->type == 1 |
239 |
? L4_MEMDESC_CONVENTIONAL : L4_MEMDESC_ARCH, |
? L4_MEMDESC_CONVENTIONAL : L4_MEMDESC_ARCH, |
240 |
mmap->type == 1 ? 0 : mmap->type); |
mmap->type == 1 ? 0 : mmap->type); |
244 |
{ |
{ |
245 |
/* mem_* are valid. */ |
/* mem_* are valid. */ |
246 |
if (mbi->mem_lower & 0x2ff) |
if (mbi->mem_lower & 0x2ff) |
247 |
panic ("Error: Lower memory end address 0x%x is unaligned", |
panic ("Lower memory end address 0x%x is unaligned", |
248 |
mbi->mem_lower); |
mbi->mem_lower); |
249 |
if (mbi->mem_upper & 0x2ff) |
if (mbi->mem_upper & 0x2ff) |
250 |
panic ("Error: Upper memory end address 0x%x is unaligned", |
panic ("Upper memory end address 0x%x is unaligned", |
251 |
mbi->mem_upper); |
mbi->mem_upper); |
252 |
|
|
253 |
add_memory_map (0, mbi->mem_lower << 10, L4_MEMDESC_CONVENTIONAL, 0); |
add_memory_map (0, mbi->mem_lower << 10, L4_MEMDESC_CONVENTIONAL, 0); |
269 |
memory_map_t *mmap; |
memory_map_t *mmap; |
270 |
|
|
271 |
for (mmap = (memory_map_t *) mbi->mmap_addr; |
for (mmap = (memory_map_t *) mbi->mmap_addr; |
272 |
(unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; |
(uint32_t) mmap < mbi->mmap_addr + mbi->mmap_length; |
273 |
mmap = (memory_map_t *) ((unsigned long) mmap |
mmap = (memory_map_t *) ((uint32_t) mmap |
274 |
+ mmap->size + sizeof (mmap->size))) |
+ mmap->size + sizeof (mmap->size))) |
275 |
{ |
{ |
276 |
if (mmap->type != 1) |
if (mmap->type != 1) |
277 |
continue; |
continue; |
278 |
|
|
279 |
if (mmap->length_low >= KMEM_SIZE |
if (((uint32_t) mmap->length) >= KMEM_SIZE |
280 |
&& mmap->base_addr_low <= KMEM_MAX - KMEM_SIZE) |
&& ((uint32_t) mmap->base_addr) <= KMEM_MAX - KMEM_SIZE) |
281 |
{ |
{ |
282 |
unsigned long high = mmap->base_addr_low + mmap->length_low; |
uint32_t high = ((uint32_t) mmap->base_addr) |
283 |
unsigned long low; |
+ ((uint32_t) mmap->length); |
284 |
|
uint32_t low; |
285 |
|
|
286 |
if (high > KMEM_MAX) |
if (high > KMEM_MAX) |
287 |
high = KMEM_MAX; |
high = KMEM_MAX; |
297 |
{ |
{ |
298 |
if ((mbi->mem_upper << 10) >= KMEM_SIZE) |
if ((mbi->mem_upper << 10) >= KMEM_SIZE) |
299 |
{ |
{ |
300 |
unsigned long high = (mbi->mem_upper << 10) + 0x100000; |
uint32_t high = (mbi->mem_upper << 10) + 0x100000; |
301 |
unsigned long low; |
uint32_t low; |
302 |
|
|
303 |
if (high > KMEM_MAX) |
if (high > KMEM_MAX) |
304 |
high = KMEM_MAX; |
high = KMEM_MAX; |