summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/chromeos/crossystem_data.h53
-rw-r--r--lib/chromeos/boot_kernel.c2
-rw-r--r--lib/chromeos/crossystem_data.c46
3 files changed, 101 insertions, 0 deletions
diff --git a/include/chromeos/crossystem_data.h b/include/chromeos/crossystem_data.h
index 874520c1b2..053e632ed7 100644
--- a/include/chromeos/crossystem_data.h
+++ b/include/chromeos/crossystem_data.h
@@ -28,6 +28,30 @@ enum {
FIRMWARE_TYPE_DEVELOPER = 2
};
+enum {
+ BOOT_REASON_OTHER = 0,
+ BOOT_REASON_S3DIAG = 9
+};
+
+enum {
+ CHSW_RECOVERY_X86 = (1 << 1),
+ CHSW_RECOVERY_EC = (1 << 2),
+ CHSW_DEVELOPER_SWITCH = (1 << 5),
+ CHSW_FIRMWARE_WP_DIS = (1 << 9)
+};
+
+enum {
+ ACTIVE_MAINFW_RECOVERY = 0,
+ ACTIVE_MAINFW_RW_A = 1,
+ ACTIVE_MAINFW_RW_B = 2
+};
+
+enum {
+ RECOVERY_REASON_NONE = 0,
+ RECOVERY_REASON_ME = 1
+};
+/* TODO(reinauer) other recovery reasons? */
+
/* the data blob format */
typedef struct {
/* Header of crossystem data blob */
@@ -93,6 +117,26 @@ typedef struct {
uint8_t vb_shared_data[VB_SHARED_DATA_REC_SIZE];
} __attribute__((packed)) crossystem_data_t;
+/*
+ * This structure is also used in coreboot. Any changes to this version have
+ * to be made to that version as well
+ */
+typedef struct {
+ /* ChromeOS specific */
+ uint32_t vbt0; /* 00 boot reason */
+ uint32_t vbt1; /* 04 active main firmware */
+ uint32_t vbt2; /* 08 active ec firmware */
+ uint16_t vbt3; /* 0c CHSW */
+ uint8_t vbt4[256]; /* 0e HWID */
+ uint8_t vbt5[64]; /* 10e FWID */
+ uint8_t vbt6[64]; /* 14e FRID - 275 */
+ uint32_t vbt7; /* 18e active main firmware type */
+ uint32_t vbt8; /* 192 recovery reason */
+ uint32_t vbt9; /* 196 fmap base address */
+ uint8_t vdat[3072]; /* 19a */
+ /* d9a */
+} __attribute__((packed)) chromeos_acpi_t;
+
#define assert_offset(MEMBER, OFFSET) \
typedef char static_assertion_##MEMBER_is_at_offset_##OFFSET[ \
(offsetof(crossystem_data_t, MEMBER) == (OFFSET)) ? 1 : -1]
@@ -184,6 +228,15 @@ int crossystem_data_set_main_firmware(crossystem_data_t *cdata,
int crossystem_data_embed_into_fdt(crossystem_data_t *cdata, void *fdt,
uint32_t *size_ptr);
+#ifdef CONFIG_X86
+/**
+ * This embeds kernel shared data into the ACPI tables.
+ *
+ * @return 0 if it succeeds, non-zero if it fails
+ */
+int crossystem_data_update_acpi(crossystem_data_t *cdata);
+#endif
+
/**
* This prints out the data blob content to debug output.
*/
diff --git a/lib/chromeos/boot_kernel.c b/lib/chromeos/boot_kernel.c
index 2012bea6f3..2edb5523ed 100644
--- a/lib/chromeos/boot_kernel.c
+++ b/lib/chromeos/boot_kernel.c
@@ -256,6 +256,8 @@ int boot_kernel(VbSelectAndLoadKernelParams *kparams, crossystem_data_t *cdata)
#endif /* CONFIG_OF_UPDATE_FDT_BEFORE_BOOT */
#ifdef CONFIG_X86
+ crossystem_data_update_acpi(cdata);
+
params = (struct boot_params *)(uintptr_t)
(kparams->bootloader_address - CROS_PARAMS_SIZE);
if (!setup_zimage(params, cmdline, 0, 0, 0))
diff --git a/lib/chromeos/crossystem_data.c b/lib/chromeos/crossystem_data.c
index c2fbaeeebb..3720254c86 100644
--- a/lib/chromeos/crossystem_data.c
+++ b/lib/chromeos/crossystem_data.c
@@ -27,6 +27,8 @@
#define PREFIX "crossystem_data: "
+DECLARE_GLOBAL_DATA_PTR;
+
int crossystem_data_init(crossystem_data_t *cdata,
cros_gpio_t *write_protect_switch,
cros_gpio_t *recovery_switch,
@@ -236,6 +238,50 @@ int crossystem_data_embed_into_fdt(crossystem_data_t *cdata, void *fdt,
}
#endif /* ^^^^ CONFIG_OF_LIBFDT NOT defined ^^^^ */
+#ifdef CONFIG_X86
+int crossystem_data_update_acpi(crossystem_data_t *cdata)
+{
+ const void *fdt = gd->blob;
+ int node_offset, len;
+ const uint32_t *cell;
+ chromeos_acpi_t *acpi_table;
+
+ node_offset = fdt_path_offset(fdt, "/chromeos-config");
+ if (node_offset < 0) {
+ VBDEBUG("crossystem_data_update_acpi: Couldn't access "
+ "chromeos-config.\n");
+ return 1;
+ }
+ cell = fdt_getprop(fdt, node_offset, "gnvs-vboot-table", NULL);
+ if (!cell) {
+ VBDEBUG("crossystem_data_update_acpi: Couldn't access "
+ "gnvs-vboot-table.\n");
+ return 1;
+ }
+ acpi_table = (chromeos_acpi_t *)(uintptr_t)ntohl(*cell);
+
+ acpi_table->vbt0 = BOOT_REASON_OTHER;
+ acpi_table->vbt1 = ACTIVE_MAINFW_RW_A;
+ acpi_table->vbt2 = cdata->active_ec_firmware;
+ acpi_table->vbt3 =
+ (cdata->boot_write_protect_switch ? CHSW_FIRMWARE_WP_DIS : 0) |
+ (cdata->boot_recovery_switch ? CHSW_RECOVERY_X86 : 0) |
+ (cdata->boot_developer_switch ? CHSW_DEVELOPER_SWITCH : 0);
+
+ len = min(ID_LEN, sizeof(acpi_table->vbt4));
+ memcpy(acpi_table->vbt4, cdata->hardware_id, len);
+ len = min(ID_LEN, sizeof(acpi_table->vbt5));
+ memcpy(acpi_table->vbt5, cdata->firmware_id, len);
+ len = min(ID_LEN, sizeof(acpi_table->vbt6));
+ memcpy(acpi_table->vbt6, cdata->readonly_firmware_id, len);
+
+ acpi_table->vbt7 = cdata->firmware_type;
+ acpi_table->vbt8 = RECOVERY_REASON_NONE;
+ acpi_table->vbt9 = cdata->fmap_offset;
+ return 0;
+}
+#endif
+
void crossystem_data_dump(crossystem_data_t *cdata)
{
#define _p(format, field) \