sysinfo: Move the global sysinfo structure into FWDB.

This structure is filled with information from the coreboot handoff table and
will eventually go away. Because it doesn't persist between modules, the
structure needs to be filled in again when each module starts. To avoid that,
we can put it in the FWDB and it will persist between modules, if there was
anything to fill it with in the first place.

Change-Id: I8f9587b02336a672d21c3797a1fdc26929aae622
diff --git a/src/arch/arm/v7/handoff/coreboot.c b/src/arch/arm/v7/handoff/coreboot.c
index f1f296c..dc0de69 100644
--- a/src/arch/arm/v7/handoff/coreboot.c
+++ b/src/arch/arm/v7/handoff/coreboot.c
@@ -38,5 +38,7 @@
 	prepare_e820_mem_ranges();
 
 	// Get information from the coreboot tables if they exist.
-	cb_parse_header((void *)(uintptr_t)handoff_parameter, 1, &lib_sysinfo);
+	create_sysinfo();
+	struct sysinfo_t *sysinfo = get_sysinfo();
+	cb_parse_header((void *)(uintptr_t)handoff_parameter, 1, sysinfo);
 }
diff --git a/src/arch/arm/v8/handoff/coreboot.c b/src/arch/arm/v8/handoff/coreboot.c
index 423f6bd..12fcad8 100644
--- a/src/arch/arm/v8/handoff/coreboot.c
+++ b/src/arch/arm/v8/handoff/coreboot.c
@@ -96,8 +96,10 @@
 
 	prepare_e820_mem_ranges();
 
+	create_sysinfo();
+	struct sysinfo_t *sysinfo = get_sysinfo();
 	// Get information from the coreboot tables if they exist.
-	cb_parse_header((void *)(uintptr_t)handoff_parameter, 1, &lib_sysinfo);
+	cb_parse_header((void *)(uintptr_t)handoff_parameter, 1, sysinfo);
 
 	post_e820_scan_mmu_setup();
 }
diff --git a/src/arch/x86/ia32/handoff/coreboot.c b/src/arch/x86/ia32/handoff/coreboot.c
index ec99aa1..82be376 100644
--- a/src/arch/x86/ia32/handoff/coreboot.c
+++ b/src/arch/x86/ia32/handoff/coreboot.c
@@ -47,6 +47,8 @@
 	prepare_e820_mem_ranges();
 
 	// Get information from the coreboot tables if they exist.
-	if (cb_parse_header((void *)0, 0x1000, &lib_sysinfo))
-		cb_parse_header((void *)0x000f0000, 0x1000, &lib_sysinfo);
+	create_sysinfo();
+	struct sysinfo_t *sysinfo = get_sysinfo();
+	if (cb_parse_header((void *)0, 0x1000, sysinfo))
+		cb_parse_header((void *)0x000f0000, 0x1000, sysinfo);
 }
diff --git a/src/arch/x86/ia32/handoff/module.c b/src/arch/x86/ia32/handoff/module.c
index 2033d25..c53e526 100644
--- a/src/arch/x86/ia32/handoff/module.c
+++ b/src/arch/x86/ia32/handoff/module.c
@@ -47,8 +47,4 @@
 	uintptr_t end = start + fwdb_db_max_size();
 	if (start != end)
 		memory_mark_used(start, end);
-
-	// Get information from the coreboot tables if they exist.
-	if (cb_parse_header((void *)0, 0x1000, &lib_sysinfo))
-		cb_parse_header((void *)0x000f0000, 0x1000, &lib_sysinfo);
 }
