[coreboot] New patch to review for coreboot: 9bf9535 Add Google ChromeOS vendor support

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Sat Mar 31 00:15:17 CEST 2012


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/817

-gerrit

commit 9bf95351c917904deb99425c738cfb3386f57c35
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Fri Mar 30 12:01:06 2012 -0700

    Add Google ChromeOS vendor support
    
    Google's ChromeOS can be booted super fast and safely
    using coreboot. This adds the ChromeOS specific code that
    is required by all ChromeBooks to do this.
    
    Change-Id: Ic03ff090a569a27acbd798ce1e5f89a34897a2f2
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 Makefile.inc                                 |    1 +
 src/vendorcode/Makefile.inc                  |    2 +-
 src/vendorcode/google/Makefile.inc           |   20 +++++
 src/vendorcode/google/chromeos/Kconfig       |   29 +++++++-
 src/vendorcode/google/chromeos/Makefile.inc  |   25 ++++++
 src/vendorcode/google/chromeos/acpi/gnvs.asl |   37 +++++++++
 src/vendorcode/google/chromeos/chromeos.c    |   37 +++++++++
 src/vendorcode/google/chromeos/chromeos.h    |   40 ++++++++++
 src/vendorcode/google/chromeos/gnvs.c        |   88 +++++++++++++++++++++
 src/vendorcode/google/chromeos/gnvs.h        |   69 ++++++++++++++++
 src/vendorcode/google/chromeos/vbnv.c        |  109 ++++++++++++++++++++++++++
 src/vendorcode/google/chromeos/vboot.c       |   63 ++++++++++++----
 12 files changed, 504 insertions(+), 16 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index b4855d0..857ad16 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -43,6 +43,7 @@ subdirs-y += src/northbridge src/superio src/drivers src/cpu src/vendorcode
 subdirs-y += util/cbfstool util/sconfig
 subdirs-y += src/arch/$(ARCHDIR-y)
 subdirs-y += src/mainboard/$(MAINBOARDDIR)
+subdirs-y += src/vendorcode
 
 subdirs-$(CONFIG_ARCH_X86) += src/pc80
 
diff --git a/src/vendorcode/Makefile.inc b/src/vendorcode/Makefile.inc
index 16c0d68..e6d6bb1 100644
--- a/src/vendorcode/Makefile.inc
+++ b/src/vendorcode/Makefile.inc
@@ -1,2 +1,2 @@
 subdirs-y += amd
-
+subdirs-y += google
diff --git a/src/vendorcode/google/Makefile.inc b/src/vendorcode/google/Makefile.inc
new file mode 100644
index 0000000..20d40a8
--- /dev/null
+++ b/src/vendorcode/google/Makefile.inc
@@ -0,0 +1,20 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+subdirs-$(CONFIG_CHROMEOS) += chromeos
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index f838b74..207431d 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -22,7 +22,34 @@ config CHROMEOS
 	select TPM
 	select CACHE_ROM
 	help
-	  Enable ChromeOS specific features
+	  Enable ChromeOS specific features like the GPIO sub table in
+	  the coreboot table. NOTE: Enabling this option on an unsupported
+	  board will most likely break your build.
 
+config VBNV_OFFSET
+	hex
+	default 0x26
+	help
+	  CMOS offset for VbNv data. This value must match cmos.layout
+	  in the mainboard directory, minus 14 bytes for the RTC.
+
+config VBNV_SIZE
+	hex
+	default 0x10
+	help
+	  CMOS storage size for VbNv data. This value must match cmos.layout
+	  in the mainboard directory.
+
+config CHROMEOS_RAMOOPS
+	bool "Reserve space for Chrome OS ramoops"
+	default y
 
+config CHROMEOS_RAMOOPS_RAM_START
+	hex "Physical address of preserved RAM"
+	default 0x00f00000
+	depends on CHROMEOS_RAMOOPS
 
