[v1.05][X86] Add preeliminary support for Meteor Lake (#255)

This commit is contained in:
Dr-Noob
2024-07-28 22:51:16 +01:00
parent 260f9ec3b8
commit ac308204c7
5 changed files with 62 additions and 10 deletions

View File

@@ -45,8 +45,9 @@ enum {
}; };
enum { enum {
CORE_TYPE_EFFICIENCY,
CORE_TYPE_PERFORMANCE, CORE_TYPE_PERFORMANCE,
CORE_TYPE_EFFICIENCY,
CORE_TYPE_LP_EFFICIENCY,
CORE_TYPE_UNKNOWN CORE_TYPE_UNKNOWN
}; };

View File

@@ -614,8 +614,9 @@ bool print_cpufetch_x86(struct cpuInfo* cpu, STYLE s, struct color** cs, struct
} }
if(hybrid_architecture) { if(hybrid_architecture) {
if(ptr->core_type == CORE_TYPE_EFFICIENCY) sprintf(cpu_num, "E-cores:"); if (ptr->core_type == CORE_TYPE_PERFORMANCE) sprintf(cpu_num, "P-cores:");
else if(ptr->core_type == CORE_TYPE_PERFORMANCE) sprintf(cpu_num, "P-cores:"); else if (ptr->core_type == CORE_TYPE_EFFICIENCY) sprintf(cpu_num, "E-cores:");
else if (ptr->core_type == CORE_TYPE_LP_EFFICIENCY) sprintf(cpu_num, "LP-E-cores:");
else printBug("Found invalid core type!\n"); else printBug("Found invalid core type!\n");
setAttribute(art, ATTRIBUTE_CPU_NUM, cpu_num); setAttribute(art, ATTRIBUTE_CPU_NUM, cpu_num);

View File

@@ -397,6 +397,17 @@ bool set_cpu_module(int m, int total_modules, int32_t* first_core) {
uint32_t edx = 0; uint32_t edx = 0;
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
int32_t core_type = eax >> 24 & 0xFF; int32_t core_type = eax >> 24 & 0xFF;
// Here we artificially create a new core type for
// LP-E cores. In case the core has no L3 (on a hybrid)
// architecture, then we now it's an LP-E core.
eax = 0x4;
ebx = 0;
ecx = 0x3;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
core_type += eax == 0;
bool found = false; bool found = false;
for(int j=0; j < total_modules && !found; j++) { for(int j=0; j < total_modules && !found; j++) {
@@ -423,13 +434,19 @@ bool set_cpu_module(int m, int total_modules, int32_t* first_core) {
#endif #endif
} }
else { else {
// This is a normal architecture // This is a non-hybrid architecture
*first_core = 0; *first_core = 0;
} }
return true; return true;
} }
// Difference between E and LP-E cores:
// According to Intel Core Ultra Processor Datasheet Volume 1 of 2
// (https://www.intel.com/content/www/us/en/content-details/792044/intel-core-ultra-processor-datasheet-volume-1-of-2.html),
// LP-E cores do not have L3 cache. This seems to be the only way of differentiating them.
// - https://community.intel.com/t5/Processors/Detecting-LP-E-Cores-on-Meteor-Lake-in-software/m-p/1584555/highlight/true#M70732
// - https://x.com/InstLatX64/status/1741416428538941718
int32_t get_core_type(void) { int32_t get_core_type(void) {
uint32_t eax = 0x0000001A; uint32_t eax = 0x0000001A;
uint32_t ebx = 0; uint32_t ebx = 0;
@@ -440,8 +457,26 @@ int32_t get_core_type(void) {
cpuid(&eax, &ebx, &ecx, &edx); cpuid(&eax, &ebx, &ecx, &edx);
int32_t type = eax >> 24 & 0xFF; int32_t type = eax >> 24 & 0xFF;
if(type == 0x20) return CORE_TYPE_EFFICIENCY; if (type == 0x40) return CORE_TYPE_PERFORMANCE;
else if(type == 0x40) return CORE_TYPE_PERFORMANCE; else if (type == 0x20) {
// get_core_type is only called iff hybrid_flag is true, which can only
// happen if CPUID maxLevel >= 0x7 so we can assume the CPU supports
// CPUID leaf 0x4
eax = 0x4;
ebx = 0;
ecx = 0x3;
edx = 0;
cpuid(&eax, &ebx, &ecx, &edx);
if (eax == 0) {
// No L3 access, this is LP-E
return CORE_TYPE_LP_EFFICIENCY;
}
else {
return CORE_TYPE_EFFICIENCY;
}
}
else { else {
printErr("Found invalid core type: 0x%.8X\n", type); printErr("Found invalid core type: 0x%.8X\n", type);
return CORE_TYPE_UNKNOWN; return CORE_TYPE_UNKNOWN;
@@ -456,7 +491,6 @@ struct cpuInfo* get_cpu_info(void) {
cpu->cach = NULL; cpu->cach = NULL;
cpu->feat = NULL; cpu->feat = NULL;
cpu->num_cpus = 1;
uint32_t eax = 0; uint32_t eax = 0;
uint32_t ebx = 0; uint32_t ebx = 0;
uint32_t ecx = 0; uint32_t ecx = 0;
@@ -514,7 +548,13 @@ struct cpuInfo* get_cpu_info(void) {
cpu->hybrid_flag = (edx >> 15) & 0x1; cpu->hybrid_flag = (edx >> 15) & 0x1;
} }
if(cpu->hybrid_flag) cpu->num_cpus = 2; if(cpu->hybrid_flag) {
struct uarch* tmp = get_cpu_uarch(cpu);
cpu->num_cpus = get_hybrid_num_cpus(tmp);
}
else {
cpu->num_cpus = 1;
}
struct cpuInfo* ptr = cpu; struct cpuInfo* ptr = cpu;
for(uint32_t i=0; i < cpu->num_cpus; i++) { for(uint32_t i=0; i < cpu->num_cpus; i++) {
@@ -529,8 +569,9 @@ struct cpuInfo* get_cpu_info(void) {
ptr->topo = NULL; ptr->topo = NULL;
ptr->cach = NULL; ptr->cach = NULL;
ptr->feat = NULL; ptr->feat = NULL;
// We assume that this cores have the // We assume that this core has the
// same cpuid capabilities // same cpuid capabilities as the core in the
// first module
ptr->cpu_vendor = cpu->cpu_vendor; ptr->cpu_vendor = cpu->cpu_vendor;
ptr->maxLevels = cpu->maxLevels; ptr->maxLevels = cpu->maxLevels;
ptr->maxExtendedLevels = cpu->maxExtendedLevels; ptr->maxExtendedLevels = cpu->maxExtendedLevels;

View File

@@ -94,6 +94,7 @@ enum {
UARCH_TIGER_LAKE, UARCH_TIGER_LAKE,
UARCH_ALDER_LAKE, UARCH_ALDER_LAKE,
UARCH_RAPTOR_LAKE, UARCH_RAPTOR_LAKE,
UARCH_METEOR_LAKE,
// AMD // // AMD //
UARCH_AM486, UARCH_AM486,
UARCH_AM5X86, UARCH_AM5X86,
@@ -248,6 +249,7 @@ struct uarch* get_uarch_from_cpuid_intel(uint32_t ef, uint32_t f, uint32_t em, u
CHECK_UARCH(arch, 0, 6, 10, 5, NA, "Comet Lake", UARCH_COMET_LAKE, 14) // wikichip CHECK_UARCH(arch, 0, 6, 10, 5, NA, "Comet Lake", UARCH_COMET_LAKE, 14) // wikichip
CHECK_UARCH(arch, 0, 6, 10, 6, NA, "Comet Lake", UARCH_COMET_LAKE, 14) // instlatx64.atw.hu (i7-10710U) CHECK_UARCH(arch, 0, 6, 10, 6, NA, "Comet Lake", UARCH_COMET_LAKE, 14) // instlatx64.atw.hu (i7-10710U)
CHECK_UARCH(arch, 0, 6, 10, 7, NA, "Rocket Lake", UARCH_ROCKET_LAKE, 14) // instlatx64.atw.hu (i7-11700K) CHECK_UARCH(arch, 0, 6, 10, 7, NA, "Rocket Lake", UARCH_ROCKET_LAKE, 14) // instlatx64.atw.hu (i7-11700K)
CHECK_UARCH(arch, 0, 6, 10, 10, NA, "Meteor Lake", UARCH_METEOR_LAKE, 7) // instlatx64.atw.hu (Ultra 7 155H)
CHECK_UARCH(arch, 0, 6, 11, 7, NA, "Raptor Lake", UARCH_RAPTOR_LAKE, 10) // instlatx64.atw.hu (i5-13600K) CHECK_UARCH(arch, 0, 6, 11, 7, NA, "Raptor Lake", UARCH_RAPTOR_LAKE, 10) // instlatx64.atw.hu (i5-13600K)
CHECK_UARCH(arch, 0, 6, 11, 10, NA, "Raptor Lake", UARCH_RAPTOR_LAKE, 10) // instlatx64.atw.hu (i7-1370P) CHECK_UARCH(arch, 0, 6, 11, 10, NA, "Raptor Lake", UARCH_RAPTOR_LAKE, 10) // instlatx64.atw.hu (i7-1370P)
CHECK_UARCH(arch, 0, 6, 11, 14, NA, "Alder Lake", UARCH_ALDER_LAKE, 10) // instlatx64.atw.hu (Alder Lake-N) CHECK_UARCH(arch, 0, 6, 11, 14, NA, "Alder Lake", UARCH_ALDER_LAKE, 10) // instlatx64.atw.hu (Alder Lake-N)
@@ -536,6 +538,7 @@ int get_number_of_vpus(struct cpuInfo* cpu) {
case UARCH_TIGER_LAKE: case UARCH_TIGER_LAKE:
case UARCH_ALDER_LAKE: case UARCH_ALDER_LAKE:
case UARCH_RAPTOR_LAKE: case UARCH_RAPTOR_LAKE:
case UARCH_METEOR_LAKE:
// AMD // AMD
case UARCH_ZEN2: case UARCH_ZEN2:
@@ -549,6 +552,11 @@ int get_number_of_vpus(struct cpuInfo* cpu) {
} }
} }
uint32_t get_hybrid_num_cpus(struct uarch* arch) {
if (arch->uarch == UARCH_METEOR_LAKE) return 3;
else return 2;
}
bool choose_new_intel_logo_uarch(struct cpuInfo* cpu) { bool choose_new_intel_logo_uarch(struct cpuInfo* cpu) {
switch(cpu->arch->uarch) { switch(cpu->arch->uarch) {
case UARCH_ALDER_LAKE: case UARCH_ALDER_LAKE:

View File

@@ -12,6 +12,7 @@ char* infer_cpu_name_from_uarch(struct uarch* arch);
bool vpus_are_AVX512(struct cpuInfo* cpu); bool vpus_are_AVX512(struct cpuInfo* cpu);
bool is_knights_landing(struct cpuInfo* cpu); bool is_knights_landing(struct cpuInfo* cpu);
int get_number_of_vpus(struct cpuInfo* cpu); int get_number_of_vpus(struct cpuInfo* cpu);
uint32_t get_hybrid_num_cpus(struct uarch* arch);
bool choose_new_intel_logo_uarch(struct cpuInfo* cpu); bool choose_new_intel_logo_uarch(struct cpuInfo* cpu);
char* get_str_uarch(struct cpuInfo* cpu); char* get_str_uarch(struct cpuInfo* cpu);
char* get_str_process(struct cpuInfo* cpu); char* get_str_process(struct cpuInfo* cpu);