diff options
author | Che-Liang Chiou <clchiou@chromium.org> | 2011-05-12 18:35:32 +0800 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2011-08-29 10:39:21 -0700 |
commit | 8ca61798f16369fa245b84fd6d22a487b61864ec (patch) | |
tree | b13fdbcd3c5224e19ae506e5f02a2295aecfcea5 | |
parent | bdfc6085f392252b2b900af4ff3e04c70d39b406 (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/Makefile | 1 | ||||
-rw-r--r-- | board/nvidia/chromeos/power_management.c | 56 | ||||
-rw-r--r-- | common/cmd_cros.c | 11 | ||||
-rw-r--r-- | common/cmd_cros_bootstub.c | 3 | ||||
-rw-r--r-- | common/cmd_cros_normal_firmware.c | 5 | ||||
-rw-r--r-- | include/chromeos/power_management.h | 20 | ||||
-rw-r--r-- | lib/chromeos/utility.c | 3 | ||||
-rw-r--r-- | lib/chromeos/vboot_nvstorage_helper.c | 5 |
8 files changed, 98 insertions, 6 deletions
diff --git a/board/nvidia/chromeos/Makefile b/board/nvidia/chromeos/Makefile index b1d3bd1b70c..7b1d1cdc6c4 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 00000000000..118f5df6002 --- /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 71bcb7de78d..a75a771bfde 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 2565e35db5e..792db983159 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 392faeecffc..ce8af10f47e 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 00000000000..737c7c22518 --- /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 db76969de23..65e1f1d3c39 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 d73615c5d1a..d04ece1b800 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"); |