+config CHROMEOS_RAMOOPS_RAM_SIZE
+	hex "Size of preserved RAM"
+	default 0x00100000
+	depends on CHROMEOS_RAMOOPS
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
new file mode 100644
index 0000000..c1b1cce
--- /dev/null
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -0,0 +1,25 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; version 2 of the License.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+romstage-y += chromeos.c
+ramstage-y += chromeos.c
+romstage-y += vbnv.c
+ramstage-y += vbnv.c
+romstage-y += vboot.c
+ramstage-y += gnvs.c
diff --git a/src/vendorcode/google/chromeos/acpi/gnvs.asl b/src/vendorcode/google/chromeos/acpi/gnvs.asl
new file mode 100644
index 0000000..dc4a0bf
--- /dev/null
+++ b/src/vendorcode/google/chromeos/acpi/gnvs.asl
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This is the ChromeOS specific ACPI information needed by
+ * the mainboard's chromeos.asl
+ */
+
+VBT0,   32,	// 0x000 - Boot Reason
+VBT1,   32,	// 0x004 - Active Main Firmware
+VBT2,   32,	// 0x008 - Active EC Firmware
+VBT3,   16,	// 0x00c - CHSW
+VBT4, 2048,	// 0x00e - HWID
+VBT5,  512,	// 0x10e - FWID
+VBT6,  512,	// 0x14e - FRID
+VBT7,   32,	// 0x18e - active main firmware type
+VBT8,   32,	// 0x192 - Recovery Reason
+VBT9,   32,	// 0x196 - FMAP base address
+CHVD, 24576,	// 0x19a - VDAT space filled by verified boot
+VBTA,	32,	// 0xd9a - pointer to smbios FWID
+MEHH,  256,	// 0xd9e - Management Engine Hash
+		// 0xdbe
diff --git a/src/vendorcode/google/chromeos/chromeos.c b/src/vendorcode/google/chromeos/chromeos.c
new file mode 100644
index 0000000..c1c3b38
--- /dev/null
+++ b/src/vendorcode/google/chromeos/chromeos.c
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "chromeos.h"
+#include <arch/coreboot_tables.h>
+#include <console/console.h>
+
+int developer_mode_enabled(void)
+{
+	return get_developer_mode_switch();
+}
+
+int recovery_mode_enabled(void)
+{
+	/* TODO(reinauer): get information from VbInit.
+	 * the recovery mode switch is not the only reason to go
+	 * to recovery mode.
+	 */
+	return get_recovery_mode_switch() || get_recovery_mode_from_vbnv();
+}
+
diff --git a/src/vendorcode/google/chromeos/chromeos.h b/src/vendorcode/google/chromeos/chromeos.h
new file mode 100644
index 0000000..ec0f3b7
--- /dev/null
+++ b/src/vendorcode/google/chromeos/chromeos.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __CHROMEOS_H__
+#define __CHROMEOS_H__
+
+/* functions implemented per mainboard: */
+int get_developer_mode_switch(void);
+int get_recovery_mode_switch(void);
+#ifdef __PRE_RAM__
+void save_chromeos_gpios(void);
+#endif
+
+/* functions implemented in vbnv.c: */
+int get_recovery_mode_from_vbnv(void);
+
+/* functions implemented in chromeos.c: */
+int developer_mode_enabled(void);
+int recovery_mode_enabled(void);
+
+/* functions implemented in vboot.c */
+void init_chromeos(int bootmode);
+
+#endif
diff --git a/src/vendorcode/google/chromeos/gnvs.c b/src/vendorcode/google/chromeos/gnvs.c
new file mode 100644
index 0000000..8d0f9bb
--- /dev/null
+++ b/src/vendorcode/google/chromeos/gnvs.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include "gnvs.h"
+
+chromeos_acpi_t *vboot_data;
+static u32 me_hash_saved[8];
+
+void chromeos_init_vboot(chromeos_acpi_t *chromeos)
+{
+	vboot_data = chromeos;
+
+	/* Copy saved ME hash into NVS */
+	memcpy(vboot_data->mehh, me_hash_saved, sizeof(vboot_data->mehh));
+}
+
+void chromeos_set_vboot_data_ptr(void *blob)
+{
+	/* This code has to be rewritten to pass the vboot table
+	 * pointer through the coreboot table instead of the 
+	 * FDT, since FDT support was rejected upstream. For now
+	 * just make the code available for reference.
+	 */
+#if 0 // CONFIG_ADD_FDT
+	int node_offset, addr_cell_len;
+	const u32 *cell;
+	uintptr_t table_addr = (uintptr_t)vboot_data;
+	u32 table_addr32;
+	u64 table_addr64;
+	void *table_ptr;
+
+	cell = fdt_getprop(blob, 0, "#address-cells", NULL);
+	if (cell && *cell == 2) {
+		addr_cell_len = 8;
+		table_addr64 = cpu_to_fdt64(table_addr);
+		table_ptr = &table_addr64;
+	} else {
+		addr_cell_len = 4;
+		table_addr32 = cpu_to_fdt32(table_addr);
+		table_ptr = &table_addr32;
+	}
+
+	node_offset = fdt_path_offset(blob, "/chromeos-config");
+	if (node_offset < 0) {
+		printk(BIOS_ERR,
+			"Couldn't find /chromeos-config in the fdt.\n");
+		return;
+	}
+
+	if (fdt_setprop(blob, node_offset, "gnvs-vboot-table",
+			table_ptr, addr_cell_len) < 0) {
+		printk(BIOS_ERR, "Couldn't set gnvs-vboot-table.\n");
+	}
+#else
+	printk(BIOS_ERR, "Can't set gnvs-vboot-table.\n");
+#endif
+}
+
+void chromeos_set_me_hash(u32 *hash, int len)
+{
+	if ((len*sizeof(u32)) > sizeof(vboot_data->mehh))
+		return;
+
+	/* Copy to NVS or save until it is ready */
+	if (vboot_data)
+		memcpy(vboot_data->mehh, hash, len*sizeof(u32));
+	else
+		memcpy(me_hash_saved, hash, len*sizeof(u32));
+}
diff --git a/src/vendorcode/google/chromeos/gnvs.h b/src/vendorcode/google/chromeos/gnvs.h
new file mode 100644
index 0000000..36922ba
--- /dev/null
+++ b/src/vendorcode/google/chromeos/gnvs.h
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __VENDORCODE_GOOGLE_CHROMEOS_GNVS_H
+#define __VENDORCODE_GOOGLE_CHROMEOS_GNVS_H
+
+#define BOOT_REASON_OTHER	0
+#define BOOT_REASON_S3DIAG	9
+
+#define CHSW_RECOVERY_X86	(1 << 1)
+#define CHSW_RECOVERY_EC	(1 << 2)
+#define CHSW_DEVELOPER_SWITCH	(1 << 5)
+#define CHSW_FIRMWARE_WP_DIS	(1 << 9)
+
+#define ACTIVE_MAINFW_RECOVERY	0
+#define ACTIVE_MAINFW_RW_A	1
+#define ACTIVE_MAINFW_RW_B	2
+
+#define ACTIVE_MAINFW_TYPE_RECOVERY	0
+#define ACTIVE_MAINFW_TYPE_NORMAL	1
+#define ACTIVE_MAINFW_TYPE_DEVELOPER	2
+
+#define RECOVERY_REASON_NONE	0
+#define RECOVERY_REASON_ME	1
+// TODO(reinauer) other recovery reasons?
+
+#define ACTIVE_ECFW_RO		0
+#define ACTIVE_ECFW_RW		1
+
+typedef struct {
+	/* ChromeOS specific */
+	u32	vbt0;		// 00 boot reason
+	u32	vbt1;		// 04 active main firmware
+	u32	vbt2;		// 08 active ec firmware
+	u16	vbt3;		// 0c CHSW
+	u8	vbt4[256];	// 0e HWID
+	u8	vbt5[64];	// 10e FWID
+	u8	vbt6[64];	// 14e FRID - 275
+	u32	vbt7;		// 18e active main firmware type
+	u32	vbt8;		// 192 recovery reason
+	u32	vbt9;		// 196 fmap base address
+	u8	vdat[3072];	// 19a
+	u32	vbt10;		// d9a smbios bios version
+	u32	mehh[8];	// d9e management engine hash
+				// dbe
+} __attribute__((packed)) chromeos_acpi_t;
+
+extern chromeos_acpi_t *vboot_data;
+void chromeos_init_vboot(chromeos_acpi_t *chromeos);
+void chromeos_set_vboot_data_ptr(void *);
+void chromeos_set_me_hash(u32*, int);
+
+#endif
diff --git a/src/vendorcode/google/chromeos/vbnv.c b/src/vendorcode/google/chromeos/vbnv.c
new file mode 100644
index 0000000..2129461
--- /dev/null
+++ b/src/vendorcode/google/chromeos/vbnv.c
@@ -0,0 +1,109 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <string.h>
+#include <console/console.h>
+#include <pc80/mc146818rtc.h>
+#include <cpu/x86/car.h>
+#include "chromeos.h"
+
+#define VBNV_BLOCK_SIZE 16	/* Size of NV storage block in bytes */
+
+/* Constants for NV storage.  We use this rather than structs and
+ * bitfields so the data format is consistent across platforms and
+ * compilers.
+ */
+#define HEADER_OFFSET                0
+#define HEADER_MASK                     0xC0
+#define HEADER_SIGNATURE                0x40
+#define HEADER_FIRMWARE_SETTINGS_RESET  0x20
+#define HEADER_KERNEL_SETTINGS_RESET    0x10
+
+#define BOOT_OFFSET                  1
+#define BOOT_DEBUG_RESET_MODE           0x80
+#define BOOT_TRY_B_COUNT_MASK           0x0F
+
+#define RECOVERY_OFFSET              2
+#define LOCALIZATION_OFFSET          3
+
+#define DEV_FLAGS_OFFSET             4
+#define DEV_BOOT_USB_MASK               0x01
+
+#define FIRMWARE_FLAGS_OFFSET        5
+#define FIRMWARE_TEST_ERR_FUNC_MASK     0x38
+#define FIRMWARE_TEST_ERR_FUNC_SHIFT    3
+#define FIRMWARE_TEST_ERR_NUM_MASK      0x07
+
+#define KERNEL_FIELD_OFFSET         11
+#define CRC_OFFSET                  15
+
+static int vbnv_initialized CAR_GLOBAL;
+uint8_t vbnv[CONFIG_VBNV_SIZE] CAR_GLOBAL;
+
+/* Return CRC-8 of the data, using x^8 + x^2 + x + 1 polynomial.  A
+ * table-based algorithm would be faster, but for only 15 bytes isn't
+ * worth the code size.
+ */
+
+static uint8_t crc8(const uint8_t * data, int len)
+{
+	unsigned crc = 0;
+	int i, j;
+
+	for (j = len; j; j--, data++) {
+		crc ^= (*data << 8);
+		for (i = 8; i; i--) {
+			if (crc & 0x8000)
+				crc ^= (0x1070 << 3);
+			crc <<= 1;
+		}
+	}
+
+	return (uint8_t) (crc >> 8);
+}
+
+static void vbnv_setup(void)
+{
+	int i;
+
+	for (i = 0; i < CONFIG_VBNV_SIZE; i++)
+		vbnv[i] = cmos_read(CONFIG_VBNV_OFFSET + 14 + i);
+
+	/* Check data for consistency */
+	if ((HEADER_SIGNATURE != (vbnv[HEADER_OFFSET] & HEADER_MASK))
+	    || (crc8(vbnv, CRC_OFFSET) != vbnv[CRC_OFFSET])) {
+
+		/* Data is inconsistent (bad CRC or header),
+		 * so reset to defaults
+		 */
+		memset(vbnv, 0, VBNV_BLOCK_SIZE);
+		vbnv[HEADER_OFFSET] =
+		    (HEADER_SIGNATURE | HEADER_FIRMWARE_SETTINGS_RESET |
+		     HEADER_KERNEL_SETTINGS_RESET);
+	}
+	vbnv_initialized = 1;
+}
+
+int get_recovery_mode_from_vbnv(void)
+{
+	if (!vbnv_initialized)
+		vbnv_setup();
+	return vbnv[RECOVERY_OFFSET];
+}
diff --git a/src/vendorcode/google/chromeos/vboot.c b/src/vendorcode/google/chromeos/vboot.c
index e0a8c9b..5bdb7a2 100644
--- a/src/vendorcode/google/chromeos/vboot.c
+++ b/src/vendorcode/google/chromeos/vboot.c
@@ -21,9 +21,11 @@
 #include <console/console.h>
 #include <arch/acpi.h>
 #include <pc80/tpm.h>
