#ifndef __CPU__ #define __CPU__ #include #include enum { // ARCH_X86 CPU_VENDOR_INTEL, CPU_VENDOR_AMD, // ARCH_ARM CPU_VENDOR_ARM, CPU_VENDOR_APPLE, CPU_VENDOR_BROADCOM, CPU_VENDOR_CAVIUM, CPU_VENDOR_NVIDIA, CPU_VENDOR_APM, CPU_VENDOR_QUALCOMM, CPU_VENDOR_HUAWUEI, CPU_VENDOR_SAMSUNG, CPU_VENDOR_MARVELL, CPU_VENDOR_PHYTIUM, // OTHERS CPU_VENDOR_UNKNOWN, CPU_VENDOR_INVALID }; enum { HV_VENDOR_KVM, HV_VENDOR_QEMU, HV_VENDOR_HYPERV, HV_VENDOR_VMWARE, HV_VENDOR_XEN, HV_VENDOR_PARALLELS, HV_VENDOR_INVALID }; #define UNKNOWN_DATA -1 #define CPU_NAME_MAX_LENGTH 64 typedef int32_t VENDOR; struct frequency { int32_t base; int32_t max; }; struct hypervisor { bool present; char* hv_name; VENDOR hv_vendor; }; struct cach { int32_t size; uint8_t num_caches; bool exists; // plenty of more properties to include in the future... }; struct cache { struct cach* L1i; struct cach* L1d; struct cach* L2; struct cach* L3; struct cach** cach_arr; uint8_t max_cache_level; }; struct topology { int32_t total_cores; struct cache* cach; #if defined(ARCH_X86) || defined(ARCH_PPC) int32_t physical_cores; int32_t logical_cores; uint32_t sockets; uint32_t smt_supported; // Number of SMT that CPU supports (equal to smt_available if SMT is enabled) #ifdef ARCH_X86 uint32_t smt_available; // Number of SMT that is currently enabled struct apic* apic; #endif #endif }; struct features { bool AES; // Must be the first field of features struct! #ifdef ARCH_X86 bool AVX; bool AVX2; bool AVX512; bool SSE; bool SSE2; bool SSE3; bool SSSE3; bool SSE4a; bool SSE4_1; bool SSE4_2; bool FMA3; bool FMA4; bool SHA; #elif ARCH_PPC bool altivec; #elif ARCH_ARM bool NEON; bool SHA1; bool SHA2; bool CRC32; #endif }; struct cpuInfo { VENDOR cpu_vendor; struct uarch* arch; struct hypervisor* hv; struct frequency* freq; struct cache* cach; struct topology* topo; struct features* feat; int64_t peak_performance; #if defined(ARCH_X86) || defined(ARCH_PPC) // CPU name from model char* cpu_name; #endif #ifdef ARCH_X86 // Max cpuids levels uint32_t maxLevels; // Max cpuids extended levels uint32_t maxExtendedLevels; // Topology Extensions (AMD only) bool topology_extensions; #elif ARCH_PPC uint32_t pvr; #elif ARCH_ARM // Main ID register uint32_t midr; #endif #ifdef ARCH_ARM struct system_on_chip* soc; // If SoC contains more than one CPU and they // are different, the others will be stored in // the next_cpu field struct cpuInfo* next_cpu; uint8_t num_cpus; #endif }; #if defined(ARCH_X86) || defined(ARCH_PPC) char* get_str_cpu_name(struct cpuInfo* cpu, bool fcpuname); char* get_str_sockets(struct topology* topo); uint32_t get_nsockets(struct topology* topo); #endif VENDOR get_cpu_vendor(struct cpuInfo* cpu); int64_t get_freq(struct frequency* freq); char* get_str_aes(struct cpuInfo* cpu); char* get_str_sha(struct cpuInfo* cpu); char* get_str_l1i(struct cache* cach); char* get_str_l1d(struct cache* cach); char* get_str_l2(struct cache* cach); char* get_str_l3(struct cache* cach); char* get_str_freq(struct frequency* freq); char* get_str_peak_performance(int64_t flops); void init_topology_struct(struct topology* topo, struct cache* cach); void init_cache_struct(struct cache* cach); void free_cache_struct(struct cache* cach); void free_freq_struct(struct frequency* freq); void free_cpuinfo_struct(struct cpuInfo* cpu); #endif