1
0
Fork 0
mirror of https://github.com/anrieff/libcpuid synced 2024-12-16 16:35:45 +00:00

Add initial support for ARM CPUs

Close #200
This commit is contained in:
The Tumultuous Unicorn Of Darkness 2024-06-28 20:41:00 +02:00
parent ca0f64099b
commit c5885699f0
No known key found for this signature in database
GPG key ID: 1E55EE2EFF18BC1A
37 changed files with 2709 additions and 279 deletions

View file

@ -23,36 +23,45 @@ jobs:
./configure
make dist
- name: Download macOS artifacts
- name: Download macOS x86_64 artifacts
uses: dawidd6/action-download-artifact@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: unix.yml
commit: ${{ github.sha }}
name: macos
path: macos
name: macos-x86_64
path: macos-x86_64
- name: Download Windows (32-bit) artifacts
- name: Download macOS AArch64 artifacts
uses: dawidd6/action-download-artifact@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: unix.yml
commit: ${{ github.sha }}
name: macos-aarch64
path: macos-aarch64
- name: Download Windows ix86 artifacts
uses: dawidd6/action-download-artifact@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: windows.yml
commit: ${{ github.sha }}
name: win32
path: win32
name: windows-ix86
path: windows-ix86
- name: Download Windows (64-bit) artifacts
- name: Download Windows x86_64 artifacts
uses: dawidd6/action-download-artifact@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: windows.yml
commit: ${{ github.sha }}
name: win64
path: win64
name: window-x86_64
path: window-x86_64
- name: Compress artifacts
run: |
for dir in macos win32 win64; do
for dir in macos-* windows-*; do
zip -r "libcpuid-$VERSION-$dir.zip" "$dir"
done
env:
@ -70,7 +79,8 @@ jobs:
As a convenience, the following binaries are provided:
- A source tarball;
- Build for 64-bit macOS (built under [macOS 14.X](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md));
- Build for 32-bit Windows, using MSVC XX.XX, in Debug, Release and Release DLL configurations (built under [Windows Server 2022](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md));
- Build for 64-bit Windows, using MSVC XX.XX, in Debug, Release and Release DLL configurations (built under [Windows Server 2022](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md)).
artifacts: "libcpuid-${{ env.VERSION }}.tar.gz,libcpuid-${{ env.VERSION }}-macos.zip,libcpuid-${{ env.VERSION }}-win32.zip,libcpuid-${{ env.VERSION }}-win64.zip"
- Build for x86_64 macOS (built under [macOS 13.X](https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md));
- Build for AArch64 macOS (built under [macOS 14.X](https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md));
- Build for ix86 Windows, using MSVC XX.XX, in Debug, Release and Release DLL configurations (built under [Windows Server 2022](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md));
- Build for x86_64 Windows, using MSVC XX.XX, in Debug, Release and Release DLL configurations (built under [Windows Server 2022](https://github.com/actions/runner-images/blob/main/images/windows/Windows2022-Readme.md)).
artifacts: "libcpuid-${{ env.VERSION }}.tar.gz,libcpuid-${{ env.VERSION }}-macos-x86_64.zip,libcpuid-${{ env.VERSION }}-macos-aarch64.zip,libcpuid-${{ env.VERSION }}-windows-ix86.zip,libcpuid-${{ env.VERSION }}-window-x86_64.zip"

View file

@ -15,8 +15,9 @@ jobs:
strategy:
matrix:
os:
- { label: macos-latest, name: macos }
- { label: ubuntu-latest, name: linux }
- { label: macos-latest, name: macos-aarch64 }
- { label: macos-13, name: macos-x86_64 }
- { label: ubuntu-latest, name: linux-x86_64 }
env:
OS_NAME: ${{ matrix.os.name }}
@ -29,6 +30,13 @@ jobs:
- name: Build
run: cmake --build build
# - name: Run cpuid_tool
# run: |
# echo "RAW dump"
# ./build/cpuid_tool/cpuid_tool --save=-
# echo "Report"
# ./build/cpuid_tool/cpuid_tool --all
- name: Run tests
run: |
make -C build consistency

View file

@ -16,8 +16,8 @@ jobs:
matrix:
config: [Debug, Release, ReleaseDLL]
platform:
- { bitness: x32, ms: Win32, name: win32 }
- { bitness: x64, ms: x64, name: win64 }
- { bitness: x32, ms: Win32, name: windows-ix86 }
- { bitness: x64, ms: x64, name: window-x86_64 }
env:
CONFIG: ${{ matrix.config }}
BITNESS: ${{ matrix.platform.bitness }}
@ -73,8 +73,8 @@ jobs:
strategy:
matrix:
platform:
- win32
- win64
- windows-ix86
- window-x86_64
steps:
- name: Merge artifacts for ${{ matrix.platform }}

View file

@ -33,6 +33,19 @@ if(HAVE_POPCOUNT64)
add_definitions(-DHAVE_POPCOUNT64)
endif(HAVE_POPCOUNT64)
# check if auxiliary vector is available
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
check_symbol_exists(getauxval "sys/auxv.h" HAVE_GETAUXVAL)
if(HAVE_GETAUXVAL)
add_definitions(-DHAVE_GETAUXVAL)
endif(HAVE_GETAUXVAL)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_ELF_AUX_INFO)
if(HAVE_ELF_AUX_INFO)
add_definitions(-DHAVE_ELF_AUX_INFO)
endif(HAVE_ELF_AUX_INFO)
endif()
# Global variables
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
@ -42,7 +55,7 @@ if(UNIX)
set(exec_prefix "\${prefix}")
set(libdir "\${exec_prefix}/lib")
set(includedir "\${prefix}/include")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wuninitialized -Wstrict-prototypes -Wformat -Wformat-security -Wunused-parameter")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wuninitialized -Wstrict-prototypes -Wformat -Wformat-security -Wunused-parameter -Wno-deprecated-declarations")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/libcpuid.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libcpuid.pc" ESCAPE_QUOTES
@ONLY)
install(FILES "${PROJECT_BINARY_DIR}/libcpuid.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

View file

@ -67,6 +67,8 @@ AC_CANONICAL_HOST
build_windows=no
build_netbsd=no
build_dragonflybsd=no
build_freebsd=no
build_linux=no
case "${host_os}" in
cygwin*|mingw*)
@ -78,6 +80,12 @@ case "${host_os}" in
dragonfly*)
build_dragonflybsd=yes
;;
freebsd*)
build_freebsd=yes
;;
linux*)
build_linux=yes
;;
esac
if test "$build_windows" = "no"; then
@ -88,6 +96,14 @@ if test "$build_netbsd" = "yes" || test "$build_dragonflybsd" = "yes"; then
AM_LDFLAGS="$AM_LDFLAGS -pthread"
fi
if test "$build_linux" = "yes"; then
AC_CHECK_FUNCS([getauxval])
fi
if test "$build_freebsd" = "yes"; then
AC_CHECK_FUNCS([elf_aux_info])
fi
AM_CONDITIONAL([WINDOWS], [test "$build_windows" = "yes"])
AC_SUBST(AM_CPPFLAGS)

View file

