Fill out ChromeOS specific coreboot table extensions
[coreboot.git] / src / arch / x86 / boot / coreboot_table.c
index 49cdb29356fa91efe1fd9f2e9f98f93b002ae807..219de7adae6f551b2be30fe498a285d136240ca1 100644 (file)
 #include <version.h>
 #include <device/device.h>
 #include <stdlib.h>
-#if (CONFIG_USE_OPTION_TABLE == 1)
-#include <option_table.h>
 #include <cbfs.h>
+#include <cbmem.h>
+#if CONFIG_USE_OPTION_TABLE
+#include <option_table.h>
 #endif
 
 static struct lb_header *lb_table_init(unsigned long addr)
@@ -112,14 +113,32 @@ static struct lb_serial *lb_serial(struct lb_header *header)
        serial = (struct lb_serial *)rec;
        serial->tag = LB_TAG_SERIAL;
        serial->size = sizeof(*serial);
-       serial->ioport = CONFIG_TTYS0_BASE;
+       serial->type = LB_SERIAL_TYPE_IO_MAPPED;
+       serial->baseaddr = CONFIG_TTYS0_BASE;
        serial->baud = CONFIG_TTYS0_BAUD;
        return serial;
+#elif CONFIG_CONSOLE_SERIAL8250MEM
+       if (uartmem_getbaseaddr()) {
+               struct lb_record *rec;
+               struct lb_serial *serial;
+               rec = lb_new_record(header);
+               serial = (struct lb_serial *)rec;
+               serial->tag = LB_TAG_SERIAL;
+               serial->size = sizeof(*serial);
+               serial->type = LB_SERIAL_TYPE_MEMORY_MAPPED;
+               serial->baseaddr = uartmem_getbaseaddr();
+               serial->baud = CONFIG_TTYS0_BAUD;
+               return serial;
+       } else {
+               return NULL;
+       }
 #else
-       return header;
+       return NULL;
 #endif
 }
 
+#if CONFIG_CONSOLE_SERIAL8250 || CONFIG_CONSOLE_SERIAL8250MEM || \
+    CONFIG_CONSOLE_LOGBUF || CONFIG_USBDEBUG
 static void add_console(struct lb_header *header, u16 consoletype)
 {
        struct lb_console *console;
@@ -129,12 +148,16 @@ static void add_console(struct lb_header *header, u16 consoletype)
        console->size = sizeof(*console);
        console->type = consoletype;
 }
+#endif
 
 static void lb_console(struct lb_header *header)
 {
 #if CONFIG_CONSOLE_SERIAL8250
        add_console(header, LB_TAG_CONSOLE_SERIAL8250);
 #endif
+#if CONFIG_CONSOLE_SERIAL8250MEM
+       add_console(header, LB_TAG_CONSOLE_SERIAL8250MEM);
+#endif
 #if CONFIG_CONSOLE_LOGBUF
        add_console(header, LB_TAG_CONSOLE_LOGBUF);
 #endif
@@ -145,7 +168,7 @@ static void lb_console(struct lb_header *header)
 
 static void lb_framebuffer(struct lb_header *header)
 {
-#if defined(CONFIG_BOOTSPLASH) && CONFIG_BOOTSPLASH && CONFIG_COREBOOT_KEEP_FRAMEBUFFER
+#if CONFIG_FRAMEBUFFER_KEEP_VESA_MODE
        void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
 
        struct lb_framebuffer *framebuffer;
@@ -156,6 +179,73 @@ static void lb_framebuffer(struct lb_header *header)
 #endif
 }
 
+#if CONFIG_CHROMEOS
+static void lb_gpios(struct lb_header *header)
+{
+       struct lb_gpios *gpios;
+       gpios = (struct lb_gpios *)lb_new_record(header);
+       gpios->tag = LB_TAG_GPIO;
+       gpios->size = sizeof(*gpios);
+       gpios->count = 0;
+       fill_lb_gpios(gpios);
+}
+
+static void lb_vdat(struct lb_header *header)
+{
+       struct lb_vdat* vdat;
+
+       vdat = (struct lb_vdat *)lb_new_record(header);
+       vdat->tag = LB_TAG_VDAT;
+       vdat->size = sizeof(*vdat);
+       acpi_get_vdat_info(&vdat->vdat_addr, &vdat->vdat_size);
+}
+
+static void lb_vbnv(struct lb_header *header)
+{
+       struct lb_vbnv* vbnv;
+
+       vbnv = (struct lb_vbnv *)lb_new_record(header);
+       vbnv->tag = LB_TAG_VBNV;
+       vbnv->size = sizeof(*vbnv);
+       vbnv->vbnv_start = CONFIG_VBNV_OFFSET + 14;
+       vbnv->vbnv_size = CONFIG_VBNV_SIZE;
+}
+#endif
+
+static void add_cbmem_pointers(struct lb_header *header)
+{
+       /*
+        * These CBMEM sections' addresses are included in the coreboot table
+        * with the appropriate tags.
+        */
+       const struct section_id {
+               int cbmem_id;
+               int table_tag;
+       } section_ids[] = {
+               {CBMEM_ID_TIMESTAMP, LB_TAG_TIMESTAMPS},
+               {CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE}
+       };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(section_ids); i++) {
+               const struct section_id *sid = section_ids + i;
+               struct lb_cbmem_ref *cbmem_ref;
+               void *cbmem_addr = cbmem_find(sid->cbmem_id);
+
+               if (!cbmem_addr)
+                       continue;  /* This section is not present */
+
+               cbmem_ref = (struct lb_cbmem_ref *)lb_new_record(header);
+               if (!cbmem_ref) {
+                       printk(BIOS_ERR, "No more room in coreboot table!\n");
+                       break;
+               }
+               cbmem_ref->tag = sid->table_tag;
+               cbmem_ref->size = sizeof(*cbmem_ref);
+               cbmem_ref->cbmem_addr = cbmem_addr;
+       }
+}
+
 static struct lb_mainboard *lb_mainboard(struct lb_header *header)
 {
        struct lb_record *rec;
@@ -180,7 +270,7 @@ static struct lb_mainboard *lb_mainboard(struct lb_header *header)
        return mainboard;
 }
 
