diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index 69d849da54..3748aef156 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -114,6 +114,7 @@ #define IA32_MSR_FS_BASE 0xc0000100 #define IA32_MSR_GS_BASE 0xc0000101 #define IA32_MSR_KERNEL_GS_BASE 0xc0000102 +#define IA32_MSR_TSC_AUX 0xc0000103 // K8 MSR registers #define K8_MSR_IPM 0xc0010055 diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index 7f735b977d..cf833bb1cb 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -1145,6 +1145,12 @@ arch_cpu_init_percpu(kernel_args* args, int cpu) gCpuIdleFunc = halt_idle; } +#ifdef __x86_64__ + // if RDTSCP is available write cpu number in TSC_AUX + if (x86_check_feature(IA32_FEATURE_AMD_EXT_RDTSCP, FEATURE_EXT_AMD)) + x86_write_msr(IA32_MSR_TSC_AUX, cpu); +#endif + return __x86_patch_errata_percpu(cpu); } diff --git a/src/tests/system/libroot/os/Jamfile b/src/tests/system/libroot/os/Jamfile index 62007f620e..41f8d01280 100644 --- a/src/tests/system/libroot/os/Jamfile +++ b/src/tests/system/libroot/os/Jamfile @@ -24,6 +24,10 @@ SimpleTest system_watching_test : system_watching_test.cpp ; +SimpleTest get_cpu_num_test : + get_cpu_num_test.cpp +; + # Tell Jam where to find these sources SEARCH on [ FGristFiles driver_settings.cpp diff --git a/src/tests/system/libroot/os/get_cpu_num_test.cpp b/src/tests/system/libroot/os/get_cpu_num_test.cpp new file mode 100644 index 0000000000..922dbb0304 --- /dev/null +++ b/src/tests/system/libroot/os/get_cpu_num_test.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2020, Jérôme Duval, jerome.duval@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include + +#include + +#include + +extern const char* __progname; + + +static void +print_usage(bool error) +{ + fprintf(error ? stderr : stdout, + "Usage: %s\n", + __progname); +} + + +static void +print_usage_and_exit(bool error) +{ + print_usage(error); + exit(error ? 1 : 0); +} + + +int +main(int argc, const char* const* argv) +{ + + if (argc > 2) + print_usage_and_exit(true); + + if (argc > 1) { + const char* arg = argv[1]; + if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) + print_usage_and_exit(false); + } + +#ifdef __x86_64__ + uint32 cpuNum; + __rdtscp(&cpuNum); + printf("%" B_PRIu32 "\n", cpuNum); + return 0; +#else + return 1; +#endif +}