Files
cpu-check/fvt_controller.cc
Eric Liu 06a0b682c0
Some checks failed
Build Alpine Package / build-alpine (push) Failing after 1m53s
Build Debian Package / build-debian (push) Successful in 1m57s
Update system header includes in fvt_controller.cc
- Remove deprecated <error.h> include
- Add <system_error> for std::system_error
- Add <cerrno> for errno handling
- Streamline and modernize system header includes
2025-02-01 06:59:33 +00:00

129 lines
3.6 KiB
C++

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "config.h"
#include "fvt_controller.h"
#include <fcntl.h>
#include <math.h>
#include <stdint.h>
#include <atomic>
#include <system_error> // for std::system_error
#include <cerrno> // for errno
#undef NDEBUG
#include <cassert>
#include <cstring>
#include <memory>
#include <mutex>
#include "fvt_controller.h"
#include "log.h"
namespace {
class NonX86FVTController : public FVTController {
public:
explicit NonX86FVTController(int cpu) : FVTController(cpu) {}
~NonX86FVTController() override {}
void SetCurrentFreqLimitMhz(int mhz) override {
LOG(FATAL) << "Unsupported platform";
}
// Returns the maximum supported CPU frequency.
int GetAbsoluteFreqLimitMhz() override {
LOG(FATAL) << "Unsupported platform";
return 0;
}
// Returns true if automatic Power Management enabled.
bool PowerManaged() const override {
LOG(FATAL) << "Unsupported platform";
return false;
}
std::string FVT() override {
LOG(FATAL) << "Unsupported platform";
return "";
}
std::string InterestingEnables() const override {
LOG(FATAL) << "Unsupported platform";
return "";
}
void ControlFastStringOps(bool enable) override {
LOG(FATAL) << "Unsupported platform";
}
protected:
int GetCurrentFreqLimitMhz() override {
LOG(FATAL) << "Unsupported platform";
return 0;
}
int GetCurrentFreqMhz() override {
LOG(FATAL) << "Unsupported platform";
return 0;
}
};
static const char IntelVendorString[] = "GenuineIntel";
static const char AMDVendorString[] = "AuthenticAMD";
} // namespace
// Only works for Linux on x86-64
void X86FVTController::GetCPUId(int cpu, uint32_t eax, CPUIDResult* result) {
constexpr size_t kCPUIDPathMax = 1024;
char CPUIDPath[kCPUIDPathMax];
snprintf(CPUIDPath, sizeof(CPUIDPath), "/dev/cpu/%d/cpuid", cpu);
int fd = open(CPUIDPath, O_RDONLY);
assert(fd >= 0);
ssize_t byte_read = pread(fd, result, sizeof(*result), eax);
if (byte_read != sizeof(*result)) {
LOG(FATAL) << "CPUID " << std::hex << eax << "failed.";
}
close(fd);
}
std::string X86FVTController::CPUIDVendorStringUncached() {
char buffer[12];
CPUIDResult result;
GetCPUId(0, 0, &result);
memcpy(buffer + 0, &result.ebx, 4);
memcpy(buffer + 4, &result.edx, 4);
memcpy(buffer + 8, &result.ecx, 4);
return std::string(buffer, sizeof(buffer));
}
std::string X86FVTController::CPUIDVendorString() {
static const std::string vendor_string = CPUIDVendorStringUncached();
return vendor_string;
}
std::unique_ptr<FVTController> FVTController::Create(int cpu) {
#if defined(__i386__) || defined(__x86_64__)
const std::string vendor_string = X86FVTController::CPUIDVendorString();
#ifdef VENDORS_INTEL_PATH
if (vendor_string == IntelVendorString) {
return NewIntelFVTController(cpu);
}
#endif
#ifdef VENDORS_AMD_PATH
if (vendor_string == AMDVendorString) {
return NewAMDFVTController(cpu);
}
#endif
LOG(FATAL) << "Unsupported x86 vendor";
return nullptr;
#else
return std::unique_ptr<FVTController>(new NonX86FVTController(cpu));
#endif
}