summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2016-04-07 12:21:03 +0800
committerChromeOS bot <3su6n15k.default@developer.gserviceaccount.com>2016-04-13 17:26:07 +0000
commit4bc9906f35507cb332456cb69f883fad4cdfcba2 (patch)
treecb9c968aa29832ac0d137a73a48406f5d7271ef1
parent37ae160e51581fd51f84ac478645251412f5ea86 (diff)
downloadvboot-firmware-glados-7820.315.B.tar.gz
Support doing battery cut-off in firmware stage.firmware-glados-7820.Bfirmware-glados-7820.315.B
Add a new crossystem value "battery_cutoff_request" to indicate that next reboot should cut-off battery and shutdown during firmware stage. This request is primarily for factories to ship devices in an safe state. Previously we have done same thing by running "ectool battery-cutoff" but that creates a problem which "ectool" (and the one to request for cut-off) must live in developer mode while the device must be shipped in normal mode. The mode transition was solved by setting "disable_dev_request=1", but that flag is may get lost on x86 systems (having NV storage in CMOS) when the battery is cut-off . From the experience from Ryu, such settings (dev mode transition and battery cut-off) should be done together inside firmware execution so we can create a new flag, battery_cutoff_request, to finalize device properly. BRANCH=none BUG=chromium:601705 TEST=emerge-chell depthcharge vboot_reference chromeos-bootimage crossystem battery_cutoff_request=1 # Unplug AC adapter reboot # See device rebooted and then shutdown immediately. # Press power button and system won't boot. # Attach AC adapter and now system boots. CQ-DEPEND=CL:338288,CL:338399 Original-Change-Id: I73ccae15b337cd65786106646546c67c155b8fa6 Original-Reviewed-on: https://chromium-review.googlesource.com/337602 Commit-Ready: Hung-Te Lin <hungte@chromium.org> Tested-by: Hung-Te Lin <hungte@chromium.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org> (cherry picked from commit aee6bd69fefac653cfc4a5679eb387d7c3280d14) Change-Id: I563602ee8437f867720942df7f658a28378579aa Reviewed-on: https://chromium-review.googlesource.com/338178 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Tested-by: Duncan Laurie <dlaurie@chromium.org> Commit-Queue: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--firmware/2lib/2nvstorage.c6
-rw-r--r--firmware/2lib/include/2nvstorage.h2
-rw-r--r--firmware/2lib/include/2nvstorage_fields.h3
-rw-r--r--firmware/include/vboot_api.h5
-rw-r--r--firmware/include/vboot_nvstorage.h5
-rw-r--r--firmware/lib/vboot_api_kernel.c12
-rw-r--r--firmware/lib/vboot_nvstorage.c13
-rw-r--r--firmware/stub/vboot_api_stub.c5
-rw-r--r--host/lib/crossystem.c4
-rw-r--r--utility/crossystem.c2
10 files changed, 55 insertions, 2 deletions
diff --git a/firmware/2lib/2nvstorage.c b/firmware/2lib/2nvstorage.c
index 3e2a8740..b40bbe78 100644
--- a/firmware/2lib/2nvstorage.c
+++ b/firmware/2lib/2nvstorage.c
@@ -172,6 +172,9 @@ uint32_t vb2_nv_get(struct vb2_context *ctx, enum vb2_nv_param param)
case VB2_NV_TRY_RO_SYNC:
return GETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_TRY_RO_SYNC);
+
+ case VB2_NV_BATTERY_CUTOFF_REQUEST:
+ return GETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_BATTERY_CUTOFF);
}
/*
@@ -350,6 +353,9 @@ void vb2_nv_set(struct vb2_context *ctx,
SETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_TRY_RO_SYNC);
break;
+ case VB2_NV_BATTERY_CUTOFF_REQUEST:
+ SETBIT(VB2_NV_OFFS_MISC, VB2_NV_MISC_BATTERY_CUTOFF);
+ break;
}
/*
diff --git a/firmware/2lib/include/2nvstorage.h b/firmware/2lib/include/2nvstorage.h
index 5c958c76..66a5fdf1 100644
--- a/firmware/2lib/include/2nvstorage.h
+++ b/firmware/2lib/include/2nvstorage.h
@@ -96,6 +96,8 @@ enum vb2_nv_param {
VB2_NV_BOOT_ON_AC_DETECT,
/* Try to update the EC-RO image after updating the EC-RW image(0=no, 1=yes). */
VB2_NV_TRY_RO_SYNC,
+ /* Cut off battery and shutdown on next boot. */
+ VB2_NV_BATTERY_CUTOFF_REQUEST,
};
/* Set default boot in developer mode */
diff --git a/firmware/2lib/include/2nvstorage_fields.h b/firmware/2lib/include/2nvstorage_fields.h
index 9ec3d884..018bdeb7 100644
--- a/firmware/2lib/include/2nvstorage_fields.h
+++ b/firmware/2lib/include/2nvstorage_fields.h
@@ -70,9 +70,10 @@ enum vb2_nv_offset {
#define VB2_NV_TPM_CLEAR_OWNER_DONE 0x02
#define VB2_NV_TPM_REBOOTED 0x04
-/* Fields in VB2_NV_OFFS_MISC (unused = 0xf8) */
+/* Fields in VB2_NV_OFFS_MISC (unused = 0xf0) */
#define VB2_NV_MISC_UNLOCK_FASTBOOT 0x01
#define VB2_NV_MISC_BOOT_ON_AC_DETECT 0x02
#define VB2_NV_MISC_TRY_RO_SYNC 0x04
+#define VB2_NV_MISC_BATTERY_CUTOFF 0x08
#endif /* VBOOT_REFERENCE_VBOOT_2NVSTORAGE_FIELDS_H_ */
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index ddc8cc62..5046d2ae 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -945,6 +945,11 @@ VbError_t VbExEcEnteringMode(int devidx, enum VbEcBootMode_t mode);
*/
VbError_t VbExEcVbootDone(int in_recovery);
+/**
+ * Request EC to stop discharging and cut-off battery.
+ */
+VbError_t VbExEcBatteryCutOff(void);
+
/*****************************************************************************/
/* Misc */
diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h
index 91f62cb4..ef78e47a 100644
--- a/firmware/include/vboot_nvstorage.h
+++ b/firmware/include/vboot_nvstorage.h
@@ -120,7 +120,10 @@ typedef enum VbNvParam {
VBNV_BOOT_ON_AC_DETECT,
/* Try to update the EC-RO image (0=no, 1=yes). */
VBNV_TRY_RO_SYNC,
-
+ /*
+ * Finish mode transition (if requested), perform battery cut-off and
+ * shutdown in next boot. */
+ VBNV_BATTERY_CUTOFF_REQUEST,
} VbNvParam;
/* Set default boot in developer mode */
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index fff30561..c3362789 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -1082,6 +1082,7 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
VbError_t retval = VBERROR_SUCCESS;
LoadKernelParams p;
uint32_t tpm_status = 0;
+ uint32_t battery_cutoff = 0;
/* Start timer */
shared->timer_vb_select_and_load_kernel_enter = VbExGetTimer();
@@ -1138,6 +1139,17 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
if (retval != VBERROR_SUCCESS)
goto VbSelectAndLoadKernel_exit;
+ /* Check if we need to cut-off battery. This must be done after EC
+ * firmware updating and before kernel started. */
+ VbNvGet(&vnc, VBNV_BATTERY_CUTOFF_REQUEST, &battery_cutoff);
+ if (battery_cutoff) {
+ VBDEBUG(("Request to cut-off battery\n"));
+ VbNvSet(&vnc, VBNV_BATTERY_CUTOFF_REQUEST, 0);
+ VbExEcBatteryCutOff();
+ retval = VBERROR_SHUTDOWN_REQUESTED;
+ goto VbSelectAndLoadKernel_exit;
+ }
+
/* Read kernel version from the TPM. Ignore errors in recovery mode. */
tpm_status = RollbackKernelRead(&shared->kernel_version_tpm);
if (0 != tpm_status) {
diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c
index d022c5d3..c131f088 100644
--- a/firmware/lib/vboot_nvstorage.c
+++ b/firmware/lib/vboot_nvstorage.c
@@ -64,6 +64,7 @@
#define MISC_UNLOCK_FASTBOOT 0x01
#define MISC_BOOT_ON_AC_DETECT 0x02
#define MISC_TRY_RO_SYNC 0x04
+#define MISC_BATTERY_CUTOFF_REQUEST 0x08
#define KERNEL_FIELD_OFFSET 11
#define CRC_OFFSET 15
@@ -231,6 +232,11 @@ int VbNvGet(VbNvContext *context, VbNvParam param, uint32_t *dest)
*dest = (raw[MISC_OFFSET] & MISC_TRY_RO_SYNC) ? 1 : 0;
return 0;
+ case VBNV_BATTERY_CUTOFF_REQUEST:
+ *dest = (raw[MISC_OFFSET] & MISC_BATTERY_CUTOFF_REQUEST)
+ ? 1 : 0;
+ return 0;
+
default:
return 1;
}
@@ -456,6 +462,13 @@ int VbNvSet(VbNvContext *context, VbNvParam param, uint32_t value)
raw[MISC_OFFSET] &= ~MISC_TRY_RO_SYNC;
break;
+ case VBNV_BATTERY_CUTOFF_REQUEST:
+ if (value)
+ raw[MISC_OFFSET] |= MISC_BATTERY_CUTOFF_REQUEST;
+ else
+ raw[MISC_OFFSET] &= ~MISC_BATTERY_CUTOFF_REQUEST;
+ break;
+
default:
return 1;
}
diff --git a/firmware/stub/vboot_api_stub.c b/firmware/stub/vboot_api_stub.c
index 2299a033..7bc4cb86 100644
--- a/firmware/stub/vboot_api_stub.c
+++ b/firmware/stub/vboot_api_stub.c
@@ -166,6 +166,11 @@ VbError_t VbExEcVbootDone(int in_recovery)
return VBERROR_SUCCESS;
}
+VbError_t VbExEcBatteryCutOff(void)
+{
+ return VBERROR_SUCCESS;
+}
+
enum VbEcBootMode_t VbGetMode(void)
{
return vboot_mode;
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index fd5cd9eb..3d2a908f 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -542,6 +542,8 @@ int VbGetSystemPropertyInt(const char* name) {
value = VbGetNvStorage(VBNV_BOOT_ON_AC_DETECT);
} else if (!strcasecmp(name, "try_ro_sync")) {
value = VbGetNvStorage(VBNV_TRY_RO_SYNC);
+ } else if (!strcasecmp(name, "battery_cutoff_request")) {
+ value = VbGetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST);
}
return value;
@@ -678,6 +680,8 @@ int VbSetSystemPropertyInt(const char* name, int value) {
return VbSetNvStorage_WithBackup(VBNV_BOOT_ON_AC_DETECT, value);
} else if (!strcasecmp(name, "try_ro_sync")) {
return VbSetNvStorage_WithBackup(VBNV_TRY_RO_SYNC, value);
+ } else if (!strcasecmp(name, "battery_cutoff_request")) {
+ return VbSetNvStorage(VBNV_BATTERY_CUTOFF_REQUEST, value);
}
return -1;
diff --git a/utility/crossystem.c b/utility/crossystem.c
index 330a3fd5..c88a444d 100644
--- a/utility/crossystem.c
+++ b/utility/crossystem.c
@@ -34,6 +34,8 @@ const Param sys_param_list[] = {
{"arch", IS_STRING, "Platform architecture"},
{"backup_nvram_request", CAN_WRITE,
"Backup the nvram somewhere at the next boot. Cleared on success."},
+ {"battery_cutoff_request", CAN_WRITE,
+ "Cut off battery and shutdown on next boot."},
{"block_devmode", CAN_WRITE, "Block all use of developer mode"},
{"clear_tpm_owner_request", CAN_WRITE, "Clear TPM owner on next boot"},
{"clear_tpm_owner_done", CAN_WRITE, "Clear TPM owner done"},