Skip to content

Commit

Permalink
Merge pull request #3998 from Sonicadvance1/move_midr_fetch
Browse files Browse the repository at this point in the history
HostFeatures: Moves MIDR querying to the frontend
  • Loading branch information
Sonicadvance1 authored Aug 23, 2024
2 parents e6aa268 + 0ec724c commit fbf62f1
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 23 deletions.
31 changes: 10 additions & 21 deletions FEXCore/Source/Interface/Core/CPUID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,27 +114,16 @@ void CPUIDEmu::SetupHostHybridFlag() {

uint64_t MIDR {};
for (size_t i = 0; i < Cores; ++i) {
std::error_code ec {};
fextl::string MIDRPath = fextl::fmt::format("/sys/devices/system/cpu/cpu{}/regs/identification/midr_el1", i);

std::array<char, 18> Data;
// Needs to be a fixed size since depending on kernel it will try to read a full page of data and fail
// Only read 18 bytes for a 64bit value prefixed with 0x
if (FEXCore::FileLoading::LoadFileToBuffer(MIDRPath, Data) == sizeof(Data)) {
uint64_t NewMIDR {};
std::string_view MIDRView(Data.data(), sizeof(Data));
if (FEXCore::StrConv::Conv(MIDRView, &NewMIDR)) {
if (MIDR != 0 && MIDR != NewMIDR) {
// CPU mismatch, claim hybrid
Hybrid = true;
}

// Truncate to 32-bits, top 32-bits are all reserved in MIDR
PerCPUData[i].ProductName = ProductNames::ARM_UNKNOWN;
PerCPUData[i].MIDR = NewMIDR;
MIDR = NewMIDR;
}
auto NewMIDR = CTX->HostFeatures.CPUMIDRs[i];
if (MIDR != 0 && MIDR != NewMIDR) {
// CPU mismatch, claim hybrid
Hybrid = true;
}

// Truncate to 32-bits, top 32-bits are all reserved in MIDR
PerCPUData[i].ProductName = ProductNames::ARM_UNKNOWN;
PerCPUData[i].MIDR = NewMIDR;
MIDR = NewMIDR;
}

struct CPUMIDR {
Expand Down Expand Up @@ -1185,7 +1174,7 @@ FEXCore::CPUID::XCRResults CPUIDEmu::XCRFunction_0h() const {

CPUIDEmu::CPUIDEmu(const FEXCore::Context::ContextImpl* ctx)
: CTX {ctx} {
Cores = FEXCore::CPUInfo::CalculateNumberOfCPUs();
Cores = CTX->HostFeatures.CPUMIDRs.size();

// Setup some state tracking
SetupHostHybridFlag();
Expand Down
6 changes: 6 additions & 0 deletions FEXCore/include/FEXCore/Core/HostFeatures.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: MIT
#pragma once

#include <FEXCore/fextl/vector.h>
#include <cstdint>

namespace FEXCore {
Expand Down Expand Up @@ -37,5 +39,9 @@ struct HostFeatures {
// Float exception behaviour
bool SupportsAFP {};
bool SupportsFloatExceptions {};

// MIDR information
// Also used for determining number of CPU cores for CPUID
fextl::vector<uint32_t> CPUMIDRs;
};
} // namespace FEXCore
29 changes: 28 additions & 1 deletion Source/Common/HostFeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#include <FEXCore/Config/Config.h>
#include <FEXCore/Core/HostFeatures.h>
#include <FEXCore/Utils/CPUInfo.h>
#include <FEXCore/Utils/FileLoading.h>
#include <FEXCore/Utils/StringUtils.h>

#ifdef _M_X86_64
#define XBYAK64
Expand All @@ -17,6 +20,28 @@

namespace FEX {

void FillMIDRInformationViaLinux(FEXCore::HostFeatures* Features) {
auto Cores = FEXCore::CPUInfo::CalculateNumberOfCPUs();
Features->CPUMIDRs.resize(Cores);
#ifdef _M_ARM_64
for (size_t i = 0; i < Cores; ++i) {
std::error_code ec {};
fextl::string MIDRPath = fextl::fmt::format("/sys/devices/system/cpu/cpu{}/regs/identification/midr_el1", i);
std::array<char, 18> Data;
// Needs to be a fixed size since depending on kernel it will try to read a full page of data and fail
// Only read 18 bytes for a 64bit value prefixed with 0x
if (FEXCore::FileLoading::LoadFileToBuffer(MIDRPath, Data) == sizeof(Data)) {
uint64_t MIDR {};
auto Results = std::from_chars(Data.data() + 2, Data.data() + sizeof(Data), MIDR, 16);
if (Results.ec == std::errc()) {
// Truncate to 32-bits, top 32-bits are all reserved in MIDR
Features->CPUMIDRs[i] = static_cast<uint32_t>(MIDR);
}
}
}
#endif
}

#ifdef _M_ARM_64
#define GetSysReg(name, reg) \
static uint64_t Get_##name() { \
Expand Down Expand Up @@ -603,6 +628,8 @@ FEXCore::HostFeatures FetchHostFeatures() {
__asm volatile("mrs %[midr], midr_el1" : [midr] "=r"(MIDR));
#endif

return FetchHostFeatures(Features, true, CTR, MIDR);
auto HostFeatures = FetchHostFeatures(Features, true, CTR, MIDR);
FillMIDRInformationViaLinux(&HostFeatures);
return HostFeatures;
}
} // namespace FEX
2 changes: 2 additions & 0 deletions Source/Common/HostFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,8 @@ class CPUFeatures {
}
};

void FillMIDRInformationViaLinux(FEXCore::HostFeatures* Features);

FEXCore::HostFeatures FetchHostFeatures(FEX::CPUFeatures& Features, bool SupportsCacheMaintenanceOps, uint64_t CTR, uint64_t MIDR);
FEXCore::HostFeatures FetchHostFeatures();
} // namespace FEX
12 changes: 11 additions & 1 deletion Source/Windows/Common/CPUFeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@

#include <FEXCore/Core/Context.h>
#include <FEXCore/Core/HostFeatures.h>
#include <FEXCore/Utils/CPUInfo.h>
#include <FEXCore/fextl/fmt.h>

#include <windows.h>

#include "CPUFeatures.h"

namespace {

static void FillMIDRInformation(FEXCore::HostFeatures* Features, uint64_t MIDR) {
auto Cores = FEXCore::CPUInfo::CalculateNumberOfCPUs();
// Truncate to 32-bits, top 32-bits are all reserved in MIDR
Features->CPUMIDRs.resize(Cores, static_cast<uint32_t>(MIDR));
}

HKEY OpenProcessorKey(uint32_t Idx) {
HKEY Out;
auto Path = fextl::fmt::format("Hardware\\Description\\System\\CentralProcessor\\{}", Idx);
Expand Down Expand Up @@ -57,7 +65,9 @@ FEXCore::HostFeatures CPUFeatures::FetchHostFeatures(bool IsWine) {

RegCloseKey(Key);

return FEX::FetchHostFeatures(Features, !IsWine, CTR, MIDR);
auto HostFeatures = FEX::FetchHostFeatures(Features, !IsWine, CTR, MIDR);
FillMIDRInformation(&HostFeatures, MIDR);
return HostFeatures;
}

CPUFeatures::CPUFeatures(FEXCore::Context::Context& CTX) {
Expand Down

0 comments on commit fbf62f1

Please sign in to comment.