+#include <reset.h>
 #include "chromeos.h"
 
 //#define EXTRA_LOGGING
+#define UBOOT_DOES_TPM_STARTUP
 
 #define TPM_LARGE_ENOUGH_COMMAND_SIZE 256	/* saves space in the firmware */
 
@@ -44,6 +46,12 @@ static const struct {
 };
 
 static const struct {
+	u8 buffer[12];
+} tpm_startup_cmd = {
+	{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1 }
+};
+
+static const struct {
 	u8 buffer[10];
 } tpm_continueselftest_cmd = {
 	{ 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53 }
@@ -169,33 +177,60 @@ static u32 TlclSendReceive(const u8 * request, u8 * response, int max_length)
 	return result;
 }
 
-void init_vboot(void)
+static void init_vboot(int bootmode)
 {
 	u32 result;
 	u8 response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
 
-	printk(BIOS_DEBUG, "TPM: Init\n");
+#ifdef UBOOT_DOES_TPM_STARTUP
+	/* Doing TPM startup when we're not coming in on the S3 resume path
+	 * saves us roughly 20ms in boot time only. This does not seem to
+	 * be worth an API change to vboot_reference-firmware right now, so
+	 * let's keep the code around, but just bail out early:
+	 */
+	if (bootmode != 2)
+		return;
+#endif
+
+	printk(BIOS_DEBUG, "Verified boot TPM initialization.\n");
+
+	printk(BIOS_SPEW, "TPM: Init\n");
 	if (tis_init())
 		return;
 
-	printk(BIOS_DEBUG, "TPM: Open\n");
+	printk(BIOS_SPEW, "TPM: Open\n");
 	if (tis_open())
 		return;
 
-	printk(BIOS_DEBUG, "TPM: Resume\n");
 
-	result =
-	    TlclSendReceive(tpm_resume_cmd.buffer, response, sizeof(response));
-
-	if (result == TPM_E_INVALID_POSTINIT) {
-		/* We're on a platform where the TPM maintains power in S3, so
-		 * it's already initialized. */
-		printk(BIOS_DEBUG, "TPM: Already initialized.\n");
-		return;
+	if (bootmode == 2) {
+		/* S3 Resume */
+		printk(BIOS_SPEW, "TPM: Resume\n");
+		result = TlclSendReceive(tpm_resume_cmd.buffer,
+					response, sizeof(response));
+		if (result == TPM_E_INVALID_POSTINIT) {
+			/* We're on a platform where the TPM maintains power
+			 * in S3, so it's already initialized.
+			 */
+			printk(BIOS_DEBUG, "TPM: Already initialized.\n");
+			return;
+		}
+	} else {
+		printk(BIOS_SPEW, "TPM: Startup\n");
+		result = TlclSendReceive(tpm_startup_cmd.buffer,
+					response, sizeof(response));
 	}
+
 	if (result == TPM_SUCCESS) {
-		printk(BIOS_DEBUG, "TPM: OK.\n");
+		printk(BIOS_SPEW, "TPM: OK.\n");
 		return;
 	}
-	// TODO(reinauer) hard reboot?
+
+	printk(BIOS_ERR, "TPM: Error code 0x%x. Hard reset!\n", result);
+	hard_reset();
+}
+
+void init_chromeos(int bootmode)
+{
+	init_vboot(bootmode);
 }




More information about the coreboot mailing list