summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChe-Liang Chiou <clchiou@chromium.org>2011-05-12 18:35:32 +0800
committerSimon Glass <sjg@chromium.org>2011-08-29 10:39:21 -0700
commit8ca61798f16369fa245b84fd6d22a487b61864ec (patch)
treeb13fdbcd3c5224e19ae506e5f02a2295aecfcea5
parentbdfc6085f392252b2b900af4ff3e04c70d39b406 (diff)
Implement cold reboot
The verified boot spec requires that firmware cold (not warm) reboots so that TPM gets reseted. BUG=chrome-os-partner:3574 TEST=manual 1. Run load_fw twice, and verify that SetupTPM failed in the second run ------------------------------------------------------------ CrOS> cros load_fw 0x0 0x01000000 0x00400000 0x10000000 ... DEBUG: TPM: SetupTPM(r0, d0) ... DEBUG: TPM: SetupTPM() succeeded ... CrOS> cros load_fw 0x0 0x01000000 0x00400000 0x10000000 ... DEBUG: TPM: SetupTPM(r0, d0) ... DEBUG: Unable to setup TPM and read stored versions. ------------------------------------------------------------ 2. Run load_fw twice and a reset in between, and results the same ------------------------------------------------------------ CrOS> cros load_fw 0x0 0x01000000 0x00400000 0x10000000 ... CrOS> reset ... CrOS> cros load_fw 0x0 0x01000000 0x00400000 0x10000000 ------------------------------------------------------------ 3. Run load_fw twice and a "cros cold_reboot" in between, and verify that SetupTPM succeeds in both runs ------------------------------------------------------------ CrOS> cros load_fw 0x0 0x01000000 0x00400000 0x10000000 ... CrOS> cros cold_reboot ... CrOS> cros load_fw 0x0 0x01000000 0x00400000 0x10000000 ------------------------------------------------------------ Cherry-pick: bbb6ba7 Change-Id: Ie74bb214c80714d1814b4ae295c4780aa2bc7ddc Reviewed-on: http://gerrit.chromium.org/gerrit/756 Tested-by: Che-Liang Chiou <clchiou@chromium.org> Reviewed-by: Rong Chang <rongchang@chromium.org>
-rw-r--r--board/nvidia/chromeos/Makefile1
-rw-r--r--board/nvidia/chromeos/power_management.c56
-rw-r--r--common/cmd_cros.c11
-rw-r--r--common/cmd_cros_bootstub.c3
-rw-r--r--common/cmd_cros_normal_firmware.c5
-rw-r--r--include/chromeos/power_management.h20
-rw-r--r--lib/chromeos/utility.c3
-rw-r--r--lib/chromeos/vboot_nvstorage_helper.c5
8 files changed, 98 insertions, 6 deletions
diff --git a/board/nvidia/chromeos/Makefile b/board/nvidia/chromeos/Makefile
index b1d3bd1b70..7b1d1cdc6c 100644
--- a/board/nvidia/chromeos/Makefile
+++ b/board/nvidia/chromeos/Makefile
@@ -39,6 +39,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libchromeos_hardware_interface.a
COBJS-$(CONFIG_CHROMEOS) += gpio.o
+COBJS-$(CONFIG_CHROMEOS) += power_management.o
COBJS := $(COBJS-y)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/nvidia/chromeos/power_management.c b/board/nvidia/chromeos/power_management.c
new file mode 100644
index 0000000000..118f5df600
--- /dev/null
+++ b/board/nvidia/chromeos/power_management.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/* Implementation of per-board power management function */
+
+#include <common.h>
+#include <i2c.h>
+
+#include <chromeos/power_management.h>
+
+#define PREFIX "cold_reboot: "
+
+#define PMIC_I2C_BUS 0x00
+#define PMIC_I2C_DEVICE_ADDRESS 0x34
+#define TPS6586X_SUPPLYENE 0x14
+
+/* This function never returns */
+void cold_reboot(void)
+{
+ uint8_t byte;
+
+ if (i2c_set_bus_num(PMIC_I2C_BUS)) {
+ debug(PREFIX "i2c_set_bus_num fail\n");
+ goto FATAL;
+ }
+
+ if (i2c_read(PMIC_I2C_DEVICE_ADDRESS, TPS6586X_SUPPLYENE, 1,
+ &byte, sizeof(byte))) {
+ debug(PREFIX "i2c_read fail\n");
+ goto FATAL;
+ }
+
+ /* Set TPS6586X_SUPPLYENE bit0 to 1 */
+ byte |= 1;
+
+ if (i2c_write(PMIC_I2C_DEVICE_ADDRESS, TPS6586X_SUPPLYENE, 1,
+ &byte, sizeof(byte))) {
+ debug(PREFIX "i2c_write fail\n");
+ goto FATAL;
+ }
+
+ /* The PMIC will reboot the whole system after 10 ms */
+ udelay(100);
+
+FATAL:
+ /* The final solution of doing a cold reboot */
+ printf("Please press cold reboot button\n");
+ while (1);
+}
diff --git a/common/cmd_cros.c b/common/cmd_cros.c
index 71bcb7de78..a75a771bfd 100644
--- a/common/cmd_cros.c
+++ b/common/cmd_cros.c
@@ -20,6 +20,7 @@
#include <chromeos/gpio.h>
#include <chromeos/load_firmware_helper.h>
#include <chromeos/load_kernel_helper.h>
+#include <chromeos/power_management.h>
#include <chromeos/vboot_nvstorage_helper.h>
#include <chromeos/os_storage.h>
@@ -47,6 +48,7 @@ int do_fmap (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_nvram (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_load_fw (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_load_k (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+int do_cold_reboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
int do_cros_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
U_BOOT_CMD(cros, CONFIG_SYS_MAXARGS, 1, do_cros,
@@ -92,6 +94,9 @@ cmd_tbl_t cmd_cros_sub[] = {
"Load kernel from the boot device",
"boot_flags shdata\n - Load kernel with boot_flags and "
"modify shared data at shdata\n"),
+ U_BOOT_CMD_MKENT(cold_reboot, 1, 1, do_cold_reboot,
+ "Cold reboot the machine",
+ ""),
U_BOOT_CMD_MKENT(help, 1, 1, do_cros_help,
"show this message",
"[action]")
@@ -566,6 +571,12 @@ int do_load_k(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return retcode;
}
+int do_cold_reboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ cold_reboot();
+ return 0;
+}
+
int do_cros_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
cmd_tbl_t *c;
diff --git a/common/cmd_cros_bootstub.c b/common/cmd_cros_bootstub.c
index 2565e35db5..792db98315 100644
--- a/common/cmd_cros_bootstub.c
+++ b/common/cmd_cros_bootstub.c
@@ -16,6 +16,7 @@
#include <chromeos/firmware_storage.h>
#include <chromeos/gpio.h>
#include <chromeos/load_firmware_helper.h>
+#include <chromeos/power_management.h>
#include <chromeos/vboot_nvstorage_helper.h>
/* Verify Boot interface */
@@ -128,7 +129,7 @@ int do_cros_bootstub(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (status == LOAD_FIRMWARE_SUCCESS) {
jump_to_firmware((void (*)(void)) firmware_data);
} else if (status == LOAD_FIRMWARE_REBOOT) {
- reset_cpu(0);
+ cold_reboot();
}
/* assert(status == LOAD_FIRMWARE_RECOVERY) */
diff --git a/common/cmd_cros_normal_firmware.c b/common/cmd_cros_normal_firmware.c
index 392faeecff..ce8af10f47 100644
--- a/common/cmd_cros_normal_firmware.c
+++ b/common/cmd_cros_normal_firmware.c
@@ -20,6 +20,7 @@
#include <chromeos/load_firmware_helper.h>
#include <chromeos/load_kernel_helper.h>
#include <chromeos/os_storage.h>
+#include <chromeos/power_management.h>
#include <chromeos/vboot_nvstorage_helper.h>
#include <boot_device.h>
@@ -138,8 +139,8 @@ int do_cros_normal_firmware(cmd_tbl_t *cmdtp, int flag, int argc,
if (status == LOAD_KERNEL_REBOOT) {
debug(PREFIX "internal error: reboot to current mode\n");
- reset_cpu(0);
- debug(PREFIX "error: reset_cpu() returns\n");
+ cold_reboot();
+ debug(PREFIX "error: cold_reboot() returns\n");
while (1);
}
diff --git a/include/chromeos/power_management.h b/include/chromeos/power_management.h
new file mode 100644
index 0000000000..737c7c2251
--- /dev/null
+++ b/include/chromeos/power_management.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ */
+
+/* power management interface for Chrome OS verified boot */
+
+#ifndef CHROMEOS_POWER_MANAGEMENT_H_
+#define CHROMEOS_POWER_MANAGEMENT_H_
+
+/* Tell PMIC to cold reboot the whole system */
+void cold_reboot(void);
+
+#endif /* CHROMEOS_POWER_MANAGEMENT_H_ */
+
diff --git a/lib/chromeos/utility.c b/lib/chromeos/utility.c
index db76969de2..65e1f1d3c3 100644
--- a/lib/chromeos/utility.c
+++ b/lib/chromeos/utility.c
@@ -15,6 +15,7 @@
#include <config.h>
#include <common.h>
#include <malloc.h>
+#include <chromeos/power_management.h>
/* HACK: Get rid of U-Boots debug and assert macros */
#undef error
@@ -35,7 +36,7 @@ int memcmp(const void *cs, const void *ct, size_t count);
*/
void _abort(void)
{
- reset_cpu(0);
+ cold_reboot();
}
#define exit(retcode) _abort()
diff --git a/lib/chromeos/vboot_nvstorage_helper.c b/lib/chromeos/vboot_nvstorage_helper.c
index d73615c5d1..d04ece1b80 100644
--- a/lib/chromeos/vboot_nvstorage_helper.c
+++ b/lib/chromeos/vboot_nvstorage_helper.c
@@ -35,6 +35,7 @@
*/
#include <common.h>
+#include <chromeos/power_management.h>
#include <chromeos/vboot_nvstorage_helper.h>
/* TODO: temporary hack for factory bring up; remove/rewrite when necessary */
@@ -210,9 +211,9 @@ void reboot_to_recovery_mode(VbNvContext *nvcxt, uint32_t reason)
}
debug(PREFIX "reboot to recovery mode\n");
- reset_cpu(0);
+ cold_reboot();
- debug(PREFIX "error: reset_cpu() returned\n");
+ debug(PREFIX "error: cold_reboot() returned\n");
FAIL:
/* FIXME: bring up a sad face? */
printf("Please reset and press recovery button when reboot.\n");