diff options
-rw-r--r-- | src/arch/i386/boot/coreboot_table.c | 38 | ||||
-rw-r--r-- | src/arch/i386/boot/coreboot_table.h | 1 | ||||
-rw-r--r-- | src/arch/i386/boot/tables.c | 29 | ||||
-rw-r--r-- | src/include/boot/coreboot_tables.h | 7 |
4 files changed, 53 insertions, 22 deletions
diff --git a/src/arch/i386/boot/coreboot_table.c b/src/arch/i386/boot/coreboot_table.c index 55a1697a59..032a0f3264 100644 --- a/src/arch/i386/boot/coreboot_table.c +++ b/src/arch/i386/boot/coreboot_table.c @@ -196,6 +196,18 @@ void lb_strings(struct lb_header *header) } +struct lb_forward *lb_forward(struct lb_header *header, struct lb_header *next_header) +{ + struct lb_record *rec; + struct lb_forward *forward; + rec = lb_new_record(header); + forward = (struct lb_forward *)rec; + forward->tag = LB_TAG_FORWARD; + forward->size = sizeof(*forward); + forward->forward = (uint64_t) next_header; + return forward; +} + void lb_memory_range(struct lb_memory *mem, uint32_t type, uint64_t start, uint64_t size) { @@ -239,14 +251,17 @@ static void lb_reserve_table_memory(struct lb_header *head) } } -unsigned long lb_table_fini(struct lb_header *head) +static unsigned long lb_table_fini(struct lb_header *head, int fixup) { struct lb_record *rec, *first_rec; rec = lb_last_record(head); if (head->table_entries) { head->table_bytes += rec->size; } - lb_reserve_table_memory(head); + + if (fixup) + lb_reserve_table_memory(head); + first_rec = lb_first_record(head); head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes); head->header_checksum = 0; @@ -406,6 +421,22 @@ unsigned long write_coreboot_table( struct lb_header *head; struct lb_memory *mem; +#if HAVE_HIGH_TABLES == 1 + printk_debug("Writing high table forward entry at 0x%08lx\n", + low_table_end); + head = lb_table_init(low_table_end); + lb_forward(head, rom_table_end); + lb_table_fini(head, 0); + + low_table_end = (unsigned long)head; + printk_debug("New low_table_end: 0x%08lx\n", low_table_end); + printk_debug("Now going to write high coreboot table at 0x%08lx\n", + rom_table_end); + + head = lb_table_init(rom_table_end); + rom_table_end = (unsigned long)head; + printk_debug("rom_table_end = 0x%08lx\n", rom_table_end); +#else if(low_table_end > (0x1000 - sizeof(struct lb_header))) { /* after 4K */ /* We need to put lbtable on to [0xf0000,0x100000) */ head = lb_table_init(rom_table_end); @@ -414,6 +445,7 @@ unsigned long write_coreboot_table( head = lb_table_init(low_table_end); low_table_end = (unsigned long)head; } +#endif printk_debug("Adjust low_table_end from 0x%08lx to ", low_table_end); low_table_end += 0xfff; // 4K aligned @@ -469,6 +501,6 @@ unsigned long write_coreboot_table( lb_strings(head); /* Remember where my valid memory ranges are */ - return lb_table_fini(head); + return lb_table_fini(head, 1); } diff --git a/src/arch/i386/boot/coreboot_table.h b/src/arch/i386/boot/coreboot_table.h index 4c8c44a18c..9a9be84d43 100644 --- a/src/arch/i386/boot/coreboot_table.h +++ b/src/arch/i386/boot/coreboot_table.h @@ -17,7 +17,6 @@ struct lb_memory *lb_memory(struct lb_header *header); void lb_memory_range(struct lb_memory *mem, uint32_t type, uint64_t start, uint64_t size); struct lb_mainboard *lb_mainboard(struct lb_header *header); -unsigned long lb_table_fini(struct lb_header *header); /* Routines to extract part so the coreboot table or information * from the coreboot table. diff --git a/src/arch/i386/boot/tables.c b/src/arch/i386/boot/tables.c index 58c5ce896a..72f2344911 100644 --- a/src/arch/i386/boot/tables.c +++ b/src/arch/i386/boot/tables.c @@ -75,7 +75,7 @@ struct lb_memory *write_tables(void) unsigned long high_table_start, high_table_end=0; if (high_tables_base) { - printk_debug("High Tables Base is %lx.\n", high_tables_base); + printk_debug("High Tables Base is %llx.\n", high_tables_base); high_table_start = high_tables_base; high_table_end = high_tables_base; } else { @@ -189,26 +189,19 @@ struct lb_memory *write_tables(void) rom_table_start, rom_table_end); #endif +#if HAVE_HIGH_TABLES == 1 + if (high_tables_base) { + write_coreboot_table(low_table_start, low_table_end, + high_table_start, high_table_end); + } else { + printk_err("ERROR: No high_tables_base.\n"); + write_coreboot_table(low_table_start, low_table_end, + rom_table_start, rom_table_end); + } +#else /* The coreboot table must be in 0-4K or 960K-1M */ write_coreboot_table(low_table_start, low_table_end, rom_table_start, rom_table_end); - -#if 0 && HAVE_HIGH_TABLES == 1 - /* This is currently broken and should be severely refactored. Ideally - * we only have a pointer to the coreboot table in the low memory, so - * anyone can find the real position. - * write_coreboot_table does a lot more than just writing the coreboot - * table. It magically decides where the table should go, and therefore - * it consumes two base addresses. If we call write_coreboot_table like - * below, we get weird effects. - */ - /* And we want another copy in high area because the low area might be - * corrupted - */ - if (high_tables_base) { - write_coreboot_table(high_table_start, high_table_end, - high_table_start, high_table_end); - } #endif return get_lb_mem(); diff --git a/src/include/boot/coreboot_tables.h b/src/include/boot/coreboot_tables.h index 3f8e60698e..f0ab7af7cb 100644 --- a/src/include/boot/coreboot_tables.h +++ b/src/include/boot/coreboot_tables.h @@ -155,6 +155,13 @@ struct lb_console { uint16_t type; }; +#define LB_TAG_FORWARD 0x0011 +struct lb_forward { + uint32_t tag; + uint32_t size; + uint64_t forward; +}; + #define LB_TAG_CONSOLE_SERIAL8250 0 #define LB_TAG_CONSOLE_VGA 1 #define LB_TAG_CONSOLE_BTEXT 2 |