| | #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 |
| |
|