From d8dbbc8dd8b50975e7a9c7f5d2415fe35526c1b6 Mon Sep 17 00:00:00 2001 From: Dr-Noob Date: Wed, 16 Jun 2021 16:01:25 +0100 Subject: [PATCH] [v0.98] Detect RPi SoC using revision codes, according to #91 --- src/arm/soc.c | 69 ++++++++++++++++++++++++++++++++++++++++++++-- src/arm/udev.c | 37 ++++++++++++++++++++----- src/arm/udev.h | 2 ++ src/common/ascii.h | 8 +++--- 4 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/arm/soc.c b/src/arm/soc.c index f391577..87b8fbc 100644 --- a/src/arm/soc.c +++ b/src/arm/soc.c @@ -10,6 +10,7 @@ #define min(a,b) (((a)<(b))?(a):(b)) #define STRING_UNKNOWN "Unknown" +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) static char* soc_trademark_string[] = { [SOC_VENDOR_SNAPDRAGON] = "Snapdragon ", @@ -19,6 +20,13 @@ static char* soc_trademark_string[] = { [SOC_VENDOR_BROADCOM] = "Broadcom BCM", }; +static char* soc_rpi_string[] = { + "BCM2835", + "BCM2836", + "BCM2837", + "BCM2711" +}; + void fill_soc(struct system_on_chip* soc, char* soc_name, SOC soc_model, int32_t process) { soc->soc_model = soc_model; soc->soc_vendor = get_soc_vendor_from_soc(soc_model); @@ -502,7 +510,7 @@ struct system_on_chip* guess_soc_from_android(struct system_on_chip* soc) { #endif struct system_on_chip* guess_soc_from_cpuinfo(struct system_on_chip* soc) { - char* tmp = get_hardware_from_cpuinfo(&strlen); + char* tmp = get_hardware_from_cpuinfo(); if(tmp != NULL) { soc->raw_name = tmp; @@ -512,12 +520,69 @@ struct system_on_chip* guess_soc_from_cpuinfo(struct system_on_chip* soc) { return soc; } +int hex2int(char c) { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + + return -1; +} + +// https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md +struct system_on_chip* guess_soc_raspbery_pi(struct system_on_chip* soc) { + char* revision = get_revision_from_cpuinfo(); + + if(revision == NULL) { + printWarn("[RPi] Couldn't find revision field in cpuinfo"); + return soc; + } + + if(strlen(revision) != 6) { + printWarn("[RPi] Found invalid RPi revision code: '%s'", revision); + return soc; + } + + int arr_size = ARRAY_SIZE(soc_rpi_string); + int pppp = hex2int(revision[2]); + if(pppp == -1) { + printErr("[RPi] Found invalid RPi PPPP code: %s", revision[2]); + return soc; + } + + if(pppp > arr_size) { + printErr("[RPi] Found invalid RPi PPPP code: %d while max is %d", pppp, arr_size); + return soc; + } + + char* soc_raw_name = soc_rpi_string[pppp]; + /*int soc_len = strlen(soc_raw_name); + soc->raw_name = malloc(sizeof(char) * (soc_len + 1)); + strncpy(soc->raw_name, soc_raw_name, soc_len + 1);*/ + + match_broadcom(soc_raw_name, soc); + return soc; +} + struct system_on_chip* get_soc() { struct system_on_chip* soc = malloc(sizeof(struct system_on_chip)); soc->raw_name = NULL; soc->soc_vendor = SOC_VENDOR_UNKNOWN; soc->process = UNKNOWN; - + + bool isRPi = is_raspberry_pi(); + if(isRPi) { + soc = guess_soc_raspbery_pi(soc); + if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) { + printWarn("SoC detection failed using revision code"); + } + else { + return soc; + } + } + soc = guess_soc_from_cpuinfo(soc); if(soc->soc_vendor == SOC_VENDOR_UNKNOWN) { if(soc->raw_name != NULL) diff --git a/src/arm/udev.c b/src/arm/udev.c index 2346ebf..c6c46c8 100644 --- a/src/arm/udev.c +++ b/src/arm/udev.c @@ -1,6 +1,7 @@ #include "udev.h" #include "midr.h" +#define _PATH_DEVICETREE_MODEL "/sys/firmware/devicetree/base/model" #define _PATH_CPUS_PRESENT _PATH_SYS_SYSTEM _PATH_SYS_CPU "/present" #define _PATH_CPUINFO "/proc/cpuinfo" //#define _PATH_CPUINFO "cpuinfo_debug" @@ -11,6 +12,7 @@ #define CPUINFO_CPU_PART_STR "CPU part\t: " #define CPUINFO_CPU_REVISION_STR "CPU revision\t: " #define CPUINFO_HARDWARE_STR "Hardware\t: " +#define CPUINFO_REVISION_STR "Revision\t: " #define CPUINFO_CPU_STRING "processor" @@ -148,24 +150,45 @@ uint32_t get_midr_from_cpuinfo(uint32_t core, bool* success) { return midr; } -char* get_hardware_from_cpuinfo() { +char* get_field_from_cpuinfo(char* CPUINFO_FIELD) { int filelen; char* buf; if((buf = read_file(_PATH_CPUINFO, &filelen)) == NULL) { perror("open"); - return NULL; + return NULL; } - - char* tmp1 = strstr(buf, CPUINFO_HARDWARE_STR); + + char* tmp1 = strstr(buf, CPUINFO_FIELD); if(tmp1 == NULL) return NULL; - tmp1 = tmp1 + strlen(CPUINFO_HARDWARE_STR); + tmp1 = tmp1 + strlen(CPUINFO_FIELD); char* tmp2 = strstr(tmp1, "\n"); - + int strlen = (1 + (tmp2-tmp1)); char* hardware = malloc(sizeof(char) * strlen); memset(hardware, 0, sizeof(char) * strlen); strncpy(hardware, tmp1, tmp2-tmp1); - + return hardware; } +char* get_hardware_from_cpuinfo() { + return get_field_from_cpuinfo(CPUINFO_HARDWARE_STR); +} + +char* get_revision_from_cpuinfo() { + return get_field_from_cpuinfo(CPUINFO_REVISION_STR); +} + +bool is_raspberry_pi() { + int filelen; + char* buf; + if((buf = read_file(_PATH_DEVICETREE_MODEL, &filelen)) == NULL) { + return false; + } + + char* tmp; + if((tmp = strstr(buf, "Raspberry Pi")) == NULL) { + return false; + } + return true; +} diff --git a/src/arm/udev.h b/src/arm/udev.h index e77d569..f3c52a0 100644 --- a/src/arm/udev.h +++ b/src/arm/udev.h @@ -7,6 +7,8 @@ int get_ncores_from_cpuinfo(); uint32_t get_midr_from_cpuinfo(uint32_t core, bool* success); char* get_hardware_from_cpuinfo(); +char* get_revision_from_cpuinfo(); +bool is_raspberry_pi(); #endif diff --git a/src/common/ascii.h b/src/common/ascii.h index 1e418f9..aff7dd7 100644 --- a/src/common/ascii.h +++ b/src/common/ascii.h @@ -133,14 +133,14 @@ #define BROADCOM_ASCII \ " \ ################ \ - ######################### \ - ############################### \ + ########################## \ + ################################ \ ################@@@@################ \ ################@@@@@@################ \ - #################@@@@@@################ \ + #################@@@@@@################# \ #################@@@@@@@@################# \ #################@@@@@@@@################# \ - #################@@@@##@@@@################ \ + ################@@@@##@@@@################ \ ################@@@@##@@@@################ \ ###############@@@@####@@@@############### \ @@@@@@@@@@####@@@@####@@@@####@@@@@@@@@@ \