@ -59,6 +59,7 @@ char out_file[256] = "";
typedef enum {
NEED_CPUID_PRESENT,
NEED_ARCHITECTURE,
NEED_FEATURE_LEVEL,
NEED_PURPOSE,
NEED_VENDOR_STR,
NEED_VENDOR_ID,
@ -68,6 +69,10 @@ typedef enum {
NEED_STEPPING,
NEED_EXT_FAMILY,
NEED_EXT_MODEL,
NEED_IMPLEMENTER,
NEED_VARIANT,
NEED_PART_NUM,
NEED_REVISION,
NEED_NUM_CORES,
NEED_NUM_LOGICAL,
NEED_TOTAL_CPUS,
@ -127,6 +132,7 @@ const struct { output_data_switch sw; const char* synopsis; int ident_required;
matchtable[] = {
{ NEED_CPUID_PRESENT, "--cpuid" , 0},
{ NEED_ARCHITECTURE , "--architecture" , 1},
{ NEED_FEATURE_LEVEL, "--feature-level", 1},
{ NEED_PURPOSE , "--purpose" , 1},
{ NEED_VENDOR_STR , "--vendorstr" , 1},
{ NEED_VENDOR_ID , "--vendorid" , 1},
@ -136,6 +142,10 @@ matchtable[] = {
{ NEED_STEPPING , "--stepping" , 1},
{ NEED_EXT_FAMILY , "--extfamily" , 1},
{ NEED_EXT_MODEL , "--extmodel" , 1},
{ NEED_IMPLEMENTER , "--implementer" , 1},
{ NEED_VARIANT , "--variant" , 1},
{ NEED_PART_NUM , "--part-num" , 1},
{ NEED_REVISION , "--revision" , 1},
{ NEED_NUM_CORES , "--cores" , 1},
{ NEED_NUM_LOGICAL , "--logical" , 1},
{ NEED_TOTAL_CPUS , "--total-cpus" , 1},
@ -371,6 +381,9 @@ static void print_info(output_data_switch query, struct cpu_id_t* data)
case NEED_ARCHITECTURE:
fprintf(fout, "%s\n", cpu_architecture_str(data->architecture));
break;
case NEED_FEATURE_LEVEL:
fprintf(fout, "%s\n", cpu_feature_level_str(data->feature_level));
break;
case NEED_PURPOSE:
fprintf(fout, "%s\n", cpu_purpose_str(data->purpose));
break;
@ -384,19 +397,31 @@ static void print_info(output_data_switch query, struct cpu_id_t* data)
fprintf(fout, "%s\n", data->brand_str);
break;
case NEED_FAMILY:
fprintf(fout, "%d\n", data->family);
fprintf(fout, "%d\n", data->x86.family);
break;
case NEED_MODEL:
fprintf(fout, "%d\n", data->model);
fprintf(fout, "%d\n", data->x86.model);
break;
case NEED_STEPPING:
fprintf(fout, "%d\n", data->stepping);
fprintf(fout, "%d\n", data->x86.stepping);
break;
case NEED_EXT_FAMILY:
fprintf(fout, "%d\n", data->ext_family);
fprintf(fout, "%d\n", data->x86.ext_family);
break;
case NEED_EXT_MODEL:
fprintf(fout, "%d\n", data->ext_model);
fprintf(fout, "%d\n", data->x86.ext_model);
break;
case NEED_IMPLEMENTER:
fprintf(fout, "%d\n", data->arm.implementer);
break;
case NEED_VARIANT:
fprintf(fout, "%d\n", data->arm.variant);
break;
case NEED_PART_NUM:
fprintf(fout, "%d\n", data->arm.part_num);
break;
case NEED_REVISION:
fprintf(fout, "%d\n", data->arm.revision);
break;
case NEED_NUM_CORES:
fprintf(fout, "%d\n", data->num_cores);
@ -532,7 +557,7 @@ static void print_info(output_data_switch query, struct cpu_id_t* data)
}
case NEED_SSE_UNIT_SIZE:
{
fprintf(fout, "%d (%s)\n", data->sse_size,
fprintf(fout, "%d (%s)\n", data->x86.sse_size,
data->detection_hints[CPU_HINT_SSE_SIZE_AUTH] ? "authoritative" : "non-authoritative");
break;
}
@ -548,7 +573,7 @@ static void print_cpulist(void)
struct cpu_list_t list;
const struct { const char *name; cpu_vendor_t vendor; } cpu_vendors[] = {
{ "Intel", VENDOR_INTEL },
{ "AMD", VENDOR_AMD },
{ "AMD/Hygon", VENDOR_AMD },
{ "Cyrix", VENDOR_CYRIX },
{ "NexGen", VENDOR_NEXGEN },
{ "Transmeta", VENDOR_TRANSMETA },
@ -557,6 +582,24 @@ static void print_cpulist(void)
{ "Rise", VENDOR_RISE },
{ "SiS", VENDOR_SIS },
{ "NSC", VENDOR_NSC },
{ "ARM", VENDOR_ARM },
{ "Broadcom", VENDOR_BROADCOM },
{ "Cavium", VENDOR_CAVIUM },
{ "DEC", VENDOR_DEC },
{ "FUJITSU", VENDOR_FUJITSU },
{ "HiSilicon", VENDOR_HISILICON },
{ "Infineon", VENDOR_INFINEON },
{ "Motorola/Freescale", VENDOR_FREESCALE },
{ "NVIDIA" , VENDOR_NVIDIA },
{ "APM", VENDOR_APM },
{ "Qualcomm", VENDOR_QUALCOMM },
{ "Samsung", VENDOR_SAMSUNG },
{ "Marvell" , VENDOR_MARVELL },
{ "Apple", VENDOR_APPLE },
{ "Faraday", VENDOR_FARADAY },
{ "Microsoft" , VENDOR_MICROSOFT },
{ "Phytium", VENDOR_PHYTIUM },
{ "Ampere" , VENDOR_AMPERE },
};
for (i = 0; i < sizeof(cpu_vendors)/sizeof(cpu_vendors[0]); i++) {
fprintf(fout, "-----%s-----\n", cpu_vendors[i].name);
@ -570,17 +613,17 @@ static void print_cpulist(void)
static void print_sgx_data(const struct cpu_raw_data_t* raw, const struct cpu_id_t* data)
{
int i;
fprintf(fout, "SGX: %d (%s)\n", data->sgx.present, data->sgx.present ? "present" : "absent");
if (data->sgx.present) {
fprintf(fout, "SGX max enclave size (32-bit): 2^%d\n", data->sgx.max_enclave_32bit);
fprintf(fout, "SGX max enclave size (64-bit): 2^%d\n", data->sgx.max_enclave_64bit);
fprintf(fout, "SGX1 extensions : %d (%s)\n", data->sgx.flags[INTEL_SGX1], data->sgx.flags[INTEL_SGX1] ? "present" : "absent");
fprintf(fout, "SGX2 extensions : %d (%s)\n", data->sgx.flags[INTEL_SGX2], data->sgx.flags[INTEL_SGX2] ? "present" : "absent");
fprintf(fout, "SGX MISCSELECT : %08x\n", data->sgx.misc_select);
fprintf(fout, "SGX SECS.ATTRIBUTES mask : %016llx\n", (unsigned long long) data->sgx.secs_attributes);
fprintf(fout, "SGX SECS.XSAVE feature mask : %016llx\n", (unsigned long long) data->sgx.secs_xfrm);
fprintf(fout, "SGX EPC sections count : %d\n", data->sgx.num_epc_sections);
for (i = 0; i < data->sgx.num_epc_sections; i++) {
fprintf(fout, "SGX: %d (%s)\n", data->x86.sgx.present, data->x86.sgx.present ? "present" : "absent");
if (data->x86.sgx.present) {
fprintf(fout, "SGX max enclave size (32-bit): 2^%d\n", data->x86.sgx.max_enclave_32bit);
fprintf(fout, "SGX max enclave size (64-bit): 2^%d\n", data->x86.sgx.max_enclave_64bit);
fprintf(fout, "SGX1 extensions : %d (%s)\n", data->x86.sgx.flags[INTEL_SGX1], data->x86.sgx.flags[INTEL_SGX1] ? "present" : "absent");
fprintf(fout, "SGX2 extensions : %d (%s)\n", data->x86.sgx.flags[INTEL_SGX2], data->x86.sgx.flags[INTEL_SGX2] ? "present" : "absent");
fprintf(fout, "SGX MISCSELECT : %08x\n", data->x86.sgx.misc_select);
fprintf(fout, "SGX SECS.ATTRIBUTES mask : %016llx\n", (unsigned long long) data->x86.sgx.secs_attributes);
fprintf(fout, "SGX SECS.XSAVE feature mask : %016llx\n", (unsigned long long) data->x86.sgx.secs_xfrm);
fprintf(fout, "SGX EPC sections count : %d\n", data->x86.sgx.num_epc_sections);
for (i = 0; i < data->x86.sgx.num_epc_sections; i++) {
struct cpu_epc_t epc = cpuid_get_epc(i, raw);
fprintf(fout, " SGX EPC section #%-8d: start = %llx, size = %llu\n", i,
(unsigned long long) epc.start_addr, (unsigned long long) epc.length);
@ -728,40 +771,51 @@ int main(int argc, char** argv)
for (cpu_type_index = 0; cpu_type_index < data.num_cpu_types; cpu_type_index++) {
fprintf(fout, "CPU Info for type #%d:\n------------------\n", cpu_type_index);
fprintf(fout, " arch : %s\n", cpu_architecture_str(data.cpu_types[cpu_type_index].architecture));
fprintf(fout, " feat_level : %s\n", cpu_feature_level_str(data.cpu_types[cpu_type_index].feature_level));
fprintf(fout, " purpose : %s\n", cpu_purpose_str(data.cpu_types[cpu_type_index].purpose));
fprintf(fout, " vendor_str : `%s'\n", data.cpu_types[cpu_type_index].vendor_str);
fprintf(fout, " vendor id : %d\n", (int) data.cpu_types[cpu_type_index].vendor);
fprintf(fout, " brand_str : `%s'\n", data.cpu_types[cpu_type_index].brand_str);
fprintf(fout, " family : %d (%02Xh)\n", data.cpu_types[cpu_type_index].family, data.cpu_types[cpu_type_index].family);
fprintf(fout, " model : %d (%02Xh)\n", data.cpu_types[cpu_type_index].model, data.cpu_types[cpu_type_index].model);
fprintf(fout, " stepping : %d (%02Xh)\n", data.cpu_types[cpu_type_index].stepping, data.cpu_types[cpu_type_index].stepping);
fprintf(fout, " ext_family : %d (%02Xh)\n", data.cpu_types[cpu_type_index].ext_family, data.cpu_types[cpu_type_index].ext_family);
fprintf(fout, " ext_model : %d (%02Xh)\n", data.cpu_types[cpu_type_index].ext_model, data.cpu_types[cpu_type_index].ext_model);
if (data.cpu_types[cpu_type_index].architecture == ARCHITECTURE_X86) {
fprintf(fout, " family : %d (%02Xh)\n", data.cpu_types[cpu_type_index].x86.family, data.cpu_types[cpu_type_index].x86.family);
fprintf(fout, " model : %d (%02Xh)\n", data.cpu_types[cpu_type_index].x86.model, data.cpu_types[cpu_type_index].x86.model);
fprintf(fout, " stepping : %d (%02Xh)\n", data.cpu_types[cpu_type_index].x86.stepping, data.cpu_types[cpu_type_index].x86.stepping);
fprintf(fout, " ext_family : %d (%02Xh)\n", data.cpu_types[cpu_type_index].x86.ext_family, data.cpu_types[cpu_type_index].x86.ext_family);
fprintf(fout, " ext_model : %d (%02Xh)\n", data.cpu_types[cpu_type_index].x86.ext_model, data.cpu_types[cpu_type_index].x86.ext_model);
}
else if (data.cpu_types[cpu_type_index].architecture == ARCHITECTURE_ARM) {
fprintf(fout, " implementer: %d (%02Xh)\n", data.cpu_types[cpu_type_index].arm.implementer, data.cpu_types[cpu_type_index].arm.implementer);
fprintf(fout, " variant : %d (%02Xh)\n", data.cpu_types[cpu_type_index].arm.variant, data.cpu_types[cpu_type_index].arm.variant);
fprintf(fout, " part_num : %d (%02Xh)\n", data.cpu_types[cpu_type_index].arm.part_num, data.cpu_types[cpu_type_index].arm.part_num);
fprintf(fout, " revision : %d (%02Xh)\n", data.cpu_types[cpu_type_index].arm.revision, data.cpu_types[cpu_type_index].arm.revision);
}
fprintf(fout, " num_cores : %d\n", data.cpu_types[cpu_type_index].num_cores);
fprintf(fout, " num_logical: %d\n", data.cpu_types[cpu_type_index].num_logical_cpus);
fprintf(fout, " tot_logical: %d\n", data.cpu_types[cpu_type_index].total_logical_cpus);
fprintf(fout, " affi_mask : 0x%s\n", affinity_mask_str(&data.cpu_types[cpu_type_index].affinity_mask));
fprintf(fout, " L1 D cache : %d KB\n", data.cpu_types[cpu_type_index].l1_data_cache);
fprintf(fout, " L1 I cache : %d KB\n", data.cpu_types[cpu_type_index].l1_instruction_cache);
fprintf(fout, " L2 cache : %d KB\n", data.cpu_types[cpu_type_index].l2_cache);
fprintf(fout, " L3 cache : %d KB\n", data.cpu_types[cpu_type_index].l3_cache);
fprintf(fout, " L4 cache : %d KB\n", data.cpu_types[cpu_type_index].l4_cache);
fprintf(fout, " L1D assoc. : %d-way\n", data.cpu_types[cpu_type_index].l1_data_assoc);
fprintf(fout, " L1I assoc. : %d-way\n", data.cpu_types[cpu_type_index].l1_instruction_assoc);
fprintf(fout, " L2 assoc. : %d-way\n", data.cpu_types[cpu_type_index].l2_assoc);
fprintf(fout, " L3 assoc. : %d-way\n", data.cpu_types[cpu_type_index].l3_assoc);
fprintf(fout, " L4 assoc. : %d-way\n", data.cpu_types[cpu_type_index].l4_assoc);
fprintf(fout, " L1D line sz: %d bytes\n", data.cpu_types[cpu_type_index].l1_data_cacheline);
fprintf(fout, " L1I line sz: %d bytes\n", data.cpu_types[cpu_type_index].l1_instruction_cacheline);
fprintf(fout, " L2 line sz : %d bytes\n", data.cpu_types[cpu_type_index].l2_cacheline);
fprintf(fout, " L3 line sz : %d bytes\n", data.cpu_types[cpu_type_index].l3_cacheline);
fprintf(fout, " L4 line sz : %d bytes\n", data.cpu_types[cpu_type_index].l4_cacheline);
fprintf(fout, " L1D inst. : %d\n", data.cpu_types[cpu_type_index].l1_data_instances);
fprintf(fout, " L1I inst. : %d\n", data.cpu_types[cpu_type_index].l1_instruction_instances);
fprintf(fout, " L2 inst. : %d\n", data.cpu_types[cpu_type_index].l2_instances);
fprintf(fout, " L3 inst. : %d\n", data.cpu_types[cpu_type_index].l3_instances);
fprintf(fout, " L4 inst. : %d\n", data.cpu_types[cpu_type_index].l4_instances);
fprintf(fout, " SSE units : %d bits (%s)\n", data.cpu_types[cpu_type_index].sse_size, data.cpu_types[cpu_type_index].detection_hints[CPU_HINT_SSE_SIZE_AUTH] ? "authoritative" : "non-authoritative");
if (data.cpu_types[cpu_type_index].architecture == ARCHITECTURE_X86) {
fprintf(fout, " L1 D cache : %d KB\n", data.cpu_types[cpu_type_index].l1_data_cache);
fprintf(fout, " L1 I cache : %d KB\n", data.cpu_types[cpu_type_index].l1_instruction_cache);
fprintf(fout, " L2 cache : %d KB\n", data.cpu_types[cpu_type_index].l2_cache);
fprintf(fout, " L3 cache : %d KB\n", data.cpu_types[cpu_type_index].l3_cache);
fprintf(fout, " L4 cache : %d KB\n", data.cpu_types[cpu_type_index].l4_cache);
fprintf(fout, " L1D assoc. : %d-way\n", data.cpu_types[cpu_type_index].l1_data_assoc);
fprintf(fout, " L1I assoc. : %d-way\n", data.cpu_types[cpu_type_index].l1_instruction_assoc);
fprintf(fout, " L2 assoc. : %d-way\n", data.cpu_types[cpu_type_index].l2_assoc);
fprintf(fout, " L3 assoc. : %d-way\n", data.cpu_types[cpu_type_index].l3_assoc);
fprintf(fout, " L4 assoc. : %d-way\n", data.cpu_types[cpu_type_index].l4_assoc);
fprintf(fout, " L1D line sz: %d bytes\n", data.cpu_types[cpu_type_index].l1_data_cacheline);
fprintf(fout, " L1I line sz: %d bytes\n", data.cpu_types[cpu_type_index].l1_instruction_cacheline);
fprintf(fout, " L2 line sz : %d bytes\n", data.cpu_types[cpu_type_index].l2_cacheline);
fprintf(fout, " L3 line sz : %d bytes\n", data.cpu_types[cpu_type_index].l3_cacheline);
fprintf(fout, " L4 line sz : %d bytes\n", data.cpu_types[cpu_type_index].l4_cacheline);
fprintf(fout, " L1D inst. : %d\n", data.cpu_types[cpu_type_index].l1_data_instances);
fprintf(fout, " L1I inst. : %d\n", data.cpu_types[cpu_type_index].l1_instruction_instances);
fprintf(fout, " L2 inst. : %d\n", data.cpu_types[cpu_type_index].l2_instances);
fprintf(fout, " L3 inst. : %d\n", data.cpu_types[cpu_type_index].l3_instances);
fprintf(fout, " L4 inst. : %d\n", data.cpu_types[cpu_type_index].l4_instances);
fprintf(fout, " SSE units : %d bits (%s)\n", data.cpu_types[cpu_type_index].x86.sse_size, data.cpu_types[cpu_type_index].detection_hints[CPU_HINT_SSE_SIZE_AUTH] ? "authoritative" : "non-authoritative");
}
fprintf(fout, " code name : `%s'\n", data.cpu_types[cpu_type_index].cpu_codename);
fprintf(fout, " features :");
/*

View file

@ -1,6 +1,7 @@
set(cpuid_sources
cpuid_main.c
recog_amd.c
recog_arm.c
recog_centaur.c
recog_intel.c
rdtsc.c

View file

@ -9,6 +9,7 @@ libcpuid_la_LDFLAGS = \
libcpuid_la_SOURCES = \
cpuid_main.c \
recog_amd.c \
recog_arm.c \
recog_centaur.c \
recog_intel.c \
rdtsc.c \
@ -37,6 +38,7 @@ noinst_HEADERS = \
libcpuid_internal.h \
libcpuid_util.h \
recog_amd.h \
recog_arm.h \
recog_centaur.h \
recog_intel.h \
rdtsc.h

View file

@ -6,7 +6,7 @@ ASM = ml64 /nologo
CC = cl.exe /nologo /TC
OPTFLAGS = /MT
DEFINES = /D "VERSION=\"0.6.5\""
OBJECTS = masm-x64.obj asm-bits.obj cpuid_main.obj libcpuid_util.obj recog_amd.obj recog_centaur.obj recog_intel.obj rdtsc.obj
OBJECTS = masm-x64.obj asm-bits.obj cpuid_main.obj libcpuid_util.obj recog_amd.obj recog_arm.obj recog_centaur.obj recog_intel.obj rdtsc.obj
libcpuid.lib: $(OBJECTS)
lib /nologo /MACHINE:AMD64 /out:libcpuid.lib $(OBJECTS) bufferoverflowU.lib
@ -26,6 +26,9 @@ libcpuid_util.obj: libcpuid_util.c
recog_amd.obj: recog_amd.c
$(CC) $(OPTFLAGS) $(DEFINES) /c recog_amd.c
recog_arm.obj: recog_arm.c
$(CC) $(OPTFLAGS) $(DEFINES) /c recog_arm.c
recog_centaur.obj: recog_centaur.c
$(CC) $(OPTFLAGS) $(DEFINES) /c recog_centaur.c

View file

@ -13,7 +13,7 @@ all: libcpuid.lib
CC = cl.exe /nologo /TC
OPTFLAGS = /MT
DEFINES = /D "VERSION=\"0.6.5\""
OBJECTS = asm-bits.obj cpuid_main.obj libcpuid_util.obj recog_amd.obj recog_centaur.obj recog_intel.obj rdtsc.obj
OBJECTS = asm-bits.obj cpuid_main.obj libcpuid_util.obj recog_amd.obj recog_arm.obj recog_centaur.obj recog_intel.obj rdtsc.obj
libcpuid.lib: $(OBJECTS)
lib /nologo /out:libcpuid.lib $(OBJECTS)
@ -30,6 +30,9 @@ libcpuid_util.obj: libcpuid_util.c
recog_amd.obj: recog_amd.c
$(CC) $(OPTFLAGS) $(DEFINES) /c recog_amd.c
recog_arm.obj: recog_arm.c
$(CC) $(OPTFLAGS) $(DEFINES) /c recog_arm.c
recog_centaur.obj: recog_centaur.c
$(CC) $(OPTFLAGS) $(DEFINES) /c recog_centaur.c

View file

@ -25,6 +25,7 @@
*/
#include "libcpuid.h"
#include "libcpuid_util.h"
#include "asm-bits.h"
int cpuid_exists_by_eflags(void)
@ -135,6 +136,8 @@ void exec_cpuid(uint32_t *regs)
:"m"(regs)
:"memory", "eax", "edi"
);
# else
UNUSED(regs);
# endif /* COMPILER_GCC */
#else
# ifdef COMPILER_MICROSOFT
@ -167,7 +170,7 @@ void exec_cpuid(uint32_t *regs)
# endif /* COMPILER_MICROSOFT */
#endif
}
#endif /* INLINE_ASSEMBLY_SUPPORTED */
#endif /* INLINE_ASM_SUPPORTED */
#ifdef INLINE_ASM_SUPPORTED
void cpu_rdtsc(uint64_t* result)
@ -516,6 +519,8 @@ void busy_sse_loop(int cycles)
" jnz 1b\n"
::"a"(cycles)
);
#else
UNUSED(cycles);
#endif
#else
# ifdef COMPILER_MICROSOFT
@ -829,4 +834,4 @@ bsLoop:
# endif /* COMPILER_MICROSOFT */
#endif /* COMPILER_GCC */
}
#endif /* INLINE_ASSEMBLY_SUPPORTED */
#endif /* INLINE_ASM_SUPPORTED */

View file

@ -51,13 +51,32 @@
#if !defined(PLATFORM_X86)
# define PLATFORM_X86
#endif
#elif defined(__ARMEL__)
#elif defined(__arm__)
#if !defined(PLATFORM_ARM)
# define PLATFORM_ARM
#endif
#elif defined(__aarch64__)
#if !defined(PLATFORM_ARM)
#if !defined(PLATFORM_AARCH64)
# define PLATFORM_AARCH64
/*
* Older assemblers don't recognize newer system register names,
* but we can still access them by the Sn_n_Cn_Cn_n syntax.
*/
# define SYS_ID_AA64PFR0_EL1 "S3_0_C0_C4_0"
# define SYS_ID_AA64PFR1_EL1 "S3_0_C0_C4_1"
# define SYS_ID_AA64PFR2_EL1 "S3_0_C0_C4_2"
# define SYS_ID_AA64ZFR0_EL1 "S3_0_C0_C4_4"
# define SYS_ID_AA64SMFR0_EL1 "S3_0_C0_C4_5"
# define SYS_ID_AA64DFR0_EL1 "S3_0_C0_C5_0"
# define SYS_ID_AA64DFR1_EL1 "S3_0_C0_C5_1"
# define SYS_ID_AA64ISAR0_EL1 "S3_0_C0_C6_0"
# define SYS_ID_AA64ISAR1_EL1 "S3_0_C0_C6_1"
# define SYS_ID_AA64ISAR2_EL1 "S3_0_C0_C6_2"
# define SYS_ID_AA64MMFR0_EL1 "S3_0_C0_C7_0"
# define SYS_ID_AA64MMFR1_EL1 "S3_0_C0_C7_1"
# define SYS_ID_AA64MMFR2_EL1 "S3_0_C0_C7_2"
# define SYS_ID_AA64MMFR3_EL1 "S3_0_C0_C7_3"
# define SYS_ID_AA64MMFR4_EL1 "S3_0_C0_C7_4"
#endif
#endif
@ -67,6 +86,16 @@
# define INLINE_ASM_SUPPORTED
#endif
#ifdef INLINE_ASM_SUPPORTED
# if defined(COMPILER_GCC) || defined(COMPILER_CLANG)
# define cpu_exec_mrs(reg_name, reg_value) __asm __volatile("mrs %0, " reg_name : "=r" (reg_value))
# elif defined(COMPILER_MICROSOFT)
# define cpu_exec_mrs(reg_name, reg_value) __asm { mrs reg_value, reg_name }
# else
# error "Unsupported compiler"
# endif /* COMPILER */
#endif /* INLINE_ASM_SUPPORTED */
int cpuid_exists_by_eflags(void);
void exec_cpuid(uint32_t *regs);
void busy_sse_loop(int cycles);

View file

@ -108,18 +108,30 @@ firstError = True
files_code = {}
rexp = re.compile('\t+{ *[0-9]+, (CPU_FEATURE_[^ }]+).*')
rexp1 = re.compile(r'.*flags\[(CPU_FEATURE_[^\]]+)\]\s*=\s*1.*') # e.g. "data->flags[CPU_FEATURE_MPAM] = 1;"
rexp2 = re.compile(r'.*(CPU_FEATURE_[^ ,]+)\s*,\s*FEATURE_LEVEL_ARM_.*') # e.g. "{ 35, 32, 0b0101, CPU_FEATURE_SPEV1P4, FEATURE_LEVEL_ARM_V8_8_A, -1 },"
rexp3 = re.compile(r'.*(CPU_FEATURE_[^ }]+).*') # e.g. "{ 28, CPU_FEATURE_HT },"
for fn in glob.glob("%s/*.c" % sys.argv[1]):
f = open(fn, "rt")
files_code[fn] = []
for s in f.readlines():
if rexp.match(s):
entry = rexp.findall(s)[0]
if rexp1.match(s):
entry = rexp1.findall(s)[0]
files_code[fn].append(entry)
elif rexp2.match(s):
entry = rexp2.findall(s)[0]
files_code[fn].append(entry)
elif rexp3.match(s):
entry = rexp3.findall(s)[0]
files_code[fn].append(entry)
f.close()
features_whitelist = ["CPU_FEATURE_SSE5"]
features_whitelist = [
"CPU_FEATURE_SSE5", # deprecated, never defined
"CPU_FEATURE_AES", # defined twice (x86 + ARM)
]
for feature in allf:
matching_files = []
for fn in files_code:
@ -131,7 +143,7 @@ for feature in allf:
firstError = False
err += 1
print("..No detection code for %s" % feature)
if len(matching_files) > 1:
if len(matching_files) > 1 and feature not in features_whitelist:
if firstError:
print("FAILED:")
firstError = False
@ -143,7 +155,7 @@ if firstError:
print("")
print("Checking processor definitions:")
cache_exp = re.compile(".*([\(/ ][0-9]+K).*")
cache_exp = re.compile(r".*([\(/ ][0-9]+K).*")
# Check whether CPU codenames for consistency:
# - Codenames should not exceed 31 characters
# - Check for common typos

File diff suppressed because it is too large Load diff

View file

@ -46,3 +46,4 @@ cpuid_free_system_id @42
affinity_mask_str_r @43
cpuid_get_hypervisor @44
cpu_clock_by_tsc @45
cpu_feature_level_str @46

View file

@ -113,6 +113,10 @@ SOURCE=.\recog_amd.c
# End Source File
# Begin Source File
SOURCE=.\recog_arm.c
# End Source File
# Begin Source File
SOURCE=.\recog_intel.c
# End Source File
# Begin Source File
@ -153,6 +157,10 @@ SOURCE=.\recog_amd.h
# End Source File
# Begin Source File
SOURCE=.\recog_arm.h
# End Source File
# Begin Source File
SOURCE=.\recog_centaur.h
# End Source File
# Begin Source File

View file

@ -116,6 +116,21 @@
/* Some limits and other constants */
#include "libcpuid_constants.h"
#ifndef LIBCPUID_DEPRECATED
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
# define LIBCPUID_DEPRECATED(message) [[deprecated(message)]]
# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__)
# define LIBCPUID_DEPRECATED(message) __attribute__((deprecated(message)))
# elif defined(__GNUC__) && (__GNUC__ >= 3)
# define LIBCPUID_DEPRECATED(message) __attribute__((deprecated))
# elif defined(_MSC_VER)
# define LIBCPUID_DEPRECATED(message) __declspec(deprecated(message))
# else
# pragma message("WARNING: You need to implement LIBCPUID_DEPRECATED for this compiler")
# define LIBCPUID_DEPRECATED(message)
# endif
#endif /* LIBCPUID_DEPRECATED */
#ifdef __cplusplus
extern "C" {
#endif
@ -135,6 +150,24 @@ typedef enum {
VENDOR_SIS, /*!< x86 CPU by SiS */
VENDOR_NSC, /*!< x86 CPU by National Semiconductor */
VENDOR_HYGON, /*!< Hygon CPU */
VENDOR_ARM, /*!< ARM CPU */
VENDOR_BROADCOM, /*!< Broadcom Corporation CPU */
VENDOR_CAVIUM, /*!< Cavium Inc. CPU */
VENDOR_DEC, /*!< Digital Equipment Corporation CPU */
VENDOR_FUJITSU, /*!< Fujitsu Ltd. CPU */
VENDOR_HISILICON, /*!< HiSilicon Technology Co., Ltd. CPU */
VENDOR_INFINEON, /*!< Infineon Technologies AG CPU */
VENDOR_FREESCALE, /*!< Motorola or Freescale Semiconductor Inc. CPU */
VENDOR_NVIDIA, /*!< NVIDIA Corporation CPU */
VENDOR_APM, /*!< Applied Micro Circuits Corporation CPU */
VENDOR_QUALCOMM, /*!< Qualcomm Inc. CPU */
VENDOR_SAMSUNG, /*!< Samsung Group CPU */
VENDOR_MARVELL, /*!< Marvell International Ltd. CPU */
VENDOR_APPLE, /*!< Apple Inc. CPU */
VENDOR_FARADAY, /*!< Faraday Technology CPU */
VENDOR_MICROSOFT, /*!< Microsoft Corporation CPU */
VENDOR_PHYTIUM, /*!< Phytium Technology Co., Ltd CPU */
VENDOR_AMPERE, /*!< Ampere Computing CPU */
NUM_CPU_VENDORS, /*!< Valid CPU vendor ids: 0..NUM_CPU_VENDORS - 1 */
VENDOR_UNKNOWN = -1,
@ -153,6 +186,50 @@ typedef enum {
} cpu_architecture_t;
#define NUM_CPU_ARCHITECTURES NUM_CPU_ARCHITECTURES
/**
* @brief CPU architecture
*/
typedef enum {
/* TODO: add x86 levels */
FEATURE_LEVEL_ARM_V1 = 100, /*!< ARMv1 */
FEATURE_LEVEL_ARM_V2, /*!< ARMv2 */
FEATURE_LEVEL_ARM_V3, /*!< ARMv3 */
FEATURE_LEVEL_ARM_V4, /*!< ARMv4 */
FEATURE_LEVEL_ARM_V4T, /*!< ARMv4T */
FEATURE_LEVEL_ARM_V5, /*!< ARMv5 (obsolete) */
FEATURE_LEVEL_ARM_V5T, /*!< ARMv5T */
FEATURE_LEVEL_ARM_V5TE, /*!< ARMv5TE */
FEATURE_LEVEL_ARM_V5TEJ, /*!< ARMv5TEJ */
FEATURE_LEVEL_ARM_V6, /*!< ARMv6 */
FEATURE_LEVEL_ARM_V6_M, /*!< ARMv6-M */
FEATURE_LEVEL_ARM_V7_A, /*!< ARMv7-A */
FEATURE_LEVEL_ARM_V7_M, /*!< ARMv7-M */
FEATURE_LEVEL_ARM_V7_R, /*!< ARMv7-R */
FEATURE_LEVEL_ARM_V7E_M, /*!< ARMv7E-M */
FEATURE_LEVEL_ARM_V8_0_A, /*!< ARMv8.0-A */
FEATURE_LEVEL_ARM_V8_0_M, /*!< ARMv8.0-M */
FEATURE_LEVEL_ARM_V8_0_R, /*!< ARMv8.0-R */
FEATURE_LEVEL_ARM_V8_1_A, /*!< ARMv8.1-A */
FEATURE_LEVEL_ARM_V8_1_M, /*!< ARMv8.1-M */
FEATURE_LEVEL_ARM_V8_2_A, /*!< ARMv8.2-A */
FEATURE_LEVEL_ARM_V8_3_A, /*!< ARMv8.3-A */
FEATURE_LEVEL_ARM_V8_4_A, /*!< ARMv8.4-A */
FEATURE_LEVEL_ARM_V8_5_A, /*!< ARMv8.5-A */
FEATURE_LEVEL_ARM_V8_6_A, /*!< ARMv8.6-A */
FEATURE_LEVEL_ARM_V8_7_A, /*!< ARMv8.7-A */
FEATURE_LEVEL_ARM_V8_8_A, /*!< ARMv8.8-A */
FEATURE_LEVEL_ARM_V8_9_A, /*!< ARMv8.9-A */
FEATURE_LEVEL_ARM_V9_0_A, /*!< ARMv9.0-A */
FEATURE_LEVEL_ARM_V9_1_A, /*!< ARMv9.1-A */
FEATURE_LEVEL_ARM_V9_2_A, /*!< ARMv9.2-A */
FEATURE_LEVEL_ARM_V9_3_A, /*!< ARMv9.3-A */
FEATURE_LEVEL_ARM_V9_4_A, /*!< ARMv9.4-A */
NUM_CPU_FEATURE_LEVELS, /*!< Valid feature level ids: 0..NUM_CPU_FEATURE_LEVELS - 1 */
FEATURE_LEVEL_UNKNOWN = -1,
} cpu_feature_level_t;
#define NUM_CPU_FEATURE_LEVELS NUM_CPU_FEATURE_LEVELS
/**
* @brief CPU purpose
*/
@ -161,6 +238,7 @@ typedef enum {
PURPOSE_PERFORMANCE, /*!< performance CPU */
PURPOSE_EFFICIENCY, /*!< efficiency CPU */
PURPOSE_LP_EFFICIENCY, /*!< low-power efficiency CPU */
PURPOSE_U_PERFORMANCE, /*!< ultimate performance CPU */
NUM_CPU_PURPOSES, /*!< Valid CPU purpose ids: 0..NUM_CPU_PURPOSES - 1 */
} cpu_purpose_t;
@ -224,6 +302,42 @@ struct cpu_raw_data_t {
* this stores the result of CPUID with eax = 8000001Dh and
* ecx = 0, 1, 2... */
uint32_t amd_fn8000001dh[MAX_AMDFN8000001DH_LEVEL][NUM_REGS];
/** when then CPU is ARM-based and supports MIDR
* (Main ID Register) */
uint64_t arm_midr;
/** when then CPU is ARM-based and supports MPIDR
* (Multiprocessor Affinity Register) */
uint64_t arm_mpidr;
/** when then CPU is ARM-based and supports REVIDR
* (Revision ID Register) */
uint64_t arm_revidr;
/** when then CPU is ARM-based and supports ID_AA64DFR*
* (AArch64 Debug Feature Register) */
uint64_t arm_id_aa64dfr[MAX_ARM_ID_AA64DFR_REGS];
/** when then CPU is ARM-based and supports D_AA64ISAR*
* (AArch64 Instruction Set Attribute Register) */
uint64_t arm_id_aa64isar[MAX_ARM_ID_AA64ISAR_REGS];
/** when then CPU is ARM-based and supports ID_AA64MMFR*
* (AArch64 Memory Model Feature Register) */
uint64_t arm_id_aa64mmfr[MAX_ARM_ID_AA64MMFR_REGS];
/** when then CPU is ARM-based and supports ID_AA64PFR*
* (AArch64 Processor Feature Register) */
uint64_t arm_id_aa64pfr[MAX_ARM_ID_AA64PFR_REGS];
/** when then CPU is ARM-based and supports ID_AA64SMFR*
* (AArch64 SME Feature ID Register ) */
uint64_t arm_id_aa64smfr[MAX_ARM_ID_AA64SMFR_REGS];
/** when then CPU is ARM-based and supports ID_AA64ZFR*
* (SVE Feature ID register) */
uint64_t arm_id_aa64zfr[MAX_ARM_ID_AA64ZFR_REGS];
};
/**
@ -314,28 +428,11 @@ struct cpu_sgx_t {
};
/**
* @brief This contains the recognized CPU features/info
* @brief Contains x86 specific info.
*
* @note This is part of \ref cpu_id_t.
*/
struct cpu_id_t {
/** contains the CPU architecture ID (e.g. ARCHITECTURE_X86) */
cpu_architecture_t architecture;
/** contains the CPU vendor string, e.g. "GenuineIntel" */
char vendor_str[VENDOR_STR_MAX];
/** contains the brand string, e.g. "Intel(R) Xeon(TM) CPU 2.40GHz" */
char brand_str[BRAND_STR_MAX];
/** contains the recognized CPU vendor */
cpu_vendor_t vendor;
/**
* contain CPU flags. Used to test for features. See
* the \ref cpu_feature_t "CPU_FEATURE_*" macros below.
* @see Features
*/
uint8_t flags[CPU_FLAGS_MAX];
struct x86_id_t {
/** CPU family (BaseFamily[3:0]) */
int32_t family;
@ -354,6 +451,107 @@ struct cpu_id_t {
*/
int32_t ext_model;
/** SSE execution unit size (64 or 128; -1 if N/A) */
int32_t sse_size;
/** contains information about SGX features if the processor, if present */
struct cpu_sgx_t sgx;
};
/**
* @brief Contains ARM specific info.
*
* @note This is part of \ref cpu_id_t.
*/
struct arm_id_t {
/** CPU implementer code */
uint8_t implementer;
/** CPU variant number */
uint8_t variant;
/** CPU primary part number */
uint16_t part_num;
/** CPU revision number */
uint8_t revision;
};
/**
* @brief This contains the recognized CPU features/info
*/
struct cpu_id_t {
/** contains the CPU architecture ID (e.g. ARCHITECTURE_X86) */
cpu_architecture_t architecture;
/**
* contains the CPU feature level,
* also know as microarchitecture levels (x86)
* and architecture version (ARM)
*/
cpu_feature_level_t feature_level;
/** contains the CPU vendor string, e.g. "GenuineIntel" */
char vendor_str[VENDOR_STR_MAX];
/** contains the brand string, e.g. "Intel(R) Xeon(TM) CPU 2.40GHz" */
char brand_str[BRAND_STR_MAX];
/** contains the recognized CPU vendor */
cpu_vendor_t vendor;
/**
* contain CPU flags. Used to test for features. See
* the \ref cpu_feature_t "CPU_FEATURE_*" macros below.
* @see Features
*/
uint8_t flags[CPU_FLAGS_MAX];
/**
* CPU family (BaseFamily[3:0])
* @deprecated replaced by \ref x86_id_t::family (prefix member with `x86.`, e.g. `id.x86.family`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.family' in your code to fix the warning")
int32_t family;
/**
* CPU model (BaseModel[3:0])
* @deprecated replaced by \ref x86_id_t::model (prefix member with `x86.`, e.g. `id.x86.model`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.model' in your code to fix the warning")
int32_t model;
/**
* CPU stepping
* @deprecated replaced by \ref x86_id_t::stepping (prefix member with `x86.`, e.g. `id.x86.stepping`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.stepping' in your code to fix the warning")
int32_t stepping;
/**
* CPU display ("true") family (computed as BaseFamily[3:0]+ExtendedFamily[7:0])
* @deprecated replaced by \ref x86_id_t::ext_family (prefix member with `x86.`, e.g. `id.x86.ext_family`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.ext_family' in your code to fix the warning")
int32_t ext_family;
/**
* CPU display ("true") model (computed as (ExtendedModel[3:0]<<4) + BaseModel[3:0])
* For detailed discussion about what BaseModel / ExtendedModel / Model are, see Github issue #150.
* @deprecated replaced by \ref x86_id_t::ext_model (prefix member with `x86.`, e.g. `id.x86.ext_model`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.ext_model' in your code to fix the warning")
int32_t ext_model;
/**
* contains architecture specific info.
* Use \ref cpu_id_t::architecture to know which member is valid.
*/
union {
struct x86_id_t x86;
struct arm_id_t arm;
};
/** Number of CPU cores on the current processor */
int32_t num_cores;
@ -409,6 +607,7 @@ struct cpu_id_t {
/** Cache associativity for the L1 data cache. -1 if undetermined
* @deprecated replaced by \ref cpu_id_t::l1_data_assoc
*/
LIBCPUID_DEPRECATED("replace with 'l1_data_assoc' in your code to fix the warning")
int32_t l1_assoc;
/** Cache associativity for the L1 data cache. -1 if undetermined */
@ -429,6 +628,7 @@ struct cpu_id_t {
/** Cache-line size for L1 data cache. -1 if undetermined
* @deprecated replaced by \ref cpu_id_t::l1_data_cacheline
*/
LIBCPUID_DEPRECATED("replace with 'l1_data_cacheline' in your code to fix the warning")
int32_t l1_cacheline;
/** Cache-line size for L1 data cache. -1 if undetermined */
@ -477,7 +677,11 @@ struct cpu_id_t {
*/
char cpu_codename[CODENAME_STR_MAX];
/** SSE execution unit size (64 or 128; -1 if N/A) */
/**
* SSE execution unit size (64 or 128; -1 if N/A)
* @deprecated replaced by \ref x86_id_t::sse_size (prefix member with `x86.`, e.g. `id.x86.sse_size`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.sse_size' in your code to fix the warning")
int32_t sse_size;
/**
@ -487,7 +691,11 @@ struct cpu_id_t {
*/
uint8_t detection_hints[CPU_HINTS_MAX];
/** contains information about SGX features if the processor, if present */
/**
* contains information about SGX features if the processor, if present
* @deprecated replaced by \ref x86_id_t::sgx (prefix member with `x86.`, e.g. `id.x86.sgx`)
*/
LIBCPUID_DEPRECATED("replace with '.x86.sgx' in your code to fix the warning")
struct cpu_sgx_t sgx;
/** bitmask of the affinity ids this processor type is occupying */
@ -658,6 +866,210 @@ typedef enum {
CPU_FEATURE_AVX512VBMI, /*!< AVX-512 Vector Bit ManipulationInstructions (version 1) */
CPU_FEATURE_AVX512VBMI2, /*!< AVX-512 Vector Bit ManipulationInstructions (version 2) */
CPU_FEATURE_HYPERVISOR, /*!< Hypervisor present (always zero on physical CPUs) */
CPU_FEATURE_ASID16, /*!< ARM: 16 bit ASID */
CPU_FEATURE_ADVSIMD, /*!< ARM: Advanced SIMD Extension */
CPU_FEATURE_CRC32, /*!< ARM: CRC32 instructions */
CPU_FEATURE_CSV2_1P1, /*!< ARM: Cache Speculation Variant 2 */
CPU_FEATURE_CSV2_1P2, /*!< ARM: Cache Speculation Variant 2 version 1.2 */
CPU_FEATURE_CSV2_2, /*!< ARM: Cache Speculation Variant 2 version 2 */
CPU_FEATURE_CSV2_3, /*!< ARM: Cache Speculation Variant 2 version 3 */
CPU_FEATURE_DOUBLELOCK, /*!< ARM: Double Lock */
CPU_FEATURE_ETS2, /*!< ARM: Enhanced Translation Synchronization */
CPU_FEATURE_FP, /*!< ARM: Floating Point extensions */
CPU_FEATURE_MIXEDEND, /*!< ARM: Mixed-endian support */
CPU_FEATURE_MIXEDENDEL0, /*!< ARM: Mixed-endian support at EL0 */
CPU_FEATURE_PMULL, /*!< ARM: Advanced SIMD PMULL instructions */
CPU_FEATURE_PMUV3, /*!< ARM: PMU extension version 3 */
CPU_FEATURE_SHA1, /*!< ARM: Advanced SIMD SHA1 instructions */
CPU_FEATURE_SHA256, /*!< ARM: Advanced SIMD SHA256 instructions */
CPU_FEATURE_HAFDBS, /*!< ARM: Hardware management of the Access flag and dirty state */
CPU_FEATURE_HPDS, /*!< ARM: Hierarchical permission disables in translations tables */
CPU_FEATURE_LOR, /*!< ARM: Limited ordering regions */
CPU_FEATURE_LSE, /*!< ARM: Large System Extensions */
CPU_FEATURE_PAN, /*!< ARM: Privileged access never */
CPU_FEATURE_PMUV3P1, /*!< ARM: Armv8.1 PMU extensions */
CPU_FEATURE_RDM, /*!< ARM: Advanced SIMD rounding double multiply accumulate instructions */
CPU_FEATURE_VHE, /*!< ARM: Virtualization Host Extensions */
CPU_FEATURE_VMID16, /*!< ARM: 16-bit VMID */
//CPU_FEATURE_AA32HPD, /*!< ARM: AArch32 Hierarchical permission disables */
//CPU_FEATURE_AA32I8MM, /*!< ARM: AArch32 Int8 matrix multiplication instructions */
CPU_FEATURE_DPB, /*!< ARM: DC CVAP instruction */
CPU_FEATURE_DEBUGV8P2, /*!< ARM: Debug v8.2 */
CPU_FEATURE_F32MM, /*!< ARM: Single-precision Matrix Multiplication */
CPU_FEATURE_F64MM, /*!< ARM: Double-precision Matrix Multiplication */
CPU_FEATURE_FP16, /*!< ARM: Half-precision floating-point data processing */
CPU_FEATURE_HPDS2, /*!< ARM: Hierarchical permission disables */
CPU_FEATURE_I8MM, /*!< ARM: AArch64 Int8 matrix multiplication instructions */
CPU_FEATURE_IESB, /*!< ARM: Implicit Error Synchronization event */
CPU_FEATURE_LPA, /*!< ARM: Large PA and IPA support */
CPU_FEATURE_LSMAOC, /*!< ARM: AArch32 Load/Store Multiple instruction atomicity and ordering controls */
CPU_FEATURE_LVA, /*!< ARM: Large VA support */
CPU_FEATURE_PAN2, /*!< ARM: AT S1E1R and AT S1E1W instruction variants affected by PSTATE.PAN */
CPU_FEATURE_RAS, /*!< ARM: Reliability, Availability and Serviceability (RAS) Extension */
CPU_FEATURE_SHA3, /*!< ARM: Advanced SIMD SHA3 instructions (ARMv8.2 architecture extension) */
CPU_FEATURE_SHA512, /*!< ARM: Advanced SIMD SHA512 instructions (ARMv8.1 architecture extension) */
CPU_FEATURE_SM3, /*!< ARM: Advanced SIMD SM3 instructions */
CPU_FEATURE_SM4, /*!< ARM: Advanced SIMD SM4 instructions */
CPU_FEATURE_SPE, /*!< ARM: Statistical Profiling Extension */
CPU_FEATURE_SVE, /*!< ARM: Scalable Vector Extension */
CPU_FEATURE_TTCNP, /*!< ARM: Translation table Common not private translations */
CPU_FEATURE_UAO, /*!< ARM: Unprivileged Access Override control */
CPU_FEATURE_XNX, /*!< ARM: Translation table stage 2 Unprivileged Execute-never */
CPU_FEATURE_CCIDX, /*!< ARM: Extended cache index */
CPU_FEATURE_CONSTPACFIELD, /*!< ARM: PAC algorithm enhancement */
CPU_FEATURE_EPAC, /*!< ARM: Enhanced pointer authentication */
CPU_FEATURE_FCMA, /*!< ARM: Floating-point complex number instructions */
CPU_FEATURE_FPAC, /*!< ARM: Faulting on AUT* instructions */
CPU_FEATURE_FPACCOMBINE, /*!< ARM: Faulting on combined pointer authentication instructions */
CPU_FEATURE_JSCVT, /*!< ARM: JavaScript conversion instructions */
CPU_FEATURE_LRCPC, /*!< ARM: Load-Acquire RCpc instructions */
CPU_FEATURE_PACIMP, /*!< ARM: Pointer authentication - IMPLEMENTATION DEFINED algorithm */
CPU_FEATURE_PACQARMA3, /*!< ARM: Pointer authentication - QARMA3 algorithm */
CPU_FEATURE_PACQARMA5, /*!< ARM: Pointer authentication - QARMA5 algorithm */
CPU_FEATURE_PAUTH, /*!< ARM: Pointer authentication */
CPU_FEATURE_SPEV1P1, /*!< ARM: Statistical Profiling Extension version 1 */
CPU_FEATURE_AMUV1, /*!< ARM: Activity Monitors Extension version 1 */
CPU_FEATURE_BBM, /*!< ARM: Translation table break-before-make levels */
CPU_FEATURE_DIT, /*!< ARM: Data Independent Timing instructions */
CPU_FEATURE_DEBUGV8P4, /*!< ARM: Debug v8.4 */
CPU_FEATURE_DOTPROD, /*!< ARM: Advanced SIMD dot product instructions */
CPU_FEATURE_DOUBLEFAULT, /*!< ARM: Double Fault Extension */
CPU_FEATURE_FHM, /*!< ARM: Floating-point half-precision to single-precision multiply-add instructions */
CPU_FEATURE_FLAGM, /*!< ARM: Condition flag manipulation instructions */
CPU_FEATURE_IDST, /*!< ARM: ID space trap handling */
CPU_FEATURE_LRCPC2, /*!< ARM: Load-Acquire RCpc instructions version 2 */
CPU_FEATURE_LSE2, /*!< ARM: Large System Extensions version 2 */
CPU_FEATURE_MPAM, /*!< ARM: Memory Partitioning and Monitoring Extension */
CPU_FEATURE_PMUV3P4, /*!< ARM: Arm8.4 PMU extensions */
CPU_FEATURE_RASV1P1, /*!< ARM: RAS extension v1.1 */
CPU_FEATURE_S2FWB, /*!< ARM: Stage 2 forced Write-Back */
CPU_FEATURE_SEL2, /*!< ARM: Secure EL2 */
CPU_FEATURE_TLBIOS, /*!< ARM: TLB invalidate instructions in Outer Shareable domain */
CPU_FEATURE_TLBIRANGE, /*!< ARM: TLB invalidate range instructions */
CPU_FEATURE_TRF, /*!< ARM: Self-hosted Trace extensions */
CPU_FEATURE_TTL, /*!< ARM: Translation Table Level */
CPU_FEATURE_TTST, /*!< ARM: Small translation tables */
CPU_FEATURE_BTI, /*!< ARM: Branch Target Identification */
CPU_FEATURE_CSV2, /*!< ARM: Cache Speculation Variant 2 */
CPU_FEATURE_CSV3, /*!< ARM: Cache Speculation Variant 3 */
CPU_FEATURE_DPB2, /*!< ARM: DC CVADP instruction */
CPU_FEATURE_E0PD, /*!< ARM: Preventing EL0 access to halves of address maps */
CPU_FEATURE_EVT, /*!< ARM: Enhanced Virtualization Traps */
CPU_FEATURE_EXS, /*!< ARM: Context synchronization and exception handling */
CPU_FEATURE_FRINTTS, /*!< ARM: Floating-point to integer instructions */
CPU_FEATURE_FLAGM2, /*!< ARM: Enhancements to flag manipulation instructions */
CPU_FEATURE_MTE, /*!< ARM: Memory Tagging Extension */
CPU_FEATURE_MTE2, /*!< ARM: Memory Tagging Extension */
CPU_FEATURE_PMUV3P5, /*!< ARM: Arm8.5 PMU extensions */
CPU_FEATURE_RNG, /*!< ARM: Random number generator */
CPU_FEATURE_RNG_TRAP, /*!< ARM: Trapping support for RNDR/RNDRRS */
CPU_FEATURE_SB, /*!< ARM: Speculation Barrier */
CPU_FEATURE_SPECRES, /*!< ARM: Speculation restriction instructions */
CPU_FEATURE_SSBS, /*!< ARM: Speculative Store Bypass Safe */
CPU_FEATURE_SSBS2, /*!< ARM: MRS and MSR instructions for SSBS version 2 */
CPU_FEATURE_AMUV1P1, /*!< ARM: Activity Monitors Extension version 1.1 */
CPU_FEATURE_BF16, /*!< ARM: AArch64 BFloat16 instructions */
CPU_FEATURE_DGH, /*!< ARM: Data Gathering Hint */
CPU_FEATURE_ECV, /*!< ARM: Enhanced Counter Virtualization */
CPU_FEATURE_FGT, /*!< ARM: Fine Grain Traps */
CPU_FEATURE_MPAMV0P1, /*!< ARM: Memory Partitioning and Monitoring version 0.1 */
CPU_FEATURE_MPAMV1P1, /*!< ARM: Memory Partitioning and Monitoring version 1.1 */
CPU_FEATURE_MTPMU, /*!< ARM: Multi-threaded PMU extensions */
CPU_FEATURE_PAUTH2, /*!< ARM: Enhancements to pointer authentication */
CPU_FEATURE_TWED, /*!< ARM: Delayed Trapping of WFE */
CPU_FEATURE_AFP, /*!< ARM: Alternate floating-point behavior */
CPU_FEATURE_EBF16, /*!< ARM: AArch64 Extended BFloat16 instructions */
CPU_FEATURE_HCX, /*!< ARM: Support for the HCRX_EL2 register */
CPU_FEATURE_LPA2, /*!< ARM: Larger physical address for 4KB and 16KB translation granules */
CPU_FEATURE_LS64, /*!< ARM: Support for 64-byte loads and stores without status */
CPU_FEATURE_LS64_ACCDATA, /*!< ARM: Support for 64-byte EL0 stores with status */
CPU_FEATURE_LS64_V, /*!< ARM: Support for 64-byte stores with status */
CPU_FEATURE_MTE3, /*!< ARM: MTE Asymmetric Fault Handling */
CPU_FEATURE_MTE_ASYM_FAULT, /*!< ARM: Memory tagging asymmetric faults */
CPU_FEATURE_PAN3, /*!< ARM: Support for SCTLR_ELx.EPAN */
CPU_FEATURE_PMUV3P7, /*!< ARM: Armv8.7 PMU extensions */
CPU_FEATURE_RPRES, /*!< ARM: Increased precision of FRECPE and FRSQRTE */
CPU_FEATURE_SPEV1P2, /*!< ARM: Statistical Profiling Extensions version 1.2 */
CPU_FEATURE_WFXT, /*!< ARM: WFE and WFI instructions with timeout */
CPU_FEATURE_XS, /*!< ARM: XS attribute */
CPU_FEATURE_CMOW, /*!< ARM: Control for cache maintenance permission */
CPU_FEATURE_DEBUGV8P8, /*!< ARM: Debug v8.8 */
CPU_FEATURE_HBC, /*!< ARM: Hinted conditional branches */
CPU_FEATURE_MOPS, /*!< ARM: Standardization of memory operations */
CPU_FEATURE_NMI, /*!< ARM: Non-maskable Interrupts */
CPU_FEATURE_PMUV3P8, /*!< ARM: Armv8.8 PMU extensions */
CPU_FEATURE_SCTLR2, /*!< ARM: Extension to SCTLR_ELx */
CPU_FEATURE_SPEV1P3, /*!< ARM: Statistical Profiling Extensions version 1.3 */
CPU_FEATURE_TCR2, /*!< ARM: Support for TCR2_ELx */
CPU_FEATURE_TIDCP1, /*!< ARM: EL0 use of IMPLEMENTATION DEFINED functionality */
CPU_FEATURE_ADERR, /*!< ARM: Asynchronous Device Error Exceptions */
CPU_FEATURE_AIE, /*!< ARM: Memory Attribute Index Enhancement */
CPU_FEATURE_ANERR, /*!< ARM: Asynchronous Normal Error Exceptions */
CPU_FEATURE_ATS1A, /*!< ARM: Address Translation operations that ignore stage 1 permissions */
CPU_FEATURE_CLRBHB, /*!< ARM: Support for Clear Branch History instruction */
CPU_FEATURE_CSSC, /*!< ARM: Common Short Sequence Compression instructions */
CPU_FEATURE_DEBUGV8P9, /*!< ARM: Debug v8.9 */
CPU_FEATURE_DOUBLEFAULT2, /*!< ARM: Double Fault Extension v2 */
CPU_FEATURE_ECBHB, /*!< ARM: Exploitative control using branch history information */
CPU_FEATURE_FGT2, /*!< ARM: Fine-grained traps 2 */
CPU_FEATURE_HAFT, /*!< ARM: Hardware managed Access Flag for Table descriptors */
CPU_FEATURE_LRCPC3, /*!< ARM: Load-Acquire RCpc instructions version 3 */
CPU_FEATURE_MTE4, /*!< ARM: Enhanced Memory Tagging Extension */
CPU_FEATURE_MTE_ASYNC, /*!< ARM: Asynchronous reporting of Tag Check Fault */
CPU_FEATURE_MTE_CANONICAL_TAGS, /*!< ARM: Canonical Tag checking for Untagged memory */
CPU_FEATURE_MTE_NO_ADDRESS_TAGS, /*!< ARM: Memory tagging with Address tagging disabled */
CPU_FEATURE_MTE_PERM, /*!< ARM: Allocation tag access permission */
CPU_FEATURE_MTE_STORE_ONLY, /*!< ARM: Store-only Tag Checking */
CPU_FEATURE_MTE_TAGGED_FAR, /*!< ARM: FAR_ELx on a Tag Check Fault */
CPU_FEATURE_PFAR, /*!< ARM: Physical Fault Address Register Extension */
CPU_FEATURE_PMUV3_ICNTR, /*!< ARM: Fixed-function instruction counter */
CPU_FEATURE_PMUV3_SS, /*!< ARM: PMU Snapshot extension */
CPU_FEATURE_PMUV3P9, /*!< ARM: Armv8.9 PMU extensions */
CPU_FEATURE_PRFMSLC, /*!< ARM: SLC target support for PRFM instructions */
CPU_FEATURE_RASV2, /*!< ARM: RAS Extension v2 */
CPU_FEATURE_RPRFM, /*!< ARM: Support for Range Prefetch Memory instruction */
CPU_FEATURE_S1PIE, /*!< ARM: Stage 1 permission indirections */
CPU_FEATURE_S1POE, /*!< ARM: Stage 1 permission overlays */
CPU_FEATURE_S2PIE, /*!< ARM: Stage 2 permission indirections */
CPU_FEATURE_S2POE, /*!< ARM: Stage 1 permission overlays */
CPU_FEATURE_SPECRES2, /*!< ARM: Enhanced speculation restriction instructions */
CPU_FEATURE_SPE_DPFZS, /*!< ARM: Disable Cycle Counter on SPE Freeze */
CPU_FEATURE_SPEV1P4, /*!< ARM: Statistical Profiling Extension version 1.4 */
CPU_FEATURE_SPMU, /*!< ARM: System Performance Monitors Extension */
CPU_FEATURE_THE, /*!< ARM: Translation Hardening Extension */
CPU_FEATURE_SVE2, /*!< ARM: Scalable Vector Extension version 2 */
CPU_FEATURE_SVE_AES, /*!< ARM: Scalable Vector AES instructions */
CPU_FEATURE_SVE_BITPERM, /*!< ARM: Scalable Vector Bit Permutes instructions */
CPU_FEATURE_SVE_PMULL128, /*!< ARM: Scalable Vector PMULL instructions */
CPU_FEATURE_SVE_SHA3, /*!< ARM: Scalable Vector SHA3 instructions */
CPU_FEATURE_SVE_SM4, /*!< ARM: Scalable Vector SM4 instructions */
CPU_FEATURE_TME, /*!< ARM: Transactional Memory Extension */
CPU_FEATURE_TRBE, /*!< ARM: Trace Buffer Extension */
CPU_FEATURE_BRBE, /*!< ARM: Branch Record Buffer Extension */
CPU_FEATURE_RME, /*!< ARM: Realm Management Extension */
CPU_FEATURE_SME, /*!< ARM: Scalable Matrix Extension */
CPU_FEATURE_SME_F64F64, /*!< ARM: Double-precision floating-point outer product instructions */
CPU_FEATURE_SME_FA64, /*!< ARM: Full A64 instruction set support in Streaming SVE mode */
CPU_FEATURE_SME_I16I64, /*!< ARM: 16-bit to 64-bit integer widening outer product instructions */
CPU_FEATURE_BRBEV1P1, /*!< ARM: Branch Record Buffer Extension version 1.1 */
CPU_FEATURE_MEC, /*!< ARM: Memory Encryption Contexts */
CPU_FEATURE_SME2, /*!< ARM: Scalable Matrix Extensions version 2 */
CPU_FEATURE_ABLE, /*!< ARM: Address Breakpoint Linking Extension */
CPU_FEATURE_BWE, /*!< ARM: Breakpoint and watchpoint enhancements */
CPU_FEATURE_D128, /*!< ARM: 128-bit Translation Tables, 56 bit PA */
CPU_FEATURE_EBEP, /*!< ARM: Exception-based Event Profiling */
CPU_FEATURE_GCS, /*!< ARM: Guarded Control Stack Extension */
CPU_FEATURE_ITE, /*!< ARM: Instrumentation Trace Extension */
CPU_FEATURE_LSE128, /*!< ARM: 128-bit Atomics */
CPU_FEATURE_LVA3, /*!< ARM: 56-bit VA */
CPU_FEATURE_SEBEP, /*!< ARM: Synchronous Exception-based Event Profiling */
CPU_FEATURE_SME2P1, /*!< ARM: Scalable Matrix Extension version 2.1 */
CPU_FEATURE_SME_F16F16, /*!< ARM: Non-widening half-precision FP16 to FP16 arithmetic for SME2. */
CPU_FEATURE_SVE2P1, /*!< ARM: Scalable Vector Extensions version 2.1 */
CPU_FEATURE_SVE_B16B16, /*!< ARM: Non-widening BFloat16 to BFloat16 arithmetic for SVE2 and SME2. */
CPU_FEATURE_SYSINSTR128, /*!< ARM: 128-bit System instructions */
CPU_FEATURE_SYSREG128, /*!< ARM: 128-bit System registers */
CPU_FEATURE_TRBE_EXT, /*!< ARM: Trace Buffer external mode */
/* termination: */
NUM_CPU_FEATURES,
} cpu_feature_t;
@ -924,6 +1336,13 @@ int cpu_request_core_type(cpu_purpose_t purpose, struct cpu_raw_data_array_t* ra
*/
const char* cpu_architecture_str(cpu_architecture_t architecture);
/**
* @brief Returns the short textual representation of a CPU feature level
* @param level - the feature level, whose textual representation is wanted.
* @returns a constant string like "ARMv8.0-A", "ARMv9.4-A", etc.
*/
const char* cpu_feature_level_str(cpu_feature_level_t level);
/**
* @brief Returns the short textual representation of a CPU purpose
* @param purpose - the purpose, whose textual representation is wanted.

View file

@ -43,3 +43,4 @@ cpuid_free_system_id
affinity_mask_str_r
cpuid_get_hypervisor
cpu_clock_by_tsc
cpu_feature_level_str

View file

@ -35,7 +35,7 @@
#define VENDOR_STR_MAX 16
#define BRAND_STR_MAX 64
#define CODENAME_STR_MAX 64
#define CPU_FLAGS_MAX 128
#define CPU_FLAGS_MAX 384
#define MAX_CPUID_LEVEL 32
#define MAX_EXT_CPUID_LEVEL 32
#define MAX_INTELFN4_LEVEL 8
@ -43,6 +43,12 @@
#define MAX_INTELFN12H_LEVEL 4
#define MAX_INTELFN14H_LEVEL 4
#define MAX_AMDFN8000001DH_LEVEL 4
#define MAX_ARM_ID_AA64DFR_REGS 2
#define MAX_ARM_ID_AA64ISAR_REGS 3
#define MAX_ARM_ID_AA64MMFR_REGS 5
#define MAX_ARM_ID_AA64PFR_REGS 3
#define MAX_ARM_ID_AA64SMFR_REGS 1
#define MAX_ARM_ID_AA64ZFR_REGS 1
#define CPU_HINTS_MAX 16
#define SGX_FLAGS_MAX 14
#define ADDRESS_EXT_CPUID_START 0x80000000

View file

@ -78,7 +78,7 @@ struct internal_id_info_t {
int32_t cache_mask[NUM_CACHE_TYPES];
};
struct internal_apic_info_t {
struct internal_topology_t {
int32_t apic_id;
int32_t package_id;
int32_t core_id;

View file

@ -97,16 +97,16 @@ static int score(const struct match_entry_t* entry, const struct cpu_id_t* data,
{
int i, tmp, res = 0;
const struct { const char *field; int entry; int data; int score; } array[] = {
{ "family", entry->family, data->family, 2 },
{ "model", entry->model, data->model, 2 },
{ "stepping", entry->stepping, data->stepping, 2 },
{ "ext_family", entry->ext_family, data->ext_family, 2 },
{ "ext_model", entry->ext_model, data->ext_model, 2 },
{ "ncores", entry->ncores, data->num_cores, 2 },
{ "l2cache", entry->l2cache, data->l2_cache, 1 },
{ "l3cache", entry->l3cache, data->l3_cache, 1 },
{ "brand_code", entry->brand_code, brand_code, 2 },
{ "model_code", entry->model_code, model_code, 2 },
{ "family", entry->family, data->x86.family, 2 },
{ "model", entry->model, data->x86.model, 2 },
{ "stepping", entry->stepping, data->x86.stepping, 2 },
{ "ext_family", entry->ext_family, data->x86.ext_family, 2 },
{ "ext_model", entry->ext_model, data->x86.ext_model, 2 },
{ "ncores", entry->ncores, data->num_cores, 2 },
{ "l2cache", entry->l2cache, data->l2_cache, 1 },
{ "l3cache", entry->l3cache, data->l3_cache, 1 },
{ "brand_code", entry->brand_code, brand_code, 2 },
{ "model_code", entry->model_code, model_code, 2 },
};
for (i = 0; i < sizeof(array) / sizeof(array[0]); i++) {
if(array[i].entry == array[i].data) {
@ -130,8 +130,8 @@ int match_cpu_codename(const struct match_entry_t* matchtable, int count,
int i, t;
debugf(3, "Matching cpu f:%d, m:%d, s:%d, xf:%d, xm:%d, ncore:%d, l2:%d, bcode:%d, bits:%llu, code:%d\n",
data->family, data->model, data->stepping, data->ext_family,
data->ext_model, data->num_cores, data->l2_cache, brand_code, (unsigned long long) bits, model_code);
data->x86.family, data->x86.model, data->x86.stepping, data->x86.ext_family,
data->x86.ext_model, data->num_cores, data->l2_cache, brand_code, (unsigned long long) bits, model_code);
for (i = 0; i < count; i++) {
t = score(&matchtable[i], data, brand_code, bits, model_code);

View file

@ -29,6 +29,7 @@
#include "libcpuid_internal.h"
#define COUNT_OF(array) (sizeof(array) / sizeof(array[0]))
#define UNUSED(x) (void)(x)
struct feature_map_t {
unsigned bit;

View file

@ -190,6 +190,7 @@
<ClCompile Include="rdmsr.c" />
<ClCompile Include="rdtsc.c" />
<ClCompile Include="recog_amd.c" />
<ClCompile Include="recog_arm.c" />
<ClCompile Include="recog_centaur.c" />
<ClCompile Include="recog_intel.c" />
</ItemGroup>
@ -200,6 +201,7 @@
<ClInclude Include="libcpuid_types.h" />
<ClInclude Include="libcpuid_util.h" />
<ClInclude Include="recog_amd.h" />
<ClInclude Include="recog_arm.h" />
<ClInclude Include="recog_centaur.h" />
<ClInclude Include="recog_intel.h" />
<ClInclude Include="rdtsc.h" />

View file

@ -30,6 +30,9 @@
<ClCompile Include="recog_amd.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="recog_arm.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="recog_centaur.c">
<Filter>Source Files</Filter>
</ClCompile>
@ -62,6 +65,9 @@
<ClInclude Include="recog_amd.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="recog_arm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="recog_centaur.h">
<Filter>Header Files</Filter>
</ClInclude>

View file

@ -170,6 +170,9 @@
<File
RelativePath=".\recog_amd.c">
</File>
<File
RelativePath=".\recog_arm.c">
</File>
<File
RelativePath=".\recog_centaur.c">
</File>
@ -214,6 +217,9 @@
<File
RelativePath=".\recog_amd.h">
</File>
<File
RelativePath=".\recog_arm.h">
</File>
<File
RelativePath=".\recog_centaur.h">
</File>

View file

@ -863,7 +863,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, double
const int num_dids = (int) COUNT_OF(divisor_t);
/* Constant values for common families */
const int magic_constant = (info->id->ext_family == 0x11) ? 0x8 : 0x10;
const int magic_constant = (info->id->x86.ext_family == 0x11) ? 0x8 : 0x10;
const int is_apu = ((FUSION_C <= info->internal->code.amd) && (info->internal->code.amd <= FUSION_A)) || (info->internal->bits & _APU_);
const double divisor = is_apu ? 1.0 : 2.0;
@ -872,7 +872,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, double
return 1;
/* Overview of AMD CPU microarchitectures: https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures#Nomenclature */
switch (info->id->ext_family) {
switch (info->id->x86.ext_family) {
case 0x12: /* K10 (Llano) / K12 */
/* BKDG 12h, page 469
MSRC001_00[6B:64][8:4] is CpuFid
@ -952,7 +952,7 @@ static int get_amd_multipliers(struct msr_info_t *info, uint32_t pstate, double
*multiplier = ((double) CpuFid / CpuDid) * 2;
break;
default:
warnf("get_amd_multipliers(): unsupported CPU extended family: %xh\n", info->id->ext_family);
warnf("get_amd_multipliers(): unsupported CPU extended family: %xh\n", info->id->x86.ext_family);
err = 1;
break;
}
@ -1131,9 +1131,9 @@ static double get_info_voltage(struct msr_info_t *info)
BKDG 10h, page 49: voltage = 1.550V - 0.0125V * SviVid (SVI1)
BKDG 15h, page 50: Voltage = 1.5500 - 0.00625 * Vid[7:0] (SVI2)
SVI2 since Piledriver (Family 15h, 2nd-gen): Models 10h-1Fh Processors */
VIDStep = ((info->id->ext_family < 0x15) || ((info->id->ext_family == 0x15) && (info->id->ext_model < 0x10))) ? 0.0125 : 0.00625;
VIDStep = ((info->id->x86.ext_family < 0x15) || ((info->id->x86.ext_family == 0x15) && (info->id->x86.ext_model < 0x10))) ? 0.0125 : 0.00625;
err = cpu_rdmsr_range(info->handle, MSR_PSTATE_S, 2, 0, &reg);
if(info->id->ext_family < 0x17)
if(info->id->x86.ext_family < 0x17)
err += cpu_rdmsr_range(info->handle, MSR_PSTATE_0 + (uint32_t) reg, 15, 9, &CpuVid);
else
err += cpu_rdmsr_range(info->handle, MSR_PSTATE_0 + (uint32_t) reg, 21, 14, &CpuVid);

View file

@ -241,7 +241,7 @@ static void adjust_march_ic_multiplier(const struct cpu_id_t* id, int* numerator
* 4. For Skylake and later, it is 1.6 IPC (we multiply by 5/8)
*/
//
if (id->sse_size < 128) {
if (id->x86.sse_size < 128) {
debugf(1, "SSE execution path is 64-bit\n");
// on a CPU with half SSE unit length, SSE instructions execute at 0.5 IPC;
// the resulting value must be multiplied by 2:
@ -251,14 +251,14 @@ static void adjust_march_ic_multiplier(const struct cpu_id_t* id, int* numerator
}
//
// Bulldozer or later: assume 1.4 IPC
if ((id->vendor == VENDOR_AMD && id->ext_family >= 21) || (id->vendor == VENDOR_HYGON)) {
if ((id->vendor == VENDOR_AMD && id->x86.ext_family >= 21) || (id->vendor == VENDOR_HYGON)) {
debugf(1, "cpu_clock_by_ic: Bulldozer (or later) detected, dividing result by 1.4\n");
*numerator = 5;
*denom = 7; // multiply by 5/7, to divide by 1.4
}
//
// Skylake or later: assume 1.6 IPC
if (id->vendor == VENDOR_INTEL && id->ext_model >= 94) {
if (id->vendor == VENDOR_INTEL && id->x86.ext_model >= 94) {
debugf(1, "cpu_clock_by_ic: Skylake (or later) detected, dividing result by 1.6\n");
*numerator = 5;
*denom = 8; // to divide by 1.6, multiply by 5/8
@ -354,9 +354,9 @@ int cpu_clock_by_tsc(struct cpu_raw_data_t* raw)
/* If ECX is 0, the nominal core crystal clock frequency is not enumerated.
For Intel processors in which CPUID.15H.EBX[31:0] ÷ CPUID.0x15.EAX[31:0] is enumerated but CPUID.15H.ECX
is not enumerated, Table 20-91 can be used to look up the nominal core crystal clock frequency. */
if ((nominal_freq_khz == 0) && (id.ext_family == 0x6)) {
debugf(1, "cpu_clock_by_tsc: nominal core crystal clock frequency is not enumerated, looking for CPUID signature %02X_%02XH\n", id.ext_family, id.ext_model);
switch (id.ext_model) {
if ((nominal_freq_khz == 0) && (id.x86.ext_family == 0x6)) {
debugf(1, "cpu_clock_by_tsc: nominal core crystal clock frequency is not enumerated, looking for CPUID signature %02X_%02XH\n", id.x86.ext_family, id.x86.ext_model);
switch (id.x86.ext_model) {
case 0x55:
/* Intel® Xeon® Scalable Processor Family with CPUID signature 06_55H */
nominal_freq_khz = 25000; // 25 MHz

View file

@ -439,11 +439,11 @@ static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
- bit 0: FP128 */
data->detection_hints[CPU_HINT_SSE_SIZE_AUTH] = 1;
if ((raw->ext_cpuid[0x1a][EAX] >> 2) & 1)
data->sse_size = 256;
data->x86.sse_size = 256;
else if ((raw->ext_cpuid[0x1a][EAX]) & 1)
data->sse_size = 128;
data->x86.sse_size = 128;
else
data->sse_size = 64;
data->x86.sse_size = 64;
}
}
@ -496,7 +496,7 @@ static void decode_amd_number_of_cores(struct cpu_raw_data_t* raw, struct cpu_id
}
if (data->flags[CPU_FEATURE_HT]) {
if (num_cores > 1) {
if ((data->ext_family >= 23) && (raw->ext_cpuid[0][EAX] >= 30))
if ((data->x86.ext_family >= 23) && (raw->ext_cpuid[0][EAX] >= 30))
/* Ryzen 3 has SMT flag, but in fact cores count is equal to threads count.
Ryzen 5/7 reports twice as many "real" cores (e.g. 16 cores instead of 8) because of SMT. */
/* On PPR 17h, page 82:

1011
libcpuid/recog_arm.c Normal file

File diff suppressed because it is too large Load diff

33
libcpuid/recog_arm.h Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright 2024 Veselin Georgiev,
* anrieffNOSPAM @ mgail_DOT.com (convert to gmail)
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#ifndef __RECOG_ARM_H__
#define __RECOG_ARM_H__
int cpuid_identify_arm(struct cpu_raw_data_t* raw, struct cpu_id_t* data);
void cpuid_get_list_arm(cpu_vendor_t vendor, struct cpu_list_t* list);
cpu_purpose_t cpuid_identify_purpose_arm(struct cpu_raw_data_t* raw);
#endif /* __RECOG_ARM_H__ */

View file

@ -694,7 +694,7 @@ static void decode_intel_oldstyle_cache_info(struct cpu_raw_data_t* raw, struct
* CPUs (notably Conroe et al), this is L2 cache. In both cases
* it means 4MB, 16-way associative, 64-byte line size.
*/
if (data->family == 0xf && data->model == 0x6) {
if (data->x86.family == 0xf && data->x86.model == 0x6) {
data->l3_cache = 4096;
data->l3_assoc = 16;
data->l3_cacheline = 64;
@ -874,7 +874,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
code = GAINESTOWN;
else if (match_pattern(bs, "[ELXW]56##"))
code = WESTMERE;
else if (data->l3_cache > 0 && data->family == 16)
else if (data->l3_cache > 0 && data->x86.family == 16)
/* restrict by family, since later Xeons also have L3 ... */
code = IRWIN;
}
@ -911,14 +911,14 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data)
}
}
if (code == CORE_DUO && (bits & MOBILE_) && data->model != 14) {
if (data->ext_model < 23) {
if (code == CORE_DUO && (bits & MOBILE_) && data->x86.model != 14) {
if (data->x86.ext_model < 23) {
code = MEROM;
} else {
code = PENRYN;
}
}
if (data->ext_model == 23 &&
if (data->x86.ext_model == 23 &&
(code == CORE_DUO || code == PENTIUM_D || (bits & CELERON_))) {
code = WOLFDALE;
}
@ -1030,31 +1030,31 @@ static void decode_intel_sgx_features(const struct cpu_raw_data_t* raw, struct c
if (raw->basic_cpuid[0x12][EAX] == 0) return; // no sub-leafs available, probably it's disabled by BIOS
// decode sub-leaf 0:
if (raw->basic_cpuid[0x12][EAX] & 1) data->sgx.flags[INTEL_SGX1] = 1;
if (raw->basic_cpuid[0x12][EAX] & 2) data->sgx.flags[INTEL_SGX2] = 1;
if (data->sgx.flags[INTEL_SGX1] || data->sgx.flags[INTEL_SGX2])
data->sgx.present = 1;
data->sgx.misc_select = raw->basic_cpuid[0x12][EBX];
data->sgx.max_enclave_32bit = (raw->basic_cpuid[0x12][EDX] ) & 0xff;
data->sgx.max_enclave_64bit = (raw->basic_cpuid[0x12][EDX] >> 8) & 0xff;
if (raw->basic_cpuid[0x12][EAX] & 1) data->x86.sgx.flags[INTEL_SGX1] = 1;
if (raw->basic_cpuid[0x12][EAX] & 2) data->x86.sgx.flags[INTEL_SGX2] = 1;
if (data->x86.sgx.flags[INTEL_SGX1] || data->x86.sgx.flags[INTEL_SGX2])
data->x86.sgx.present = 1;
data->x86.sgx.misc_select = raw->basic_cpuid[0x12][EBX];
data->x86.sgx.max_enclave_32bit = (raw->basic_cpuid[0x12][EDX] ) & 0xff;
data->x86.sgx.max_enclave_64bit = (raw->basic_cpuid[0x12][EDX] >> 8) & 0xff;
// decode sub-leaf 1:
data->sgx.secs_attributes = raw->intel_fn12h[1][EAX] | (((uint64_t) raw->intel_fn12h[1][EBX]) << 32);
data->sgx.secs_xfrm = raw->intel_fn12h[1][ECX] | (((uint64_t) raw->intel_fn12h[1][EDX]) << 32);
data->x86.sgx.secs_attributes = raw->intel_fn12h[1][EAX] | (((uint64_t) raw->intel_fn12h[1][EBX]) << 32);
data->x86.sgx.secs_xfrm = raw->intel_fn12h[1][ECX] | (((uint64_t) raw->intel_fn12h[1][EDX]) << 32);
// decode higher-order subleafs, whenever present:
data->sgx.num_epc_sections = -1;
data->x86.sgx.num_epc_sections = -1;
for (i = 0; i < 1000000; i++) {
epc = cpuid_get_epc(i, raw);
if (epc.length == 0) {
debugf(2, "SGX: epc section request for %d returned null, no more EPC sections.\n", i);
data->sgx.num_epc_sections = i;
data->x86.sgx.num_epc_sections = i;
break;
}
}
if (data->sgx.num_epc_sections == -1) {
if (data->x86.sgx.num_epc_sections == -1) {
debugf(1, "SGX: warning: seems to be infinitude of EPC sections.\n");
data->sgx.num_epc_sections = 1000000;
data->x86.sgx.num_epc_sections = 1000000;
}
}

View file

@ -0,0 +1,87 @@
_________________ Logical CPU #0 _________________
arm_midr=00000000410fd030
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000010000
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
_________________ Logical CPU #1 _________________
arm_midr=00000000410fd030
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000010000
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
_________________ Logical CPU #2 _________________
arm_midr=00000000410fd030
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000010000
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
_________________ Logical CPU #3 _________________
arm_midr=00000000410fd030
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000010000
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
--------------------------------------------------------------------------------
ARM
efficiency
65
0
3331
0
1
4
Apollo
advsimd crc32 doublelock fp sve bbm fhm sel2

View file

@ -0,0 +1,87 @@
_________________ Logical CPU #0 _________________
arm_midr=00000000411fd070
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000011120
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
_________________ Logical CPU #1 _________________
arm_midr=00000000411fd070
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000011120
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
_________________ Logical CPU #2 _________________
arm_midr=00000000411fd070
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000011120
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
_________________ Logical CPU #3 _________________
arm_midr=00000000411fd070
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=0000000000011120
arm_id_aa64isar1=0000000000000000
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000000000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0000000000000011
arm_id_aa64pfr1=0000000000000000
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000000000000000
--------------------------------------------------------------------------------
ARM
performance
65
1
3335
0
1
4
Atlas
advsimd crc32 doublelock fp pmull sha1 sha256 sm4 sve bbm dotprod fhm sel2

View file

@ -0,0 +1,87 @@
_________________ Logical CPU #0 _________________
arm_midr=00000000410fd493
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=1021111110212120
arm_id_aa64isar1=0011101101211052
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000100000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0001000100110011
arm_id_aa64pfr1=0000000000000121
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000110100110021
_________________ Logical CPU #1 _________________
arm_midr=00000000410fd493
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=1021111110212120
arm_id_aa64isar1=0011101101211052
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000100000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0001000100110011
arm_id_aa64pfr1=0000000000000121
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000110100110021
_________________ Logical CPU #2 _________________
arm_midr=00000000410fd493
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=1021111110212120
arm_id_aa64isar1=0011101101211052
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000100000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0001000100110011
arm_id_aa64pfr1=0000000000000121
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000110100110021
_________________ Logical CPU #3 _________________
arm_midr=00000000410fd493
arm_mpidr=0000000080000000
arm_revidr=0000000000000000
arm_id_aa64dfr0=0000000000000006
arm_id_aa64dfr1=0000000000000000
arm_id_aa64isar0=1021111110212120
arm_id_aa64isar1=0011101101211052
arm_id_aa64isar2=0000000000000000
arm_id_aa64mmfr0=00000111ff000000
arm_id_aa64mmfr1=0000000000000000
arm_id_aa64mmfr2=0000000100000000
arm_id_aa64mmfr3=0000000000000000
arm_id_aa64mmfr4=0000000000000000
arm_id_aa64pfr0=0001000100110011
arm_id_aa64pfr1=0000000000000121
arm_id_aa64pfr2=0000000000000000
arm_id_aa64smfr0=0000000000000000
arm_id_aa64zfr0=0000110100110021
--------------------------------------------------------------------------------
ARM
general
65
0
3401
3
1
4
Perseus
advsimd crc32 csv2_1p1 doublelock pmull sha1 lse rdm f32mm fp16 sha512 sm4 sve fcma fpaccombine jscvt pacqarma5 pauth bbm dit fhm lrcpc2 sel2 bti dpb2 flagm2 mte rng ssbs2 bf16 dgh xs sve2 sve_bitperm sve_pmull128 sve_sha3 rme sme

View file

@ -12,7 +12,11 @@ if len(args) != 3:
def readRawFile():
rawdata = []
for line in open(args[1], "rt").readlines():
lookfor = ["basic_cpuid", "ext_cpuid", "intel_fn4", "intel_fn11", "amd_fn8000001dh", "Logical CPU", "CPUID", "CPU#"]
lookfor = [
"Logical CPU", "CPUID", "CPU#", # common
"basic_cpuid", "ext_cpuid", "intel_fn4", "intel_fn11", "amd_fn8000001dh", # x86
"arm_midr", "arm_mpidr", "arm_revidr", "arm_id_aa64dfr", "arm_id_aa64isar", "arm_id_aa64mmfr", "arm_id_aa64pfr", "arm_id_aa64smfr", "arm_id_aa64zfr" # ARM
]
ignore = ["MSR Register"]
good = False
for match in lookfor:
@ -35,6 +39,7 @@ def readResultFile():
if s.find(":") == -1:
continue
numeric = ["family", "model", "stepping", "ext_family", "ext_model",
"implementer", "variant", "part_num", "revision",
"num_cores", "num_logical",
"L1 D cache", "L1 I cache", "L2 cache", "L3 cache", "L4 cache",
"L1D assoc.", "L1I assoc.", "L2 assoc.", "L3 assoc.", "L4 assoc.",

View file

@ -5,13 +5,16 @@ import os, sys, re, random
### Constants:
fields = [ "architecture", "purpose", "family", "model", "stepping", "extfamily",
fields_x86 = [ "architecture", "purpose", "family", "model", "stepping", "extfamily",
"extmodel", "cores", "logical",
"l1d-cache", "l1i-cache", "l2-cache", "l3-cache", "l4-cache",
"l1d-assoc", "l1i-assoc", "l2-assoc", "l3-assoc", "l4-assoc",
"l1d-cacheline", "l1i-cacheline", "l2-cacheline", "l3-cacheline", "l4-cacheline",
"l1d-instances", "l1i-instances", "l2-instances", "l3-instances", "l4-instances",
"sse-size", "codename", "flags" ]
fields_arm = [ "architecture", "purpose", "implementer", "variant", "part-num", "revision",
"cores", "logical",
"codename", "flags" ]
args = sys.argv
fix = False
@ -79,6 +82,13 @@ def do_test(inp, expected_out, binary, test_file_name, num_cpu_type):
f = open(fninp, "wt")
f.writelines([s + "\n" for s in inp])
f.close()
architecture = os.popen("%s --load=%s --architecture" % (binary, fninp)).read().splitlines()[-1]
if architecture == "x86":
fields = fields_x86
elif architecture == "ARM":
fields = fields_arm
else:
fields = []
cmd = "%s --load=%s --outfile=%s %s" % (binary, fninp, fnoutp, " ".join(["--" + s for s in fields]))
os.system(cmd)
os.unlink(fninp)

47
utils/parse_arm_arm_pdf.sh Executable file
View file

@ -0,0 +1,47 @@
#!/bin/bash
# This script extracts some data from Arm Architecture Reference Manual PDF file
# PDF file can be downloaded here: https://developer.arm.com/documentation/ddi0487/latest/
print_help() {
echo "$(basename "$0") PDF_FILE"
echo -e "\n\033[1mPDF_FILE:\033[0m Arm Architecture Reference Manual PDF file"
}
if [[ $# -lt 1 ]]; then
print_help
exit 1
fi
PDF_FILE="$1"
TMP_DIR="$(mktemp -d -t libcpuid.XXXXXX)"
TMP_LIBCPUID_H="$TMP_DIR/cpu_feature.h"
TMP_CPUID_MAIN_C="$TMP_DIR/matchtable.c"
echo "typedef enum {" > "$TMP_LIBCPUID_H"
echo " matchtable[] = {" > "$TMP_CPUID_MAIN_C"
IFS='
'
for line in $(pdfgrep --cache -e 'A[0-9]+\.[0-9]+\.[0-9]+\s+The Armv[0-9]\.[0-9] architecture extension' -e ' FEAT_[a-zA-Z0-9_]+, ' "$PDF_FILE"); do
if [[ "$line" == "A"* ]]; then
echo "$line"
echo -e "\t/* $line */" >> "$TMP_LIBCPUID_H"
echo -e "\t\t/* $line */" >> "$TMP_CPUID_MAIN_C"
elif [[ "$line" == " FEAT_"* ]]; then
feat="$(echo "$line" | awk '{ print $1 }' | cut -d, -f1)"
#pdfgrep --cache "$feat implements the functionality identified by the value" "$PDF_FILE"
feat_upper="${feat^^}"
feat_lower="${feat,,}"
feat_enum="${feat_upper/FEAT_/CPU_FEATURE_}"
feat_name="$(echo $feat_lower | cut -d_ -f2-)"
feat_descr="$(echo "$line" | cut -d, -f2-)"
echo -e "\t$feat_enum, /*!< ARM:$feat_descr */" >> "$TMP_LIBCPUID_H"
echo -e "\t\t{ $feat_enum, \"$feat_name\" }," >> "$TMP_CPUID_MAIN_C"
fi
done
echo "} cpu_feature_t;" >> "$TMP_LIBCPUID_H"
echo " };" >> "$TMP_CPUID_MAIN_C"
echo "Extracted data for enum cpu_feature_t written to '$TMP_LIBCPUID_H' file."
echo "Extracted data for cpu_feature_str() matchtable written to '$TMP_CPUID_MAIN_C' file."