Skip to content

Commit

Permalink
HostFeatures: Moves MIDR querying to the frontend
Browse files Browse the repository at this point in the history
The MIDR querying is inherently OS specific and needs a bit of special
casing. Instead let the frontend inform FEXCore how many CPU cores there
are and their MIDRs instead.

This lets us keep the Linux specific code in the frontend.
  • Loading branch information
Sonicadvance1 committed Aug 23, 2024
1 parent 4f40416 commit 0ec724c
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 0ec724c

Please sign in to comment.