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>
This commit is contained in:
Bernie Thompson
2011-12-28 07:40:48 -08:00
committed by Gerrit
parent 946370d012
commit 0b5789fee9
3 changed files with 107 additions and 0 deletions

View File

@@ -32,6 +32,21 @@
#define SECTOR_SIZE 512 #define SECTOR_SIZE 512
#define MAX_NMMCBLK 9 #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) { static int FindEmmcDev(void) {
int mmcblk; int mmcblk;
char filename[FNAME_SIZE]; char filename[FNAME_SIZE];
@@ -137,6 +152,38 @@ static char * ReadFdtString(const char *property) {
return (char *)str; 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) { static int VbGetGpioStatus(unsigned gpio_number) {
char const *gpio_name_format = "/sys/class/gpio/gpio%d/value"; char const *gpio_name_format = "/sys/class/gpio/gpio%d/value";
char gpio_name[FNAME_SIZE]; char gpio_name[FNAME_SIZE];
@@ -330,6 +377,9 @@ const char* VbGetArchPropertyString(const char* name, char* dest, int size) {
if (prop) if (prop)
str = ReadFdtString(prop); str = ReadFdtString(prop);
if (!strcasecmp(name, "platform_family"))
str = ReadFdtPlatformFamily();
if (str) { if (str) {
rv = StrCopy(dest, str, size); rv = StrCopy(dest, str, size);
free(str); free(str);

View File

@@ -87,6 +87,27 @@
/* Filename for legacy firmware update tries */ /* Filename for legacy firmware update tries */
#define NEED_FWUPDATE_PATH "/mnt/stateful_partition/.need_firmware_update" #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) { static void VbFixCmosChecksum(FILE* file) {
int fd = fileno(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>/, /* 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, * 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: default:
return NULL; return NULL;
} }
} else if (!strcasecmp(name,"platform_family")) {
return ReadPlatformFamilyString(dest, size);
} }
return NULL; return NULL;

View File

@@ -56,6 +56,7 @@ const Param sys_param_list[] = {
{"mainfw_act", IS_STRING, "Active main firmware"}, {"mainfw_act", IS_STRING, "Active main firmware"},
{"mainfw_type", IS_STRING, "Active main firmware type"}, {"mainfw_type", IS_STRING, "Active main firmware type"},
{"nvram_cleared", CAN_WRITE, "Have NV settings been lost? Write 0 to clear"}, {"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_reason", 0, "Recovery mode reason for current boot"},
{"recovery_request", CAN_WRITE, "Recovery mode request (writable)"}, {"recovery_request", CAN_WRITE, "Recovery mode request (writable)"},
{"recoverysw_boot", 0, "Recovery switch position at boot"}, {"recoverysw_boot", 0, "Recovery switch position at boot"},