3 * Copyright (C) 2008 Advanced Micro Devices, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <libpayload-config.h>
30 #include <libpayload.h>
31 #include <multiboot_tables.h>
33 extern unsigned long loader_eax
;
34 extern unsigned long loader_ebx
;
36 static int mb_add_memrange(struct sysinfo_t
*info
, unsigned long long base
,
37 unsigned long long size
, unsigned int type
)
39 if (info
->n_memranges
>= SYSINFO_MAX_MEM_RANGES
)
42 #if CONFIG(LP_MEMMAP_RAM_ONLY)
43 /* 1 == normal RAM. Ignore everything else for now */
48 info
->memrange
[info
->n_memranges
].base
= base
;
49 info
->memrange
[info
->n_memranges
].size
= size
;
50 info
->memrange
[info
->n_memranges
].type
= type
;
56 static void mb_parse_mmap(struct multiboot_header
*table
,
57 struct sysinfo_t
*info
)
59 u8
*start
= (u8
*) phys_to_virt(table
->mmap_addr
);
62 info
->n_memranges
= 0;
64 while(ptr
< (start
+ table
->mmap_length
)) {
65 struct multiboot_mmap
*mmap
= (struct multiboot_mmap
*) ptr
;
67 if (mb_add_memrange(info
, mmap
->addr
, mmap
->length
, mmap
->type
))
70 ptr
+= (mmap
->size
+ sizeof(mmap
->size
));
74 static void mb_parse_meminfo(struct multiboot_header
*table
,
75 struct sysinfo_t
*info
)
77 unsigned long long mem_low
= table
->mem_lower
;
78 unsigned long long mem_high
= table
->mem_higher
;
80 info
->n_memranges
= 0;
83 mb_add_memrange(info
, 0 * MiB
, mem_low
* KiB
, 1);
86 mb_add_memrange(info
, 1 * MiB
, mem_high
* KiB
, 1);
89 static void mb_parse_cmdline(struct multiboot_header
*table
)
92 extern char *main_argv
[];
93 char *c
= phys_to_virt(table
->cmdline
);
95 while(*c
!= '\0' && main_argc
< MAX_ARGC_COUNT
) {
96 main_argv
[main_argc
++] = c
;
98 for( ; *c
!= '\0' && !isspace(*c
); c
++);
107 int get_multiboot_info(struct sysinfo_t
*info
)
109 struct multiboot_header
*table
;
111 if (loader_eax
!= MULTIBOOT_MAGIC
)
114 table
= (struct multiboot_header
*) phys_to_virt(loader_ebx
);
116 info
->mbtable
= phys_to_virt(loader_ebx
);
118 if (table
->flags
& MULTIBOOT_FLAGS_MMAP
)
119 mb_parse_mmap(table
, info
);
120 else if (table
->flags
& MULTIBOOT_FLAGS_MEMINFO
)
121 mb_parse_meminfo(table
, info
);
123 if (table
->flags
& MULTIBOOT_FLAGS_CMDLINE
)
124 mb_parse_cmdline(table
);