summaryrefslogtreecommitdiff
path: root/indra/llcommon/llprocessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llprocessor.cpp')
-rw-r--r--indra/llcommon/llprocessor.cpp148
1 files changed, 135 insertions, 13 deletions
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 456f2b02d4..a83aeb8477 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -460,13 +460,21 @@ static F64 calculate_cpu_frequency(U32 measure_msecs)
//// completed now (serialization)
//__asm cpuid
int cpu_info[4] = {-1};
+#if _M_ARM64
+ std::fill(cpu_info, cpu_info + 4, 0);
+#else
__cpuid(cpu_info, 0);
+#endif
// We ask the high-res timer for the start time
QueryPerformanceCounter((LARGE_INTEGER *) &starttime);
// Then we get the current cpu clock and store it
+#if _M_ARM64
+ start = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+#else
start = __rdtsc();
+#endif
// Now we wart for some msecs
_Delay(measure_msecs);
@@ -476,7 +484,11 @@ static F64 calculate_cpu_frequency(U32 measure_msecs)
QueryPerformanceCounter((LARGE_INTEGER *) &endtime);
// And also for the end cpu clock
+#if _M_ARM64
+ end = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+#else
end = __rdtsc();
+#endif
// Now we can restore the default process and thread priorities
SetProcessAffinityMask(hProcess, dwProcessMask);
@@ -516,17 +528,21 @@ private:
// the other three array elements. The CPU identification string is
// not in linear order. The code below arranges the information
// in a human readable form.
+#if !_M_ARM64
int cpu_info[4] = {-1};
__cpuid(cpu_info, 0);
unsigned int ids = (unsigned int)cpu_info[0];
setConfig(eMaxID, (S32)ids);
+#endif
char cpu_vendor[0x20];
memset(cpu_vendor, 0, sizeof(cpu_vendor));
+#if !_M_ARM64
*((int*)cpu_vendor) = cpu_info[1];
*((int*)(cpu_vendor+4)) = cpu_info[3];
*((int*)(cpu_vendor+8)) = cpu_info[2];
setInfo(eVendor, cpu_vendor);
+#endif
std::string cmp_vendor(cpu_vendor);
bool is_amd = false;
if (cmp_vendor == "AuthenticAMD")
@@ -534,6 +550,20 @@ private:
is_amd = true;
}
+#if _M_ARM64
+ HKEY hKey;
+ DWORD gotType;
+ char inBuffer[48] = "";
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ if (!RegQueryValueExA(hKey, "ProcessorNameString", nullptr, &gotType, (PBYTE)(inBuffer), nullptr))
+ {
+ if ((gotType == REG_SZ) && strlen(inBuffer))
+ setInfo(eModel, inBuffer);
+ }
+ RegCloseKey(hKey);
+ }
+#else
// Get the information associated with each valid Id
for(unsigned int i=0; i<=ids; ++i)
{
@@ -671,13 +701,12 @@ private:
setConfig(eCacheSizeK, (cpu_info[2] >> 16) & 0xffff);
}
}
+#endif
}
};
#elif LL_DARWIN
-#include <CoreFoundation/CoreFoundation.h>
-#include <IOKit/IOKitLib.h>
#include <mach/machine.h>
#include <sys/sysctl.h>
@@ -688,9 +717,13 @@ public:
{
getCPUIDInfo();
uint64_t frequency = getSysctlInt64("hw.cpufrequency");
- if (frequency == 0) // fallback to clockrate and tbfrequency
+ if (!frequency)
{
- frequency = getSysctlClockrate() * getSysctlInt64("hw.tbfrequency");
+ auto tbfrequency = getSysctlInt64("hw.tbfrequency");
+ struct clockinfo clockrate;
+ auto clockrate_len = sizeof(clockrate);
+ if (!sysctlbyname("kern.clockrate", &clockrate, &clockrate_len, NULL, 0))
+ frequency = tbfrequency * clockrate.hz;
}
setInfo(eFrequency, (F64)frequency / (F64)1000000);
}
@@ -730,14 +763,6 @@ private:
return result == -1 ? 0 : value;
}
- uint64_t getSysctlClockrate()
- {
- struct clockinfo clockrate{};
- size_t size = sizeof(clockrate);
- int error = sysctlbyname("kern.clockrate", &clockrate, &size, nullptr, 0);
- return error == -1 ? 0 : clockrate.hz;
- }
-
void getCPUIDInfo()
{
size_t len = 0;
@@ -853,6 +878,100 @@ private:
}
};
+#elif __FreeBSD__
+
+#include <sys/sysctl.h>
+class LLProcessorInfoFreeBSDImpl : public LLProcessorInfoImpl
+{
+public:
+ LLProcessorInfoFreeBSDImpl()
+ {
+ size_t len = 0;
+ using std::string;
+
+ char cpu_brand_string[0x40];
+ len = sizeof cpu_brand_string;
+ memset(cpu_brand_string, '\0', len);
+ sysctlbyname("hw.model", (void *)cpu_brand_string, &len,
+ NULL, 0);
+ cpu_brand_string[0x3f] = '\0';
+ setInfo(eBrandName, cpu_brand_string);
+
+ uint64_t cpu_frequency = 0;
+ len = sizeof cpu_frequency;
+ sysctlbyname("hw.clockrate", (void *)&cpu_frequency, &len,
+ NULL, 0);
+ setInfo(eFrequency, (F64)cpu_frequency);
+
+ auto dmesgboot = LLFile::fopen("/var/run/dmesg.boot", "rb");
+ std::ostringstream s;
+ if (dmesgboot) {
+ char line[MAX_STRING];
+ memset(line, 0, MAX_STRING);
+ while (fgets(line, MAX_STRING, dmesgboot)) {
+ line[strlen(line) - 1] = ' ';
+ s << line;
+ s << std::endl;
+ }
+ fclose(dmesgboot);
+ s << std::endl;
+ }
+
+ auto dmesgboot_str = s.str();
+ int decimal;
+
+ auto idx1 = dmesgboot_str.find_first_of("\"") + 1;
+ auto idx2 = (idx1 != string::npos)
+ ? dmesgboot_str.find_first_of("\"", idx1)
+ : string::npos;
+ auto vendor = dmesgboot_str.substr(idx1, idx2 - idx1);
+ if (vendor.length() > 0) setInfo(eVendor, vendor.c_str());
+
+ idx1 = dmesgboot_str.find_first_of("=", idx2);
+ idx1 = dmesgboot_str.find_first_of("=", idx1 + 1) + 3;
+ idx2 = dmesgboot_str.find_first_of(" ", idx1);
+ auto family = dmesgboot_str.substr(idx1, idx2 - idx1);
+ std::istringstream(family) >> std::hex >> decimal;
+ setInfo(eFamily, decimal);
+ setInfo(eFamilyName, compute_CPUFamilyName(vendor.c_str(),
+ decimal, 0));
+
+ idx1 = dmesgboot_str.find_first_of("=", idx2) + 3;
+ idx2 = dmesgboot_str.find_first_of(" ", idx1);
+ auto model = dmesgboot_str.substr(idx1, idx2 - idx1);
+ std::istringstream(model) >> std::hex >> decimal;
+ setInfo(eModel, decimal);
+
+ idx1 = dmesgboot_str.find_first_of("=", idx2) + 1;
+ idx2 = dmesgboot_str.find_first_of("\n", idx1);
+ auto stepping = dmesgboot_str.substr(idx1, idx2 - idx1);
+ setInfo(eStepping, std::stoi(stepping));
+
+ if (dmesgboot_str.find(",SSE,") != string::npos)
+ setExtension(cpu_feature_names[eSSE_Ext]);
+
+ if (dmesgboot_str.find(",SSE2,") != string::npos)
+ setExtension(cpu_feature_names[eSSE2_Ext]);
+
+ if (dmesgboot_str.find("<SSE3,") != string::npos)
+ setExtension(cpu_feature_names[eSSE3_Features]);
+
+ if (dmesgboot_str.find(",SSSE3,") != string::npos)
+ setExtension(cpu_feature_names[eSSE3S_Features]);
+
+ if (dmesgboot_str.find(",SSE4.1,") != string::npos)
+ setExtension(cpu_feature_names[eSSE4_1_Features]);
+
+ if (dmesgboot_str.find(",SSE4.2,") != string::npos)
+ setExtension(cpu_feature_names[eSSE4_2_Features]);
+
+ if (dmesgboot_str.find(",SSE4A,") != string::npos)
+ setExtension(cpu_feature_names[eSSE4a_Features]);
+ }
+
+ virtual ~LLProcessorInfoFreeBSDImpl() {}
+};
+
#elif LL_LINUX
// *NOTE:Mani - eww, macros! srry.
@@ -937,7 +1056,6 @@ private:
}
fclose(cpuinfo_fp);
}
-# if LL_X86
F64 mhzFromSys = getCPUMaxMHZ();
F64 mhzFromProc {};
@@ -952,6 +1070,7 @@ private:
setInfo(eFrequency,(F64)(mhzFromProc));
}
+# if LL_X86
LLPI_SET_INFO_STRING(eBrandName, "model name");
LLPI_SET_INFO_STRING(eVendor, "vendor_id");
@@ -1079,6 +1198,9 @@ LLProcessorInfo::LLProcessorInfo() : mImpl(NULL)
#elif LL_DARWIN
static LLProcessorInfoDarwinImpl the_impl;
mImpl = &the_impl;
+#elif __FreeBSD__
+ static LLProcessorInfoFreeBSDImpl the_impl;
+ mImpl = &the_impl;
#else
static LLProcessorInfoLinuxImpl the_impl;
mImpl = &the_impl;