2020-04-02 23:48:34 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2009-08-27 13:23:06 +02:00
|
|
|
|
2016-04-21 21:06:17 +02:00
|
|
|
#include <arch/cbconfig.h>
|
2003-04-22 21:02:15 +02:00
|
|
|
#include <console/console.h>
|
2014-02-17 20:34:42 +01:00
|
|
|
#include <console/uart.h>
|
2003-04-22 21:02:15 +02:00
|
|
|
#include <ip_checksum.h>
|
2008-01-18 17:16:45 +01:00
|
|
|
#include <boot/coreboot_tables.h>
|
2016-04-20 03:37:51 +02:00
|
|
|
#include <boot/tables.h>
|
2015-07-14 18:15:51 +02:00
|
|
|
#include <boot_device.h>
|
2003-04-22 21:02:15 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <version.h>
|
2014-07-29 01:03:07 +02:00
|
|
|
#include <boardid.h>
|
2004-10-14 22:54:17 +02:00
|
|
|
#include <device/device.h>
|
2015-07-14 18:15:51 +02:00
|
|
|
#include <fmap.h>
|
2004-10-14 22:54:17 +02:00
|
|
|
#include <stdlib.h>
|
2011-08-16 01:35:10 +02:00
|
|
|
#include <cbfs.h>
|
2011-09-23 18:56:11 +02:00
|
|
|
#include <cbmem.h>
|
2014-02-19 04:55:02 +01:00
|
|
|
#include <bootmem.h>
|
2019-07-28 09:28:33 +02:00
|
|
|
#include <bootsplash.h>
|
2015-01-08 19:29:19 +01:00
|
|
|
#include <spi_flash.h>
|
2019-03-13 11:10:52 +01:00
|
|
|
#include <security/vboot/misc.h>
|
2017-10-17 17:02:29 +02:00
|
|
|
#include <security/vboot/vbnv_layout.h>
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(USE_OPTION_TABLE)
|
2015-09-21 20:11:47 +02:00
|
|
|
#include <option_table.h>
|
|
|
|
#endif
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(CHROMEOS)
|
|
|
|
#if CONFIG(HAVE_ACPI_TABLES)
|
2020-05-02 19:24:23 +02:00
|
|
|
#include <acpi/acpi.h>
|
2013-03-20 22:08:04 +01:00
|
|
|
#endif
|
2013-03-08 06:15:06 +01:00
|
|
|
#include <vendorcode/google/chromeos/chromeos.h>
|
2012-04-27 00:34:54 +02:00
|
|
|
#include <vendorcode/google/chromeos/gnvs.h>
|
|
|
|
#endif
|
2020-05-28 08:04:58 +02:00
|
|
|
#if CONFIG(PLATFORM_USES_FSP2_0)
|
|
|
|
#include <fsp/util.h>
|
|
|
|
#else
|
|
|
|
void lb_string_platform_blob_version(struct lb_header *header);
|
|
|
|
#endif
|
2003-04-22 21:02:15 +02:00
|
|
|
|
2009-08-27 13:23:06 +02:00
|
|
|
static struct lb_header *lb_table_init(unsigned long addr)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_header *header;
|
|
|
|
|
|
|
|
/* 16 byte align the address */
|
|
|
|
addr += 15;
|
|
|
|
addr &= ~15;
|
|
|
|
|
|
|
|
header = (void *)addr;
|
|
|
|
header->signature[0] = 'L';
|
|
|
|
header->signature[1] = 'B';
|
|
|
|
header->signature[2] = 'I';
|
|
|
|
header->signature[3] = 'O';
|
|
|
|
header->header_bytes = sizeof(*header);
|
|
|
|
header->header_checksum = 0;
|
|
|
|
header->table_bytes = 0;
|
|
|
|
header->table_checksum = 0;
|
|
|
|
header->table_entries = 0;
|
|
|
|
return header;
|
|
|
|
}
|
|
|
|
|
2009-08-27 13:23:06 +02:00
|
|
|
static struct lb_record *lb_first_record(struct lb_header *header)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_record *rec;
|
|
|
|
rec = (void *)(((char *)header) + sizeof(*header));
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
2009-08-27 13:23:06 +02:00
|
|
|
static struct lb_record *lb_last_record(struct lb_header *header)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_record *rec;
|
2017-03-11 00:23:24 +01:00
|
|
|
rec = (void *)(((char *)header) + sizeof(*header)
|
|
|
|
+ header->table_bytes);
|
2003-04-22 21:02:15 +02:00
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
2013-08-28 00:48:32 +02:00
|
|
|
struct lb_record *lb_new_record(struct lb_header *header)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_record *rec;
|
|
|
|
rec = lb_last_record(header);
|
2017-03-09 02:37:06 +01:00
|
|
|
if (header->table_entries)
|
2003-04-22 21:02:15 +02:00
|
|
|
header->table_bytes += rec->size;
|
|
|
|
rec = lb_last_record(header);
|
|
|
|
header->table_entries++;
|
|
|
|
rec->tag = LB_TAG_UNUSED;
|
|
|
|
rec->size = sizeof(*rec);
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
2009-08-27 13:23:06 +02:00
|
|
|
static struct lb_memory *lb_memory(struct lb_header *header)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_record *rec;
|
|
|
|
struct lb_memory *mem;
|
|
|
|
rec = lb_new_record(header);
|
|
|
|
mem = (struct lb_memory *)rec;
|
|
|
|
mem->tag = LB_TAG_MEMORY;
|
|
|
|
mem->size = sizeof(*mem);
|
|
|
|
return mem;
|
|
|
|
}
|
|
|
|
|
2014-03-15 00:32:55 +01:00
|
|
|
void lb_add_serial(struct lb_serial *new_serial, void *data)
|
2008-01-25 19:28:18 +01:00
|
|
|
{
|
2014-03-15 00:32:55 +01:00
|
|
|
struct lb_header *header = (struct lb_header *)data;
|
2008-01-25 19:28:18 +01:00
|
|
|
struct lb_serial *serial;
|
2014-03-15 00:32:55 +01:00
|
|
|
|
|
|
|
serial = (struct lb_serial *)lb_new_record(header);
|
2008-01-25 19:28:18 +01:00
|
|
|
serial->tag = LB_TAG_SERIAL;
|
|
|
|
serial->size = sizeof(*serial);
|
2014-03-15 00:32:55 +01:00
|
|
|
serial->type = new_serial->type;
|
|
|
|
serial->baseaddr = new_serial->baseaddr;
|
|
|
|
serial->baud = new_serial->baud;
|
2015-01-10 01:54:19 +01:00
|
|
|
serial->regwidth = new_serial->regwidth;
|
2016-05-04 20:59:19 +02:00
|
|
|
serial->input_hertz = new_serial->input_hertz;
|
|
|
|
serial->uart_pci_addr = new_serial->uart_pci_addr;
|
2008-01-25 19:28:18 +01:00
|
|
|
}
|
|
|
|
|
2014-03-15 00:32:55 +01:00
|
|
|
void lb_add_console(uint16_t consoletype, void *data)
|
2008-01-27 15:12:54 +01:00
|
|
|
{
|
2014-03-15 00:32:55 +01:00
|
|
|
struct lb_header *header = (struct lb_header *)data;
|
2008-01-27 15:12:54 +01:00
|
|
|
struct lb_console *console;
|
2009-04-21 22:14:31 +02:00
|
|
|
|
2008-01-27 15:12:54 +01:00
|
|
|
console = (struct lb_console *)lb_new_record(header);
|
|
|
|
console->tag = LB_TAG_CONSOLE;
|
|
|
|
console->size = sizeof(*console);
|
|
|
|
console->type = consoletype;
|
|
|
|
}
|
|
|
|
|
2017-05-17 04:39:50 +02:00
|
|
|
static void lb_framebuffer(struct lb_header *header)
|
|
|
|
{
|
2010-02-22 05:33:13 +01:00
|
|
|
struct lb_framebuffer *framebuffer;
|
2017-06-26 10:50:14 +02:00
|
|
|
struct lb_framebuffer fb = {0};
|
2017-05-17 04:39:50 +02:00
|
|
|
|
2019-03-06 01:53:33 +01:00
|
|
|
if (!CONFIG(LINEAR_FRAMEBUFFER) || fill_lb_framebuffer(&fb))
|
2017-05-17 04:39:50 +02:00
|
|
|
return;
|
|
|
|
|
2010-02-22 05:33:13 +01:00
|
|
|
framebuffer = (struct lb_framebuffer *)lb_new_record(header);
|
2017-05-17 04:39:50 +02:00
|
|
|
memcpy(framebuffer, &fb, sizeof(*framebuffer));
|
2010-02-22 05:33:13 +01:00
|
|
|
framebuffer->tag = LB_TAG_FRAMEBUFFER;
|
|
|
|
framebuffer->size = sizeof(*framebuffer);
|
2019-07-28 09:28:33 +02:00
|
|
|
|
|
|
|
if (CONFIG(BOOTSPLASH)) {
|
|
|
|
uint8_t *fb_ptr = (uint8_t *)(uintptr_t)framebuffer->physical_address;
|
|
|
|
unsigned int width = framebuffer->x_resolution;
|
|
|
|
unsigned int height = framebuffer->y_resolution;
|
|
|
|
unsigned int depth = framebuffer->bits_per_pixel;
|
|
|
|
set_bootsplash(fb_ptr, width, height, depth);
|
|
|
|
}
|
2010-02-22 05:33:13 +01:00
|
|
|
}
|
|
|
|
|
chromeos: Simplify fill_lb_gpios even further
A long time ago many Chrome OS boards had pages full of duplicated
boilerplate code for the fill_lb_gpios() function, and we spent a lot of
time bikeshedding a proper solution that passes a table of lb_gpio
structs which can be concisely written with a static struct initializer
in http://crosreview.com/234648. Unfortunately we never really finished
that patch and in the mean time a different solution using the
fill_lb_gpio() helper got standardized onto most boards.
Still, that solution is not quite as clean and concise as the one we had
already designed, and it also wasn't applied consistently to all recent
boards (causing more boards with bad code to get added afterwards). This
patch switches all boards newer than Link to the better solution and
also adds some nicer debug output for the GPIOs while I'm there.
If more boards need to be converted from fill_lb_gpio() to this model
later (e.g. from a branch), it's quite easy to do with:
s/fill_lb_gpio(gpio++,\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\));/\t{\1, \2, \4, \3},/
Based on a patch by Furquan Shaikh <furquan@google.com>.
BUG=None
BRANCH=None
TEST=Booted on Oak. Ran abuild -x.
Change-Id: I449974d1c75c8ed187f5e10935495b2f03725811
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14226
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2016-04-01 02:27:05 +02:00
|
|
|
void lb_add_gpios(struct lb_gpios *gpios, const struct lb_gpio *gpio_table,
|
|
|
|
size_t count)
|
2013-12-22 02:12:38 +01:00
|
|
|
{
|
chromeos: Simplify fill_lb_gpios even further
A long time ago many Chrome OS boards had pages full of duplicated
boilerplate code for the fill_lb_gpios() function, and we spent a lot of
time bikeshedding a proper solution that passes a table of lb_gpio
structs which can be concisely written with a static struct initializer
in http://crosreview.com/234648. Unfortunately we never really finished
that patch and in the mean time a different solution using the
fill_lb_gpio() helper got standardized onto most boards.
Still, that solution is not quite as clean and concise as the one we had
already designed, and it also wasn't applied consistently to all recent
boards (causing more boards with bad code to get added afterwards). This
patch switches all boards newer than Link to the better solution and
also adds some nicer debug output for the GPIOs while I'm there.
If more boards need to be converted from fill_lb_gpio() to this model
later (e.g. from a branch), it's quite easy to do with:
s/fill_lb_gpio(gpio++,\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\));/\t{\1, \2, \4, \3},/
Based on a patch by Furquan Shaikh <furquan@google.com>.
BUG=None
BRANCH=None
TEST=Booted on Oak. Ran abuild -x.
Change-Id: I449974d1c75c8ed187f5e10935495b2f03725811
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14226
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2016-04-01 02:27:05 +02:00
|
|
|
size_t table_size = count * sizeof(struct lb_gpio);
|
|
|
|
|
|
|
|
memcpy(&gpios->gpios[gpios->count], gpio_table, table_size);
|
|
|
|
gpios->count += count;
|
|
|
|
gpios->size += table_size;
|
2013-12-22 02:12:38 +01:00
|
|
|
}
|
|
|
|
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(CHROMEOS)
|
2012-04-05 21:22:02 +02:00
|
|
|
static void lb_gpios(struct lb_header *header)
|
|
|
|
{
|
|
|
|
struct lb_gpios *gpios;
|
chromeos: Simplify fill_lb_gpios even further
A long time ago many Chrome OS boards had pages full of duplicated
boilerplate code for the fill_lb_gpios() function, and we spent a lot of
time bikeshedding a proper solution that passes a table of lb_gpio
structs which can be concisely written with a static struct initializer
in http://crosreview.com/234648. Unfortunately we never really finished
that patch and in the mean time a different solution using the
fill_lb_gpio() helper got standardized onto most boards.
Still, that solution is not quite as clean and concise as the one we had
already designed, and it also wasn't applied consistently to all recent
boards (causing more boards with bad code to get added afterwards). This
patch switches all boards newer than Link to the better solution and
also adds some nicer debug output for the GPIOs while I'm there.
If more boards need to be converted from fill_lb_gpio() to this model
later (e.g. from a branch), it's quite easy to do with:
s/fill_lb_gpio(gpio++,\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\));/\t{\1, \2, \4, \3},/
Based on a patch by Furquan Shaikh <furquan@google.com>.
BUG=None
BRANCH=None
TEST=Booted on Oak. Ran abuild -x.
Change-Id: I449974d1c75c8ed187f5e10935495b2f03725811
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14226
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2016-04-01 02:27:05 +02:00
|
|
|
struct lb_gpio *g;
|
2014-09-23 03:48:41 +02:00
|
|
|
|
2012-04-05 21:22:02 +02:00
|
|
|
gpios = (struct lb_gpios *)lb_new_record(header);
|
|
|
|
gpios->tag = LB_TAG_GPIO;
|
|
|
|
gpios->size = sizeof(*gpios);
|
|
|
|
gpios->count = 0;
|
|
|
|
fill_lb_gpios(gpios);
|
chromeos: Simplify fill_lb_gpios even further
A long time ago many Chrome OS boards had pages full of duplicated
boilerplate code for the fill_lb_gpios() function, and we spent a lot of
time bikeshedding a proper solution that passes a table of lb_gpio
structs which can be concisely written with a static struct initializer
in http://crosreview.com/234648. Unfortunately we never really finished
that patch and in the mean time a different solution using the
fill_lb_gpio() helper got standardized onto most boards.
Still, that solution is not quite as clean and concise as the one we had
already designed, and it also wasn't applied consistently to all recent
boards (causing more boards with bad code to get added afterwards). This
patch switches all boards newer than Link to the better solution and
also adds some nicer debug output for the GPIOs while I'm there.
If more boards need to be converted from fill_lb_gpio() to this model
later (e.g. from a branch), it's quite easy to do with:
s/fill_lb_gpio(gpio++,\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\));/\t{\1, \2, \4, \3},/
Based on a patch by Furquan Shaikh <furquan@google.com>.
BUG=None
BRANCH=None
TEST=Booted on Oak. Ran abuild -x.
Change-Id: I449974d1c75c8ed187f5e10935495b2f03725811
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14226
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2016-04-01 02:27:05 +02:00
|
|
|
|
|
|
|
printk(BIOS_INFO, "Passing %u GPIOs to payload:\n"
|
|
|
|
" NAME | PORT | POLARITY | VALUE\n",
|
|
|
|
gpios->count);
|
|
|
|
for (g = &gpios->gpios[0]; g < &gpios->gpios[gpios->count]; g++) {
|
|
|
|
printk(BIOS_INFO, "%16s | ", g->name);
|
|
|
|
if (g->port == -1)
|
|
|
|
printk(BIOS_INFO, " undefined | ");
|
|
|
|
else
|
|
|
|
printk(BIOS_INFO, "%#.8x | ", g->port);
|
|
|
|
if (g->polarity == ACTIVE_HIGH)
|
|
|
|
printk(BIOS_INFO, " high | ");
|
|
|
|
else
|
|
|
|
printk(BIOS_INFO, " low | ");
|
|
|
|
switch (g->value) {
|
|
|
|
case 0:
|
2018-03-07 22:06:53 +01:00
|
|
|
printk(BIOS_INFO, " low\n");
|
chromeos: Simplify fill_lb_gpios even further
A long time ago many Chrome OS boards had pages full of duplicated
boilerplate code for the fill_lb_gpios() function, and we spent a lot of
time bikeshedding a proper solution that passes a table of lb_gpio
structs which can be concisely written with a static struct initializer
in http://crosreview.com/234648. Unfortunately we never really finished
that patch and in the mean time a different solution using the
fill_lb_gpio() helper got standardized onto most boards.
Still, that solution is not quite as clean and concise as the one we had
already designed, and it also wasn't applied consistently to all recent
boards (causing more boards with bad code to get added afterwards). This
patch switches all boards newer than Link to the better solution and
also adds some nicer debug output for the GPIOs while I'm there.
If more boards need to be converted from fill_lb_gpio() to this model
later (e.g. from a branch), it's quite easy to do with:
s/fill_lb_gpio(gpio++,\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\));/\t{\1, \2, \4, \3},/
Based on a patch by Furquan Shaikh <furquan@google.com>.
BUG=None
BRANCH=None
TEST=Booted on Oak. Ran abuild -x.
Change-Id: I449974d1c75c8ed187f5e10935495b2f03725811
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14226
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2016-04-01 02:27:05 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
2018-03-07 22:06:53 +01:00
|
|
|
printk(BIOS_INFO, " high\n");
|
chromeos: Simplify fill_lb_gpios even further
A long time ago many Chrome OS boards had pages full of duplicated
boilerplate code for the fill_lb_gpios() function, and we spent a lot of
time bikeshedding a proper solution that passes a table of lb_gpio
structs which can be concisely written with a static struct initializer
in http://crosreview.com/234648. Unfortunately we never really finished
that patch and in the mean time a different solution using the
fill_lb_gpio() helper got standardized onto most boards.
Still, that solution is not quite as clean and concise as the one we had
already designed, and it also wasn't applied consistently to all recent
boards (causing more boards with bad code to get added afterwards). This
patch switches all boards newer than Link to the better solution and
also adds some nicer debug output for the GPIOs while I'm there.
If more boards need to be converted from fill_lb_gpio() to this model
later (e.g. from a branch), it's quite easy to do with:
s/fill_lb_gpio(gpio++,\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\),\n\?\s*\([^,]*\));/\t{\1, \2, \4, \3},/
Based on a patch by Furquan Shaikh <furquan@google.com>.
BUG=None
BRANCH=None
TEST=Booted on Oak. Ran abuild -x.
Change-Id: I449974d1c75c8ed187f5e10935495b2f03725811
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/14226
Tested-by: build bot (Jenkins)
Reviewed-by: David Hendricks <dhendrix@chromium.org>
2016-04-01 02:27:05 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printk(BIOS_INFO, "undefined\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-04-05 21:22:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void lb_vbnv(struct lb_header *header)
|
|
|
|
{
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(PC80_SYSTEM)
|
2013-08-28 00:38:54 +02:00
|
|
|
struct lb_range *vbnv;
|
2012-04-05 21:22:02 +02:00
|
|
|
|
2013-08-28 00:38:54 +02:00
|
|
|
vbnv = (struct lb_range *)lb_new_record(header);
|
2012-04-05 21:22:02 +02:00
|
|
|
vbnv->tag = LB_TAG_VBNV;
|
|
|
|
vbnv->size = sizeof(*vbnv);
|
2016-07-25 20:48:03 +02:00
|
|
|
vbnv->range_start = CONFIG_VBOOT_VBNV_OFFSET + 14;
|
|
|
|
vbnv->range_size = VBOOT_VBNV_BLOCK_SIZE;
|
2013-03-20 22:08:04 +01:00
|
|
|
#endif
|
2012-04-05 21:22:02 +02:00
|
|
|
}
|
2019-03-13 11:10:52 +01:00
|
|
|
#endif /* CONFIG_CHROMEOS */
|
2013-03-08 06:15:06 +01:00
|
|
|
|
2018-04-21 22:45:32 +02:00
|
|
|
__weak uint32_t board_id(void) { return UNDEFINED_STRAPPING_ID; }
|
|
|
|
__weak uint32_t ram_code(void) { return UNDEFINED_STRAPPING_ID; }
|
|
|
|
__weak uint32_t sku_id(void) { return UNDEFINED_STRAPPING_ID; }
|
2017-12-02 04:01:55 +01:00
|
|
|
|
2014-07-29 01:03:07 +02:00
|
|
|
static void lb_board_id(struct lb_header *header)
|
|
|
|
{
|
2017-12-05 22:39:10 +01:00
|
|
|
struct lb_strapping_id *rec;
|
|
|
|
uint32_t bid = board_id();
|
2014-07-29 01:03:07 +02:00
|
|
|
|
2017-12-02 04:01:55 +01:00
|
|
|
if (bid == UNDEFINED_STRAPPING_ID)
|
|
|
|
return;
|
|
|
|
|
2017-12-05 22:39:10 +01:00
|
|
|
rec = (struct lb_strapping_id *)lb_new_record(header);
|
2014-07-29 01:03:07 +02:00
|
|
|
|
2017-12-05 22:39:10 +01:00
|
|
|
rec->tag = LB_TAG_BOARD_ID;
|
|
|
|
rec->size = sizeof(*rec);
|
|
|
|
rec->id_code = bid;
|
|
|
|
|
|
|
|
printk(BIOS_INFO, "Board ID: %d\n", bid);
|
2014-07-29 01:03:07 +02:00
|
|
|
}
|
|
|
|
|
2015-07-14 18:15:51 +02:00
|
|
|
static void lb_boot_media_params(struct lb_header *header)
|
|
|
|
{
|
|
|
|
struct lb_boot_media_params *bmp;
|
|
|
|
const struct region_device *boot_dev;
|
2019-11-18 20:35:21 +01:00
|
|
|
struct region_device cbfs_dev;
|
2015-07-14 18:15:51 +02:00
|
|
|
|
|
|
|
boot_device_init();
|
|
|
|
|
2019-11-18 20:35:21 +01:00
|
|
|
if (cbfs_boot_region_device(&cbfs_dev))
|
2015-07-14 18:15:51 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
boot_dev = boot_device_ro();
|
|
|
|
if (boot_dev == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
bmp = (struct lb_boot_media_params *)lb_new_record(header);
|
|
|
|
bmp->tag = LB_TAG_BOOT_MEDIA_PARAMS;
|
|
|
|
bmp->size = sizeof(*bmp);
|
|
|
|
|
2019-11-18 20:35:21 +01:00
|
|
|
bmp->cbfs_offset = region_device_offset(&cbfs_dev);
|
|
|
|
bmp->cbfs_size = region_device_sz(&cbfs_dev);
|
2015-07-14 18:15:51 +02:00
|
|
|
bmp->boot_media_size = region_device_sz(boot_dev);
|
|
|
|
|
2019-09-27 08:51:46 +02:00
|
|
|
bmp->fmap_offset = get_fmap_flash_offset();
|
2015-07-14 18:15:51 +02:00
|
|
|
}
|
|
|
|
|
2014-11-04 02:42:09 +01:00
|
|
|
static void lb_ram_code(struct lb_header *header)
|
|
|
|
{
|
2017-12-05 22:39:10 +01:00
|
|
|
struct lb_strapping_id *rec;
|
|
|
|
uint32_t code = ram_code();
|
2014-11-04 02:42:09 +01:00
|
|
|
|
2017-12-02 04:01:55 +01:00
|
|
|
if (code == UNDEFINED_STRAPPING_ID)
|
|
|
|
return;
|
|
|
|
|
2017-12-05 22:39:10 +01:00
|
|
|
rec = (struct lb_strapping_id *)lb_new_record(header);
|
|
|
|
|
|
|
|
rec->tag = LB_TAG_RAM_CODE;
|
|
|
|
rec->size = sizeof(*rec);
|
|
|
|
rec->id_code = code;
|
2014-11-04 02:42:09 +01:00
|
|
|
|
2017-12-05 22:39:10 +01:00
|
|
|
printk(BIOS_INFO, "RAM code: %d\n", code);
|
2014-11-04 02:42:09 +01:00
|
|
|
}
|
|
|
|
|
2017-12-02 04:12:14 +01:00
|
|
|
static void lb_sku_id(struct lb_header *header)
|
|
|
|
{
|
|
|
|
struct lb_strapping_id *rec;
|
|
|
|
uint32_t sid = sku_id();
|
|
|
|
|
|
|
|
if (sid == UNDEFINED_STRAPPING_ID)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rec = (struct lb_strapping_id *)lb_new_record(header);
|
|
|
|
|
|
|
|
rec->tag = LB_TAG_SKU_ID;
|
|
|
|
rec->size = sizeof(*rec);
|
|
|
|
rec->id_code = sid;
|
|
|
|
|
|
|
|
printk(BIOS_INFO, "SKU ID: %d\n", sid);
|
|
|
|
}
|
|
|
|
|
2018-03-31 01:03:32 +02:00
|
|
|
static void lb_mmc_info(struct lb_header *header)
|
|
|
|
{
|
|
|
|
struct lb_mmc_info *rec;
|
|
|
|
int32_t *ms_cbmem;
|
|
|
|
|
|
|
|
ms_cbmem = cbmem_find(CBMEM_ID_MMC_STATUS);
|
|
|
|
if (!ms_cbmem)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rec = (struct lb_mmc_info *)lb_new_record(header);
|
|
|
|
|
|
|
|
rec->tag = LB_TAG_MMC_INFO;
|
|
|
|
rec->size = sizeof(*rec);
|
|
|
|
rec->early_cmd1_status = *ms_cbmem;
|
|
|
|
}
|
|
|
|
|
2011-10-03 23:58:57 +02:00
|
|
|
static void add_cbmem_pointers(struct lb_header *header)
|
2011-09-23 18:56:11 +02:00
|
|
|
{
|
2011-10-03 23:58:57 +02:00
|
|
|
/*
|
|
|
|
* 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},
|
2013-12-12 19:43:21 +01:00
|
|
|
{CBMEM_ID_CONSOLE, LB_TAG_CBMEM_CONSOLE},
|
|
|
|
{CBMEM_ID_ACPI_GNVS, LB_TAG_ACPI_GNVS},
|
2015-07-13 09:49:57 +02:00
|
|
|
{CBMEM_ID_VPD, LB_TAG_VPD},
|
2018-05-13 12:42:42 +02:00
|
|
|
{CBMEM_ID_WIFI_CALIBRATION, LB_TAG_WIFI_CALIBRATION},
|
2019-09-12 13:21:37 +02:00
|
|
|
{CBMEM_ID_TCPA_LOG, LB_TAG_TCPA_LOG},
|
|
|
|
{CBMEM_ID_FMAP, LB_TAG_FMAP},
|
2019-11-26 06:31:32 +01:00
|
|
|
{CBMEM_ID_VBOOT_WORKBUF, LB_TAG_VBOOT_WORKBUF},
|
2011-10-03 23:58:57 +02:00
|
|
|
};
|
|
|
|
int i;
|
2011-09-23 18:56:11 +02:00
|
|
|
|
2011-10-03 23:58:57 +02:00
|
|
|
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);
|
2011-09-23 18:56:11 +02:00
|
|
|
|
2011-10-03 23:58:57 +02:00
|
|
|
if (!cbmem_addr)
|
|
|
|
continue; /* This section is not present */
|
2011-09-23 18:56:11 +02:00
|
|
|
|
2011-10-03 23:58:57 +02:00
|
|
|
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);
|
2013-01-11 19:41:42 +01:00
|
|
|
cbmem_ref->cbmem_addr = (unsigned long)cbmem_addr;
|
2011-10-03 23:58:57 +02:00
|
|
|
}
|
2011-09-23 18:56:11 +02:00
|
|
|
}
|
|
|
|
|
2010-01-30 10:47:18 +01:00
|
|
|
static struct lb_mainboard *lb_mainboard(struct lb_header *header)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_record *rec;
|
|
|
|
struct lb_mainboard *mainboard;
|
|
|
|
rec = lb_new_record(header);
|
|
|
|
mainboard = (struct lb_mainboard *)rec;
|
|
|
|
mainboard->tag = LB_TAG_MAINBOARD;
|
|
|
|
|
2017-01-18 08:20:48 +01:00
|
|
|
mainboard->size = ALIGN_UP(sizeof(*mainboard) +
|
2010-04-27 08:56:47 +02:00
|
|
|
strlen(mainboard_vendor) + 1 +
|
2017-01-18 08:20:48 +01:00
|
|
|
strlen(mainboard_part_number) + 1, 8);
|
2003-04-22 21:02:15 +02:00
|
|
|
|
|
|
|
mainboard->vendor_idx = 0;
|
|
|
|
mainboard->part_number_idx = strlen(mainboard_vendor) + 1;
|
|
|
|
|
|
|
|
memcpy(mainboard->strings + mainboard->vendor_idx,
|
|
|
|
mainboard_vendor, strlen(mainboard_vendor) + 1);
|
|
|
|
memcpy(mainboard->strings + mainboard->part_number_idx,
|
|
|
|
mainboard_part_number, strlen(mainboard_part_number) + 1);
|
|
|
|
|
|
|
|
return mainboard;
|
|
|
|
}
|
|
|
|
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(USE_OPTION_TABLE)
|
2015-09-21 20:11:47 +02:00
|
|
|
static struct cmos_checksum *lb_cmos_checksum(struct lb_header *header)
|
|
|
|
{
|
|
|
|
struct lb_record *rec;
|
|
|
|
struct cmos_checksum *cmos_checksum;
|
|
|
|
rec = lb_new_record(header);
|
|
|
|
cmos_checksum = (struct cmos_checksum *)rec;
|
|
|
|
cmos_checksum->tag = LB_TAG_OPTION_CHECKSUM;
|
|
|
|
|
|
|
|
cmos_checksum->size = (sizeof(*cmos_checksum));
|
|
|
|
|
|
|
|
cmos_checksum->range_start = LB_CKS_RANGE_START * 8;
|
2017-03-07 18:47:22 +01:00
|
|
|
cmos_checksum->range_end = (LB_CKS_RANGE_END * 8) + 7;
|
2015-09-21 20:11:47 +02:00
|
|
|
cmos_checksum->location = LB_CKS_LOC * 8;
|
|
|
|
cmos_checksum->type = CHECKSUM_PCBIOS;
|
|
|
|
|
|
|
|
return cmos_checksum;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-08-27 13:23:06 +02:00
|
|
|
static void lb_strings(struct lb_header *header)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
static const struct {
|
|
|
|
uint32_t tag;
|
2007-10-24 00:17:45 +02:00
|
|
|
const char *string;
|
2003-04-22 21:02:15 +02:00
|
|
|
} strings[] = {
|
2008-01-18 16:08:58 +01:00
|
|
|
{ LB_TAG_VERSION, coreboot_version, },
|
|
|
|
{ LB_TAG_EXTRA_VERSION, coreboot_extra_version, },
|
|
|
|
{ LB_TAG_BUILD, coreboot_build, },
|
|
|
|
{ LB_TAG_COMPILE_TIME, coreboot_compile_time, },
|
2003-04-22 21:02:15 +02:00
|
|
|
};
|
2003-05-19 21:16:21 +02:00
|
|
|
unsigned int i;
|
2017-03-09 03:02:24 +01:00
|
|
|
for (i = 0; i < ARRAY_SIZE(strings); i++) {
|
2003-04-22 21:02:15 +02:00
|
|
|
struct lb_string *rec;
|
|
|
|
size_t len;
|
|
|
|
rec = (struct lb_string *)lb_new_record(header);
|
|
|
|
len = strlen(strings[i].string);
|
|
|
|
rec->tag = strings[i].tag;
|
2017-01-18 08:20:48 +01:00
|
|
|
rec->size = ALIGN_UP(sizeof(*rec) + len + 1, 8);
|
2003-04-22 21:02:15 +02:00
|
|
|
memcpy(rec->string, strings[i].string, len+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-08-23 01:08:09 +02:00
|
|
|
static void lb_record_version_timestamp(struct lb_header *header)
|
|
|
|
{
|
|
|
|
struct lb_timestamp *rec;
|
|
|
|
rec = (struct lb_timestamp *)lb_new_record(header);
|
|
|
|
rec->tag = LB_TAG_VERSION_TIMESTAMP;
|
|
|
|
rec->size = sizeof(*rec);
|
|
|
|
rec->timestamp = coreboot_version_timestamp;
|
|
|
|
}
|
|
|
|
|
2018-04-21 22:45:32 +02:00
|
|
|
void __weak lb_board(struct lb_header *header) { /* NOOP */ }
|
2013-08-28 00:48:32 +02:00
|
|
|
|
2016-08-11 21:51:38 +02:00
|
|
|
/*
|
|
|
|
* It's possible that the system is using a SPI flash as the boot device,
|
|
|
|
* however it is not probing for devices to fill in specifics. In that
|
|
|
|
* case don't provide any information as the correct information is
|
|
|
|
* not known.
|
|
|
|
*/
|
2018-04-21 22:45:32 +02:00
|
|
|
void __weak lb_spi_flash(struct lb_header *header) { /* NOOP */ }
|
2016-08-11 21:51:38 +02:00
|
|
|
|
2017-03-11 00:23:24 +01:00
|
|
|
static struct lb_forward *lb_forward(struct lb_header *header,
|
|
|
|
struct lb_header *next_header)
|
2009-03-17 15:38:48 +01:00
|
|
|
{
|
|
|
|
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);
|
2009-04-06 16:00:53 +02:00
|
|
|
forward->forward = (uint64_t)(unsigned long)next_header;
|
2009-03-17 15:38:48 +01:00
|
|
|
return forward;
|
|
|
|
}
|
|
|
|
|
2013-03-23 06:06:36 +01:00
|
|
|
static unsigned long lb_table_fini(struct lb_header *head)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_record *rec, *first_rec;
|
|
|
|
rec = lb_last_record(head);
|
2017-03-09 02:37:06 +01:00
|
|
|
if (head->table_entries)
|
2003-04-22 21:02:15 +02:00
|
|
|
head->table_bytes += rec->size;
|
2009-03-17 15:38:48 +01:00
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
first_rec = lb_first_record(head);
|
2017-03-11 00:23:24 +01:00
|
|
|
head->table_checksum = compute_ip_checksum(first_rec,
|
|
|
|
head->table_bytes);
|
2003-04-22 21:02:15 +02:00
|
|
|
head->header_checksum = 0;
|
|
|
|
head->header_checksum = compute_ip_checksum(head, sizeof(*head));
|
2011-08-16 20:44:35 +02:00
|
|
|
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;
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
|
|
|
|
2016-04-20 00:06:09 +02:00
|
|
|
size_t write_coreboot_forwarding_table(uintptr_t entry, uintptr_t target)
|
|
|
|
{
|
|
|
|
struct lb_header *head;
|
|
|
|
|
2019-12-09 22:03:29 +01:00
|
|
|
printk(BIOS_DEBUG, "Writing table forward entry at %p\n",
|
2016-04-20 00:06:09 +02:00
|
|
|
(void *)entry);
|
|
|
|
|
|
|
|
head = lb_table_init(entry);
|
2017-03-09 01:52:22 +01:00
|
|
|
lb_forward(head, (struct lb_header *)target);
|
2016-04-20 00:06:09 +02:00
|
|
|
|
|
|
|
return (uintptr_t)lb_table_fini(head) - entry;
|
|
|
|
}
|
|
|
|
|
2016-04-20 04:38:18 +02:00
|
|
|
static uintptr_t write_coreboot_table(uintptr_t rom_table_end)
|
2003-04-22 21:02:15 +02:00
|
|
|
{
|
|
|
|
struct lb_header *head;
|
|
|
|
|
2013-03-20 22:08:04 +01:00
|
|
|
printk(BIOS_DEBUG, "Writing coreboot table at 0x%08lx\n",
|
2016-04-20 04:38:18 +02:00
|
|
|
(long)rom_table_end);
|
2010-04-27 08:56:47 +02:00
|
|
|
|
2009-03-17 15:38:48 +01:00
|
|
|
head = lb_table_init(rom_table_end);
|
2006-07-19 17:32:49 +02:00
|
|
|
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(USE_OPTION_TABLE)
|
2007-04-06 14:14:51 +02:00
|
|
|
{
|
2015-05-16 06:39:23 +02:00
|
|
|
struct cmos_option_table *option_table =
|
|
|
|
cbfs_boot_map_with_leak("cmos_layout.bin",
|
2014-01-12 13:45:52 +01:00
|
|
|
CBFS_COMPONENT_CMOS_LAYOUT, NULL);
|
2011-01-18 14:56:36 +01:00
|
|
|
if (option_table) {
|
|
|
|
struct lb_record *rec_dest = lb_new_record(head);
|
2017-03-11 00:23:24 +01:00
|
|
|
/* Copy the option config table, it's already a
|
|
|
|
* lb_record...
|
|
|
|
*/
|
2011-01-24 22:07:57 +01:00
|
|
|
memcpy(rec_dest, option_table, option_table->size);
|
2020-02-16 10:01:33 +01:00
|
|
|
/* Create CMOS checksum entry in coreboot table */
|
2015-09-21 20:11:47 +02:00
|
|
|
lb_cmos_checksum(head);
|
2011-01-18 15:28:45 +01:00
|
|
|
} else {
|
2017-03-11 00:23:24 +01:00
|
|
|
printk(BIOS_ERR,
|
|
|
|
"cmos_layout.bin could not be found!\n");
|
2011-01-18 14:56:36 +01:00
|
|
|
}
|
2004-10-27 10:53:57 +02:00
|
|
|
}
|
2007-04-06 14:14:51 +02:00
|
|
|
#endif
|
2013-03-20 22:08:04 +01:00
|
|
|
|
2018-04-03 08:08:12 +02:00
|
|
|
/* Serialize resource map into mem table types (LB_MEM_*) */
|
2014-02-25 07:24:22 +01:00
|
|
|
bootmem_write_memory_table(lb_memory(head));
|
2003-04-22 21:02:15 +02:00
|
|
|
|
2008-01-25 19:28:18 +01:00
|
|
|
/* Record our motherboard */
|
2003-04-22 21:02:15 +02:00
|
|
|
lb_mainboard(head);
|
2014-03-15 00:32:55 +01:00
|
|
|
|
|
|
|
/* Record the serial ports and consoles */
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(CONSOLE_SERIAL)
|
2014-03-15 00:32:55 +01:00
|
|
|
uart_fill_lb(head);
|
|
|
|
#endif
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(CONSOLE_USB)
|
2014-03-15 00:32:55 +01:00
|
|
|
lb_add_console(LB_TAG_CONSOLE_EHCI, head);
|
|
|
|
#endif
|
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
/* Record our various random string information */
|
|
|
|
lb_strings(head);
|
2020-05-28 08:04:58 +02:00
|
|
|
if (CONFIG(PLATFORM_USES_FSP2_0))
|
|
|
|
lb_string_platform_blob_version(head);
|
2014-08-23 01:08:09 +02:00
|
|
|
lb_record_version_timestamp(head);
|
2010-02-22 05:33:13 +01:00
|
|
|
/* Record our framebuffer */
|
|
|
|
lb_framebuffer(head);
|
2003-04-22 21:02:15 +02:00
|
|
|
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(CHROMEOS)
|
2012-04-05 21:22:02 +02:00
|
|
|
/* Record our GPIO settings (ChromeOS specific) */
|
|
|
|
lb_gpios(head);
|
|
|
|
|
|
|
|
/* pass along VBNV offsets in CMOS */
|
|
|
|
lb_vbnv(head);
|
|
|
|
#endif
|
2014-07-29 01:03:07 +02:00
|
|
|
|
2017-12-02 04:12:14 +01:00
|
|
|
/* Add strapping IDs if available */
|
2014-07-29 01:03:07 +02:00
|
|
|
lb_board_id(head);
|
2014-11-04 02:42:09 +01:00
|
|
|
lb_ram_code(head);
|
2017-12-02 04:12:14 +01:00
|
|
|
lb_sku_id(head);
|
2014-11-04 02:42:09 +01:00
|
|
|
|
2018-03-31 01:03:32 +02:00
|
|
|
/* Pass mmc early init status */
|
|
|
|
lb_mmc_info(head);
|
|
|
|
|
2015-01-08 19:29:19 +01:00
|
|
|
/* Add SPI flash description if available */
|
2019-03-06 01:53:33 +01:00
|
|
|
if (CONFIG(BOOT_DEVICE_SPI_FLASH))
|
2016-08-11 21:51:38 +02:00
|
|
|
lb_spi_flash(head);
|
2015-01-08 19:29:19 +01:00
|
|
|
|
2011-10-03 23:58:57 +02:00
|
|
|
add_cbmem_pointers(head);
|
|
|
|
|
2013-08-28 00:48:32 +02:00
|
|
|
/* Add board-specific table entries, if any. */
|
|
|
|
lb_board(head);
|
|
|
|
|
2019-03-06 01:53:33 +01:00
|
|
|
#if CONFIG(CHROMEOS_RAMOOPS)
|
2014-11-09 02:34:27 +01:00
|
|
|
lb_ramoops(head);
|
|
|
|
#endif
|
|
|
|
|
2015-07-14 18:15:51 +02:00
|
|
|
lb_boot_media_params(head);
|
|
|
|
|
2016-02-10 17:52:47 +01:00
|
|
|
/* Add architecture records. */
|
|
|
|
lb_arch_add_records(head);
|
|
|
|
|
2015-09-30 19:26:54 +02:00
|
|
|
/* Add all cbmem entries into the coreboot tables. */
|
|
|
|
cbmem_add_records_to_cbtable(head);
|
|
|
|
|
2003-04-22 21:02:15 +02:00
|
|
|
/* Remember where my valid memory ranges are */
|
2013-03-23 06:06:36 +01:00
|
|
|
return lb_table_fini(head);
|
2003-04-22 21:02:15 +02:00
|
|
|
}
|
2016-04-20 04:38:18 +02:00
|
|
|
|
2018-07-18 23:35:01 +02:00
|
|
|
void *write_tables(void)
|
2016-04-20 04:38:18 +02:00
|
|
|
{
|
|
|
|
uintptr_t cbtable_start;
|
|
|
|
uintptr_t cbtable_end;
|
|
|
|
size_t cbtable_size;
|
2016-04-21 21:06:17 +02:00
|
|
|
const size_t max_table_size = COREBOOT_TABLE_SIZE;
|
2016-04-20 04:38:18 +02:00
|
|
|
|
|
|
|
cbtable_start = (uintptr_t)cbmem_add(CBMEM_ID_CBTABLE, max_table_size);
|
|
|
|
|
|
|
|
if (!cbtable_start) {
|
|
|
|
printk(BIOS_ERR, "Could not add CBMEM for coreboot table.\n");
|
2018-07-18 23:35:01 +02:00
|
|
|
return NULL;
|
2016-04-20 04:38:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add architecture specific tables. */
|
|
|
|
arch_write_tables(cbtable_start);
|
|
|
|
|
|
|
|
/* Write the coreboot table. */
|
|
|
|
cbtable_end = write_coreboot_table(cbtable_start);
|
|
|
|
cbtable_size = cbtable_end - cbtable_start;
|
|
|
|
|
|
|
|
if (cbtable_size > max_table_size) {
|
|
|
|
printk(BIOS_ERR, "%s: coreboot table didn't fit (%zx/%zx)\n",
|
|
|
|
__func__, cbtable_size, max_table_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
printk(BIOS_DEBUG, "coreboot table: %zd bytes.\n", cbtable_size);
|
|
|
|
|
|
|
|
/* Print CBMEM sections */
|
|
|
|
cbmem_list();
|
2018-07-18 23:35:01 +02:00
|
|
|
return (void *)cbtable_start;
|
2016-04-20 04:38:18 +02:00
|
|
|
}
|