diff options
-rw-r--r-- | include/chromeos/crossystem_data.h | 53 | ||||
-rw-r--r-- | lib/chromeos/boot_kernel.c | 2 | ||||
-rw-r--r-- | lib/chromeos/crossystem_data.c | 46 |
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) \ |