aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/boot/coreboot_table.c38
-rw-r--r--src/arch/i386/boot/coreboot_table.h1
-rw-r--r--src/arch/i386/boot/tables.c29
-rw-r--r--src/include/boot/coreboot_tables.h7
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