|
#include <ctype.h> |
|
#include <stdbool.h> |
|
#include <stdint.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
|
|
#include <arm/linux/api.h> |
|
#ifdef __ANDROID__ |
|
#include <arm/android/api.h> |
|
#endif |
|
#include <cpuinfo/log.h> |
|
#include <cpuinfo/common.h> |
|
|
|
|
|
static inline bool is_ascii_whitespace(char c) { |
|
switch (c) { |
|
case ' ': |
|
case '\t': |
|
case '\r': |
|
case '\n': |
|
return true; |
|
default: |
|
return false; |
|
} |
|
} |
|
|
|
static inline bool is_ascii_alphabetic(char c) { |
|
const char lower_c = c | '\x20'; |
|
return (uint8_t) (lower_c - 'a') <= (uint8_t) ('z' - 'a'); |
|
} |
|
|
|
static inline bool is_ascii_alphabetic_uppercase(char c) { |
|
return (uint8_t) (c - 'A') <= (uint8_t) ('Z' - 'A'); |
|
} |
|
|
|
static inline bool is_ascii_numeric(char c) { |
|
return (uint8_t) (c - '0') < 10; |
|
} |
|
|
|
static inline uint16_t load_u16le(const void* ptr) { |
|
#if defined(__ARM_ARCH_7A__) || defined(__aarch64__) |
|
return *((const uint16_t*) ptr); |
|
#else |
|
const uint8_t* byte_ptr = (const uint8_t*) ptr; |
|
return ((uint16_t) byte_ptr[1] << 8) | (uint16_t) byte_ptr[0]; |
|
#endif |
|
} |
|
|
|
static inline uint32_t load_u24le(const void* ptr) { |
|
#if defined(__ARM_ARCH_7A__) || defined(__aarch64__) |
|
return ((uint32_t) ((const uint8_t*) ptr)[2] << 16) | ((uint32_t) *((const uint16_t*) ptr)); |
|
#else |
|
const uint8_t* byte_ptr = (const uint8_t*) ptr; |
|
return ((uint32_t) byte_ptr[2] << 16) | ((uint32_t) byte_ptr[1] << 8) | (uint32_t) byte_ptr[0]; |
|
#endif |
|
} |
|
|
|
static inline uint32_t load_u32le(const void* ptr) { |
|
#if defined(__ARM_ARCH_7A__) || defined(__aarch64__) |
|
return *((const uint32_t*) ptr); |
|
#else |
|
return ((uint32_t) ((const uint8_t*) ptr)[3] << 24) | load_u24le(ptr); |
|
#endif |
|
} |
|
|
|
|
|
|
|
|
|
|
|
static enum cpuinfo_arm_chipset_vendor chipset_series_vendor[cpuinfo_arm_chipset_series_max] = { |
|
[cpuinfo_arm_chipset_series_unknown] = cpuinfo_arm_chipset_vendor_unknown, |
|
[cpuinfo_arm_chipset_series_qualcomm_qsd] = cpuinfo_arm_chipset_vendor_qualcomm, |
|
[cpuinfo_arm_chipset_series_qualcomm_msm] = cpuinfo_arm_chipset_vendor_qualcomm, |
|
[cpuinfo_arm_chipset_series_qualcomm_apq] = cpuinfo_arm_chipset_vendor_qualcomm, |
|
[cpuinfo_arm_chipset_series_qualcomm_snapdragon] = cpuinfo_arm_chipset_vendor_qualcomm, |
|
[cpuinfo_arm_chipset_series_mediatek_mt] = cpuinfo_arm_chipset_vendor_mediatek, |
|
[cpuinfo_arm_chipset_series_samsung_exynos] = cpuinfo_arm_chipset_vendor_samsung, |
|
[cpuinfo_arm_chipset_series_hisilicon_k3v] = cpuinfo_arm_chipset_vendor_hisilicon, |
|
[cpuinfo_arm_chipset_series_hisilicon_hi] = cpuinfo_arm_chipset_vendor_hisilicon, |
|
[cpuinfo_arm_chipset_series_hisilicon_kirin] = cpuinfo_arm_chipset_vendor_hisilicon, |
|
[cpuinfo_arm_chipset_series_actions_atm] = cpuinfo_arm_chipset_vendor_actions, |
|
[cpuinfo_arm_chipset_series_allwinner_a] = cpuinfo_arm_chipset_vendor_allwinner, |
|
[cpuinfo_arm_chipset_series_amlogic_aml] = cpuinfo_arm_chipset_vendor_amlogic, |
|
[cpuinfo_arm_chipset_series_amlogic_s] = cpuinfo_arm_chipset_vendor_amlogic, |
|
[cpuinfo_arm_chipset_series_broadcom_bcm] = cpuinfo_arm_chipset_vendor_broadcom, |
|
[cpuinfo_arm_chipset_series_lg_nuclun] = cpuinfo_arm_chipset_vendor_lg, |
|
[cpuinfo_arm_chipset_series_leadcore_lc] = cpuinfo_arm_chipset_vendor_leadcore, |
|
[cpuinfo_arm_chipset_series_marvell_pxa] = cpuinfo_arm_chipset_vendor_marvell, |
|
[cpuinfo_arm_chipset_series_mstar_6a] = cpuinfo_arm_chipset_vendor_mstar, |
|
[cpuinfo_arm_chipset_series_novathor_u] = cpuinfo_arm_chipset_vendor_novathor, |
|
[cpuinfo_arm_chipset_series_nvidia_tegra_t] = cpuinfo_arm_chipset_vendor_nvidia, |
|
[cpuinfo_arm_chipset_series_nvidia_tegra_ap] = cpuinfo_arm_chipset_vendor_nvidia, |
|
[cpuinfo_arm_chipset_series_nvidia_tegra_sl] = cpuinfo_arm_chipset_vendor_nvidia, |
|
[cpuinfo_arm_chipset_series_pinecone_surge_s] = cpuinfo_arm_chipset_vendor_pinecone, |
|
[cpuinfo_arm_chipset_series_renesas_mp] = cpuinfo_arm_chipset_vendor_renesas, |
|
[cpuinfo_arm_chipset_series_rockchip_rk] = cpuinfo_arm_chipset_vendor_rockchip, |
|
[cpuinfo_arm_chipset_series_spreadtrum_sc] = cpuinfo_arm_chipset_vendor_spreadtrum, |
|
[cpuinfo_arm_chipset_series_telechips_tcc] = cpuinfo_arm_chipset_vendor_telechips, |
|
[cpuinfo_arm_chipset_series_texas_instruments_omap] = cpuinfo_arm_chipset_vendor_texas_instruments, |
|
[cpuinfo_arm_chipset_series_wondermedia_wm] = cpuinfo_arm_chipset_vendor_wondermedia, |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_msm_apq( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 7 > end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint32_t series_signature = UINT32_C(0x00202020) | load_u24le(start); |
|
enum cpuinfo_arm_chipset_series series; |
|
switch (series_signature) { |
|
case UINT32_C(0x6D736D): |
|
series = cpuinfo_arm_chipset_series_qualcomm_msm; |
|
break; |
|
case UINT32_C(0x717061): |
|
series = cpuinfo_arm_chipset_series_qualcomm_apq; |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
const char* pos = start + 3; |
|
if (*pos == ' ') { |
|
pos++; |
|
|
|
|
|
if (pos + 4 > end) { |
|
return false; |
|
} |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 0; i < 4; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) (*pos++) - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_qualcomm, |
|
.series = series, |
|
.model = model, |
|
}; |
|
|
|
|
|
for (uint32_t i = 0; i < CPUINFO_ARM_CHIPSET_SUFFIX_MAX; i++) { |
|
if (pos + i == end) { |
|
break; |
|
} |
|
|
|
const char c = pos[i]; |
|
if (is_ascii_alphabetic(c)) { |
|
|
|
chipset->suffix[i] = c & '\xDF'; |
|
} else if (c == '-') { |
|
|
|
chipset->suffix[i] = c; |
|
} else { |
|
|
|
break; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_sdm( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 6 != end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
const uint32_t expected_sdm = load_u24le(start); |
|
if (expected_sdm != UINT32_C(0x004D4453) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 3; i < 6; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_qualcomm, |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_sm( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 6 != end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
const uint32_t expected_sm = load_u16le(start); |
|
if (expected_sm != UINT16_C(0x4D53) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 2; i < 6; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_qualcomm, |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
struct special_map_entry { |
|
const char* platform; |
|
uint16_t model; |
|
uint8_t series; |
|
char suffix; |
|
}; |
|
|
|
static const struct special_map_entry qualcomm_hardware_map_entries[] = { |
|
{ |
|
|
|
.platform = "Kona", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = 865, |
|
}, |
|
{ |
|
|
|
.platform = "Bengal", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = 662, |
|
}, |
|
{ |
|
|
|
.platform = "Bengalp", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = 662, |
|
}, |
|
{ |
|
|
|
.platform = "Lito", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = 765, |
|
.suffix = 'G' |
|
}, |
|
{ |
|
|
|
.platform = "Lagoon", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_snapdragon, |
|
.model = 0, |
|
}, |
|
}; |
|
|
|
|
|
int strcicmp(char const *a, char const *b) |
|
{ |
|
for (;; a++, b++) { |
|
int d = tolower((unsigned char)*a) - tolower((unsigned char)*b); |
|
if (d != 0 || !*a) |
|
return d; |
|
} |
|
} |
|
|
|
static bool match_qualcomm_special( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(qualcomm_hardware_map_entries); i++) { |
|
int length = end - start; |
|
if (strcicmp(qualcomm_hardware_map_entries[i].platform, start) == 0 && |
|
qualcomm_hardware_map_entries[i].platform[length] == 0) |
|
{ |
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = chipset_series_vendor[qualcomm_hardware_map_entries[i].series], |
|
.series = (enum cpuinfo_arm_chipset_series) qualcomm_hardware_map_entries[i].series, |
|
.model = qualcomm_hardware_map_entries[i].model, |
|
.suffix = { |
|
[0] = qualcomm_hardware_map_entries[i].suffix, |
|
}, |
|
}; |
|
return true; |
|
} |
|
} |
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_samsung_exynos( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
|
|
|
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 18: |
|
case 19: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint32_t expected_sams = UINT32_C(0x20202000) | load_u32le(start); |
|
if (expected_sams != UINT32_C(0x736D6153) ) { |
|
return false; |
|
} |
|
const uint32_t expected_ung = UINT32_C(0x00202020) | load_u32le(start + 4); |
|
if (expected_ung != UINT32_C(0x20676E75) ) { |
|
return false; |
|
} |
|
const uint32_t expected_exyn = UINT32_C(0x20202000) | load_u32le(start + 8); |
|
if (expected_exyn != UINT32_C(0x6E797845) ) { |
|
return false; |
|
} |
|
const uint16_t expected_os = UINT16_C(0x2020) | load_u16le(start + 12); |
|
if (expected_os != UINT16_C(0x736F) ) { |
|
return false; |
|
} |
|
|
|
const char* pos = start + 14; |
|
|
|
|
|
if (*pos == ' ') { |
|
pos++; |
|
|
|
|
|
if (length != 19) { |
|
return false; |
|
} |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 0; i < 4; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) (*pos++) - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_samsung, |
|
.series = cpuinfo_arm_chipset_series_samsung_exynos, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_exynos( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 10 != end) { |
|
return false; |
|
} |
|
|
|
|
|
const uint32_t expected_exyn = load_u32le(start); |
|
if (expected_exyn != UINT32_C(0x6E797865) ) { |
|
return false; |
|
} |
|
|
|
|
|
const uint16_t expected_os = load_u16le(start + 4); |
|
if (expected_os != UINT16_C(0x736F) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 6; i < 10; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_samsung, |
|
.series = cpuinfo_arm_chipset_series_samsung_exynos, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_universal( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 13 != end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
const uint8_t expected_u = UINT8_C(0x20) | (uint8_t) start[0]; |
|
if (expected_u != UINT8_C(0x75) ) { |
|
return false; |
|
} |
|
const uint32_t expected_nive = UINT32_C(0x20202020) | load_u32le(start + 1); |
|
if (expected_nive != UINT32_C(0x6576696E) ) { |
|
return false; |
|
} |
|
const uint32_t expected_ersa = UINT32_C(0x20202020) | load_u32le(start + 5); |
|
if (expected_ersa != UINT32_C(0x6C617372) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 9; i < 13; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_samsung, |
|
.series = cpuinfo_arm_chipset_series_samsung_exynos, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_and_parse_smdk( |
|
const char* start, const char* end, uint32_t cores, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 8 != end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint32_t expected_smdk = UINT32_C(0x20202020) | load_u32le(start); |
|
if (expected_smdk != UINT32_C(0x6B646D73) ) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t model = 0; |
|
const uint32_t expected_model = load_u32le(start + 4); |
|
switch (expected_model) { |
|
case UINT32_C(0x30313234): |
|
model = 4210; |
|
break; |
|
case UINT32_C(0x32317834): |
|
switch (cores) { |
|
case 2: |
|
model = 4212; |
|
break; |
|
case 4: |
|
model = 4412; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core Exynos 4x12 chipset", cores); |
|
} |
|
} |
|
|
|
if (model == 0) { |
|
return false; |
|
} |
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_samsung, |
|
.series = cpuinfo_arm_chipset_series_samsung_exynos, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_mt( |
|
const char* start, const char* end, bool match_end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 6 > end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint16_t mt = UINT16_C(0x2020) | load_u16le(start); |
|
if (mt != UINT16_C(0x746D) ) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
const char* pos = start + 2; |
|
if (((uint8_t) *pos | UINT8_C(0x20)) == (uint8_t) 'k') { |
|
pos++; |
|
|
|
|
|
if (pos + 4 > end) { |
|
return false; |
|
} |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 0; i < 4; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) (*pos++) - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_mediatek, |
|
.series = cpuinfo_arm_chipset_series_mediatek_mt, |
|
.model = model, |
|
}; |
|
|
|
if (match_end) { |
|
|
|
const size_t suffix_length = end - pos; |
|
if (suffix_length > CPUINFO_ARM_CHIPSET_SUFFIX_MAX) { |
|
return false; |
|
} |
|
|
|
|
|
for (size_t i = 0; i < suffix_length; i++) { |
|
const char c = (*pos++); |
|
if (is_ascii_alphabetic(c)) { |
|
|
|
chipset->suffix[i] = c & '\xDF'; |
|
} else if (c == '/') { |
|
|
|
chipset->suffix[i] = c; |
|
} else { |
|
|
|
return false; |
|
} |
|
} |
|
} else { |
|
|
|
for (size_t i = 0; i < CPUINFO_ARM_CHIPSET_SUFFIX_MAX; i++) { |
|
if (pos + i == end) { |
|
break; |
|
} |
|
|
|
const char c = pos[i]; |
|
if (is_ascii_alphabetic(c)) { |
|
|
|
chipset->suffix[i] = c & '\xDF'; |
|
} else if (c == '/') { |
|
|
|
chipset->suffix[i] = c; |
|
} else { |
|
|
|
break; |
|
} |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_kirin( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 8: |
|
case 9: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
if (((uint8_t) start[0] | UINT8_C(0x20)) != (uint8_t) 'k') { |
|
return false; |
|
} |
|
|
|
const uint32_t irin = load_u32le(start + 1); |
|
if (irin != UINT32_C(0x6E697269) ) { |
|
return false; |
|
} |
|
|
|
|
|
if (is_ascii_whitespace(start[5])) { |
|
|
|
if (length != 9) { |
|
return false; |
|
} |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (int32_t i = 0; i < 3; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) end[i - 3] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_hisilicon, |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_rk( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 6: |
|
case 7: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint16_t expected_rk = UINT16_C(0x2020) | load_u16le(start); |
|
if (expected_rk != UINT16_C(0x6B72) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 2; i < 6; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
char suffix = 0; |
|
if (length == 7) { |
|
|
|
const char c = start[6]; |
|
if (is_ascii_alphabetic(c)) { |
|
|
|
suffix = c & '\xDF'; |
|
} else { |
|
|
|
return false; |
|
} |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_rockchip, |
|
.series = cpuinfo_arm_chipset_series_rockchip_rk, |
|
.model = model, |
|
.suffix = { |
|
[0] = suffix, |
|
}, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_sc( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 5 > end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
const uint16_t expected_sc_or_sp = UINT16_C(0x2020) | load_u16le(start); |
|
switch (expected_sc_or_sp) { |
|
case UINT16_C(0x6373): |
|
case UINT16_C(0x7073): |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
if ((start[2] | '\x20') == 'x') { |
|
|
|
if (start + 5 != end) { |
|
return false; |
|
} |
|
|
|
|
|
const uint16_t expected_15 = load_u16le(start + 3); |
|
if (expected_15 != UINT16_C(0x3531) ) { |
|
return false; |
|
} |
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_spreadtrum, |
|
.series = cpuinfo_arm_chipset_series_spreadtrum_sc, |
|
.model = 7715, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
if (start + 6 > end) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 2; i < 6; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_spreadtrum, |
|
.series = cpuinfo_arm_chipset_series_spreadtrum_sc, |
|
.model = model, |
|
}; |
|
|
|
|
|
const char* suffix = start + 6; |
|
for (size_t i = 0; i < CPUINFO_ARM_CHIPSET_SUFFIX_MAX; i++) { |
|
if (suffix + i == end) { |
|
break; |
|
} |
|
|
|
const char c = suffix[i]; |
|
if (!is_ascii_alphabetic(c)) { |
|
|
|
return false; |
|
} |
|
|
|
chipset->suffix[i] = c & '\xDF'; |
|
} |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_lc( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 6: |
|
case 7: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
const uint16_t expected_lc = load_u16le(start); |
|
if (expected_lc != UINT16_C(0x636C) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 2; i < 6; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
char suffix = 0; |
|
if (length == 7) { |
|
const char c = start[6]; |
|
if (is_ascii_alphabetic(c)) { |
|
|
|
chipset->suffix[0] = c & '\xDF'; |
|
} else { |
|
|
|
return false; |
|
} |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_leadcore, |
|
.series = cpuinfo_arm_chipset_series_leadcore_lc, |
|
.model = model, |
|
.suffix = { |
|
[0] = suffix, |
|
}, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_pxa( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 6: |
|
case 7: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
if (start[0] != 'P') { |
|
return false; |
|
} |
|
const uint16_t expected_xa = load_u16le(start + 1); |
|
if (expected_xa != UINT16_C(0x4158) ) { |
|
return false; |
|
} |
|
|
|
uint32_t model = 0; |
|
|
|
|
|
|
|
if (length == 7) { |
|
|
|
const uint32_t expected_1L88 = load_u32le(start + 3); |
|
if (expected_1L88 == UINT32_C(0x38384C31) ) { |
|
model = 1088; |
|
goto write_chipset; |
|
} |
|
} |
|
|
|
|
|
for (uint32_t i = 3; i < length; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
write_chipset: |
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_marvell, |
|
.series = cpuinfo_arm_chipset_series_marvell_pxa, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_bcm( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 7 != end) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
const uint32_t expected_bcm = load_u24le(start); |
|
if (expected_bcm != UINT32_C(0x004D4342) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 3; i < 7; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_broadcom, |
|
.series = cpuinfo_arm_chipset_series_broadcom_bcm, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_omap( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 8 != end) { |
|
return false; |
|
} |
|
|
|
|
|
const uint32_t expected_omap = load_u32le(start); |
|
if (expected_omap != UINT32_C(0x50414D4F) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 4; i < 8; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_texas_instruments, |
|
.series = cpuinfo_arm_chipset_series_texas_instruments_omap, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_and_parse_broadcom( |
|
const char* start, const char* end, uint32_t cores, uint32_t max_cpu_freq_max, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 4: |
|
case 5: |
|
case 6: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t model = 0; |
|
char suffix = 0; |
|
const uint32_t expected_platform = load_u32le(start); |
|
switch (expected_platform) { |
|
case UINT32_C(0x61656872): |
|
if (length == 4) { |
|
|
|
|
|
|
|
|
|
|
|
if (cores == 1) { |
|
model = 21654; |
|
if (max_cpu_freq_max >= 999999) { |
|
suffix = 'G'; |
|
} |
|
} |
|
} |
|
break; |
|
case UINT32_C(0x6176616A): |
|
if (length == 4) { |
|
|
|
|
|
|
|
|
|
if (cores == 4) { |
|
model = 23550; |
|
} |
|
} |
|
break; |
|
case UINT32_C(0x61776168): |
|
if (length == 6) { |
|
|
|
const uint16_t expected_ii = load_u16le(start + 4); |
|
if (expected_ii == UINT16_C(0x6969) ) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (cores) { |
|
case 1: |
|
model = 21663; |
|
break; |
|
case 2: |
|
model = 21664; |
|
if (max_cpu_freq_max >= 1200000) { |
|
suffix = 'T'; |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
break; |
|
case UINT32_C(0x72706163): |
|
if (length == 5) { |
|
|
|
if (start[4] == 'i') { |
|
|
|
|
|
|
|
|
|
if (cores == 2) { |
|
model = 28155; |
|
} |
|
} |
|
} |
|
break; |
|
} |
|
|
|
if (model != 0) { |
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_broadcom, |
|
.series = cpuinfo_arm_chipset_series_broadcom_bcm, |
|
.model = model, |
|
.suffix = { |
|
[0] = suffix, |
|
}, |
|
}; |
|
} |
|
return model != 0; |
|
} |
|
|
|
struct sunxi_map_entry { |
|
uint8_t sunxi; |
|
uint8_t cores; |
|
uint8_t model; |
|
char suffix; |
|
}; |
|
|
|
static const struct sunxi_map_entry sunxi_map_entries[] = { |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.sunxi = 4, |
|
.cores = 1, |
|
.model = 10, |
|
}, |
|
{ |
|
|
|
.sunxi = 5, |
|
.cores = 1, |
|
.model = 13, |
|
}, |
|
{ |
|
|
|
.sunxi = 6, |
|
.cores = 4, |
|
.model = 31, |
|
}, |
|
{ |
|
|
|
.sunxi = 7, |
|
.cores = 2, |
|
.model = 20, |
|
|
|
}, |
|
{ |
|
|
|
.sunxi = 8, |
|
.cores = 2, |
|
.model = 23, |
|
}, |
|
{ |
|
|
|
.sunxi = 8, |
|
.cores = 4, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.sunxi = 8, |
|
.cores = 8, |
|
.model = 83, |
|
.suffix = 'T', |
|
}, |
|
{ |
|
|
|
.sunxi = 9, |
|
.cores = 8, |
|
.model = 80, |
|
}, |
|
#endif |
|
{ |
|
|
|
.sunxi = 50, |
|
.cores = 4, |
|
.model = 64, |
|
}, |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_and_parse_sunxi( |
|
const char* start, const char* end, uint32_t cores, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 5 > end) { |
|
return false; |
|
} |
|
|
|
|
|
if (start[0] != 's') { |
|
return false; |
|
} |
|
const uint16_t expected_un = load_u16le(start + 1); |
|
if (expected_un != UINT16_C(0x6E75) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t sunxi_platform = 0; |
|
{ |
|
const uint32_t digit = (uint32_t) (uint8_t) start[3] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
sunxi_platform = digit; |
|
} |
|
|
|
|
|
const char* pos = start + 4; |
|
{ |
|
const uint32_t digit = (uint32_t) (uint8_t) (*pos) - '0'; |
|
if (digit < 10) { |
|
sunxi_platform = sunxi_platform * 10 + digit; |
|
if (++pos == end) { |
|
|
|
return false; |
|
} |
|
} |
|
} |
|
|
|
|
|
if (*pos != 'i') { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
char suffix = 0; |
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(sunxi_map_entries); i++) { |
|
if (sunxi_platform == sunxi_map_entries[i].sunxi && cores == sunxi_map_entries[i].cores) { |
|
model = sunxi_map_entries[i].model; |
|
suffix = sunxi_map_entries[i].suffix; |
|
break; |
|
} |
|
} |
|
|
|
if (model == 0) { |
|
cpuinfo_log_info("unrecognized %"PRIu32"-core Allwinner sun%"PRIu32" platform", cores, sunxi_platform); |
|
} |
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_allwinner, |
|
.series = cpuinfo_arm_chipset_series_allwinner_a, |
|
.model = model, |
|
.suffix = { |
|
[0] = suffix, |
|
}, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_and_parse_wmt( |
|
const char* start, const char* end, uint32_t cores, uint32_t max_cpu_freq_max, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 3 != end) { |
|
return false; |
|
} |
|
|
|
|
|
if (start[0] != 'W') { |
|
return false; |
|
} |
|
const uint16_t expected_mt = load_u16le(start + 1); |
|
if (expected_mt != UINT16_C(0x544D) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
switch (cores) { |
|
case 1: |
|
switch (max_cpu_freq_max) { |
|
case 1008000: |
|
|
|
model = 8950; |
|
break; |
|
case 1200000: |
|
|
|
model = 8850; |
|
break; |
|
} |
|
break; |
|
case 2: |
|
if (max_cpu_freq_max == 1500000) { |
|
|
|
model = 8880; |
|
} |
|
break; |
|
} |
|
|
|
if (model == 0) { |
|
cpuinfo_log_info("unrecognized WonderMedia platform with %"PRIu32" cores at %"PRIu32" KHz", |
|
cores, max_cpu_freq_max); |
|
} |
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_wondermedia, |
|
.series = cpuinfo_arm_chipset_series_wondermedia_wm, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
struct huawei_map_entry { |
|
uint32_t platform; |
|
uint32_t model; |
|
}; |
|
|
|
static const struct huawei_map_entry huawei_platform_map[] = { |
|
{ |
|
|
|
.platform = UINT32_C(0x00504C41), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00434142), |
|
.model = 659, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00414C42), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004C4B42), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00544C43), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004C4F43), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00524F43), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004B5544), |
|
.model = 960, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004C4D45), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00415645), |
|
.model = 955, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00445246), |
|
.model = 950, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00454E49), |
|
.model = 710, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00544E4B), |
|
.model = 950, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004E4F4C), |
|
.model = 960, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x0041594C), |
|
.model = 980, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004E434D), |
|
.model = 980, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x0041484D), |
|
.model = 960, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004F454E), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x0054584E), |
|
.model = 950, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004E4150), |
|
.model = 980, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00524150), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x004C5652), |
|
.model = 970, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00465453), |
|
.model = 960, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00455553), |
|
.model = 980, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00454956), |
|
.model = 955, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00594B56), |
|
.model = 960, |
|
}, |
|
{ |
|
|
|
.platform = UINT32_C(0x00525456), |
|
.model = 960, |
|
}, |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_and_parse_huawei( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 3: |
|
case 7: |
|
case 8: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
uint32_t model = 0; |
|
const uint32_t target_platform_id = load_u24le(start); |
|
for (uint32_t i = 0; i < CPUINFO_COUNT_OF(huawei_platform_map); i++) { |
|
if (huawei_platform_map[i].platform == target_platform_id) { |
|
model = huawei_platform_map[i].model; |
|
break; |
|
} |
|
} |
|
|
|
if (model == 0) { |
|
|
|
return false; |
|
} |
|
|
|
if (length > 3) { |
|
|
|
|
|
|
|
|
|
|
|
if (start[3] != '-' || !is_ascii_alphabetic_uppercase(start[4])) { |
|
return false; |
|
} |
|
|
|
|
|
if (end[-3] != 'L' || !is_ascii_numeric(end[-2]) || !is_ascii_numeric(end[-1])) { |
|
return false; |
|
} |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_hisilicon, |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = model, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool match_tcc( |
|
const char* start, const char* end, |
|
struct cpuinfo_arm_chipset chipset[restrict static 1]) |
|
{ |
|
|
|
if (start + 7 != end) { |
|
return false; |
|
} |
|
|
|
|
|
if (start[0] != 't') { |
|
return false; |
|
} |
|
|
|
|
|
const uint16_t expected_cc = load_u16le(start + 1); |
|
if (expected_cc != UINT16_C(0x6363) ) { |
|
return false; |
|
} |
|
|
|
|
|
uint32_t model = 0; |
|
for (uint32_t i = 3; i < 6; i++) { |
|
const uint32_t digit = (uint32_t) (uint8_t) start[i] - '0'; |
|
if (digit >= 10) { |
|
|
|
return false; |
|
} |
|
model = model * 10 + digit; |
|
} |
|
|
|
|
|
if (start[6] != 'x') { |
|
return false; |
|
} |
|
|
|
|
|
*chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_telechips, |
|
.series = cpuinfo_arm_chipset_series_telechips_tcc, |
|
.model = model, |
|
.suffix = { |
|
[0] = 'X' |
|
}, |
|
}; |
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool is_tegra(const char* start, const char* end) { |
|
|
|
const size_t length = end - start; |
|
switch (length) { |
|
case 5: |
|
case 6: |
|
break; |
|
default: |
|
return false; |
|
} |
|
|
|
|
|
if (start[0] != 't') { |
|
return false; |
|
} |
|
const uint32_t expected_egra = load_u32le(start + 1); |
|
if (expected_egra != UINT32_C(0x61726765) ) { |
|
return false; |
|
} |
|
|
|
|
|
return (length == 5 || start[5] == '3'); |
|
} |
|
|
|
static const struct special_map_entry special_hardware_map_entries[] = { |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "k3v2oem1", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_k3v, |
|
.model = 2, |
|
}, |
|
{ |
|
|
|
.platform = "hi6620oem", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 910, |
|
.suffix = 'T' |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "hi6250", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 650, |
|
}, |
|
{ |
|
|
|
.platform = "hi6210sft", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 620, |
|
}, |
|
{ |
|
|
|
.platform = "hi3751", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_hi, |
|
.model = 3751, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "hi3630", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 920, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "hi3635", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 930, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "gs702a", |
|
.series = cpuinfo_arm_chipset_series_actions_atm, |
|
.model = 7029, |
|
}, |
|
{ |
|
|
|
.platform = "gs702c", |
|
.series = cpuinfo_arm_chipset_series_actions_atm, |
|
.model = 7029, |
|
.suffix = 'B', |
|
}, |
|
{ |
|
|
|
.platform = "gs703d", |
|
.series = cpuinfo_arm_chipset_series_actions_atm, |
|
.model = 7039, |
|
.suffix = 'S', |
|
}, |
|
{ |
|
|
|
.platform = "gs705a", |
|
.series = cpuinfo_arm_chipset_series_actions_atm, |
|
.model = 7059, |
|
.suffix = 'A', |
|
}, |
|
{ |
|
|
|
.platform = "Amlogic Meson8", |
|
.series = cpuinfo_arm_chipset_series_amlogic_s, |
|
.model = 812, |
|
}, |
|
{ |
|
|
|
.platform = "Amlogic Meson8B", |
|
.series = cpuinfo_arm_chipset_series_amlogic_s, |
|
.model = 805, |
|
}, |
|
{ |
|
|
|
.platform = "mapphone_CDMA", |
|
.series = cpuinfo_arm_chipset_series_texas_instruments_omap, |
|
.model = 4430, |
|
}, |
|
{ |
|
|
|
.platform = "Superior", |
|
.series = cpuinfo_arm_chipset_series_texas_instruments_omap, |
|
.model = 4470, |
|
}, |
|
{ |
|
|
|
.platform = "Tuna", |
|
.series = cpuinfo_arm_chipset_series_texas_instruments_omap, |
|
.model = 4460, |
|
}, |
|
{ |
|
|
|
.platform = "Manta", |
|
.series = cpuinfo_arm_chipset_series_samsung_exynos, |
|
.model = 5250, |
|
}, |
|
{ |
|
|
|
.platform = "Odin", |
|
.series = cpuinfo_arm_chipset_series_lg_nuclun, |
|
.model = 7111, |
|
}, |
|
{ |
|
|
|
.platform = "Madison", |
|
.series = cpuinfo_arm_chipset_series_mstar_6a, |
|
.model = 338, |
|
}, |
|
#endif |
|
}; |
|
|
|
static const struct special_map_entry tegra_hardware_map_entries[] = { |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "cardhu", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "kai", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "p3", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 20, |
|
}, |
|
{ |
|
|
|
.platform = "n1", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 20, |
|
.suffix = 'H', |
|
}, |
|
{ |
|
|
|
.platform = "SHW-M380S", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 20, |
|
}, |
|
{ |
|
|
|
.platform = "m470", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "endeavoru", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "evitareul", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "enrc2b", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "mozart", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "tegratab", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "tn8", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 124, |
|
}, |
|
{ |
|
|
|
.platform = "roth", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "pisces", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "mocha", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 124, |
|
}, |
|
{ |
|
|
|
.platform = "stingray", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 20, |
|
.suffix = 'H', |
|
}, |
|
{ |
|
|
|
.platform = "Ceres", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_sl, |
|
.model = 460, |
|
.suffix = 'N', |
|
}, |
|
{ |
|
|
|
.platform = "MT799", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "t8400n", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "chagall", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "ventana", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 20, |
|
}, |
|
{ |
|
|
|
.platform = "bobsleigh", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "tegra_fjdev101", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "tegra_fjdev103", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "nbx03", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 20, |
|
}, |
|
{ |
|
|
|
.platform = "txs03", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "x3", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "vu10", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 33, |
|
}, |
|
{ |
|
|
|
.platform = "BIRCH", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "macallan", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "maya", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "antares", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 20, |
|
}, |
|
{ |
|
|
|
.platform = "tostab12AL", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "tostab12BL", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "sphinx", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "tostab11BS", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "tostab12BA", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "vangogh", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 20, |
|
}, |
|
{ |
|
|
|
.platform = "a110", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "picasso_e", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 20, |
|
.suffix = 'H', |
|
}, |
|
{ |
|
|
|
.platform = "picasso_e2", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "picasso", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_ap, |
|
.model = 20, |
|
.suffix = 'H', |
|
}, |
|
{ |
|
|
|
.platform = "picasso_m", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "picasso_mf", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "avalon", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "NS_14T004", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
{ |
|
|
|
.platform = "WIKIPAD", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
}, |
|
{ |
|
|
|
.platform = "kb", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "foster_e", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 210, |
|
}, |
|
{ |
|
|
|
.platform = "foster_e_hdd", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 210, |
|
}, |
|
{ |
|
|
|
.platform = "darcy", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 210, |
|
}, |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_hardware( |
|
const char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX], |
|
uint32_t cores, uint32_t max_cpu_freq_max, bool is_tegra) |
|
{ |
|
struct cpuinfo_arm_chipset chipset; |
|
const size_t hardware_length = strnlen(hardware, CPUINFO_HARDWARE_VALUE_MAX); |
|
const char* hardware_end = hardware + hardware_length; |
|
|
|
if (is_tegra) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(tegra_hardware_map_entries); i++) { |
|
if (strncmp(tegra_hardware_map_entries[i].platform, hardware, hardware_length) == 0 && |
|
tegra_hardware_map_entries[i].platform[hardware_length] == 0) |
|
{ |
|
cpuinfo_log_debug( |
|
"found /proc/cpuinfo Hardware string \"%.*s\" in Nvidia Tegra chipset table", |
|
(int) hardware_length, hardware); |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = chipset_series_vendor[tegra_hardware_map_entries[i].series], |
|
.series = (enum cpuinfo_arm_chipset_series) tegra_hardware_map_entries[i].series, |
|
.model = tegra_hardware_map_entries[i].model, |
|
.suffix = { |
|
[0] = tegra_hardware_map_entries[i].suffix, |
|
}, |
|
}; |
|
} |
|
} |
|
} else { |
|
|
|
|
|
bool word_start = true; |
|
for (const char* pos = hardware; pos != hardware_end; pos++) { |
|
const char c = *pos; |
|
switch (c) { |
|
case ' ': |
|
case '\t': |
|
case ',': |
|
word_start = true; |
|
break; |
|
default: |
|
if (word_start && is_ascii_alphabetic(c)) { |
|
|
|
if (match_msm_apq(pos, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm MSM/APQ signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_sdm(pos, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm SDM signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_sm(pos, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm SM signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_mt(pos, hardware_end, true, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched MediaTek MT signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_kirin(pos, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched HiSilicon Kirin signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_rk(pos, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Rockchip RK signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
if (match_qualcomm_special(pos, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
} |
|
word_start = false; |
|
break; |
|
} |
|
} |
|
|
|
|
|
if (match_samsung_exynos(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Samsung Exynos signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_universal(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched UNIVERSAL (Samsung Exynos) signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_and_parse_smdk(hardware, hardware_end, cores, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched SMDK (Samsung Exynos) signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
#endif |
|
|
|
|
|
if (match_sc(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Spreadtrum SC signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_pxa(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Marvell PXA signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
#endif |
|
|
|
|
|
if (match_and_parse_sunxi(hardware, hardware_end, cores, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched sunxi (Allwinner Ax) signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_bcm(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Broadcom BCM signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_omap(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Texas Instruments OMAP signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_and_parse_wmt(hardware, hardware_end, cores, max_cpu_freq_max, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched WonderMedia WMT signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
#endif |
|
|
|
|
|
if (match_tcc(hardware, hardware_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Telechips TCC signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) hardware_length, hardware); |
|
return chipset; |
|
} |
|
|
|
|
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(special_hardware_map_entries); i++) { |
|
if (strncmp(special_hardware_map_entries[i].platform, hardware, hardware_length) == 0 && |
|
special_hardware_map_entries[i].platform[hardware_length] == 0) |
|
{ |
|
cpuinfo_log_debug( |
|
"found /proc/cpuinfo Hardware string \"%.*s\" in special chipset table", |
|
(int) hardware_length, hardware); |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = chipset_series_vendor[special_hardware_map_entries[i].series], |
|
.series = (enum cpuinfo_arm_chipset_series) special_hardware_map_entries[i].series, |
|
.model = special_hardware_map_entries[i].model, |
|
.suffix = { |
|
[0] = special_hardware_map_entries[i].suffix, |
|
}, |
|
}; |
|
} |
|
} |
|
} |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
} |
|
|
|
#ifdef __ANDROID__ |
|
static const struct special_map_entry special_board_map_entries[] = { |
|
{ |
|
|
|
.platform = "hi6250", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 650, |
|
}, |
|
{ |
|
|
|
.platform = "hi6210sft", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 620, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "hi3630", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 920, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "hi3635", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 930, |
|
}, |
|
{ |
|
|
|
.platform = "hi3650", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 950, |
|
}, |
|
{ |
|
|
|
.platform = "hi3660", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 960, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "mp523x", |
|
.series = cpuinfo_arm_chipset_series_renesas_mp, |
|
.model = 5232, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "BEETHOVEN", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 950, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "hws7701u", |
|
.series = cpuinfo_arm_chipset_series_rockchip_rk, |
|
.model = 3168, |
|
}, |
|
{ |
|
|
|
.platform = "g2mv", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_sl, |
|
.model = 460, |
|
.suffix = 'N', |
|
}, |
|
{ |
|
|
|
.platform = "K00F", |
|
.series = cpuinfo_arm_chipset_series_rockchip_rk, |
|
.model = 3188, |
|
}, |
|
{ |
|
|
|
.platform = "T7H", |
|
.series = cpuinfo_arm_chipset_series_rockchip_rk, |
|
.model = 3066, |
|
}, |
|
{ |
|
|
|
.platform = "tuna", |
|
.series = cpuinfo_arm_chipset_series_texas_instruments_omap, |
|
.model = 4460, |
|
}, |
|
{ |
|
|
|
.platform = "grouper", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 30, |
|
.suffix = 'L', |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "flounder", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 132, |
|
}, |
|
{ |
|
|
|
.platform = "dragon", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 210, |
|
}, |
|
{ |
|
|
|
.platform = "sailfish", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_msm, |
|
.model = 8996, |
|
.suffix = 'P', |
|
}, |
|
{ |
|
|
|
.platform = "marlin", |
|
.series = cpuinfo_arm_chipset_series_qualcomm_msm, |
|
.model = 8996, |
|
.suffix = 'P', |
|
}, |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_product_board( |
|
const char ro_product_board[restrict static CPUINFO_BUILD_PROP_VALUE_MAX], |
|
uint32_t cores, uint32_t max_cpu_freq_max) |
|
{ |
|
struct cpuinfo_arm_chipset chipset; |
|
const char* board = ro_product_board; |
|
const size_t board_length = strnlen(ro_product_board, CPUINFO_BUILD_PROP_VALUE_MAX); |
|
const char* board_end = ro_product_board + board_length; |
|
|
|
|
|
if (match_msm_apq(board, board_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm MSM/APQ signature in ro.product.board string \"%.*s\"", (int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_universal(board, board_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched UNIVERSAL (Samsung Exynos) signature in ro.product.board string \"%.*s\"", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_and_parse_smdk(board, board_end, cores, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched SMDK (Samsung Exynos) signature in ro.product.board string \"%.*s\"", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
#endif |
|
|
|
|
|
if (match_mt(board, board_end, true, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched MediaTek MT signature in ro.product.board string \"%.*s\"", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_sc(board, board_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Spreadtrum SC signature in ro.product.board string \"%.*s\"", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_pxa(board, board_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Marvell PXA signature in ro.product.board string \"%.*s\"", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_lc(board, board_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Leadcore LC signature in ro.product.board string \"%.*s\"", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (match_and_parse_broadcom(board, board_end, cores, max_cpu_freq_max, &chipset)) { |
|
cpuinfo_log_debug( |
|
"found ro.product.board string \"%.*s\" in Broadcom chipset table", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
#endif |
|
|
|
|
|
if (match_and_parse_huawei(board, board_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"found ro.product.board string \"%.*s\" in Huawei chipset table", |
|
(int) board_length, board); |
|
return chipset; |
|
} |
|
|
|
|
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(special_board_map_entries); i++) { |
|
if (strncmp(special_board_map_entries[i].platform, board, board_length) == 0 && |
|
special_board_map_entries[i].platform[board_length] == 0) |
|
{ |
|
cpuinfo_log_debug( |
|
"found ro.product.board string \"%.*s\" in special chipset table", |
|
(int) board_length, board); |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = chipset_series_vendor[special_board_map_entries[i].series], |
|
.series = (enum cpuinfo_arm_chipset_series) special_board_map_entries[i].series, |
|
.model = special_board_map_entries[i].model, |
|
.suffix = { |
|
[0] = special_board_map_entries[i].suffix, |
|
|
|
[1] = special_board_map_entries[i].suffix == 'P' ? 'R' : 0, |
|
[2] = special_board_map_entries[i].suffix == 'P' ? 'O' : 0, |
|
}, |
|
}; |
|
} |
|
} |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
} |
|
|
|
struct amlogic_map_entry { |
|
char ro_board_platform[6]; |
|
uint16_t model; |
|
uint8_t series; |
|
char suffix[3]; |
|
}; |
|
|
|
static const struct amlogic_map_entry amlogic_map_entries[] = { |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.ro_board_platform = "meson3", |
|
.series = cpuinfo_arm_chipset_series_amlogic_aml, |
|
.model = 8726, |
|
.suffix = "-M", |
|
}, |
|
{ |
|
|
|
.ro_board_platform = "meson6", |
|
.series = cpuinfo_arm_chipset_series_amlogic_aml, |
|
.model = 8726, |
|
.suffix = "-MX", |
|
}, |
|
{ |
|
|
|
.ro_board_platform = "meson8", |
|
.series = cpuinfo_arm_chipset_series_amlogic_s, |
|
.model = 805, |
|
}, |
|
#endif |
|
{ |
|
|
|
.ro_board_platform = "gxbaby", |
|
.series = cpuinfo_arm_chipset_series_amlogic_s, |
|
.model = 905, |
|
}, |
|
{ |
|
|
|
.ro_board_platform = "gxl", |
|
.series = cpuinfo_arm_chipset_series_amlogic_s, |
|
.model = 905, |
|
.suffix = "X", |
|
}, |
|
{ |
|
|
|
.ro_board_platform = "gxm", |
|
.series = cpuinfo_arm_chipset_series_amlogic_s, |
|
.model = 912, |
|
}, |
|
}; |
|
|
|
static const struct special_map_entry special_platform_map_entries[] = { |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "hi6620oem", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 910, |
|
.suffix = 'T', |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "hi6250", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 650, |
|
}, |
|
{ |
|
|
|
.platform = "hi6210sft", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 620, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "hi3630", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 920, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "hi3635", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 930, |
|
}, |
|
{ |
|
|
|
.platform = "hi3650", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 950, |
|
}, |
|
{ |
|
|
|
.platform = "hi3660", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_kirin, |
|
.model = 960, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "k3v2oem1", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_k3v, |
|
.model = 2, |
|
}, |
|
{ |
|
|
|
.platform = "k3v200", |
|
.series = cpuinfo_arm_chipset_series_hisilicon_k3v, |
|
.model = 2, |
|
}, |
|
{ |
|
|
|
.platform = "montblanc", |
|
.series = cpuinfo_arm_chipset_series_novathor_u, |
|
.model = 8500, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "song", |
|
.series = cpuinfo_arm_chipset_series_pinecone_surge_s, |
|
.model = 1, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "rk322x", |
|
.series = cpuinfo_arm_chipset_series_rockchip_rk, |
|
.model = 3229, |
|
}, |
|
#endif |
|
{ |
|
|
|
.platform = "tegra132", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 132, |
|
}, |
|
{ |
|
|
|
.platform = "tegra210_dragon", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 210, |
|
}, |
|
#if CPUINFO_ARCH_ARM |
|
{ |
|
|
|
.platform = "tegra4", |
|
.series = cpuinfo_arm_chipset_series_nvidia_tegra_t, |
|
.model = 114, |
|
}, |
|
{ |
|
|
|
.platform = "s5pc110", |
|
.series = cpuinfo_arm_chipset_series_samsung_exynos, |
|
.model = 3110, |
|
}, |
|
#endif |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_board_platform( |
|
const char platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX], |
|
uint32_t cores, uint32_t max_cpu_freq_max) |
|
{ |
|
struct cpuinfo_arm_chipset chipset; |
|
const size_t platform_length = strnlen(platform, CPUINFO_BUILD_PROP_VALUE_MAX); |
|
const char* platform_end = platform + platform_length; |
|
|
|
|
|
if (match_msm_apq(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm MSM/APQ signature in ro.board.platform string \"%.*s\"", |
|
(int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_exynos(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched exynosXXXX (Samsung Exynos) signature in ro.board.platform string \"%.*s\"", |
|
(int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_mt(platform, platform_end, true, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched MediaTek MT signature in ro.board.platform string \"%.*s\"", (int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_kirin(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched HiSilicon Kirin signature in ro.board.platform string \"%.*s\"", (int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_sc(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Spreadtrum SC signature in ro.board.platform string \"%.*s\"", (int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_rk(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Rockchip RK signature in ro.board.platform string \"%.*s\"", (int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_lc(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Leadcore LC signature in ro.board.platform string \"%.*s\"", (int) platform_length, platform); |
|
return chipset; |
|
} |
|
#endif |
|
|
|
|
|
if (match_and_parse_huawei(platform, platform_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"found ro.board.platform string \"%.*s\" in Huawei chipset table", |
|
(int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
|
|
|
|
|
|
if (match_and_parse_broadcom(platform, platform_end, cores, max_cpu_freq_max, &chipset)) { |
|
cpuinfo_log_debug( |
|
"found ro.board.platform string \"%.*s\" in Broadcom chipset table", |
|
(int) platform_length, platform); |
|
return chipset; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (platform_length == 5 && cores == 2 && max_cpu_freq_max == 1008000 && memcmp(platform, "omap4", 5) == 0) { |
|
cpuinfo_log_debug( |
|
"matched Texas Instruments OMAP4 signature in ro.board.platform string \"%.*s\"", |
|
(int) platform_length, platform); |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_texas_instruments, |
|
.series = cpuinfo_arm_chipset_series_texas_instruments_omap, |
|
.model = 4430, |
|
}; |
|
} |
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
if (platform_length <= 6) { |
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(amlogic_map_entries); i++) { |
|
if (strncmp(amlogic_map_entries[i].ro_board_platform, platform, 6) == 0) { |
|
cpuinfo_log_debug( |
|
"found ro.board.platform string \"%.*s\" in Amlogic chipset table", |
|
(int) platform_length, platform); |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_amlogic, |
|
.series = (enum cpuinfo_arm_chipset_series) amlogic_map_entries[i].series, |
|
.model = amlogic_map_entries[i].model, |
|
.suffix = { |
|
[0] = amlogic_map_entries[i].suffix[0], |
|
[1] = amlogic_map_entries[i].suffix[1], |
|
[2] = amlogic_map_entries[i].suffix[2], |
|
}, |
|
}; |
|
} |
|
} |
|
} |
|
|
|
|
|
for (size_t i = 0; i < CPUINFO_COUNT_OF(special_platform_map_entries); i++) { |
|
if (strncmp(special_platform_map_entries[i].platform, platform, platform_length) == 0 && |
|
special_platform_map_entries[i].platform[platform_length] == 0) |
|
{ |
|
|
|
cpuinfo_log_debug( |
|
"found ro.board.platform string \"%.*s\" in special chipset table", (int) platform_length, platform); |
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = chipset_series_vendor[special_platform_map_entries[i].series], |
|
.series = (enum cpuinfo_arm_chipset_series) special_platform_map_entries[i].series, |
|
.model = special_platform_map_entries[i].model, |
|
.suffix = { |
|
[0] = special_platform_map_entries[i].suffix, |
|
}, |
|
}; |
|
} |
|
} |
|
|
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_mediatek_platform( |
|
const char platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]) |
|
{ |
|
struct cpuinfo_arm_chipset chipset; |
|
const char* platform_end = platform + strnlen(platform, CPUINFO_BUILD_PROP_VALUE_MAX); |
|
|
|
|
|
if (match_mt(platform, platform_end, false, &chipset)) { |
|
return chipset; |
|
} |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_arch( |
|
const char arch[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]) |
|
{ |
|
struct cpuinfo_arm_chipset chipset; |
|
const char* arch_end = arch + strnlen(arch, CPUINFO_BUILD_PROP_VALUE_MAX); |
|
|
|
|
|
if (match_exynos(arch, arch_end, &chipset)) { |
|
return chipset; |
|
} |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset_from_ro_chipname( |
|
const char chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]) |
|
{ |
|
struct cpuinfo_arm_chipset chipset; |
|
const size_t chipname_length = strnlen(chipname, CPUINFO_BUILD_PROP_VALUE_MAX); |
|
const char* chipname_end = chipname + chipname_length; |
|
|
|
|
|
if (match_msm_apq(chipname, chipname_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm MSM/APQ signature in ro.chipname string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_sm(chipname, chipname_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Qualcomm SM signature in /proc/cpuinfo Hardware string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_exynos(chipname, chipname_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched exynosXXXX (Samsung Exynos) signature in ro.chipname string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_universal(chipname, chipname_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched UNIVERSAL (Samsung Exynos) signature in ro.chipname Hardware string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_mt(chipname, chipname_end, true, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched MediaTek MT signature in ro.chipname string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
|
|
if (match_sc(chipname, chipname_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Spreadtrum SC signature in ro.chipname string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
#if CPUINFO_ARCH_ARM |
|
|
|
if (match_pxa(chipname, chipname_end, &chipset)) { |
|
cpuinfo_log_debug( |
|
"matched Marvell PXA signature in ro.chipname string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
return chipset; |
|
} |
|
|
|
|
|
if (chipname_length == 6 && memcmp(chipname, "mp523x", 6) == 0) { |
|
cpuinfo_log_debug( |
|
"matched Renesas MP5232 signature in ro.chipname string \"%.*s\"", |
|
(int) chipname_length, chipname); |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_renesas, |
|
.series = cpuinfo_arm_chipset_series_renesas_mp, |
|
.model = 5232, |
|
}; |
|
} |
|
#endif |
|
|
|
return (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
} |
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cpuinfo_arm_fixup_chipset( |
|
struct cpuinfo_arm_chipset chipset[restrict static 1], uint32_t cores, uint32_t max_cpu_freq_max) |
|
{ |
|
switch (chipset->series) { |
|
case cpuinfo_arm_chipset_series_qualcomm_msm: |
|
|
|
if (chipset->suffix[0] == 0) { |
|
|
|
switch (chipset->model) { |
|
case 8216: |
|
|
|
cpuinfo_log_info("reinterpreted MSM8216 chipset as MSM8916"); |
|
chipset->model = 8916; |
|
break; |
|
case 8916: |
|
|
|
switch (cores) { |
|
case 4: |
|
break; |
|
case 8: |
|
cpuinfo_log_info("reinterpreted MSM8916 chipset with 8 cores as MSM8939"); |
|
chipset->model = 8939; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core MSM%"PRIu32" chipset", |
|
cores, chipset->model); |
|
chipset->model = 0; |
|
} |
|
break; |
|
case 8937: |
|
|
|
switch (cores) { |
|
case 4: |
|
cpuinfo_log_info("reinterpreted MSM8937 chipset with 4 cores as MSM8917"); |
|
chipset->model = 8917; |
|
break; |
|
case 8: |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core MSM%"PRIu32" chipset", |
|
cores, chipset->model); |
|
chipset->model = 0; |
|
} |
|
break; |
|
case 8960: |
|
|
|
switch (cores) { |
|
case 2: |
|
break; |
|
case 4: |
|
cpuinfo_log_info("reinterpreted MSM8960 chipset with 4 cores as APQ8064"); |
|
chipset->series = cpuinfo_arm_chipset_series_qualcomm_apq; |
|
chipset->model = 8064; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core MSM%"PRIu32" chipset", |
|
cores, chipset->model); |
|
chipset->model = 0; |
|
} |
|
break; |
|
case 8996: |
|
|
|
switch (cores) { |
|
case 4: |
|
break; |
|
case 8: |
|
cpuinfo_log_info("reinterpreted MSM8996 chipset with 8 cores as MSM8994"); |
|
chipset->model = 8994; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core MSM%"PRIu32" chipset", |
|
cores, chipset->model); |
|
chipset->model = 0; |
|
} |
|
break; |
|
#if CPUINFO_ARCH_ARM |
|
case 8610: |
|
|
|
switch (cores) { |
|
case 2: |
|
break; |
|
case 4: |
|
cpuinfo_log_info("reinterpreted MSM8610 chipset with 4 cores as MSM8612"); |
|
chipset->model = 8612; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core MSM%"PRIu32" chipset", |
|
cores, chipset->model); |
|
chipset->model = 0; |
|
} |
|
break; |
|
#endif |
|
} |
|
} else { |
|
|
|
const uint32_t suffix_word = load_u32le(chipset->suffix); |
|
if (suffix_word == UINT32_C(0x004D534D) ) { |
|
|
|
|
|
|
|
|
|
chipset->suffix[0] = 0; |
|
chipset->suffix[1] = 0; |
|
chipset->suffix[2] = 0; |
|
} else { |
|
switch (chipset->model) { |
|
case 8976: |
|
|
|
if (suffix_word == UINT32_C(0x00004753) ) { |
|
chipset->suffix[0] = 'P'; |
|
chipset->suffix[1] = 'R'; |
|
chipset->suffix[2] = 'O'; |
|
} |
|
break; |
|
case 8996: |
|
|
|
if (suffix_word == UINT32_C(0x004F5250) ) { |
|
chipset->suffix[3] = '-'; |
|
chipset->suffix[4] = 'A'; |
|
chipset->suffix[5] = 'B' + (char) (max_cpu_freq_max >= 2188800); |
|
} |
|
break; |
|
} |
|
} |
|
} |
|
break; |
|
case cpuinfo_arm_chipset_series_qualcomm_apq: |
|
{ |
|
|
|
const uint32_t expected_apq = load_u32le(chipset->suffix); |
|
if (expected_apq == UINT32_C(0x00515041) ) { |
|
|
|
|
|
|
|
|
|
chipset->suffix[0] = 0; |
|
chipset->suffix[1] = 0; |
|
chipset->suffix[2] = 0; |
|
} |
|
break; |
|
} |
|
case cpuinfo_arm_chipset_series_samsung_exynos: |
|
switch (chipset->model) { |
|
#if CPUINFO_ARCH_ARM |
|
case 4410: |
|
|
|
chipset->model = 4412; |
|
break; |
|
case 5420: |
|
|
|
switch (cores) { |
|
case 4: |
|
break; |
|
case 6: |
|
cpuinfo_log_info("reinterpreted Exynos 5420 chipset with 6 cores as Exynos 5260"); |
|
chipset->model = 5260; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core Exynos 5420 chipset", cores); |
|
chipset->model = 0; |
|
} |
|
break; |
|
#endif |
|
case 7580: |
|
|
|
switch (cores) { |
|
case 4: |
|
cpuinfo_log_info("reinterpreted Exynos 7580 chipset with 4 cores as Exynos 7578"); |
|
chipset->model = 7578; |
|
break; |
|
case 8: |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core Exynos 7580 chipset", cores); |
|
chipset->model = 0; |
|
} |
|
break; |
|
} |
|
break; |
|
case cpuinfo_arm_chipset_series_mediatek_mt: |
|
if (chipset->model == 6752) { |
|
|
|
switch (cores) { |
|
case 4: |
|
cpuinfo_log_info("reinterpreted MT6752 chipset with 4 cores as MT6732"); |
|
chipset->model = 6732; |
|
break; |
|
case 8: |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core MT6752 chipset", cores); |
|
chipset->model = 0; |
|
} |
|
} |
|
if (chipset->suffix[0] == 'T') { |
|
|
|
const uint32_t suffix_word = load_u32le(chipset->suffix + 1); |
|
switch (suffix_word) { |
|
case UINT32_C(0x4F425255): |
|
case UINT32_C(0x4F425552): |
|
if (chipset->suffix[5] == 0) { |
|
chipset->suffix[1] = 0; |
|
chipset->suffix[2] = 0; |
|
chipset->suffix[3] = 0; |
|
chipset->suffix[4] = 0; |
|
} |
|
break; |
|
} |
|
} |
|
break; |
|
case cpuinfo_arm_chipset_series_rockchip_rk: |
|
if (chipset->model == 3288) { |
|
|
|
switch (cores) { |
|
case 4: |
|
break; |
|
case 6: |
|
cpuinfo_log_info("reinterpreted RK3288 chipset with 6 cores as RK3399"); |
|
chipset->model = 3399; |
|
break; |
|
default: |
|
cpuinfo_log_warning("system reported invalid %"PRIu32"-core RK3288 chipset", cores); |
|
chipset->model = 0; |
|
} |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
} |
|
|
|
|
|
static const char* chipset_vendor_string[cpuinfo_arm_chipset_vendor_max] = { |
|
[cpuinfo_arm_chipset_vendor_unknown] = "Unknown", |
|
[cpuinfo_arm_chipset_vendor_qualcomm] = "Qualcomm", |
|
[cpuinfo_arm_chipset_vendor_mediatek] = "MediaTek", |
|
[cpuinfo_arm_chipset_vendor_samsung] = "Samsung", |
|
[cpuinfo_arm_chipset_vendor_hisilicon] = "HiSilicon", |
|
[cpuinfo_arm_chipset_vendor_actions] = "Actions", |
|
[cpuinfo_arm_chipset_vendor_allwinner] = "Allwinner", |
|
[cpuinfo_arm_chipset_vendor_amlogic] = "Amlogic", |
|
[cpuinfo_arm_chipset_vendor_broadcom] = "Broadcom", |
|
[cpuinfo_arm_chipset_vendor_lg] = "LG", |
|
[cpuinfo_arm_chipset_vendor_leadcore] = "Leadcore", |
|
[cpuinfo_arm_chipset_vendor_marvell] = "Marvell", |
|
[cpuinfo_arm_chipset_vendor_mstar] = "MStar", |
|
[cpuinfo_arm_chipset_vendor_novathor] = "NovaThor", |
|
[cpuinfo_arm_chipset_vendor_nvidia] = "Nvidia", |
|
[cpuinfo_arm_chipset_vendor_pinecone] = "Pinecone", |
|
[cpuinfo_arm_chipset_vendor_renesas] = "Renesas", |
|
[cpuinfo_arm_chipset_vendor_rockchip] = "Rockchip", |
|
[cpuinfo_arm_chipset_vendor_spreadtrum] = "Spreadtrum", |
|
[cpuinfo_arm_chipset_vendor_telechips] = "Telechips", |
|
[cpuinfo_arm_chipset_vendor_texas_instruments] = "Texas Instruments", |
|
[cpuinfo_arm_chipset_vendor_wondermedia] = "WonderMedia", |
|
}; |
|
|
|
|
|
static const char* chipset_series_string[cpuinfo_arm_chipset_series_max] = { |
|
[cpuinfo_arm_chipset_series_unknown] = NULL, |
|
[cpuinfo_arm_chipset_series_qualcomm_qsd] = "QSD", |
|
[cpuinfo_arm_chipset_series_qualcomm_msm] = "MSM", |
|
[cpuinfo_arm_chipset_series_qualcomm_apq] = "APQ", |
|
[cpuinfo_arm_chipset_series_qualcomm_snapdragon] = "Snapdragon ", |
|
[cpuinfo_arm_chipset_series_mediatek_mt] = "MT", |
|
[cpuinfo_arm_chipset_series_samsung_exynos] = "Exynos ", |
|
[cpuinfo_arm_chipset_series_hisilicon_k3v] = "K3V", |
|
[cpuinfo_arm_chipset_series_hisilicon_hi] = "Hi", |
|
[cpuinfo_arm_chipset_series_hisilicon_kirin] = "Kirin ", |
|
[cpuinfo_arm_chipset_series_actions_atm] = "ATM", |
|
[cpuinfo_arm_chipset_series_allwinner_a] = "A", |
|
[cpuinfo_arm_chipset_series_amlogic_aml] = "AML", |
|
[cpuinfo_arm_chipset_series_amlogic_s] = "S", |
|
[cpuinfo_arm_chipset_series_broadcom_bcm] = "BCM", |
|
[cpuinfo_arm_chipset_series_lg_nuclun] = "Nuclun ", |
|
[cpuinfo_arm_chipset_series_leadcore_lc] = "LC", |
|
[cpuinfo_arm_chipset_series_marvell_pxa] = "PXA", |
|
[cpuinfo_arm_chipset_series_mstar_6a] = "6A", |
|
[cpuinfo_arm_chipset_series_novathor_u] = "U", |
|
[cpuinfo_arm_chipset_series_nvidia_tegra_t] = "Tegra T", |
|
[cpuinfo_arm_chipset_series_nvidia_tegra_ap] = "Tegra AP", |
|
[cpuinfo_arm_chipset_series_nvidia_tegra_sl] = "Tegra SL", |
|
[cpuinfo_arm_chipset_series_pinecone_surge_s] = "Surge S", |
|
[cpuinfo_arm_chipset_series_renesas_mp] = "MP", |
|
[cpuinfo_arm_chipset_series_rockchip_rk] = "RK", |
|
[cpuinfo_arm_chipset_series_spreadtrum_sc] = "SC", |
|
[cpuinfo_arm_chipset_series_telechips_tcc] = "TCC", |
|
[cpuinfo_arm_chipset_series_texas_instruments_omap] = "OMAP", |
|
[cpuinfo_arm_chipset_series_wondermedia_wm] = "WM", |
|
}; |
|
|
|
|
|
void cpuinfo_arm_chipset_to_string( |
|
const struct cpuinfo_arm_chipset chipset[restrict static 1], |
|
char name[restrict static CPUINFO_ARM_CHIPSET_NAME_MAX]) |
|
{ |
|
enum cpuinfo_arm_chipset_vendor vendor = chipset->vendor; |
|
if (vendor >= cpuinfo_arm_chipset_vendor_max) { |
|
vendor = cpuinfo_arm_chipset_vendor_unknown; |
|
} |
|
enum cpuinfo_arm_chipset_series series = chipset->series; |
|
if (series >= cpuinfo_arm_chipset_series_max) { |
|
series = cpuinfo_arm_chipset_series_unknown; |
|
} |
|
const char* vendor_string = chipset_vendor_string[vendor]; |
|
const char* series_string = chipset_series_string[series]; |
|
const uint32_t model = chipset->model; |
|
if (model == 0) { |
|
if (series == cpuinfo_arm_chipset_series_unknown) { |
|
strncpy(name, vendor_string, CPUINFO_ARM_CHIPSET_NAME_MAX); |
|
} else { |
|
snprintf(name, CPUINFO_ARM_CHIPSET_NAME_MAX, |
|
"%s %s", vendor_string, series_string); |
|
} |
|
} else { |
|
const size_t suffix_length = strnlen(chipset->suffix, CPUINFO_ARM_CHIPSET_SUFFIX_MAX); |
|
snprintf(name, CPUINFO_ARM_CHIPSET_NAME_MAX, |
|
"%s %s%"PRIu32"%.*s", vendor_string, series_string, model, (int) suffix_length, chipset->suffix); |
|
} |
|
} |
|
|
|
#ifdef __ANDROID__ |
|
static inline struct cpuinfo_arm_chipset disambiguate_qualcomm_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_product_board_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_board_platform_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_chipname_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_hardware_chipname_chipset[restrict static 1]) |
|
{ |
|
if (ro_hardware_chipname_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_hardware_chipname_chipset; |
|
} |
|
if (ro_chipname_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_chipname_chipset; |
|
} |
|
if (proc_cpuinfo_hardware_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
if (ro_product_board_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_product_board_chipset; |
|
} |
|
return *ro_board_platform_chipset; |
|
} |
|
|
|
static inline struct cpuinfo_arm_chipset disambiguate_mediatek_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_product_board_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_board_platform_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_mediatek_platform_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_chipname_chipset[restrict static 1]) |
|
{ |
|
if (ro_chipname_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_chipname_chipset; |
|
} |
|
if (proc_cpuinfo_hardware_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
if (ro_product_board_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_product_board_chipset; |
|
} |
|
if (ro_board_platform_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_board_platform_chipset; |
|
} |
|
return *ro_mediatek_platform_chipset; |
|
} |
|
|
|
static inline struct cpuinfo_arm_chipset disambiguate_hisilicon_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_product_board_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_board_platform_chipset[restrict static 1]) |
|
{ |
|
if (proc_cpuinfo_hardware_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
if (ro_product_board_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_product_board_chipset; |
|
} |
|
return *ro_board_platform_chipset; |
|
} |
|
|
|
static inline struct cpuinfo_arm_chipset disambiguate_amlogic_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_board_platform_chipset[restrict static 1]) |
|
{ |
|
if (proc_cpuinfo_hardware_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
return *ro_board_platform_chipset; |
|
} |
|
|
|
static inline struct cpuinfo_arm_chipset disambiguate_marvell_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_product_board_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_chipname_chipset[restrict static 1]) |
|
{ |
|
if (ro_chipname_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_chipname_chipset; |
|
} |
|
if (ro_product_board_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_product_board_chipset; |
|
} |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
|
|
static inline struct cpuinfo_arm_chipset disambiguate_rockchip_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_product_board_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_board_platform_chipset[restrict static 1]) |
|
{ |
|
if (ro_product_board_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_product_board_chipset; |
|
} |
|
if (proc_cpuinfo_hardware_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
return *ro_board_platform_chipset; |
|
} |
|
|
|
static inline struct cpuinfo_arm_chipset disambiguate_spreadtrum_chipset( |
|
const struct cpuinfo_arm_chipset proc_cpuinfo_hardware_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_product_board_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_board_platform_chipset[restrict static 1], |
|
const struct cpuinfo_arm_chipset ro_chipname_chipset[restrict static 1]) |
|
{ |
|
if (ro_chipname_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_chipname_chipset; |
|
} |
|
if (ro_product_board_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *ro_product_board_chipset; |
|
} |
|
if (proc_cpuinfo_hardware_chipset->series != cpuinfo_arm_chipset_series_unknown) { |
|
return *proc_cpuinfo_hardware_chipset; |
|
} |
|
return *ro_board_platform_chipset; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_android_decode_chipset( |
|
const struct cpuinfo_android_properties properties[restrict static 1], |
|
uint32_t cores, |
|
uint32_t max_cpu_freq_max) |
|
{ |
|
struct cpuinfo_arm_chipset chipset = { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
|
|
const bool tegra_platform = is_tegra( |
|
properties->ro_board_platform, |
|
properties->ro_board_platform + strnlen(properties->ro_board_platform, CPUINFO_BUILD_PROP_VALUE_MAX)); |
|
|
|
struct cpuinfo_arm_chipset chipsets[cpuinfo_android_chipset_property_max] = { |
|
[cpuinfo_android_chipset_property_proc_cpuinfo_hardware] = |
|
cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_hardware( |
|
properties->proc_cpuinfo_hardware, cores, max_cpu_freq_max, tegra_platform), |
|
[cpuinfo_android_chipset_property_ro_product_board] = |
|
cpuinfo_arm_android_decode_chipset_from_ro_product_board( |
|
properties->ro_product_board, cores, max_cpu_freq_max), |
|
[cpuinfo_android_chipset_property_ro_board_platform] = |
|
cpuinfo_arm_android_decode_chipset_from_ro_board_platform( |
|
properties->ro_board_platform, cores, max_cpu_freq_max), |
|
[cpuinfo_android_chipset_property_ro_mediatek_platform] = |
|
cpuinfo_arm_android_decode_chipset_from_ro_mediatek_platform(properties->ro_mediatek_platform), |
|
[cpuinfo_android_chipset_property_ro_arch] = |
|
cpuinfo_arm_android_decode_chipset_from_ro_arch(properties->ro_arch), |
|
[cpuinfo_android_chipset_property_ro_chipname] = |
|
cpuinfo_arm_android_decode_chipset_from_ro_chipname(properties->ro_chipname), |
|
[cpuinfo_android_chipset_property_ro_hardware_chipname] = |
|
cpuinfo_arm_android_decode_chipset_from_ro_chipname(properties->ro_hardware_chipname), |
|
}; |
|
enum cpuinfo_arm_chipset_vendor vendor = cpuinfo_arm_chipset_vendor_unknown; |
|
for (size_t i = 0; i < cpuinfo_android_chipset_property_max; i++) { |
|
const enum cpuinfo_arm_chipset_vendor decoded_vendor = chipsets[i].vendor; |
|
if (decoded_vendor != cpuinfo_arm_chipset_vendor_unknown) { |
|
if (vendor == cpuinfo_arm_chipset_vendor_unknown) { |
|
vendor = decoded_vendor; |
|
} else if (vendor != decoded_vendor) { |
|
|
|
cpuinfo_log_error( |
|
"chipset detection failed: different chipset vendors reported in different system properties"); |
|
goto finish; |
|
} |
|
} |
|
} |
|
if (vendor == cpuinfo_arm_chipset_vendor_unknown) { |
|
cpuinfo_log_warning( |
|
"chipset detection failed: none of the system properties matched known signatures"); |
|
goto finish; |
|
} |
|
|
|
|
|
for (size_t i = 0; i < cpuinfo_android_chipset_property_max; i++) { |
|
cpuinfo_arm_fixup_chipset(&chipsets[i], cores, max_cpu_freq_max); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < cpuinfo_android_chipset_property_max; i++) { |
|
const size_t chipset_i_suffix_length = strnlen(chipsets[i].suffix, CPUINFO_ARM_CHIPSET_SUFFIX_MAX); |
|
for (size_t j = 0; j < i; j++) { |
|
if (chipsets[i].series == chipsets[j].series) { |
|
const size_t chipset_j_suffix_length = strnlen(chipsets[j].suffix, CPUINFO_ARM_CHIPSET_SUFFIX_MAX); |
|
if (chipset_i_suffix_length != chipset_j_suffix_length) { |
|
const size_t common_prefix_length = (chipset_i_suffix_length < chipset_j_suffix_length) ? |
|
chipset_i_suffix_length : chipset_j_suffix_length; |
|
if (common_prefix_length == 0 || |
|
memcmp(chipsets[i].suffix, chipsets[j].suffix, common_prefix_length) == 0) |
|
{ |
|
if (chipset_i_suffix_length > chipset_j_suffix_length) { |
|
memcpy(chipsets[j].suffix, chipsets[i].suffix, chipset_i_suffix_length); |
|
} else { |
|
memcpy(chipsets[i].suffix, chipsets[j].suffix, chipset_j_suffix_length); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
for (size_t i = 0; i < cpuinfo_android_chipset_property_max; i++) { |
|
if (chipsets[i].series != cpuinfo_arm_chipset_series_unknown) { |
|
if (chipset.series == cpuinfo_arm_chipset_series_unknown) { |
|
chipset = chipsets[i]; |
|
} else if (chipsets[i].series != chipset.series || chipsets[i].model != chipset.model || |
|
strncmp(chipsets[i].suffix, chipset.suffix, CPUINFO_ARM_CHIPSET_SUFFIX_MAX) != 0) |
|
{ |
|
cpuinfo_log_info( |
|
"different chipsets reported in different system properties; " |
|
"vendor-specific disambiguation heuristic would be used"); |
|
switch (vendor) { |
|
case cpuinfo_arm_chipset_vendor_qualcomm: |
|
return disambiguate_qualcomm_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_product_board], |
|
&chipsets[cpuinfo_android_chipset_property_ro_board_platform], |
|
&chipsets[cpuinfo_android_chipset_property_ro_chipname], |
|
&chipsets[cpuinfo_android_chipset_property_ro_hardware_chipname]); |
|
case cpuinfo_arm_chipset_vendor_mediatek: |
|
return disambiguate_mediatek_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_product_board], |
|
&chipsets[cpuinfo_android_chipset_property_ro_board_platform], |
|
&chipsets[cpuinfo_android_chipset_property_ro_mediatek_platform], |
|
&chipsets[cpuinfo_android_chipset_property_ro_chipname]); |
|
case cpuinfo_arm_chipset_vendor_hisilicon: |
|
return disambiguate_hisilicon_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_product_board], |
|
&chipsets[cpuinfo_android_chipset_property_ro_board_platform]); |
|
case cpuinfo_arm_chipset_vendor_amlogic: |
|
return disambiguate_amlogic_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_board_platform]); |
|
case cpuinfo_arm_chipset_vendor_marvell: |
|
return disambiguate_marvell_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_product_board], |
|
&chipsets[cpuinfo_android_chipset_property_ro_chipname]); |
|
case cpuinfo_arm_chipset_vendor_rockchip: |
|
return disambiguate_rockchip_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_product_board], |
|
&chipsets[cpuinfo_android_chipset_property_ro_board_platform]); |
|
case cpuinfo_arm_chipset_vendor_spreadtrum: |
|
return disambiguate_spreadtrum_chipset( |
|
&chipsets[cpuinfo_android_chipset_property_proc_cpuinfo_hardware], |
|
&chipsets[cpuinfo_android_chipset_property_ro_product_board], |
|
&chipsets[cpuinfo_android_chipset_property_ro_board_platform], |
|
&chipsets[cpuinfo_android_chipset_property_ro_chipname]); |
|
default: |
|
cpuinfo_log_error( |
|
"chipset detection failed: " |
|
"could not disambiguate different chipsets reported in different system properties"); |
|
|
|
chipset = (struct cpuinfo_arm_chipset) { |
|
.vendor = cpuinfo_arm_chipset_vendor_unknown, |
|
.series = cpuinfo_arm_chipset_series_unknown, |
|
}; |
|
goto finish; |
|
} |
|
} |
|
} |
|
} |
|
|
|
finish: |
|
return chipset; |
|
} |
|
#else |
|
|
|
|
|
|
|
|
|
|
|
|
|
void cpuinfo_arm_fixup_raspberry_pi_chipset( |
|
struct cpuinfo_arm_chipset chipset[restrict static 1], |
|
const char revision[restrict static CPUINFO_HARDWARE_VALUE_MAX]) |
|
{ |
|
const size_t revision_length = strnlen(revision, CPUINFO_REVISION_VALUE_MAX); |
|
|
|
|
|
#if CPUINFO_ARCH_ARM |
|
if (revision_length == 4) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
if (chipset->model == 2708) { |
|
chipset->model = 2835; |
|
} |
|
return; |
|
} |
|
#endif |
|
if ((size_t) (revision_length - 5) <= (size_t) (8 - 5) ) { |
|
|
|
|
|
uint32_t model = 0; |
|
switch (revision[revision_length - 4]) { |
|
case '0': |
|
|
|
model = 2835; |
|
break; |
|
case '1': |
|
|
|
model = 2836; |
|
break; |
|
case '2': |
|
|
|
model = 2837; |
|
break; |
|
case '3': |
|
|
|
model = 2711; |
|
break; |
|
} |
|
|
|
if (model != 0) { |
|
chipset->model = model; |
|
chipset->suffix[0] = 0; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct cpuinfo_arm_chipset cpuinfo_arm_linux_decode_chipset( |
|
const char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX], |
|
const char revision[restrict static CPUINFO_REVISION_VALUE_MAX], |
|
uint32_t cores, |
|
uint32_t max_cpu_freq_max) |
|
{ |
|
struct cpuinfo_arm_chipset chipset = |
|
cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_hardware( |
|
hardware, cores, max_cpu_freq_max, false); |
|
if (chipset.vendor == cpuinfo_arm_chipset_vendor_unknown) { |
|
cpuinfo_log_warning( |
|
"chipset detection failed: /proc/cpuinfo Hardware string did not match known signatures"); |
|
} else if (chipset.vendor == cpuinfo_arm_chipset_vendor_broadcom) { |
|
|
|
cpuinfo_arm_fixup_raspberry_pi_chipset(&chipset, revision); |
|
} else { |
|
cpuinfo_arm_fixup_chipset(&chipset, cores, max_cpu_freq_max); |
|
} |
|
return chipset; |
|
} |
|
|
|
#endif |
|
|