From: Hector Palacios Date: Wed, 9 Oct 2013 12:07:37 +0200 Subject: [PATCH] version: parse ROM version from FDT if available New kernels don't get CPU information from U-Boot ATAGS and so the /proc/cpuinfo file does not have the Hardware/Revision lines filled in. This patch gets the CPU model from the device tree information at /proc/device-tree/compatible. For backwards compatibility, if the CPU model cannot be retrieved from this file, we try to get it from /proc/cpuinfo. Signed-off-by: Hector Palacios Reviewed-by: Javier Viguera --- src/main.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index c8d4e7f..c90c452 100644 --- a/src/main.c +++ b/src/main.c @@ -802,7 +802,7 @@ out: return r; } -void discover_boot_rom_version(void) +int get_rom_version_from_cpuinfo(void) { FILE *cpuinfo; char line_buffer[100]; @@ -811,6 +811,7 @@ void discover_boot_rom_version(void) static char *v1_rom_tag = "28"; static char *v2_rom_tag = "53"; char *rev; + int version = ROM_Version_Unknown; //---------------------------------------------------------------------- // Attempt to open /proc/cpuinfo. @@ -847,17 +848,17 @@ void discover_boot_rom_version(void) rev += 2; memcpy(tmp, rev, 2); if (!strncmp(tmp, v0_rom_tag, strlen(v0_rom_tag))) { - rom_version = ROM_Version_0; + version = ROM_Version_0; break; } else if (!strncmp(tmp, v1_rom_tag, strlen(v1_rom_tag))) { - rom_version = ROM_Version_1; + version = ROM_Version_1; break; } else if (!strncmp(tmp, v2_rom_tag, strlen(v2_rom_tag))) { - rom_version = ROM_Version_2; + version = ROM_Version_2; break; } } @@ -867,18 +868,76 @@ void discover_boot_rom_version(void) //---------------------------------------------------------------------- // Close /proc/cpuinfo. //---------------------------------------------------------------------- - fclose(cpuinfo); + return version; +} + +#define MAX_STRLEN 256 +int get_rom_version_from_fdt(void) +{ + FILE *fd; + char *line_buffer; + static char *v0_rom_tag = "fsl,imx23"; + static char *v1_rom_tag = "fsl,imx28"; + static char *v2_rom_tag = "fsl,imx53"; + char *rev; + int version = ROM_Version_Unknown; + + fd = fopen("/proc/device-tree/compatible", "r"); + if (!fd) + return ROM_Version_Unknown; + + line_buffer = malloc(MAX_STRLEN); + if (!line_buffer) + return ROM_Version_Unknown; + memset(line_buffer, MAX_STRLEN, 0); + if (fgets(line_buffer, MAX_STRLEN, fd)) { + /* + * The compatible string can contain more than one string. + * Each string value is separated from the next one by a + * NULL char. We must check all values one by one until + * we find two consecutive NULL chars. + */ + while (line_buffer[0] != 0) { + if (!strncmp(line_buffer, v0_rom_tag, + strlen(v0_rom_tag))) { + version = ROM_Version_0; + break; + } + else if (!strncmp(line_buffer, v1_rom_tag, + strlen(v1_rom_tag))) { + version = ROM_Version_1; + break; + } + else if (!strncmp(line_buffer, v2_rom_tag, + strlen(v2_rom_tag))) { + version = ROM_Version_2; + break; + } + /* Move string pointer to next possible value */ + line_buffer += strlen(line_buffer) + 1; + } + } + + fclose(fd); + + return version; +} + +void discover_boot_rom_version(void) +{ + rom_version = get_rom_version_from_fdt(); + if (rom_version == ROM_Version_Unknown) + rom_version = get_rom_version_from_cpuinfo(); + //---------------------------------------------------------------------- // Check if we found what we needed. //---------------------------------------------------------------------- - if (rom_version == ROM_Version_Unknown) { fprintf(stderr, "Couldn't discover Boot ROM version\n"); exit(1); } - } int main(int argc, char **argv)