mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-23 23:35:14 +00:00
target-i386: Implement CPUID[0xB] (Extended Topology Enumeration)
I looked at a dozen Intel CPU that have this CPUID and all of them always had Core offset as 1 (a wasted bit when hyperthreading is disabled) and Package offset at least 4 (wasted bits at <= 4 cores). QEMU uses more compact IDs and it doesn't make much sense to change it now. I keep the SMT and Core sub-leaves even if there is just one thread/core; it makes the code simpler and there should be no harm. Backports commit 5232d00a041c8f3628b3532ef35d703a1f0dac19 from qemu
This commit is contained in:
parent
8991e8bf0b
commit
610a52e9c7
|
@ -35,6 +35,7 @@
|
|||
#include "hw/hw.h"
|
||||
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "topology.h"
|
||||
#include "hw/cpu/icc_bus.h"
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include "exec/address-spaces.h"
|
||||
|
@ -2423,6 +2424,36 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
|
|||
*ecx = 0;
|
||||
*edx = 0;
|
||||
break;
|
||||
case 0xB:
|
||||
/* Extended Topology Enumeration Leaf */
|
||||
if (!cpu->enable_cpuid_0xb) {
|
||||
*eax = *ebx = *ecx = *edx = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
*ecx = count & 0xff;
|
||||
*edx = cpu->apic_id;
|
||||
|
||||
switch (count) {
|
||||
case 0:
|
||||
*eax = apicid_core_offset(smp_cores, smp_threads);
|
||||
*ebx = smp_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
|
||||
break;
|
||||
case 1:
|
||||
*eax = apicid_pkg_offset(smp_cores, smp_threads);
|
||||
*ebx = smp_cores * smp_threads;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
|
||||
break;
|
||||
default:
|
||||
*eax = 0;
|
||||
*ebx = 0;
|
||||
*ecx |= CPUID_TOPOLOGY_LEVEL_INVALID;
|
||||
}
|
||||
|
||||
assert(!(*eax & ~0x1f));
|
||||
*ebx &= 0xffff; /* The count doesn't need to be reliable. */
|
||||
break;
|
||||
case 0xD: {
|
||||
uint64_t ena_mask;
|
||||
int i;
|
||||
|
|
|
@ -635,6 +635,11 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
|
|||
#define CPUID_MWAIT_IBE (1U << 1) /* Interrupts can exit capability */
|
||||
#define CPUID_MWAIT_EMX (1U << 0) /* enumeration supported */
|
||||
|
||||
/* CPUID[0xB].ECX level types */
|
||||
#define CPUID_TOPOLOGY_LEVEL_INVALID (0U << 8)
|
||||
#define CPUID_TOPOLOGY_LEVEL_SMT (1U << 8)
|
||||
#define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
|
||||
|
||||
#ifndef HYPERV_SPINLOCK_NEVER_RETRY
|
||||
#define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF
|
||||
#endif
|
||||
|
@ -1160,6 +1165,9 @@ typedef struct X86CPU {
|
|||
*/
|
||||
bool enable_pmu;
|
||||
|
||||
/* Compatibility bits for old machine types: */
|
||||
bool enable_cpuid_0xb;
|
||||
|
||||
/* in order to simplify APIC support, we leave this pointer to the
|
||||
user */
|
||||
struct DeviceState *apic_state;
|
||||
|
|
Loading…
Reference in a new issue