Index: lib/chromeos/os_storage.c |
diff --git a/lib/chromeos/os_storage.c b/lib/chromeos/os_storage.c |
index 113b732efd87363657becb4fbf1577f9dba48cd9..ddccb400d2e0a503f87e3031b2634d17ef268309 100644 |
--- a/lib/chromeos/os_storage.c |
+++ b/lib/chromeos/os_storage.c |
@@ -13,6 +13,15 @@ |
#include <part.h> |
#include <chromeos/os_storage.h> |
+/* TODO For load fmap; remove when not used */ |
+#include <chromeos/firmware_storage.h> |
+ |
+/* TODO For strcpy; remove when not used */ |
+#include <linux/string.h> |
+ |
+/* TODO remove when not used */ |
+extern uint64_t get_nvcxt_lba(void); |
+ |
#include <boot_device.h> |
#include <load_kernel_fw.h> |
#include <vboot_nvstorage.h> |
@@ -160,6 +169,18 @@ int load_kernel_wrapper(LoadKernelParams *params, |
void *gbb_data, uint64_t gbb_size, uint64_t boot_flags, |
VbNvContext *nvcxt, uint8_t *shared_data_blob) |
{ |
+ /* |
+ * TODO(clchiou): Hack for bringing up factory; preserve recovery |
+ * reason before LoadKernel destroys it. Remove when not needed. |
+ * |
+ * XXX: I found a potential bug that for example, VbNvGet() returns |
+ * reason == 0x81 |
+ * but if you access the raw data directly, it gives you |
+ * nvcxt->raw[RECOVERY_OFFSET] == 0x02. |
+ */ |
+ uint32_t reason = 0; |
+ VbNvGet(&nvcxt, VBNV_RECOVERY_REQUEST, &reason); |
+ |
int status = LOAD_KERNEL_NOT_FOUND; |
block_dev_desc_t *dev_desc; |
@@ -226,5 +247,106 @@ EXIT: |
} |
} |
+ /* |
+ * TODO(clchiou): This is an urgent hack for bringing up factory. We |
+ * fill in data that will be used by kernel at last 1MB space. |
+ * |
+ * Rewrite this part after the protocol specification between |
+ * Chrome OS firmware and kernel is finalized. |
+ */ |
+ if (status == LOAD_KERNEL_SUCCESS) { |
+ DECLARE_GLOBAL_DATA_PTR; |
+ |
+ void *kernel_shared_data = (void*) |
+ gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS-1].start + |
+ gd->bd->bi_dram[CONFIG_NR_DRAM_BANKS-1].size - SZ_1M; |
+ |
+ struct { |
+ uint8_t signature[16]; |
+ uint32_t chsw; |
+ uint8_t hwid[256]; |
+ uint8_t fwid[256]; |
+ uint8_t frid[256]; |
+ uint32_t binf[5]; |
+ uint32_t gpio[11]; |
+ uint32_t vbnv[2]; |
+ uint64_t fmap_start_address; |
+ uint64_t nvcxt_lba; |
+ uint8_t nvcxt_cache[VBNV_BLOCK_SIZE]; |
+ } __attribute__((packed)) *sd = kernel_shared_data; |
+ |
+ void *kernel_shared_data_body = |
+ kernel_shared_data + sizeof(*sd); |
+ |
+ int i; |
+ |
+ debug(PREFIX "kernel shared data at %p\n", kernel_shared_data); |
+ |
+ memset(sd, '\0', sizeof(*sd)); |
+ |
+ strcpy((char*) sd->signature, "CHROMEOS"); |
+ |
+ /* |
+ * chsw bit value |
+ * bit 0x00000002 : recovery button pressed |
+ * bit 0x00000020 : developer mode enabled |
+ * bit 0x00000200 : firmware write protect disabled |
+ */ |
+ if (params->boot_flags & BOOT_FLAG_RECOVERY) |
+ sd->chsw |= 0x002; |
+ if (params->boot_flags & BOOT_FLAG_DEVELOPER) |
+ sd->chsw |= 0x020; |
+ sd->chsw |= 0x200; /* so far write protect is disabled */ |
+ |
+ strcpy((char*) sd->hwid, CONFIG_CHROMEOS_HWID); |
+ strcpy((char*) sd->fwid, "ARM Firmware ID"); |
+ strcpy((char*) sd->frid, "ARM Read-Only Firmware ID"); |
+ |
+ sd->binf[0] = 0; /* boot reason; always 0 */ |
+ if (params->boot_flags & BOOT_FLAG_RECOVERY) { |
+ sd->binf[1] = 0; /* active main firmware */ |
+ sd->binf[3] = 0; /* active firmware type */ |
+ } else { |
+ sd->binf[1] = 1; /* active main firmware */ |
+ sd->binf[3] = 1; /* active firmware type */ |
+ } |
+ sd->binf[2] = 0; /* active EC firmware */ |
+ sd->binf[4] = reason; |
+ |
+ /* sd->gpio[i] == 1 if it is active-high */ |
+ sd->gpio[1] = 1; /* only developer mode gpio is active high */ |
+ |
+ sd->vbnv[0] = 0; |
+ sd->vbnv[1] = VBNV_BLOCK_SIZE; |
+ |
+ firmware_storage_t file; |
+ firmware_storage_init(&file); |
+ firmware_storage_read(&file, |
+ CONFIG_OFFSET_FMAP, CONFIG_LENGTH_FMAP, |
+ kernel_shared_data_body); |
+ file.close(file.context); |
+ sd->fmap_start_address = (uint64_t) kernel_shared_data_body; |
+ kernel_shared_data_body += CONFIG_LENGTH_FMAP; |
+ |
+ sd->nvcxt_lba = get_nvcxt_lba(); |
+ |
+ memcpy(sd->nvcxt_cache, |
+ params->nv_context->raw, VBNV_BLOCK_SIZE); |
+ |
+ debug(PREFIX "chsw %08x\n", sd->chsw); |
+ for (i = 0; i < 5; i++) |
+ debug(PREFIX "binf[%2d] %08x\n", i, sd->binf[i]); |
+ for (i = 0; i < 11; i++) |
+ debug(PREFIX "gpio[%2d] %08x\n", i, sd->gpio[i]); |
+ debug(PREFIX "vbnv[ 0] %08x\n", sd->vbnv[0]); |
+ debug(PREFIX "vbnv[ 1] %08x\n", sd->vbnv[1]); |
+ debug(PREFIX "fmap %08llx\n", sd->fmap_start_address); |
+ debug(PREFIX "nvcxt %08llx\n", sd->nvcxt_lba); |
+ debug(PREFIX "nvcxt_c "); |
+ for (i = 0; i < VBNV_BLOCK_SIZE; i++) |
+ debug("%02x", sd->nvcxt_cache[i]); |
+ putc('\n'); |
+ } |
+ |
return status; |
} |