summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernie Thompson <bhthompson@chromium.org>2011-12-28 07:40:48 -0800
committerGerrit <chrome-bot@google.com>2012-01-09 15:44:31 -0800
commit0b5789fee96b7213a9762c5b2cf7f705a99d95ef (patch)
treeb40690b70dbddd109717895c5c9279cc74122195
parent946370d012a809bba833ff9d37fe0ce86af09860 (diff)
downloadvboot-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.c50
-rw-r--r--host/arch/x86/lib/crossystem_arch.c56
-rw-r--r--utility/crossystem_main.c1
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"},