mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-13 03:15:06 +00:00
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>
This commit is contained in:
@@ -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.
|
||||
*
|
||||
@@ -236,6 +236,12 @@ typedef struct VbKernelPreambleHeader {
|
||||
/* VbInit() was told the system supports EC software sync */
|
||||
#define VBSD_EC_SOFTWARE_SYNC 0x00000800
|
||||
|
||||
/* Supported flags by header version. It's ok to add new flags while keeping
|
||||
* struct version 2 as long as flag-NOT-present is the correct value for
|
||||
* existing hardware (Stumpy/Lumpy). */
|
||||
#define VBSD_FLAGS_VERSION_1 0x00000007 /* Alex, ZGB */
|
||||
#define VBSD_FLAGS_VERSION_2 0x00000F7F
|
||||
|
||||
/* Result codes for VbSharedDataHeader.check_fw_a_result (and b_result) */
|
||||
#define VBSD_LF_CHECK_NOT_DONE 0
|
||||
#define VBSD_LF_CHECK_DEV_MISMATCH 1
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
Reference in New Issue
Block a user