diff --git a/Android.bp b/Android.bp new file mode 100644 index 00000000..8465b945 --- /dev/null +++ b/Android.bp @@ -0,0 +1,134 @@ +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package { + default_applicable_licenses: ["external_cpuinfo_license"], +} + +// Added automatically by a large-scale-change +// See: http://go/android-license-faq +license { + name: "external_cpuinfo_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-BSD", + ], + license_text: [ + "LICENSE", + ], +} + +cpuinfo_arm_common_src_files = [ + "src/arm/uarch.c", + "src/arm/cache.c", + "src/arm/linux/init.c", + "src/arm/linux/cpuinfo.c", + "src/arm/linux/clusters.c", + "src/arm/linux/chipset.c", + "src/arm/linux/midr.c", + "src/arm/linux/hwcap.c", + "src/arm/android/properties.c", +] + +cpuinfo_x86_common_src_files = [ + "src/x86/init.c", + "src/x86/info.c", + "src/x86/name.c", + "src/x86/isa.c", + "src/x86/vendor.c", + "src/x86/uarch.c", + "src/x86/topology.c", + "src/x86/cache/init.c", + "src/x86/cache/descriptor.c", + "src/x86/cache/deterministic.c", + "src/x86/linux/cpuinfo.c", + "src/x86/linux/init.c", +] + +cc_library { + name: "libcpuinfo", + export_include_dirs: ["include"], + host_supported: true, + vendor_available: true, + product_available: true, + min_sdk_version: "29", + sdk_version: "current", + local_include_dirs: [ + "src", + "include", + ], + srcs: [ + "src/init.c", + "src/api.c", + "src/cache.c", + "src/log.c", + "src/linux/processors.c", + "src/linux/smallfile.c", + "src/linux/multiline.c", + "src/linux/cpulist.c", + ], + arch: { + arm: { + srcs: cpuinfo_arm_common_src_files + [ + "src/arm/linux/aarch32-isa.c", + ], + }, + arm64: { + srcs: cpuinfo_arm_common_src_files + [ + "src/arm/linux/aarch64-isa.c", + ], + }, + riscv64: { + srcs: [ + "src/riscv/linux/init.c", + "src/riscv/linux/riscv-hw.c", + "src/riscv/linux/riscv-isa.c", + "src/riscv/uarch.c", + ], + }, + x86: { + srcs: cpuinfo_x86_common_src_files, + }, + x86_64: { + srcs: cpuinfo_x86_common_src_files, + }, + }, + cflags: [ + "-std=c99", + "-Oz", + "-D_GNU_SOURCE=1", + "-DCPUINFO_LOG_LEVEL=2", + "-Wno-unused-function", + "-Wno-unused-parameter", + "-Wno-missing-field-initializers", + // __riscv_hwprobe() changed from unsigned long* to cpu_set_t*, + // but upstream hasn't updated yet. + "-Wno-incompatible-pointer-types", + ], + product_variables: { + debuggable: { + cflags: [ + "-DDEBUG_CPUINFO", + ], + }, + }, + shared_libs: [ + "liblog", + "libclog", + ], + apex_available: [ + "//apex_available:platform", + "//apex_available:anyapex", + ], +} diff --git a/include/cpuinfo.h b/include/cpuinfo.h index 891416ab..7dae54e7 100644 --- a/include/cpuinfo.h +++ b/include/cpuinfo.h @@ -890,10 +890,122 @@ struct cpuinfo_x86_isa { bool phe; bool pmm; bool lwp; + bool erms; + bool smap; + bool serialize; }; extern struct cpuinfo_x86_isa cpuinfo_isa; + +struct cpuid_regs { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +}; + +struct cpuinfo_x86_cache { + uint32_t size; + uint32_t associativity; + uint32_t sets; + uint32_t partitions; + uint32_t line_size; + uint32_t flags; + uint32_t apic_bits; +}; + +struct cpuinfo_x86_caches { + struct cpuinfo_trace_cache trace; + struct cpuinfo_x86_cache l1i; + struct cpuinfo_x86_cache l1d; + struct cpuinfo_x86_cache l2; + struct cpuinfo_x86_cache l3; + struct cpuinfo_x86_cache l4; + uint32_t prefetch_size; +}; + +struct cpuinfo_x86_tlbs { + struct cpuinfo_tlb itlb_4KB; + struct cpuinfo_tlb itlb_2MB; + struct cpuinfo_tlb itlb_4MB; + struct cpuinfo_tlb dtlb0_4KB; + struct cpuinfo_tlb dtlb0_2MB; + struct cpuinfo_tlb dtlb0_4MB; + struct cpuinfo_tlb dtlb_4KB; + struct cpuinfo_tlb dtlb_2MB; + struct cpuinfo_tlb dtlb_4MB; + struct cpuinfo_tlb dtlb_1GB; + struct cpuinfo_tlb stlb2_4KB; + struct cpuinfo_tlb stlb2_2MB; + struct cpuinfo_tlb stlb2_1GB; +}; + +struct cpuinfo_x86_model_info { + uint32_t model; + uint32_t family; + uint32_t base_model; + uint32_t base_family; + uint32_t stepping; + uint32_t extended_model; + uint32_t extended_family; + uint32_t processor_type; +}; + +struct cpuinfo_x86_topology { + uint32_t apic_id; + uint32_t thread_bits_offset; + uint32_t thread_bits_length; + uint32_t core_bits_offset; + uint32_t core_bits_length; +}; + +struct cpuinfo_x86_processor { + uint32_t cpuid; + enum cpuinfo_vendor vendor; + enum cpuinfo_uarch uarch; +#ifdef __linux__ + int linux_id; +#endif + struct cpuinfo_x86_caches cache; + struct cpuinfo_x86_tlbs tlb; + struct cpuinfo_x86_topology topology; + char brand_string[CPUINFO_PACKAGE_NAME_MAX]; +}; + +#ifdef __ANDROID__ +static const char CPUID_INFO_FILE[] = "/data/vendor/cpuinfo/cpuid.info"; + +struct cpuinfo_x86_cpuid_info { + struct cpuinfo_x86_isa isa; + struct cpuinfo_x86_model_info model; + struct cpuinfo_x86_processor processor; +}; +#endif //__ANDROID__ +#endif //CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + +static inline bool cpuinfo_has_x86_erms(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.erms; +#else + return false; #endif +} + +static inline bool cpuinfo_has_x86_smap(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.smap; +#else + return false; +#endif +} + +static inline bool cpuinfo_has_x86_serialize(void) { +#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 + return cpuinfo_isa.serialize; +#else + return false; +#endif +} static inline bool cpuinfo_has_x86_rdtsc(void) { #if CPUINFO_ARCH_X86_64 diff --git a/src/cpuinfo/log.h b/src/cpuinfo/log.h index 52e3475f..53888eee 100644 --- a/src/cpuinfo/log.h +++ b/src/cpuinfo/log.h @@ -15,6 +15,11 @@ #define CPUINFO_LOG_INFO 4 #define CPUINFO_LOG_DEBUG 5 +#ifdef DEBUG_CPUINFO +#undef CPUINFO_LOG_LEVEL +#define CPUINFO_LOG_LEVEL CPUINFO_LOG_DEBUG +#endif + #ifndef CPUINFO_LOG_DEBUG_PARSERS #define CPUINFO_LOG_DEBUG_PARSERS 0 #endif diff --git a/src/x86/api.h b/src/x86/api.h index 1331ed04..b76c572f 100644 --- a/src/x86/api.h +++ b/src/x86/api.h @@ -6,80 +6,6 @@ #include #include -struct cpuid_regs { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; -}; - -struct cpuinfo_x86_cache { - uint32_t size; - uint32_t associativity; - uint32_t sets; - uint32_t partitions; - uint32_t line_size; - uint32_t flags; - uint32_t apic_bits; -}; - -struct cpuinfo_x86_caches { - struct cpuinfo_trace_cache trace; - struct cpuinfo_x86_cache l1i; - struct cpuinfo_x86_cache l1d; - struct cpuinfo_x86_cache l2; - struct cpuinfo_x86_cache l3; - struct cpuinfo_x86_cache l4; - uint32_t prefetch_size; -}; - -struct cpuinfo_x86_model_info { - uint32_t model; - uint32_t family; - - uint32_t base_model; - uint32_t base_family; - uint32_t stepping; - uint32_t extended_model; - uint32_t extended_family; - uint32_t processor_type; -}; - -struct cpuinfo_x86_topology { - uint32_t apic_id; - uint32_t thread_bits_offset; - uint32_t thread_bits_length; - uint32_t core_bits_offset; - uint32_t core_bits_length; -}; - -struct cpuinfo_x86_processor { - uint32_t cpuid; - enum cpuinfo_vendor vendor; - enum cpuinfo_uarch uarch; -#ifdef __linux__ - int linux_id; -#endif - struct cpuinfo_x86_caches cache; - struct { - struct cpuinfo_tlb itlb_4KB; - struct cpuinfo_tlb itlb_2MB; - struct cpuinfo_tlb itlb_4MB; - struct cpuinfo_tlb dtlb0_4KB; - struct cpuinfo_tlb dtlb0_2MB; - struct cpuinfo_tlb dtlb0_4MB; - struct cpuinfo_tlb dtlb_4KB; - struct cpuinfo_tlb dtlb_2MB; - struct cpuinfo_tlb dtlb_4MB; - struct cpuinfo_tlb dtlb_1GB; - struct cpuinfo_tlb stlb2_4KB; - struct cpuinfo_tlb stlb2_2MB; - struct cpuinfo_tlb stlb2_1GB; - } tlb; - struct cpuinfo_x86_topology topology; - char brand_string[CPUINFO_PACKAGE_NAME_MAX]; -}; - CPUINFO_INTERNAL void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor); CPUINFO_INTERNAL enum cpuinfo_vendor cpuinfo_x86_decode_vendor(uint32_t ebx, uint32_t ecx, uint32_t edx); diff --git a/src/x86/init.c b/src/x86/init.c index adc5d361..12283fb1 100644 --- a/src/x86/init.c +++ b/src/x86/init.c @@ -7,11 +7,41 @@ #include #include #include +#include -struct cpuinfo_x86_isa cpuinfo_isa = {0}; +/* + * Structs cpuinfo_x86_isa, cpuinfo_x86_model_info and cpuinfo_x86_processor + * are dumped into cpuid.info file by cpuinfo-svc service on boot. + * Whenever libcpuinfo is initialized by any application, it will attempt to + * read cpuid.info file, if it exists, and the binary dump in the file is + * copied to these structs. If the file doesn't exist, we will fall back to + * original method of calling __cpuid() intrinsics to get the info. + * By this method, we can avoid __cpuid() calls during each init of cpuinfo. + * This will reduce VMX events in virtualized environments thereby + * improving performance. + * CPUID being a privileged instn costs considerable number of CPU cycles. + */ + +#ifdef __ANDROID__ +struct cpuinfo_x86_cpuid_info x86_cpuid_info = { 0 }; +#endif //__ANDROID__ + +struct cpuinfo_x86_isa cpuinfo_isa = { 0 }; CPUINFO_INTERNAL uint32_t cpuinfo_x86_clflush_size = 0; void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { + #ifdef __ANDROID__ + if (cpuinfo_x86_linux_parse_cpuid_info(&x86_cpuid_info)) { + *processor = x86_cpuid_info.processor; + cpuinfo_isa = x86_cpuid_info.isa; + #ifdef DEBUG_CPUINFO + debug_print_cpuid_info_file(); + #endif //DEBUG_CPUINFO + return; + } + cpuinfo_log_debug("falling back to CPUID method"); + #endif //__ANDROID__ + const struct cpuid_regs leaf0 = cpuid(0); const uint32_t max_base_index = leaf0.eax; const enum cpuinfo_vendor vendor = processor->vendor = @@ -66,6 +96,10 @@ void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { cpuinfo_isa = cpuinfo_x86_detect_isa( leaf1, leaf0x80000001, max_base_index, max_extended_index, vendor, uarch); + + #ifdef __ANDROID__ + x86_cpuid_info.model = model_info; + #endif //__ANDROID__ } if (max_extended_index >= UINT32_C(0x80000004)) { struct cpuid_regs brand_string[3]; @@ -75,4 +109,11 @@ void cpuinfo_x86_init_processor(struct cpuinfo_x86_processor* processor) { memcpy(processor->brand_string, brand_string, sizeof(processor->brand_string)); cpuinfo_log_debug("raw CPUID brand string: \"%48s\"", processor->brand_string); } + #ifdef __ANDROID__ + x86_cpuid_info.processor = *processor; + x86_cpuid_info.isa = cpuinfo_isa; + #ifdef DEBUG_CPUINFO + debug_print_cpuid_info_file(); + #endif //DEBUG_CPUINFO + #endif //__ANDROID__ } diff --git a/src/x86/isa.c b/src/x86/isa.c index 222bd231..eb54a052 100644 --- a/src/x86/isa.c +++ b/src/x86/isa.c @@ -828,5 +828,23 @@ struct cpuinfo_x86_isa cpuinfo_x86_detect_isa( */ isa.rdpid = !!(structured_feature_info0.ecx & UINT32_C(0x00400000)); + /* + * ERMS instruction: + * - Intel: ebx[bit 9] in structured feature info (ecx = 0). + */ + isa.erms = !!(structured_feature_info0.ebx & UINT32_C(0x00000200)); + + /* + * SMAP instruction: + * - Intel: ebx[bit 20] in structured feature info (ecx = 0). + */ + isa.smap = !!(structured_feature_info0.ebx & UINT32_C(0x00100000)); + + /* + * SERIALIZE instruction: + * - Intel: edx[bit 14] in structured feature info (ecx = 0). + */ + isa.serialize = !!(structured_feature_info0.edx & UINT32_C(0x00004000)); + return isa; } diff --git a/src/x86/linux/api.h b/src/x86/linux/api.h index 26fc5de0..9c868a1c 100644 --- a/src/x86/linux/api.h +++ b/src/x86/linux/api.h @@ -17,3 +17,12 @@ struct cpuinfo_x86_linux_processor { CPUINFO_INTERNAL bool cpuinfo_x86_linux_parse_proc_cpuinfo( uint32_t max_processors_count, struct cpuinfo_x86_linux_processor processors[restrict static max_processors_count]); + +#ifdef __ANDROID__ +CPUINFO_INTERNAL bool cpuinfo_x86_linux_parse_cpuid_info( + struct cpuinfo_x86_cpuid_info* x86_cpuid_info); + +#ifdef DEBUG_CPUINFO +CPUINFO_INTERNAL void debug_print_cpuid_info_file(void); +#endif //DEBUG_CPUINFO +#endif //__ANDROID__ diff --git a/src/x86/linux/cpuinfo.c b/src/x86/linux/cpuinfo.c index f09d1c9f..a55b8e36 100644 --- a/src/x86/linux/cpuinfo.c +++ b/src/x86/linux/cpuinfo.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -213,3 +214,108 @@ bool cpuinfo_x86_linux_parse_proc_cpuinfo( }; return cpuinfo_linux_parse_multiline_file("/proc/cpuinfo", BUFFER_SIZE, parse_line, &state); } + +#ifdef __ANDROID__ +bool cpuinfo_x86_linux_parse_cpuid_info( + struct cpuinfo_x86_cpuid_info* x86_cpuid_info) { + cpuinfo_log_debug("reading cpuid.info file"); + FILE* fd_info = fopen(CPUID_INFO_FILE, "rb"); + if (!fd_info) { + cpuinfo_log_warning("failed to open file %s: %s", CPUID_INFO_FILE, strerror(errno)); + return false; + } + + int ret = fread(x86_cpuid_info, sizeof(struct cpuinfo_x86_cpuid_info), 1, fd_info); + if (!ret) { + cpuinfo_log_warning("failed to read cpuid info from %s: %s", CPUID_INFO_FILE, strerror(errno)); + } + + if (fclose(fd_info)) { + cpuinfo_log_warning("failed to close file %s: %s", CPUID_INFO_FILE, strerror(errno)); + } + + return ret ? true : false; +} + +#ifdef DEBUG_CPUINFO +void debug_print_cpuid_info_file (void) { + cpuinfo_log_debug("cpuinfo: ----------------------------"); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "erms", cpuinfo_has_x86_erms()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "smap", cpuinfo_has_x86_smap()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "serialize", cpuinfo_has_x86_serialize()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "adx", cpuinfo_has_x86_adx()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "aes", cpuinfo_has_x86_aes()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx", cpuinfo_has_x86_avx()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx2", cpuinfo_has_x86_avx2()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512bf16", cpuinfo_has_x86_avx512bf16()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512bitalg", cpuinfo_has_x86_avx512bitalg()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512bw", cpuinfo_has_x86_avx512bw()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512cd", cpuinfo_has_x86_avx512cd()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512dq", cpuinfo_has_x86_avx512dq()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512er", cpuinfo_has_x86_avx512er()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512f", cpuinfo_has_x86_avx512f()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512ifma", cpuinfo_has_x86_avx512ifma()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512pf", cpuinfo_has_x86_avx512pf()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512vbmi", cpuinfo_has_x86_avx512vbmi()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512vbmi2", cpuinfo_has_x86_avx512vbmi2()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512vl", cpuinfo_has_x86_avx512vl()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512vnni", cpuinfo_has_x86_avx512vnni()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512vp2intersect", cpuinfo_has_x86_avx512vp2intersect()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512vpopcntdq", cpuinfo_has_x86_avx512vpopcntdq()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512_4fmaps", cpuinfo_has_x86_avx512_4fmaps()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "avx512_4vnniw", cpuinfo_has_x86_avx512_4vnniw()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "bmi", cpuinfo_has_x86_bmi()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "bmi2", cpuinfo_has_x86_bmi2()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "clwb", cpuinfo_has_x86_clwb()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "clzero", cpuinfo_has_x86_clzero()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "cmpxchg16b", cpuinfo_has_x86_cmpxchg16b()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "f16c", cpuinfo_has_x86_f16c()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "fma3", cpuinfo_has_x86_fma3()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "fma4", cpuinfo_has_x86_fma4()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "gfni", cpuinfo_has_x86_gfni()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "hle", cpuinfo_has_x86_hle()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "lzcnt", cpuinfo_has_x86_lzcnt()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "misaligned_sse", cpuinfo_has_x86_misaligned_sse()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "movbe", cpuinfo_has_x86_movbe()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "mpx", cpuinfo_has_x86_mpx()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "mwait", cpuinfo_has_x86_mwait()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "mwaitx", cpuinfo_has_x86_mwaitx()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "pclmulqdq", cpuinfo_has_x86_pclmulqdq()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "popcnt", cpuinfo_has_x86_popcnt()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "prefetch", cpuinfo_has_x86_prefetch()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "prefetchw", cpuinfo_has_x86_prefetchw()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "prefetchwt1", cpuinfo_has_x86_prefetchwt1()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "rdpid", cpuinfo_has_x86_rdpid()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "rdrand", cpuinfo_has_x86_rdrand()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "rdseed", cpuinfo_has_x86_rdseed()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "rdtscp", cpuinfo_has_x86_rdtscp()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "rtm", cpuinfo_has_x86_rtm()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sha", cpuinfo_has_x86_sha()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sse3", cpuinfo_has_x86_sse3()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sse4a", cpuinfo_has_x86_sse4a()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sse4_1", cpuinfo_has_x86_sse4_1()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sse4_2", cpuinfo_has_x86_sse4_2()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "ssse3", cpuinfo_has_x86_ssse3()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "tbm", cpuinfo_has_x86_tbm()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "three_d_now", cpuinfo_has_x86_3dnow()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "three_d_now_plus", cpuinfo_has_x86_3dnow_plus()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "vaes", cpuinfo_has_x86_vaes()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "vpclmulqdq", cpuinfo_has_x86_vpclmulqdq()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "xop", cpuinfo_has_x86_xop()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "xsave", cpuinfo_has_x86_xsave()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "xtest", cpuinfo_has_x86_xtest()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "cmov", cpuinfo_has_x86_cmov()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "cmpxchg8b", cpuinfo_has_x86_cmpxchg8b()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "daz", cpuinfo_has_x86_daz()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "fpu", cpuinfo_has_x86_fpu()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "mmx", cpuinfo_has_x86_mmx()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "mmx_plus", cpuinfo_has_x86_mmx_plus()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "rdtsc", cpuinfo_has_x86_rdtsc()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sse", cpuinfo_has_x86_sse()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "sse2", cpuinfo_has_x86_sse2()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "three_d_now_geode", cpuinfo_has_x86_3dnow_geode()); + cpuinfo_log_debug("cpuinfo: %-20s: %d", "lahf_sahf", cpuinfo_has_x86_lahf_sahf()); + cpuinfo_log_debug("cpuinfo: ----------------------------"); +} +#endif //DEBUG_CPUINFO +#endif //__ANDROID__ diff --git a/tools/Android.bp b/tools/Android.bp new file mode 100644 index 00000000..055d6ccc --- /dev/null +++ b/tools/Android.bp @@ -0,0 +1,42 @@ +// Copyright (C) 2020 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +cc_binary { + name: "cpuinfo-svc", + vendor: true, + host_supported: true, + min_sdk_version: "29", + sdk_version: "current", + + include_dirs: [ + "external/cpuinfo/include", + ], + srcs: [ + "cpuinfo-svc.c", + ], + cflags: [ + "-std=c99", + "-Oz", + "-D_GNU_SOURCE=1", + "-Wno-unused-function", + "-Wno-unused-parameter", + "-Wno-missing-field-initializers", + ], + whole_static_libs: [ + "libcpuinfo", + ], + shared_libs: [ + "liblog", + ], +} diff --git a/tools/cpuinfo-svc.c b/tools/cpuinfo-svc.c new file mode 100644 index 00000000..bf814568 --- /dev/null +++ b/tools/cpuinfo-svc.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2024 Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + *    this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + *    this list of conditions and the following disclaimer in the documentation + *    and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Description: cpuinfo-service to initialize and dump cpu info collected + * through __cpuid() calls during device boot. + * it will delete cpuid.info file if it exists and create new. + * + * Author: Unnithan, Balakrishnan + */ + + +#include +#include +#include +#include + +#include + +#ifdef __ANDROID__ +#include + +extern struct cpuinfo_x86_cpuid_info x86_cpuid_info; + +static bool write_cpuid_info_file (void) { + ALOGI("writing cpuid.info file"); + FILE* fd_info = fopen(CPUID_INFO_FILE, "wb"); + if (!fd_info) { + ALOGE("failed to open file %s: %s", + CPUID_INFO_FILE, strerror(errno)); + return false; + } + + int ret = fwrite(&x86_cpuid_info, + sizeof(struct cpuinfo_x86_cpuid_info), 1, fd_info); + if (!ret) { + ALOGE("failed to write file %s: %s", + CPUID_INFO_FILE, strerror(errno)); + } + + if (fclose(fd_info)) { + ALOGE("failed to close file %s: %s", + CPUID_INFO_FILE, strerror(errno)); + return false; + } + + return ret ? true : false; +} +#endif //__ANDROID_ + +int main (void) { +#ifdef __ANDROID__ + ALOGI("start service"); + if (remove(CPUID_INFO_FILE)) { + ALOGW("failed to delete file %s: %s", + CPUID_INFO_FILE, strerror(errno)); + } + + if (!cpuinfo_initialize()) { + ALOGE("failed to init cpuinfo lib. exit"); + return 1; + } + + if (!write_cpuid_info_file()) { + ALOGE("failed to save cpuid info. exit"); + return 1; + } + ALOGI("exit service"); +#endif //__ANDROID_ + return 0; +} \ No newline at end of file