Add function for parse CPUID information

Used to detect whether mwaitx instruction is supported

Change-Id: I66fe906325aa523c8815133cf782df3a17a7edab


[ROCm/ROCR-Runtime commit: 0ed1568afc]
This commit is contained in:
David Yat Sin
2023-02-16 14:54:29 +00:00
parent 90e271e19b
commit 72e7fe7aec
4 changed files with 48 additions and 1 deletions
@@ -1396,8 +1396,14 @@ Runtime::Runtime()
kfd_version{0} {}
hsa_status_t Runtime::Load() {
flag_.Refresh();
os::cpuid_t cpuinfo;
// Assume features are not supported if parse CPUID fails
if (!os::ParseCpuID(&cpuinfo)) {
fprintf(stderr, "Failed to parse CPUID\n");
}
flag_.Refresh();
g_use_interrupt_wait = flag_.enable_interrupt();
if (!AMD::Load()) {
@@ -60,6 +60,7 @@
#include <string>
#include <utility>
#include "core/inc/runtime.h"
#include <cpuid.h>
namespace rocr {
namespace os {
@@ -643,6 +644,29 @@ uint64_t SystemClockFrequency() {
return 1000000000 / sys_clock_period_;
}
bool ParseCpuID(cpuid_t* cpuinfo) {
uint32_t eax, ebx, ecx, edx, max_eax = 0;
memset(cpuinfo, 0, sizeof(*cpuinfo));
/* Make sure current CPU supports at least EAX 4 */
if (!__get_cpuid_max(0x80000004, NULL)) return false;
// Manufacturer ID is a twelve-character ASCII string stored in order EBX, EDX, ECX.
if (!__get_cpuid(0, &max_eax, (uint32_t*)&cpuinfo->ManufacturerID[0],
(uint32_t*)&cpuinfo->ManufacturerID[8],
(uint32_t*)&cpuinfo->ManufacturerID[4])) {
return false;
}
if (!strcmp(cpuinfo->ManufacturerID, "AuthenticAMD")) {
if (__get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx)) {
cpuinfo->mwaitx = !!((ecx >> 29) & 0x1);
}
}
return true;
}
} // namespace os
} // namespace rocr
@@ -285,6 +285,15 @@ uint64_t ReadSystemClock();
/// @brief read the system clock frequency
uint64_t SystemClockFrequency();
typedef struct cpuid_s {
char ManufacturerID[13]; // 12 char, NULL terminated
bool mwaitx;
} cpuid_t;
/// @brief parse CPUID
/// @param: cpuinfo struct to be filled
bool ParseCpuID(cpuid_t* cpuinfo);
} // namespace os
} // namespace rocr
@@ -282,11 +282,19 @@ void DestroySharedMutex(SharedMutex lock) {
uint64_t ReadSystemClock() {
assert(false && "Not implemented.");
abort();
return 0;
}
uint64_t SystemClockFrequency() {
assert(false && "Not implemented.");
abort();
return 0;
}
bool ParseCpuID(cpuid_t* cpuinfo) {
assert(false && "Not implemented.");
abort();
return false;
}
} // namespace os