diff --git a/src/base/cbfs/cbfs.c b/src/base/cbfs/cbfs.c
index b7b3aa9..5f7024d 100644
--- a/src/base/cbfs/cbfs.c
+++ b/src/base/cbfs/cbfs.c
@@ -91,9 +91,9 @@
 	const struct cbfs_header *header;
 
 	if (media == CBFS_DEFAULT_MEDIA &&
-		lib_sysinfo.cbfs_offset && lib_sysinfo.cbfs_size) {
-		*offset = lib_sysinfo.cbfs_offset;
-		*cbfs_end = *offset + lib_sysinfo.cbfs_size;
+		get_sysinfo()->cbfs_offset && get_sysinfo()->cbfs_size) {
+		*offset = get_sysinfo()->cbfs_offset;
+		*cbfs_end = *offset + get_sysinfo()->cbfs_size;
 		return 0;
 	}
 
diff --git a/src/base/coreboot.c b/src/base/coreboot.c
index b8c6f32..ca5d625 100644
--- a/src/base/coreboot.c
+++ b/src/base/coreboot.c
@@ -26,6 +26,7 @@
  * SUCH DAMAGE.
  */
 
+#include <assert.h>
 #include <coreboot_tables.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -36,7 +37,28 @@
 #include "drivers/framebuffer/framebuffer.h"
 #include "vboot/util/vboot_handoff.h"
 
