CPUID: Adds 4000_0001h function

Exposes the host architecture through this CPUID function. Only exposes
the architectures we support. Not burning 16-bits on using ELF machine
definitions here.

Uses 4 bits still for future expansion.
This commit is contained in:
Ryan Houdek 2022-03-22 16:26:21 -07:00
parent a247df50ea
commit 4cf48ca9bb
3 changed files with 42 additions and 6 deletions

View File

@ -826,7 +826,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_4000_0000h(uint32_t Leaf) {
// CPUID documentation information:
// 4000_0000h - 4FFF_FFFFh - No existing or future CPU will return information in this range
// Reserved entirely for VMs to do whatever they want.
Res.eax = 0x40000000;
Res.eax = 0x40000001;
// EBX, EDX, ECX become the hypervisor ID signature
constexpr static char HypervisorID[12] = "FEXIFEXIEMU";
@ -834,6 +834,25 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_4000_0000h(uint32_t Leaf) {
return Res;
}
// Hypervisor CPUID information leaf
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_4000_0001h(uint32_t Leaf) {
FEXCore::CPUID::FunctionResults Res{};
if (Leaf == 0) {
// EAX[3:0] Is the host architecture that FEX is running under
#ifdef _M_X86_64
// EAX[3:0] = 1 = x86_64 host architecture
Res.eax |= 0b0001;
#elif defined(_M_ARM_64)
// EAX[3:0] = 2 = AArch64 host architecture
Res.eax |= 0b0010;
#else
// EAX[3:0] = 0 = Unknown architecture
#endif
}
return Res;
}
// Highest extended function implemented
FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0000h(uint32_t Leaf) {
FEXCore::CPUID::FunctionResults Res{};
@ -1228,6 +1247,7 @@ void CPUIDEmu::Init(FEXCore::Context::Context *ctx) {
#endif
// Hypervisor CPUID information leaf
RegisterFunction(0x4000'0000, &CPUIDEmu::Function_4000_0000h);
RegisterFunction(0x4000'0001, &CPUIDEmu::Function_4000_0001h);
// Largest extended function number
RegisterFunction(0x8000'0000, &CPUIDEmu::Function_8000_0000h);

View File

@ -80,6 +80,7 @@ private:
FEXCore::CPUID::FunctionResults Function_15h(uint32_t Leaf);
FEXCore::CPUID::FunctionResults Function_1Ah(uint32_t Leaf);
FEXCore::CPUID::FunctionResults Function_4000_0000h(uint32_t Leaf);
FEXCore::CPUID::FunctionResults Function_4000_0001h(uint32_t Leaf);
FEXCore::CPUID::FunctionResults Function_8000_0000h(uint32_t Leaf);
FEXCore::CPUID::FunctionResults Function_8000_0001h(uint32_t Leaf);
FEXCore::CPUID::FunctionResults Function_8000_0002h(uint32_t Leaf);

View File

@ -6,17 +6,32 @@
* https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/feature-discovery
* EAX - The maximum input value for the hypervisor CPUID information
** 4000_0000h - Only first leaf
* 4000_0001h
* EBX - Hypervisor vendor ID signature
** 'FEXI' - 4958_4546h
* 'FEXI' - 4958_4546h
* ECX - Hypervisor vendor ID signature
** 'FEXI' - 4958_4546h
* 'FEXI' - 4958_4546h
* EDX - Hypervisor vendor ID signature
** 'EMU\0' - 0055_4d45h
* 'EMU\0' - 0055_4d45h
* memcpy ebx:ecx:edx in to a 12 byte string to get 'FEXIFEXIEMU\0' for determining running under FEX
## 4000_0001h - 4000_000Fh
## 4000_0001h - Hypervisor config function
### Sub-Leaf 0: ECX == 0
* EAX:
* Bits EAX[3:0] - Host architecture
* 0 - Unknown architecture
* 1 - x86_64
* 2 - AArch64
* 3-15: **Reserved**
* EBX - **Reserved** - Read as zero
* ECX - **Reserved** - Read as zero
* EDX - **Reserved** - Read as zero
### Sub-Leaf 0000_0001 - FFFF_FFFF: **Reserved**
## 4000_0002h - 4000_000Fh
* **Reserved range**
* Returns zero until implemented