diff options
Diffstat (limited to 'host/arch')
-rw-r--r-- | host/arch/arm/lib/crossystem_arch.c | 294 | ||||
-rw-r--r-- | host/arch/x86/lib/crossystem_arch.c | 4 |
2 files changed, 234 insertions, 64 deletions
diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c index 4304ce7c..6d62e7c3 100644 --- a/host/arch/arm/lib/crossystem_arch.c +++ b/host/arch/arm/lib/crossystem_arch.c @@ -6,103 +6,277 @@ #include <stdio.h> #include <string.h> #include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <ctype.h> -#include "host_common.h" - -#include "crossystem.h" -#include "crossystem_arch.h" -#include "utility.h" #include "vboot_common.h" #include "vboot_nvstorage.h" -#include "vboot_struct.h" +#include "host_common.h" +#include "crossystem_arch.h" +#define CONFIG_LENGTH_FMAP 0x400 -int VbReadNvStorage(VbNvContext* vnc) { - /* TODO: IMPLEMENT ME! */ - return -1; +#define offsetof(struct_name, field) ((int) &(((struct_name*)0)->field)) + +/* This is used to keep u-boot and kernel in sync */ +#define SHARED_MEM_VERSION 1 +#define SHARED_MEM_SIGNATURE "CHROMEOS" + +typedef struct { + const char *signal_name; + unsigned gpio_number; +} GpioMap; + +static const GpioMap vb_gpio_map_kaen[] = { + {"recoverysw_cur", 56}, + {"devsw_cur", 168}, + {"wpsw_cur", 59}, +}; + +/* This is map is for kaen, function to gpio number mapping */ + +/* + * This structure has been copied from u-boot-next + * files/lib/chromeos/os_storage.c. Keep it in sync until a better interface + * is implemented. + */ +typedef struct { + uint32_t total_size; + uint8_t signature[10]; + uint16_t version; + uint64_t nvcxt_lba; + uint16_t vbnv[2]; + uint8_t nvcxt_cache[VBNV_BLOCK_SIZE]; + uint8_t write_protect_sw; + uint8_t recovery_sw; + uint8_t developer_sw; + uint8_t binf[5]; + uint32_t chsw; + uint8_t hwid[256]; + uint8_t fwid[256]; + uint8_t frid[256]; + uint32_t fmap_base; + uint8_t shared_data_body[CONFIG_LENGTH_FMAP]; +} __attribute__((packed)) VbSharedMem; + +typedef struct { + const char *cs_field_name; + const void *cs_value; +} VbVarInfo; + +static VbSharedMem shared_memory; +static const char *blob_name = "/sys/kernel/debug/chromeos_arm"; +static VbVarInfo vb_cs_map[] = { + {"hwid", &shared_memory.hwid}, + {"fwid", &shared_memory.fwid}, + {"ro_fwid", &shared_memory.frid}, + {"devsw_boot", &shared_memory.developer_sw}, + {"recoverysw_boot", &shared_memory.recovery_sw}, + {"wpsw_boot", &shared_memory.write_protect_sw}, + {"recovery_reason", &shared_memory.binf[4]}, +}; + +static int VbGetGpioStatus(unsigned gpio_number) { + char const *gpio_name_format = "/sys/class/gpio/gpio%d/value"; + char gpio_name [80]; + char gpio_value[3]; /* gpio value file contains the value and the CR */ + FILE *gpio_file; + int rv = -1, size; + + snprintf(gpio_name, sizeof(gpio_name), gpio_name_format, gpio_number); + gpio_file = fopen(gpio_name, "r"); + if (!gpio_file) { + fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, gpio_name); + return -1; + } + + size = fread(&gpio_value, 1, sizeof(gpio_value), gpio_file); + if ((size == 2) && (gpio_value[1] == 0xa)) { + rv = gpio_value[0] - '0'; /* we expect 0 or 1 only */ + } else { + fprintf(stderr, "%s: failed to read %s, got %d\n", + __FUNCTION__, gpio_name, size); + } + fclose(gpio_file); + return rv; } +static int VbGetVarGpio(const char* name) { + int i; -int VbWriteNvStorage(VbNvContext* vnc) { - /* TODO: IMPLEMENT ME! */ - return -1; + for (i = 0; i < ARRAY_SIZE(vb_gpio_map_kaen); i++) { + if (!strcmp(name, vb_gpio_map_kaen[i].signal_name)) + return VbGetGpioStatus(vb_gpio_map_kaen[i].gpio_number); + } + return 2; /* means not found */ } +static int VbReadSharedMemory(void) { + FILE *data_file = NULL; + int rv = -1; + int size; + + do { + data_file = fopen(blob_name, "rb"); + if (!data_file) { + fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, blob_name); + break; + } + size = fread(&shared_memory, 1, sizeof(shared_memory), data_file); + if ((size != sizeof(shared_memory)) || (size != shared_memory.total_size)) { + fprintf(stderr, "%s: failed to read shared memory: got %d bytes, " + "expected %d, should have been %d\n", + __FUNCTION__, + size, + sizeof(shared_memory), + shared_memory.total_size); + break; + } + + if (strcmp((const char*)shared_memory.signature, SHARED_MEM_SIGNATURE)) { + fprintf(stderr, "%s: signature verification failed\n", __FUNCTION__); + break; + } -VbSharedDataHeader* VbSharedDataRead(void) { - /* TODO: IMPLEMENT ME! */ + if (shared_memory.version != SHARED_MEM_VERSION) { + fprintf(stderr, "%s: version mismatch: %d != %d\n", + __FUNCTION__, shared_memory.version, SHARED_MEM_VERSION); + break; + } + rv = 0; + } while (0); + + if (data_file) + fclose(data_file); + + return rv; +} + +/* Retrieve the address of an entity in the shared memory based on the entity + * name, as described in vb_cs_map table. + * + * Return NULL if the entity name is not found in the table. + */ +static const void* VbGetVarAuto(const char* name) { + int i; + VbVarInfo *pi; + + for (i = 0, pi = vb_cs_map; i < ARRAY_SIZE(vb_cs_map); i++, pi++) { + if (strcmp(pi->cs_field_name, name)) continue; + return pi->cs_value; + } return NULL; } +int VbReadNvStorage(VbNvContext* vnc) { + Memcpy(vnc->raw, shared_memory.nvcxt_cache, sizeof(vnc->raw)); + return 0; +} + +int VbWriteNvStorage(VbNvContext* vnc) { + FILE *data_file = NULL; + int rv = -1; + int size; + + do { + data_file = fopen(blob_name, "w"); + if (!data_file) { + fprintf(stderr, "%s: failed to open %s\n", __FUNCTION__, blob_name); + break; + } + size = fwrite(vnc->raw, 1, sizeof(vnc->raw), data_file); + if (size != sizeof(vnc->raw)) { + fprintf(stderr, "%s: failed to write shared memory (%d)\n", + __FUNCTION__, size); + break; + } + rv = 0; + } while (0); + + if (data_file) + fclose(data_file); + + return rv; +} + +VbSharedDataHeader *VbSharedDataRead(void) { + /* don't need this malloc/copy, but have to do it to comply with the + * wrapper. + */ + VbSharedDataHeader *p = Malloc(sizeof(*p)); + Memcpy(p, shared_memory.shared_data_body, sizeof(*p)); + return p; +} int VbGetArchPropertyInt(const char* name) { - /* TODO: IMPLEMENT ME! For now, return reasonable defaults for - * values where reasonable defaults exist. */ - if (!strcasecmp(name,"recovery_reason")) { - } else if (!strcasecmp(name,"fmap_base")) { - } - /* Switch positions */ - else if (!strcasecmp(name,"devsw_cur")) { - return 1; - } else if (!strcasecmp(name,"recoverysw_cur")) { - return 0; - } else if (!strcasecmp(name,"wpsw_cur")) { - return 1; - } else if (!strcasecmp(name,"devsw_boot")) { - return 1; - } else if (!strcasecmp(name,"recoverysw_boot")) { - return 0; - } else if (!strcasecmp(name,"recoverysw_ec_boot")) { - return 0; - } else if (!strcasecmp(name,"wpsw_boot")) { - return 1; - } + const uint8_t *value; + int rv; + + value = VbGetVarAuto(name); - /* 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")) { - } else if (!strcasecmp(name,"savedmem_size")) { + if (value) return (int) *value; + + rv = VbGetVarGpio(name); + if (rv <= 1) return rv; + + if (!strcasecmp(name,"fmap_base")) { + return shared_memory.fmap_base; } return -1; } - const char* VbGetArchPropertyString(const char* name, char* dest, int size) { - /* TODO: IMPLEMENT ME! For now, return reasonable defaults for - * values where reasonable defaults exist. */ + const char* value = VbGetVarAuto(name); + if (value) return StrCopy(dest, value, size); + if (!strcasecmp(name,"arch")) { return StrCopy(dest, "arm", size); - } else if (!strcasecmp(name,"hwid")) { - return StrCopy(dest, "UnknownArmHwid", size); - } else if (!strcasecmp(name,"fwid")) { - return StrCopy(dest, "UnknownArmFwid", size); - } else if (!strcasecmp(name,"ro_fwid")) { - return StrCopy(dest, "UnknownArmRoFwid", size); } else if (!strcasecmp(name,"mainfw_act")) { - return StrCopy(dest, "A", size); + switch(shared_memory.binf[2]) { + case 0: + return StrCopy(dest, "recovery", size); + case 1: + return StrCopy(dest, "A", size); + case 2: + return StrCopy(dest, "B", size); + default: + return NULL; + } } else if (!strcasecmp(name,"mainfw_type")) { - return StrCopy(dest, "developer", size); + switch(shared_memory.binf[3]) { + case BINF3_RECOVERY: + return StrCopy(dest, "recovery", size); + case BINF3_NORMAL: + return StrCopy(dest, "normal", size); + case BINF3_DEVELOPER: + return StrCopy(dest, "developer", size); + default: + return NULL; + } } else if (!strcasecmp(name,"ecfw_act")) { - return StrCopy(dest, "RO", size); + switch(shared_memory.binf[2]) { + case 0: + return StrCopy(dest, "RO", size); + case 1: + return StrCopy(dest, "RW", size); + default: + return NULL; + } } - return NULL; } - int VbSetArchPropertyInt(const char* name, int value) { - /* TODO: IMPLEMENT ME! */ + /* All is handled in arch independent fashion */ return -1; } - int VbSetArchPropertyString(const char* name, const char* value) { - /* If there were settable architecture-dependent string properties, - * they'd be here. */ + /* All is handled in arch independent fashion */ return -1; } + +int VbArchInit(void) +{ + return VbReadSharedMemory(); +} diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c index 9f766949..8b320e4b 100644 --- a/host/arch/x86/lib/crossystem_arch.c +++ b/host/arch/x86/lib/crossystem_arch.c @@ -48,10 +48,6 @@ #define BINF0_S3_RESUME_FAILED 10 /* Recovery caused by TPM error */ #define BINF0_RECOVERY_TPM_ERROR 11 -/* Firmware types from BINF.3 */ -#define BINF3_RECOVERY 0 -#define BINF3_NORMAL 1 -#define BINF3_DEVELOPER 2 /* CHSW bitflags */ #define CHSW_RECOVERY_BOOT 0x00000002 #define CHSW_RECOVERY_EC_BOOT 0x00000004 |