-#if (CONFIG_USE_OPTION_TABLE == 1)
+#if CONFIG_USE_OPTION_TABLE
 static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header)
 {
        struct lb_record *rec;
@@ -302,9 +392,10 @@ static unsigned long lb_table_fini(struct lb_header *head, int fixup)
        head->table_checksum = compute_ip_checksum(first_rec, head->table_bytes);
        head->header_checksum = 0;
        head->header_checksum = compute_ip_checksum(head, sizeof(*head));
-       printk(BIOS_DEBUG, "Wrote coreboot table at: %p - %p  checksum %x\n",
-               head, rec, head->table_checksum);
-       return (unsigned long)rec;
+       printk(BIOS_DEBUG,
+              "Wrote coreboot table at: %p, 0x%x bytes, checksum %x\n",
+              head, head->table_bytes, head->table_checksum);
+       return (unsigned long)rec + rec->size;
 }
 
 static void lb_cleanup_memory_ranges(struct lb_memory *mem)
@@ -494,10 +585,6 @@ static void add_lb_reserved(struct lb_memory *mem)
                lb_add_rsvd_range, mem);
 }
 
-#if CONFIG_WRITE_HIGH_TABLES == 1
-extern uint64_t high_tables_base, high_tables_size;
-#endif
-
 unsigned long write_coreboot_table(
        unsigned long low_table_start, unsigned long low_table_end,
        unsigned long rom_table_start, unsigned long rom_table_end)
@@ -505,7 +592,7 @@ unsigned long write_coreboot_table(
        struct lb_header *head;
        struct lb_memory *mem;
 
-#if CONFIG_WRITE_HIGH_TABLES == 1
+#if CONFIG_WRITE_HIGH_TABLES
        printk(BIOS_DEBUG, "Writing high table forward entry at 0x%08lx\n",
                        low_table_end);
        head = lb_table_init(low_table_end);
@@ -541,7 +628,7 @@ unsigned long write_coreboot_table(
        rom_table_end &= ~0xffff;
        printk(BIOS_DEBUG, "0x%08lx \n", rom_table_end);
 
-#if (CONFIG_USE_OPTION_TABLE == 1)
+#if CONFIG_USE_OPTION_TABLE
        {
                struct cmos_option_table *option_table = cbfs_find_file("cmos_layout.bin", 0x1aa);
                if (option_table) {
@@ -566,7 +653,7 @@ unsigned long write_coreboot_table(
        lb_add_memory_range(mem, LB_MEM_TABLE,
                rom_table_start, rom_table_end-rom_table_start);
 
-#if CONFIG_WRITE_HIGH_TABLES == 1
+#if CONFIG_WRITE_HIGH_TABLES
        printk(BIOS_DEBUG, "Adding high table area\n");
        // should this be LB_MEM_ACPI?
        lb_add_memory_range(mem, LB_MEM_TABLE,
@@ -576,7 +663,7 @@ unsigned long write_coreboot_table(
        /* Add reserved regions */
        add_lb_reserved(mem);
 
-#if (CONFIG_HAVE_MAINBOARD_RESOURCES == 1)
+#if CONFIG_HAVE_MAINBOARD_RESOURCES
        add_mainboard_resources(mem);
 #endif
 
@@ -600,6 +687,18 @@ unsigned long write_coreboot_table(
        /* Record our framebuffer */
        lb_framebuffer(head);
 
+#if CONFIG_CHROMEOS
+       /* Record our GPIO settings (ChromeOS specific) */
+       lb_gpios(head);
+
+       /* pass along the VDAT buffer adress */
+       lb_vdat(head);
+
+       /* pass along VBNV offsets in CMOS */
+       lb_vbnv(head);
+#endif
+       add_cbmem_pointers(head);
+
        /* Remember where my valid memory ranges are */
        return lb_table_fini(head, 1);