-struct sysinfo_t lib_sysinfo;
+struct sysinfo_t *get_sysinfo(void)
+{
+	static struct sysinfo_t *sysinfo;
+	if (sysinfo)
+		return sysinfo;
+
+	FwdbEntry sysinfo_entry;
+	assert(fwdb_access("lib_sysinfo", &sysinfo_entry, NULL) == 0);
+	assert(sysinfo_entry.size == sizeof(struct sysinfo_t));
+	sysinfo = (struct sysinfo_t *)sysinfo_entry.ptr;
+
+	return sysinfo;
+}
+
+int create_sysinfo(void)
+{
+	FwdbEntry sysinfo_entry = {
+		.ptr = NULL,
+		.size = sizeof(struct sysinfo_t),
+	};
+	return fwdb_access("lib_sysinfo", NULL, &sysinfo_entry);
+}
 
 /*
  * The code in this file applies to all coreboot architectures. Some coreboot
diff --git a/src/base/timestamp.c b/src/base/timestamp.c
index 7cfb977..71aef04 100644
--- a/src/base/timestamp.c
+++ b/src/base/timestamp.c
@@ -39,7 +39,7 @@
 
 static int timestamp_init(void)
 {
-	ts_table = lib_sysinfo.tstamp_table;
+	ts_table = get_sysinfo()->tstamp_table;
 	timestamp_add_now(TS_START);
 	return 0;
 }
diff --git a/src/boot/coreboot.c b/src/boot/coreboot.c
index 33e6cab..54f1b72 100644
--- a/src/boot/coreboot.c
+++ b/src/boot/coreboot.c
@@ -65,9 +65,9 @@
 	uint64_t reg_sizes[2];
 
 	// First 'reg' address range is the coreboot table.
-	reg_addrs[0] = (uintptr_t)lib_sysinfo.header;
-	reg_sizes[0] = lib_sysinfo.header->header_bytes +
-		       lib_sysinfo.header->table_bytes;
+	reg_addrs[0] = (uintptr_t)get_sysinfo()->header;
+	reg_sizes[0] = get_sysinfo()->header->header_bytes +
+		       get_sysinfo()->header->table_bytes;
 
 	// Second is the CBMEM area (which usually includes the coreboot table).
 	reg_addrs[1] = cbmem_range->base;
@@ -77,9 +77,9 @@
 			addr_cells, size_cells);
 
 	// Expose board ID and RAM code exported from coreboot to userspace.
-	if (lib_sysinfo.board_id != ~0) {
+	if (get_sysinfo()->board_id != ~0) {
 		dt_add_u32_prop(coreboot_node,
-				"board-id", lib_sysinfo.board_id);
+				"board-id", get_sysinfo()->board_id);
 	}
 	FwdbEntry ram_code_entry;
 	if (fwdb_access("coreboot.ram_code", &ram_code_entry, NULL)) {
diff --git a/src/boot/fit.c b/src/boot/fit.c
index 3e3fe40..6cf0b05 100644
--- a/src/boot/fit.c
+++ b/src/boot/fit.c
@@ -47,14 +47,14 @@
 static void fit_set_default_compat(void)
 {
 	const char pattern[] = "google,%s-rev%u";
-	uint32_t rev = lib_sysinfo.board_id;
+	uint32_t rev = get_sysinfo()->board_id;
 
 	// Make sure board ID is not ~0 and will fit in two digits, so that
 	// it doesn't require more space than the '%u' in the pattern string.
 	assert(rev < 100);
 
 	char *compat = malloc(sizeof(pattern) + sizeof(CONFIG_BOARD));
-	sprintf(compat, pattern, CONFIG_BOARD, lib_sysinfo.board_id);
+	sprintf(compat, pattern, CONFIG_BOARD, get_sysinfo()->board_id);
 
 	char *c;
 	for (c = compat; *c != '\0'; c++)
diff --git a/src/boot/ramoops.c b/src/boot/ramoops.c
index 9b3fd5e..32d2f9a 100644
--- a/src/boot/ramoops.c
+++ b/src/boot/ramoops.c
@@ -104,12 +104,12 @@
 
 static int ramoops_init(void)
 {
-	if (lib_sysinfo.ramoops_buffer == 0 ||
-	    lib_sysinfo.ramoops_buffer_size == 0)
+	if (get_sysinfo()->ramoops_buffer == 0 ||
+	    get_sysinfo()->ramoops_buffer_size == 0)
 		return 0;
 
-	ramoops_buffer(lib_sysinfo.ramoops_buffer,
-		       lib_sysinfo.ramoops_buffer_size, 0x20000);
+	ramoops_buffer(get_sysinfo()->ramoops_buffer,
+		       get_sysinfo()->ramoops_buffer_size, 0x20000);
 
 	return 0;
 }
diff --git a/src/drivers/board/rambi/board.c b/src/drivers/board/rambi/board.c
index 4594c2e..1a95f3a 100644
--- a/src/drivers/board/rambi/board.c
+++ b/src/drivers/board/rambi/board.c
@@ -73,7 +73,7 @@
 
 static int board_setup(void)
 {
-	device_nvs_t *nvs = lib_sysinfo.acpi_gnvs + DEVICE_NVS_OFFSET;
+	device_nvs_t *nvs = get_sysinfo()->acpi_gnvs + DEVICE_NVS_OFFSET;
 
 	CrosEcLpcBus *cros_ec_lpc_bus =
 		new_cros_ec_lpc_bus(CROS_EC_LPC_BUS_GENERIC);
diff --git a/src/drivers/board/rush/board.c b/src/drivers/board/rush/board.c
index 7098603..8eb215a 100644
--- a/src/drivers/board/rush/board.c
+++ b/src/drivers/board/rush/board.c
@@ -120,12 +120,12 @@
 
 static void choose_devicetree_by_boardid(void)
 {
-	switch(lib_sysinfo.board_id) {
+	switch(get_sysinfo()->board_id) {
 	case BOARD_ID_PROTO_0:
 		fit_set_compat("nvidia,norrin");
 		break;
 	default:
-		printf("Unknown board id: %x\n", lib_sysinfo.board_id);
+		printf("Unknown board id: %x\n", get_sysinfo()->board_id);
 		break;
 	}
 }
diff --git a/src/drivers/board/rush_ryu/board.c b/src/drivers/board/rush_ryu/board.c
index 6841f3f..e422534 100644
--- a/src/drivers/board/rush_ryu/board.c
+++ b/src/drivers/board/rush_ryu/board.c
@@ -85,7 +85,7 @@
 {
 	const char *pattern = "google,ryu-rev%d";
 	char *compat = strdup(pattern);
-	sprintf(compat, pattern, lib_sysinfo.board_id);
+	sprintf(compat, pattern, get_sysinfo()->board_id);
 	fit_set_compat(compat);
 }
 
@@ -108,7 +108,8 @@
 PUB_STAT(flag_option_roms_loaded, gpio_get(&fwdb_gpio_oprom.ops))
 // Lid always open for now.
 PUB_STAT(flag_lid_open, 1)
-PUB_STAT(flag_power, (lib_sysinfo.board_id >= 2) ^ gpio_get(get_power_gpio()))
+PUB_STAT(flag_power, (get_sysinfo()->board_id >= 2) ^
+		      gpio_get(get_power_gpio()))
 PUB_STAT(flag_ec_in_rw, gpio_get(get_ec_in_rw_gpio()))
 
 static TegraApbDmaController *build_dma_controller(void)
diff --git a/src/drivers/board/rush_ryu/keyboard.c b/src/drivers/board/rush_ryu/keyboard.c
index 686ee48..5a98319 100644
--- a/src/drivers/board/rush_ryu/keyboard.c
+++ b/src/drivers/board/rush_ryu/keyboard.c
@@ -134,7 +134,7 @@
 int mainboard_read_input(void)
 {
 	int power_button = gpio_get(get_power_button_gpio());
-	if (lib_sysinfo.board_id >= 2)
+	if (get_sysinfo()->board_id >= 2)
 		power_button = !power_button;
 
 	int input = (power_button << PWR_BTN_SHIFT) |
diff --git a/src/drivers/board/samus/board.c b/src/drivers/board/samus/board.c
index b4de88f..fddcc21 100644
--- a/src/drivers/board/samus/board.c
+++ b/src/drivers/board/samus/board.c
@@ -70,7 +70,7 @@
 // Put device in D0 state.
 static void device_enable(int sio_index)
 {
-	device_nvs_t *nvs = lib_sysinfo.acpi_gnvs + DEVICE_NVS_OFFSET;
+	device_nvs_t *nvs = get_sysinfo()->acpi_gnvs + DEVICE_NVS_OFFSET;
 	uint32_t *reg_pcs =
 		(uint32_t *)(uintptr_t)(nvs->bar1[sio_index] + 0x84);
 
@@ -81,7 +81,7 @@
 
 static DesignwareI2c *i2c_enable(int sio_index)
 {
-	device_nvs_t *nvs = lib_sysinfo.acpi_gnvs + DEVICE_NVS_OFFSET;
+	device_nvs_t *nvs = get_sysinfo()->acpi_gnvs + DEVICE_NVS_OFFSET;
 	uint32_t *ppr_clock =
 		(uint32_t *)(uintptr_t)(nvs->bar0[sio_index] + 0x800);
 
@@ -96,7 +96,7 @@
 
 static BdwI2s *i2s_enable(int ssp)
 {
-	device_nvs_t *nvs = lib_sysinfo.acpi_gnvs + DEVICE_NVS_OFFSET;
+	device_nvs_t *nvs = get_sysinfo()->acpi_gnvs + DEVICE_NVS_OFFSET;
 
 	device_enable(SIO_NVS_ADSP);
 
diff --git a/src/drivers/board/smaug/board.c b/src/drivers/board/smaug/board.c
index cc8551f..b836581 100644
--- a/src/drivers/board/smaug/board.c
+++ b/src/drivers/board/smaug/board.c
@@ -116,8 +116,8 @@
  */
 static void flash_params_override(void)
 {
-	lib_sysinfo.spi_flash.sector_size = 64 * KiB;
-	lib_sysinfo.spi_flash.erase_cmd = SPI_FLASH_BLOCK_ERASE_64KB;
+	get_sysinfo()->spi_flash.sector_size = 64 * KiB;
+	get_sysinfo()->spi_flash.erase_cmd = SPI_FLASH_BLOCK_ERASE_64KB;
 }
 
 PRIV_DYN(pwr_i2c, &new_tegra_i2c((void *)0x7000d000, 5,
diff --git a/src/drivers/board/smaug/emc.c b/src/drivers/board/smaug/emc.c
index 217a2dc..6b2d2b4 100644
--- a/src/drivers/board/smaug/emc.c
+++ b/src/drivers/board/smaug/emc.c
@@ -53,13 +53,13 @@
 
 	uint32_t addr_cells = 2, size_cells = 2;
 
-	dt_add_reg_prop(emc_table_node, &lib_sysinfo.mtc_start,
-			(uint64_t *)&lib_sysinfo.mtc_size, 1, addr_cells,
+	dt_add_reg_prop(emc_table_node, &get_sysinfo()->mtc_start,
+			(uint64_t *)&get_sysinfo()->mtc_size, 1, addr_cells,
 			size_cells);
 
 	DeviceTreeReserveMapEntry *reserve = xzalloc(sizeof(*reserve));
-	reserve->start = lib_sysinfo.mtc_start;
-	reserve->size = lib_sysinfo.mtc_size;
+	reserve->start = get_sysinfo()->mtc_start;
+	reserve->size = get_sysinfo()->mtc_size;
 	list_insert_after(&reserve->list_node, &tree->reserve_map);
 
 	printf("EMC: Added /%s/%s to device-tree\n", emc_dt_name[0],
diff --git a/src/drivers/board/strago/board.c b/src/drivers/board/strago/board.c
index ec7a9b4..bd2be7a 100755
--- a/src/drivers/board/strago/board.c
+++ b/src/drivers/board/strago/board.c
@@ -70,7 +70,7 @@
 
 static int board_setup(void)
 {
-	device_nvs_t *nvs = lib_sysinfo.acpi_gnvs + DEVICE_NVS_OFFSET;
+	device_nvs_t *nvs = get_sysinfo()->acpi_gnvs + DEVICE_NVS_OFFSET;
 
 #if CONFIG_DRIVER_EC_CROS
   #if CONFIG_DRIVER_EC_CROS_LPC
diff --git a/src/drivers/flash/spi.c b/src/drivers/flash/spi.c
index 8764463..6274c1c 100644
--- a/src/drivers/flash/spi.c
+++ b/src/drivers/flash/spi.c
@@ -215,9 +215,9 @@
 
 SpiFlash *new_spi_flash(SpiOps *spi)
 {
-	uint32_t rom_size = lib_sysinfo.spi_flash.size;
-	uint32_t sector_size = lib_sysinfo.spi_flash.sector_size;
-	uint8_t erase_cmd = lib_sysinfo.spi_flash.erase_cmd;
+	uint32_t rom_size = get_sysinfo()->spi_flash.size;
+	uint32_t sector_size = get_sysinfo()->spi_flash.sector_size;
+	uint8_t erase_cmd = get_sysinfo()->spi_flash.erase_cmd;
 
 	SpiFlash *flash = xzalloc(sizeof(*flash));
 	flash->ops.read = &spi_flash_read;
diff --git a/src/libpayload/drivers/cbmem_console.c b/src/libpayload/drivers/cbmem_console.c
index 698b323..d211c96 100644
--- a/src/libpayload/drivers/cbmem_console.c
+++ b/src/libpayload/drivers/cbmem_console.c
@@ -58,7 +58,7 @@
 
 static int cbmem_console_init(void)
 {
-	cbmem_console_p = lib_sysinfo.cbmem_cons;
+	cbmem_console_p = get_sysinfo()->cbmem_cons;
 	if (cbmem_console_p)
 		list_insert_after(&cbmem_console.list_node, &console_list);
 
diff --git a/src/libpayload/drivers/video/graphics.c b/src/libpayload/drivers/video/graphics.c
index 6b18a5a..9c045dc 100644
--- a/src/libpayload/drivers/video/graphics.c
+++ b/src/libpayload/drivers/video/graphics.c
@@ -118,7 +118,7 @@
 	if (initialized)
 		return 0;
 
-	fbinfo = lib_sysinfo.framebuffer;
+	fbinfo = get_sysinfo()->framebuffer;
 	if (!fbinfo)
 		return -1;
 
diff --git a/src/libpayload/include/sysinfo.h b/src/libpayload/include/sysinfo.h
index a9e0158..f9c8985 100644
--- a/src/libpayload/include/sysinfo.h
+++ b/src/libpayload/include/sysinfo.h
@@ -56,7 +56,8 @@
 	uint32_t mtc_size;
 };
 
-extern struct sysinfo_t lib_sysinfo;
+struct sysinfo_t *get_sysinfo(void);
+int create_sysinfo(void);
 
 /*
  * Check if this is an architecture specific coreboot table record and process
diff --git a/src/vboot/callbacks/display.c b/src/vboot/callbacks/display.c
index bb694a4..1bd336b 100644
--- a/src/vboot/callbacks/display.c
+++ b/src/vboot/callbacks/display.c
@@ -136,7 +136,7 @@
 VbError_t VbExDisplaySetDimension(uint32_t width, uint32_t height)
 {
 	// TODO(hungte) Shift or scale images if width/height is not equal to
-	// lib_sysinfo.framebuffer->{x,y}_resolution.
+	// get_sysinfo()->framebuffer->{x,y}_resolution.
 	return VBERROR_SUCCESS;
 }
 
diff --git a/src/vboot/callbacks/nvstorage_cmos.c b/src/vboot/callbacks/nvstorage_cmos.c
index 745181c..f60c26c 100644
--- a/src/vboot/callbacks/nvstorage_cmos.c
+++ b/src/vboot/callbacks/nvstorage_cmos.c
@@ -27,28 +27,28 @@
 
 VbError_t VbExNvStorageRead(uint8_t* buf)
 {
-	if (lib_sysinfo.vbnv_start == (uint32_t)(-1)) {
+	if (get_sysinfo()->vbnv_start == (uint32_t)(-1)) {
 		printf("%s:%d - vbnv address undefined\n",
 		       __FUNCTION__, __LINE__);
 		return VBERROR_INVALID_PARAMETER;
 	}
 
-	for (int i = 0; i < lib_sysinfo.vbnv_size; i++)
-		buf[i] = nvram_read(lib_sysinfo.vbnv_start + i);
+	for (int i = 0; i < get_sysinfo()->vbnv_size; i++)
+		buf[i] = nvram_read(get_sysinfo()->vbnv_start + i);
 
 	return VBERROR_SUCCESS;
 }
 
 VbError_t VbExNvStorageWrite(const uint8_t* buf)
 {
-	if (lib_sysinfo.vbnv_start == (uint32_t)(-1)) {
+	if (get_sysinfo()->vbnv_start == (uint32_t)(-1)) {
 		printf("%s:%d - vbnv address undefined\n",
 		       __FUNCTION__, __LINE__);
 		return VBERROR_INVALID_PARAMETER;
 	}
 
-	for (int i = 0; i < lib_sysinfo.vbnv_size; i++)
-		nvram_write(buf[i], lib_sysinfo.vbnv_start + i);
+	for (int i = 0; i < get_sysinfo()->vbnv_size; i++)
+		nvram_write(buf[i], get_sysinfo()->vbnv_start + i);
 
 	return VBERROR_SUCCESS;
 }
diff --git a/src/vboot/crossystem/acpi.c b/src/vboot/crossystem/acpi.c
index 59bd0e4..02204e4 100644
--- a/src/vboot/crossystem/acpi.c
+++ b/src/vboot/crossystem/acpi.c
@@ -48,7 +48,7 @@
 	if (common_params_init())
 		return 1;
 
-	chromeos_acpi_t *acpi_table = (chromeos_acpi_t *)lib_sysinfo.vdat_addr;
+	chromeos_acpi_t *acpi_table = (chromeos_acpi_t *)get_sysinfo()->vdat_addr;
 	VbSharedDataHeader *vdat = (VbSharedDataHeader *)&acpi_table->vdat;
 
 	memcpy(vdat, cparams.shared_data_blob, cparams.shared_data_size);