summaryrefslogtreecommitdiff
path: root/host
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-08-03 12:48:24 -0700
committerGerrit <chrome-bot@google.com>2012-08-06 13:15:43 -0700
commitda8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79ac (patch)
tree8fe914a9e29c0e7d5384713f31750f38cf030c7e /host
parent63a0c47f501dd0ca59d763eb6c99022b4ba9d73c (diff)
downloadvboot-da8d32dc8d0fb5ebcfffa305f4a3ecb2dd7c79ac.tar.gz
Crossystem should return at-boot switch positions from VbSharedData
This is more reliable than reading them through FDT/ACPI, since it reflects the positions as shown to verified boot code. Notes: 1. This affects ALL platforms with virtual dev switches (x86 AND arm) 2. The fix should have no effect on older platforms, but I haven't tested those. BUG=chrome-os-partner:11805 TEST=manual 1. boot in normal mode. devsw_boot = 0 # Developer switch position at boot recovery_reason = 0 # Recovery mode reason for current boot recoverysw_boot = 0 # Recovery switch position at boot wpsw_boot = 1 # Firmware write protect hardware switch position at boot 2. boot in developer mode. localhost ~ # crossystem devsw_boot = 1 # Developer switch position at boot recovery_reason = 0 # Recovery mode reason for current boot recoverysw_boot = 0 # Recovery switch position at boot wpsw_boot = 1 # Firmware write protect hardware switch position at boot 3. boot in developer-recovery mode using keyboard combo. devsw_boot = 1 # Developer switch position at boot recovery_reason = 2 # Recovery mode reason for current boot recoverysw_boot = 1 # Recovery switch position at boot wpsw_boot = 1 # Firmware write protect hardware switch position at boot 4. disable WP and reboot. wpsw_boot should be 0. Change-Id: If4156b5e14c6923c5b331c7e5feaabbffe1dad37 Reviewed-on: https://gerrit.chromium.org/gerrit/29199 Commit-Ready: Randall Spangler <rspangler@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'host')
-rw-r--r--host/arch/arm/lib/crossystem_arch.c25
-rw-r--r--host/arch/x86/lib/crossystem_arch.c54
-rw-r--r--host/include/crossystem_arch.h6
-rw-r--r--host/lib/crossystem.c60
4 files changed, 83 insertions, 62 deletions
diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c
index 76be1588..3ccb0baf 100644
--- a/host/arch/arm/lib/crossystem_arch.c
+++ b/host/arch/arm/lib/crossystem_arch.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*/
@@ -89,20 +89,6 @@ static int ReadFdtValue(const char *property, int *value) {
return 0;
}
-static int ReadFdtBool(const char *property) {
- char filename[FNAME_SIZE];
- struct stat tmp;
- int err;
-
- snprintf(filename, sizeof(filename), FDT_BASE_PATH "/%s", property);
- err = stat(filename, &tmp);
-
- if (err == 0)
- return 1;
-
- return 0;
-}
-
static int ReadFdtInt(const char *property) {
int value;
if (ReadFdtValue(property, &value))
@@ -368,19 +354,14 @@ VbSharedDataHeader *VbSharedDataRead(void) {
int VbGetArchPropertyInt(const char* name) {
if (!strcasecmp(name, "fmap_base"))
return ReadFdtInt("fmap-offset");
- else if (!strcasecmp(name, "devsw_boot"))
- return ReadFdtBool("boot-developer-switch");
- else if (!strcasecmp(name, "recoverysw_boot"))
- return ReadFdtBool("boot-recovery-switch");
- else if (!strcasecmp(name, "wpsw_boot"))
- return ReadFdtBool("boot-write-protect-switch");
else if (!strcasecmp(name, "devsw_cur"))
return VbGetVarGpio("developer-switch");
else if (!strcasecmp(name, "recoverysw_cur"))
return VbGetVarGpio("recovery-switch");
else if (!strcasecmp(name, "wpsw_cur"))
- return VbGetVarGpio("write-protect-switch");
+ return VbGetVarGpio("write-protect-switch");
else if (!strcasecmp(name, "recoverysw_ec_boot"))
+ /* TODO: read correct value using ectool */
return 0;
else
return -1;
diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c
index b0ab10fa..448a8ffa 100644
--- a/host/arch/x86/lib/crossystem_arch.c
+++ b/host/arch/x86/lib/crossystem_arch.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*/
@@ -426,19 +426,8 @@ static const char* VbReadMainFwType(char* dest, int size) {
/* Read the recovery reason. Returns the reason code or -1 if error. */
static int VbGetRecoveryReason(void) {
- VbSharedDataHeader* sh;
int value = -1;
- /* Try reading from VbSharedData first */
- sh = VbSharedDataRead();
- if (sh) {
- if (sh->struct_version >= 2)
- value = sh->recovery_reason;
- free(sh);
- if (-1 != value)
- return value;
- }
-
/* Try reading type from BINF.4 */
value = ReadFileInt(ACPI_BINF_PATH ".4");
if (-1 != value)
@@ -601,13 +590,11 @@ int VbGetArchPropertyInt(const char* name) {
int value = -1;
/* Values from ACPI */
- if (!strcasecmp(name,"recovery_reason")) {
- value = VbGetRecoveryReason();
- } else if (!strcasecmp(name,"fmap_base")) {
+ if (!strcasecmp(name,"fmap_base"))
value = ReadFileInt(ACPI_FMAP_PATH);
- }
+
/* Switch positions */
- else if (!strcasecmp(name,"devsw_cur")) {
+ if (!strcasecmp(name,"devsw_cur")) {
value = ReadGpio(GPIO_SIGNAL_TYPE_DEV);
} else if (!strcasecmp(name,"recoverysw_cur")) {
value = ReadGpio(GPIO_SIGNAL_TYPE_RECOVERY);
@@ -615,28 +602,36 @@ int VbGetArchPropertyInt(const char* name) {
value = ReadGpio(GPIO_SIGNAL_TYPE_WP);
if (-1 != value && FwidStartsWith("Mario."))
value = 1 - value; /* Mario reports this backwards */
- } else if (!strcasecmp(name,"devsw_boot")) {
- value = ReadFileBit(ACPI_CHSW_PATH, CHSW_DEV_BOOT);
- } else if (!strcasecmp(name,"recoverysw_boot")) {
- value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_BOOT);
} else if (!strcasecmp(name,"recoverysw_ec_boot")) {
value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_EC_BOOT);
- } else if (!strcasecmp(name,"wpsw_boot")) {
- value = ReadFileBit(ACPI_CHSW_PATH, CHSW_WP_BOOT);
- if (-1 != value && FwidStartsWith("Mario."))
- value = 1 - value; /* Mario reports this backwards */
+ }
+
+ /* Fields for old systems which don't have VbSharedData */
+ if (VbSharedDataVersion() < 2) {
+ if (!strcasecmp(name,"recovery_reason")) {
+ value = VbGetRecoveryReason();
+ } else if (!strcasecmp(name,"devsw_boot")) {
+ value = ReadFileBit(ACPI_CHSW_PATH, CHSW_DEV_BOOT);
+ } else if (!strcasecmp(name,"recoverysw_boot")) {
+ value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_BOOT);
+ } else if (!strcasecmp(name,"wpsw_boot")) {
+ value = ReadFileBit(ACPI_CHSW_PATH, CHSW_WP_BOOT);
+ if (-1 != value && FwidStartsWith("Mario."))
+ value = 1 - value; /* Mario reports this backwards */
+ }
}
/* Saved memory is at a fixed location for all H2C BIOS. If the CHSW
* path exists in sysfs, it's a H2C BIOS. */
- else if (!strcasecmp(name,"savedmem_base")) {
+ if (!strcasecmp(name,"savedmem_base")) {
return (-1 == ReadFileInt(ACPI_CHSW_PATH) ? -1 : 0x00F00000);
} else if (!strcasecmp(name,"savedmem_size")) {
return (-1 == ReadFileInt(ACPI_CHSW_PATH) ? -1 : 0x00100000);
}
+
/* NV storage values. If unable to get from NV storage, fall back to the
- * CMOS reboot field used by older BIOS. */
- else if (!strcasecmp(name,"recovery_request")) {
+ * CMOS reboot field used by older BIOS (e.g. Mario). */
+ if (!strcasecmp(name,"recovery_request")) {
value = VbGetNvStorage(VBNV_RECOVERY_REQUEST);
if (-1 == value)
value = VbGetCmosRebootField(CMOSRF_RECOVERY);
@@ -649,10 +644,11 @@ int VbGetArchPropertyInt(const char* name) {
if (-1 == value)
value = VbGetCmosRebootField(CMOSRF_TRY_B);
}
+
/* Firmware update tries is now stored in the kernel field. On
* older systems where it's not, it was stored in a file in the
* stateful partition. */
- else if (!strcasecmp(name,"fwupdate_tries")) {
+ if (!strcasecmp(name,"fwupdate_tries")) {
if (-1 != VbGetNvStorage(VBNV_KERNEL_FIELD))
return -1; /* NvStorage supported; fail through arch-specific
* implementation to normal implementation. */
diff --git a/host/include/crossystem_arch.h b/host/include/crossystem_arch.h
index be6b5439..4044c749 100644
--- a/host/include/crossystem_arch.h
+++ b/host/include/crossystem_arch.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*
@@ -36,8 +36,10 @@ int VbSetNvStorage(VbNvParam param, int value);
/* Return true if the FWID starts with the specified string. */
int FwidStartsWith(const char *start);
+/* Return version of VbSharedData struct or -1 if not found. */
+int VbSharedDataVersion(void);
-/* APIS WITH ARCH-SPECIFIC IMPLEMENTATIONS */
+/* Apis WITH ARCH-SPECIFIC IMPLEMENTATIONS */
/* Read the non-volatile context from NVRAM.
*
diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c
index 1515ecf3..e120abcc 100644
--- a/host/lib/crossystem.c
+++ b/host/lib/crossystem.c
@@ -34,6 +34,12 @@ typedef enum VdatStringField {
/* Fields that GetVdatInt() can get */
typedef enum VdatIntField {
VDAT_INT_FLAGS = 0, /* Flags */
+ VDAT_INT_HEADER_VERSION, /* Header version for VbSharedData */
+ VDAT_INT_DEVSW_BOOT, /* Dev switch position at boot */
+ VDAT_INT_DEVSW_VIRTUAL, /* Dev switch is virtual */
+ VDAT_INT_RECSW_BOOT, /* Recovery switch position at boot */
+ VDAT_INT_WPSW_BOOT, /* WP switch position at boot */
+
VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */
VDAT_INT_KERNEL_VERSION_TPM, /* Current kernel version in TPM */
VDAT_INT_TRIED_FIRMWARE_B, /* Tried firmware B due to fwb_tries */
@@ -322,15 +328,13 @@ int GetVdatInt(VdatIntField field) {
if (!sh)
return -1;
+ /* Fields supported in version 1 */
switch (field) {
case VDAT_INT_FLAGS:
value = (int)sh->flags;
break;
- case VDAT_INT_FW_VERSION_TPM:
- value = (int)sh->fw_version_tpm;
- break;
- case VDAT_INT_KERNEL_VERSION_TPM:
- value = (int)sh->kernel_version_tpm;
+ case VDAT_INT_HEADER_VERSION:
+ value = sh->struct_version;
break;
case VDAT_INT_TRIED_FIRMWARE_B:
value = (sh->flags & VBSD_FWB_TRIED ? 1 : 0);
@@ -338,17 +342,47 @@ int GetVdatInt(VdatIntField field) {
case VDAT_INT_KERNEL_KEY_VERIFIED:
value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0);
break;
- case VDAT_INT_RECOVERY_REASON:
- /* Field added in struct version 2 */
- if (sh->struct_version >= 2)
- value = sh->recovery_reason;
+ default:
break;
}
+ /* Fields added in struct version 2 */
+ if (sh->struct_version >= 2) {
+ switch(field) {
+ case VDAT_INT_DEVSW_BOOT:
+ value = (sh->flags & VBSD_BOOT_DEV_SWITCH_ON ? 1 : 0);
+ break;
+ case VDAT_INT_DEVSW_VIRTUAL:
+ value = (sh->flags & VBSD_HONOR_VIRT_DEV_SWITCH ? 1 : 0);
+ break;
+ case VDAT_INT_RECSW_BOOT:
+ value = (sh->flags & VBSD_BOOT_REC_SWITCH_ON ? 1 : 0);
+ break;
+ case VDAT_INT_WPSW_BOOT:
+ value = (sh->flags & VBSD_BOOT_FIRMWARE_WP_ENABLED ? 1 : 0);
+ break;
+ case VDAT_INT_FW_VERSION_TPM:
+ value = (int)sh->fw_version_tpm;
+ break;
+ case VDAT_INT_KERNEL_VERSION_TPM:
+ value = (int)sh->kernel_version_tpm;
+ break;
+ case VDAT_INT_RECOVERY_REASON:
+ value = sh->recovery_reason;
+ break;
+ default:
+ break;
+ }
+ }
+
free(sh);
return value;
}
+/* Return version of VbSharedData struct or -1 if not found. */
+int VbSharedDataVersion(void) {
+ return GetVdatInt(VDAT_INT_HEADER_VERSION);
+}
int VbGetSystemPropertyInt(const char* name) {
int value = -1;
@@ -387,6 +421,14 @@ int VbGetSystemPropertyInt(const char* name) {
/* Other parameters */
else if (!strcasecmp(name,"cros_debug")) {
value = VbGetCrosDebug();
+ } else if (!strcasecmp(name,"devsw_boot")) {
+ value = GetVdatInt(VDAT_INT_DEVSW_BOOT);
+ } else if (!strcasecmp(name,"devsw_virtual")) {
+ value = GetVdatInt(VDAT_INT_DEVSW_VIRTUAL);
+ } else if (!strcasecmp(name, "recoverysw_boot")) {
+ value = GetVdatInt(VDAT_INT_RECSW_BOOT);
+ } else if (!strcasecmp(name, "wpsw_boot")) {
+ value = GetVdatInt(VDAT_INT_WPSW_BOOT);
} else if (!strcasecmp(name,"vdat_flags")) {
value = GetVdatInt(VDAT_INT_FLAGS);
} else if (!strcasecmp(name,"tpm_fwver")) {