Generate multiboot tables from coreboot tables.
Signed-off-by: Juhana Helovuo <juhe@iki.fi> Acked-by: Myles Watson <mylesgw@gmail.com> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5806 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
50b78b66d3
commit
6b56e43b6d
|
@ -22,62 +22,16 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <device/resource.h>
|
#include <device/resource.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <boot/coreboot_tables.h>
|
||||||
|
#include <arch/coreboot_tables.h>
|
||||||
|
|
||||||
static struct multiboot_mmap_entry *mb_mem;
|
|
||||||
struct multiboot_info *mbi = NULL;
|
struct multiboot_info *mbi = NULL;
|
||||||
|
|
||||||
static struct {
|
unsigned long write_multiboot_info(unsigned long rom_table_end)
|
||||||
u64 addr;
|
|
||||||
u64 len;
|
|
||||||
} reserved_mem[2];
|
|
||||||
|
|
||||||
static void build_mb_mem_range_nooverlap(u64 addr, u64 len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) {
|
|
||||||
/* free region fully contained in reserved region, abort */
|
|
||||||
if (addr >= reserved_mem[i].addr && addr + len <= reserved_mem[i].addr + reserved_mem[i].len)
|
|
||||||
return;
|
|
||||||
/* reserved region splits free region */
|
|
||||||
if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr + reserved_mem[i].len) {
|
|
||||||
build_mb_mem_range_nooverlap(addr, reserved_mem[i].addr - addr);
|
|
||||||
build_mb_mem_range_nooverlap(reserved_mem[i].addr + reserved_mem[i].len, (addr + len) - (reserved_mem[i].addr + reserved_mem[i].len));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* left overlap */
|
|
||||||
if (addr < reserved_mem[i].addr + reserved_mem[i].len && addr + len > reserved_mem[i].addr + reserved_mem[i].len) {
|
|
||||||
len += addr;
|
|
||||||
addr = reserved_mem[i].addr + reserved_mem[i].len;
|
|
||||||
len -= addr;
|
|
||||||
/* len += addr - old_addr */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* right overlap */
|
|
||||||
if (addr < reserved_mem[i].addr && addr + len > reserved_mem[i].addr) {
|
|
||||||
len = reserved_mem[i].addr - addr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* none of the above, just add it */
|
|
||||||
}
|
|
||||||
|
|
||||||
mb_mem->addr = addr;
|
|
||||||
mb_mem->len = len;
|
|
||||||
mb_mem->type = 1;
|
|
||||||
mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
|
|
||||||
mb_mem++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void build_mb_mem_range(void *gp, struct device *dev, struct resource *res)
|
|
||||||
{
|
|
||||||
build_mb_mem_range_nooverlap(res->base, res->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ROUND(_r,_a) (((_r) + (((_a) - 1))) & ~((_a) - 1))
|
|
||||||
|
|
||||||
unsigned long write_multiboot_info(
|
|
||||||
unsigned long low_table_start, unsigned long low_table_end,
|
|
||||||
unsigned long rom_table_start, unsigned long rom_table_end)
|
|
||||||
{
|
{
|
||||||
|
static struct multiboot_mmap_entry *mb_mem;
|
||||||
|
struct lb_memory* coreboot_table;
|
||||||
|
int entries;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mbi = (struct multiboot_info *)rom_table_end;
|
mbi = (struct multiboot_info *)rom_table_end;
|
||||||
|
@ -88,26 +42,31 @@ unsigned long write_multiboot_info(
|
||||||
mbi->mmap_addr = (u32) rom_table_end;
|
mbi->mmap_addr = (u32) rom_table_end;
|
||||||
mb_mem = (struct multiboot_mmap_entry *)rom_table_end;
|
mb_mem = (struct multiboot_mmap_entry *)rom_table_end;
|
||||||
|
|
||||||
/* FIXME This code is broken, it does not know about high memory
|
/* copy regions from coreboot tables */
|
||||||
* tables, nor does it reserve the coreboot table area.
|
coreboot_table = get_lb_mem();
|
||||||
*/
|
entries = (coreboot_table->size - sizeof(*coreboot_table))/sizeof(coreboot_table->map[0]);
|
||||||
/* reserved regions */
|
|
||||||
reserved_mem[0].addr = low_table_start;
|
|
||||||
reserved_mem[0].len = ROUND(low_table_end - low_table_start, 4096);
|
|
||||||
reserved_mem[1].addr = rom_table_start;
|
|
||||||
reserved_mem[1].len = ROUND(rom_table_end - rom_table_start, 4096);
|
|
||||||
|
|
||||||
for (i = 0; i < sizeof(reserved_mem) / sizeof(reserved_mem[0]); i++) {
|
if (coreboot_table == NULL || entries < 1) {
|
||||||
mb_mem->addr = reserved_mem[i].addr;
|
printk(BIOS_INFO, "%s: Cannot find coreboot table.\n", __func__);
|
||||||
mb_mem->len = reserved_mem[i].len;
|
return (unsigned long) mb_mem;
|
||||||
mb_mem->type = 2;
|
|
||||||
mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
|
|
||||||
mb_mem++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free regions */
|
for (i = 0; i < entries; i++) {
|
||||||
search_global_resources( IORESOURCE_MEM | IORESOURCE_CACHEABLE,
|
uint64_t entry_start = unpack_lb64(coreboot_table->map[i].start);
|
||||||
IORESOURCE_MEM | IORESOURCE_CACHEABLE, build_mb_mem_range, NULL);
|
uint64_t entry_size = unpack_lb64(coreboot_table->map[i].size);
|
||||||
|
mb_mem->addr = entry_start;
|
||||||
|
mb_mem->len = entry_size;
|
||||||
|
switch (coreboot_table->map[i].type) {
|
||||||
|
case LB_MEM_RAM:
|
||||||
|
mb_mem->type = MULTIBOOT_MEMORY_AVAILABLE;
|
||||||
|
break;
|
||||||
|
default: // anything other than usable RAM
|
||||||
|
mb_mem->type = MULTIBOOT_MEMORY_RESERVED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mb_mem->size = sizeof(*mb_mem) - sizeof(mb_mem->size);
|
||||||
|
mb_mem++;
|
||||||
|
}
|
||||||
|
|
||||||
mbi->mmap_length = ((u32) mb_mem) - mbi->mmap_addr;
|
mbi->mmap_length = ((u32) mb_mem) - mbi->mmap_addr;
|
||||||
mbi->flags |= MB_INFO_MEM_MAP;
|
mbi->flags |= MB_INFO_MEM_MAP;
|
||||||
|
|
|
@ -179,14 +179,6 @@ struct lb_memory *write_tables(void)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_MULTIBOOT
|
|
||||||
post_code(0x9d);
|
|
||||||
|
|
||||||
/* The Multiboot information structure */
|
|
||||||
rom_table_end = write_multiboot_info(
|
|
||||||
low_table_start, low_table_end,
|
|
||||||
rom_table_start, rom_table_end);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_COREBOOT_TABLE_SIZE (8 * 1024)
|
#define MAX_COREBOOT_TABLE_SIZE (8 * 1024)
|
||||||
post_code(0x9d);
|
post_code(0x9d);
|
||||||
|
@ -210,8 +202,9 @@ struct lb_memory *write_tables(void)
|
||||||
new_high_table_pointer - high_table_pointer);
|
new_high_table_pointer - high_table_pointer);
|
||||||
} else {
|
} else {
|
||||||
/* The coreboot table must be in 0-4K or 960K-1M */
|
/* The coreboot table must be in 0-4K or 960K-1M */
|
||||||
write_coreboot_table(low_table_start, low_table_end,
|
rom_table_end = write_coreboot_table(
|
||||||
rom_table_start, rom_table_end);
|
low_table_start, low_table_end,
|
||||||
|
rom_table_start, rom_table_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
post_code(0x9e);
|
post_code(0x9e);
|
||||||
|
@ -224,6 +217,13 @@ struct lb_memory *write_tables(void)
|
||||||
cbmem_add(CBMEM_ID_RESUME, 1024 * (1024-64));
|
cbmem_add(CBMEM_ID_RESUME, 1024 * (1024-64));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_MULTIBOOT
|
||||||
|
post_code(0x9d);
|
||||||
|
|
||||||
|
/* The Multiboot information structure */
|
||||||
|
write_multiboot_info(rom_table_end);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Remove before sending upstream
|
// Remove before sending upstream
|
||||||
cbmem_list();
|
cbmem_list();
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,9 @@ struct multiboot_info {
|
||||||
uint16_t vbe_interface_len;
|
uint16_t vbe_interface_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||||
|
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||||
|
|
||||||
struct multiboot_mmap_entry {
|
struct multiboot_mmap_entry {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint64_t addr;
|
uint64_t addr;
|
||||||
|
@ -176,6 +179,6 @@ struct multiboot_mmap_entry {
|
||||||
|
|
||||||
extern struct multiboot_info *mbi;
|
extern struct multiboot_info *mbi;
|
||||||
|
|
||||||
unsigned long write_multiboot_info(unsigned long, unsigned long, unsigned long, unsigned long);
|
unsigned long write_multiboot_info(unsigned long rom_table_end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue