diff options
author | Bernie Thompson <bhthompson@chromium.org> | 2011-12-28 07:40:48 -0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-01-09 15:44:31 -0800 |
commit | 0b5789fee96b7213a9762c5b2cf7f705a99d95ef (patch) | |
tree | b40690b70dbddd109717895c5c9279cc74122195 | |
parent | 946370d012a809bba833ff9d37fe0ce86af09860 (diff) | |
download | vboot-0b5789fee96b7213a9762c5b2cf7f705a99d95ef.tar.gz |
Add in a platform_family value to crossystem
This implements a platform_family value within the crossystem utility,
as the platform (particularly for ARM) is not easily accessable elsewhere at
runtime.
For the ARM side this contains a table which is used to determine the platform
family based on the /proc/device-tree/compatible entry. Similarly on x86 the
table is used to check against PCI entries. Additional entries can be made
as new platform families emerge.
BUG=chromium-os:24669
TEST=Manual, verified that crossystem runs properly and returns a valid
platform_family value on various platforms (mario, alex, z600, x220, etc).
Change-Id: Id0e973902d27ead471c1243bcc6c3292acc8479d
Reviewed-on: https://gerrit.chromium.org/gerrit/13520
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Ready: Olof Johansson <olofj@chromium.org>
Reviewed-by: Olof Johansson <olofj@chromium.org>
Tested-by: Olof Johansson <olofj@chromium.org>
-rw-r--r-- | host/arch/arm/lib/crossystem_arch.c | 50 | ||||
-rw-r--r-- | host/arch/x86/lib/crossystem_arch.c | 56 | ||||
-rw-r--r-- | utility/crossystem_main.c | 1 |
3 files changed, 107 insertions, 0 deletions
diff --git a/host/arch/arm/lib/crossystem_arch.c b/host/arch/arm/lib/crossystem_arch.c index 7e6095eb..aa740b06 100644 --- a/host/arch/arm/lib/crossystem_arch.c +++ b/host/arch/arm/lib/crossystem_arch.c @@ -32,6 +32,21 @@ #define SECTOR_SIZE 512 #define MAX_NMMCBLK 9 +typedef struct PlatformFamily { + const char* compatible_string; /* Last string in FDT compatible entry */ + const char* platform_string; /* String to return */ +} PlatformFamily; + +/* Array of platform family names, terminated with a NULL entry */ +const PlatformFamily platform_family_array[] = { + {"nvidia,tegra250", "Tegra2"}, + {"nvidia,tegra20", "Tegra2"}, + {"ti,omap4", "OMAP4"}, + {"ti,omap3", "OMAP3"}, + /* Terminate with NULL entry */ + {NULL, NULL} +}; + static int FindEmmcDev(void) { int mmcblk; char filename[FNAME_SIZE]; @@ -137,6 +152,38 @@ static char * ReadFdtString(const char *property) { return (char *)str; } +static char * ReadFdtPlatformFamily(void) { + char *compat = NULL; + char *s; + FILE *file; + const PlatformFamily* p; + size_t size = 0; + int slen; + + /* TODO: Allow this to be a more direct path by modifying ReadFdtBlock */ + ReadFdtBlock("../../compatible", &compat, &size); + + if (size > 0) + compat[size-1] = 0; + + /* Check each null separated string in compatible against the family array */ + s = compat; + while ((s-compat) < size) { + slen = strlen(s); + for (p = platform_family_array; p->compatible_string; p++) { + if (!strcmp(s, p->compatible_string)) { + free(compat); + return strdup(p->platform_string); + } + } + s += slen + 1; + } + + /* No recognized 'compatible' entry found */ + free(compat); + return NULL; +} + static int VbGetGpioStatus(unsigned gpio_number) { char const *gpio_name_format = "/sys/class/gpio/gpio%d/value"; char gpio_name[FNAME_SIZE]; @@ -330,6 +377,9 @@ const char* VbGetArchPropertyString(const char* name, char* dest, int size) { if (prop) str = ReadFdtString(prop); + if (!strcasecmp(name, "platform_family")) + str = ReadFdtPlatformFamily(); + if (str) { rv = StrCopy(dest, str, size); free(str); diff --git a/host/arch/x86/lib/crossystem_arch.c b/host/arch/x86/lib/crossystem_arch.c index 1042c66e..6ef9063e 100644 --- a/host/arch/x86/lib/crossystem_arch.c +++ b/host/arch/x86/lib/crossystem_arch.c @@ -87,6 +87,27 @@ /* Filename for legacy firmware update tries */ #define NEED_FWUPDATE_PATH "/mnt/stateful_partition/.need_firmware_update" +/* Filenames for PCI Vendor and Device IDs */ +#define PCI_VENDOR_ID_PATH "/sys/bus/pci/devices/0000:00:00.0/vendor" +#define PCI_DEVICE_ID_PATH "/sys/bus/pci/devices/0000:00:00.0/device" + +typedef struct PlatformFamily { + unsigned int vendor; /* Vendor id value */ + unsigned int device; /* Device id value */ + const char* platform_string; /* String to return */ +} PlatformFamily; + +/* Array of platform family names, terminated with a NULL entry */ +const PlatformFamily platform_family_array[] = { + {0x8086, 0xA010, "PineTrail"}, + {0x8086, 0x3406, "Westmere"}, + {0x8086, 0x0104, "SandyBridge"}, /* mobile */ + {0x8086, 0x0100, "SandyBridge"}, /* desktop */ + {0x8086, 0x0154, "IvyBridge"}, /* mobile */ + {0x8086, 0x0150, "IvyBridge"}, /* desktop */ + /* Terminate with NULL entry */ + {NULL, NULL, NULL} +}; static void VbFixCmosChecksum(FILE* file) { int fd = fileno(file); @@ -444,6 +465,39 @@ static int VbGetRecoveryReason(void) { } } +/* Determine the platform family and return it in the dest string. + * This uses the PCI Bus 0, Device 0, Function 0 vendor and device id values + * taken from sysfs to determine the platform family. This assumes there will + * be a unique pair of values here for any given platform. + */ +static char* ReadPlatformFamilyString(char* dest, int size) { + FILE* f; + const PlatformFamily* p; + unsigned int v = 0xFFFF; + unsigned int d = 0xFFFF; + + f = fopen(PCI_VENDOR_ID_PATH, "rt"); + if (!f) + return NULL; + if(fscanf(f, "0x%4x", &v) != 1) + return NULL; + fclose(f); + + f = fopen(PCI_DEVICE_ID_PATH, "rt"); + if (!f) + return NULL; + if(fscanf(f, "0x%4x", &d) != 1) + return NULL; + fclose(f); + + for (p = platform_family_array; p->vendor; p++) { + if((v == p->vendor) && (d == p->device)) + return StrCopy(dest, p->platform_string, size); + } + + /* No recognized platform family was found */ + return NULL; +} /* Physical GPIO number <N> may be accessed through /sys/class/gpio/gpio<M>/, * but <N> and <M> may differ by some offset <O>. To determine that constant, @@ -642,6 +696,8 @@ const char* VbGetArchPropertyString(const char* name, char* dest, int size) { default: return NULL; } + } else if (!strcasecmp(name,"platform_family")) { + return ReadPlatformFamilyString(dest, size); } return NULL; diff --git a/utility/crossystem_main.c b/utility/crossystem_main.c index b9c540e5..0a2e6def 100644 --- a/utility/crossystem_main.c +++ b/utility/crossystem_main.c @@ -56,6 +56,7 @@ const Param sys_param_list[] = { {"mainfw_act", IS_STRING, "Active main firmware"}, {"mainfw_type", IS_STRING, "Active main firmware type"}, {"nvram_cleared", CAN_WRITE, "Have NV settings been lost? Write 0 to clear"}, + {"platform_family", IS_STRING, "Platform family type"}, {"recovery_reason", 0, "Recovery mode reason for current boot"}, {"recovery_request", CAN_WRITE, "Recovery mode request (writable)"}, {"recoverysw_boot", 0, "Recovery switch position at boot"}, |