mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2025-02-25 18:55:23 -06:00
Rework Line #7 left block. Add preliminary CPUID function to detect CPU Topology
This commit is contained in:
committed by
Sam Demeulemeester
parent
fac6e2a973
commit
979b85548d
112
system/cpuid.c
112
system/cpuid.c
@@ -1,12 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2020-2022 Martin Whitaker.
|
||||
// Copyright (C) 2004-2022 Sam Demeulemeester.
|
||||
//
|
||||
// Derived from memtest86+ cpuid.h
|
||||
// (original contained no copyright statement)
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpuid.h"
|
||||
#include "display.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Variables
|
||||
@@ -20,7 +22,7 @@ cpuid_info_t cpuid_info;
|
||||
|
||||
void cpuid_init(void)
|
||||
{
|
||||
uint32_t dummy[3];
|
||||
uint32_t reg[4];
|
||||
char *p, *q;
|
||||
|
||||
// Get the max standard cpuid & vendor ID.
|
||||
@@ -46,26 +48,26 @@ void cpuid_init(void)
|
||||
if (cpuid_info.max_cpuid >= 6) {
|
||||
cpuid(0x6, 0,
|
||||
&cpuid_info.dts_pmp,
|
||||
&dummy[0],
|
||||
&dummy[1],
|
||||
&dummy[2]
|
||||
®[0],
|
||||
®[1],
|
||||
®[2]
|
||||
);
|
||||
}
|
||||
|
||||
// Get the max extended cpuid.
|
||||
cpuid(0x80000000, 0,
|
||||
&cpuid_info.max_xcpuid,
|
||||
&dummy[0],
|
||||
&dummy[1],
|
||||
&dummy[2]
|
||||
®[0],
|
||||
®[1],
|
||||
®[2]
|
||||
);
|
||||
|
||||
// Get extended feature flags, only save EDX.
|
||||
if (cpuid_info.max_xcpuid >= 0x80000001) {
|
||||
cpuid(0x80000001, 0,
|
||||
&dummy[0],
|
||||
&dummy[1],
|
||||
&dummy[2],
|
||||
®[0],
|
||||
®[1],
|
||||
®[2],
|
||||
&cpuid_info.flags.raw[2]
|
||||
);
|
||||
}
|
||||
@@ -112,16 +114,16 @@ void cpuid_init(void)
|
||||
// AMD Processors
|
||||
if (cpuid_info.max_xcpuid >= 0x80000005) {
|
||||
cpuid(0x80000005, 0,
|
||||
&dummy[0],
|
||||
&dummy[1],
|
||||
®[0],
|
||||
®[1],
|
||||
&cpuid_info.cache_info.raw[0],
|
||||
&cpuid_info.cache_info.raw[1]
|
||||
);
|
||||
}
|
||||
if (cpuid_info.max_xcpuid >= 0x80000006) {
|
||||
cpuid(0x80000006, 0,
|
||||
&dummy[0],
|
||||
&dummy[1],
|
||||
®[0],
|
||||
®[1],
|
||||
&cpuid_info.cache_info.raw[2],
|
||||
&cpuid_info.cache_info.raw[3]
|
||||
);
|
||||
@@ -132,4 +134,84 @@ void cpuid_init(void)
|
||||
// No cpuid info to read.
|
||||
break;
|
||||
}
|
||||
|
||||
// Detect CPU Topology (Core/Thread) infos
|
||||
cpuid_info.topology.core_count = -1;
|
||||
cpuid_info.topology.thread_count = -1;
|
||||
cpuid_info.topology.is_hybrid = 0;
|
||||
cpuid_info.topology.ecore_count = -1;
|
||||
cpuid_info.topology.pcore_count = -1;
|
||||
|
||||
int thread_per_core = 1;
|
||||
|
||||
switch (cpuid_info.vendor_id.str[0]) {
|
||||
case 'A':
|
||||
// AMD Processors
|
||||
if (cpuid_info.max_xcpuid >= 0x80000008) {
|
||||
|
||||
cpuid(0x80000008, 0, ®[0], ®[1], ®[2], ®[3]);
|
||||
cpuid_info.topology.thread_count = (reg[2] & 0xFF) + 1;
|
||||
|
||||
if (cpuid_info.max_xcpuid >= 0x8000001E) {
|
||||
cpuid(0x8000001E, 0, ®[0], ®[1], ®[2], ®[3]);
|
||||
|
||||
if (((reg[1] >> 8) & 0x3) > 0) {
|
||||
thread_per_core = 2;
|
||||
}
|
||||
} else if (cpuid_info.flags.htt) {
|
||||
thread_per_core = 2;
|
||||
}
|
||||
cpuid_info.topology.core_count = cpuid_info.topology.thread_count / thread_per_core;
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
// VIA / CentaurHauls
|
||||
break;
|
||||
case 'G':
|
||||
if (cpuid_info.vendor_id.str[7] == 'T') break; // Transmeta
|
||||
// Intel
|
||||
if (cpuid_info.max_cpuid >= 0xB) {
|
||||
|
||||
// Populate Hybrid Status (CPUID 7.EDX[15]) for Alder Lake+
|
||||
cpuid(0x7, 0, ®[0], ®[1], ®[2], ®[3]);
|
||||
if (reg[3] & (1 << 15)) {
|
||||
cpuid_info.topology.is_hybrid = 1;
|
||||
}
|
||||
|
||||
for (int i=0; i < 4; i++) {
|
||||
cpuid(0xB, i, ®[0], ®[1], ®[2], ®[3]);
|
||||
|
||||
switch((reg[2] >> 8) & 0xFF) {
|
||||
case 1: // SMT
|
||||
thread_per_core = reg[1] & 0xFF;
|
||||
break;
|
||||
case 2: // Cores
|
||||
cpuid_info.topology.thread_count = reg[1] & 0xFFFF;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
cpuid_info.topology.core_count = cpuid_info.topology.thread_count / thread_per_core;
|
||||
|
||||
} else if (cpuid_info.max_cpuid >= 0x4) {
|
||||
cpuid(4, 0, ®[0], ®[1], ®[2], ®[3]);
|
||||
|
||||
cpuid_info.topology.core_count = (reg[0] >> 26) + 1;
|
||||
cpuid_info.topology.thread_count = cpuid_info.topology.core_count;
|
||||
|
||||
if (cpuid_info.flags.htt){
|
||||
cpuid_info.topology.thread_count *= 2;
|
||||
}
|
||||
} else if (cpuid_info.max_cpuid >= 0x2) {
|
||||
if(cpuid_info.flags.htt){
|
||||
cpuid_info.topology.core_count = 1;
|
||||
cpuid_info.topology.thread_count = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user