Rework Line #7 left block. Add preliminary CPUID function to detect CPU Topology
This commit is contained in:
parent
fac6e2a973
commit
979b85548d
|
@ -66,16 +66,12 @@
|
|||
|
||||
#define SEL_AREA (SEL_W * SEL_H)
|
||||
|
||||
static const char *cpu_mode_str[] = { "PAR", "SEQ", "RR " };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private Variables
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
static uint16_t popup_save_buffer[POP_W * POP_H];
|
||||
|
||||
static bool smp_enabled = true;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Variables
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -91,6 +87,8 @@ error_mode_t error_mode = ERROR_MODE_NONE;
|
|||
|
||||
cpu_state_t cpu_state[MAX_CPUS];
|
||||
|
||||
bool smp_enabled = true;
|
||||
|
||||
bool enable_temperature = true;
|
||||
bool enable_trace = false;
|
||||
|
||||
|
@ -867,7 +865,7 @@ void config_menu(bool initial)
|
|||
}
|
||||
|
||||
if (cpu_mode != old_cpu_mode) {
|
||||
display_cpu_mode(cpu_mode_str[cpu_mode]);
|
||||
display_cpu_topology();
|
||||
restart = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ extern error_mode_t error_mode;
|
|||
|
||||
extern cpu_state_t cpu_state[MAX_CPUS];
|
||||
|
||||
extern bool smp_enabled;
|
||||
|
||||
extern bool enable_temperature;
|
||||
extern bool enable_trace;
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
|
||||
static const char spin_state[NUM_SPIN_STATES] = { '|', '/', '-', '\\' };
|
||||
|
||||
static const char *cpu_mode_str[] = { "PAR", "SEQ", "RR " };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Private Variables
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -91,8 +93,8 @@ void display_init(void)
|
|||
prints(4, 0, "L3 Cache: N/A | Testing: ");
|
||||
prints(5, 0, "Memory : N/A | Pattern: ");
|
||||
prints(6, 0, "-------------------------------------------------------------------------------");
|
||||
prints(7, 0, "CPU cores: available, enabled | Time: Status: Init. ");
|
||||
prints(8, 0, "Run mode : PAR Using: | Pass: Errors: ");
|
||||
prints(7, 0, "CPU: SMP: N/A | Time: Status: Init. ");
|
||||
prints(8, 0, "Using: | Pass: Errors: ");
|
||||
prints(9, 0, "-------------------------------------------------------------------------------");
|
||||
|
||||
// Redraw lines using box drawing characters.
|
||||
|
@ -133,11 +135,6 @@ void display_init(void)
|
|||
if (clks_per_msec) {
|
||||
display_cpu_clk((int)(clks_per_msec / 1000));
|
||||
}
|
||||
if (cpuid_info.flags.lm) {
|
||||
display_cpu_addr_mode("(x64)");
|
||||
} else if (cpuid_info.flags.pae) {
|
||||
display_cpu_addr_mode("(PAE)");
|
||||
}
|
||||
if (l1_cache) {
|
||||
display_l1_cache_size(l1_cache);
|
||||
}
|
||||
|
@ -167,6 +164,55 @@ void display_init(void)
|
|||
scroll_message_row = ROW_SCROLL_T;
|
||||
}
|
||||
|
||||
void display_cpu_topology(void)
|
||||
{
|
||||
extern int num_enabled_cpus;
|
||||
int num_cpu_sockets = 1;
|
||||
|
||||
if(smp_enabled) {
|
||||
printf(7,30, "%uT (%s)", num_enabled_cpus, cpu_mode_str[cpu_mode]);
|
||||
} else {
|
||||
prints(7,30, "Disabled");
|
||||
}
|
||||
|
||||
// If topology failed, assume topology according to APIC
|
||||
if(cpuid_info.topology.core_count <= 0) {
|
||||
|
||||
cpuid_info.topology.core_count = num_enabled_cpus;
|
||||
cpuid_info.topology.thread_count = num_enabled_cpus;
|
||||
|
||||
if(cpuid_info.flags.htt && num_enabled_cpus >= 2 && num_enabled_cpus % 2 == 0) {
|
||||
cpuid_info.topology.core_count /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute number of sockets according to individual CPU core count
|
||||
if(num_enabled_cpus > cpuid_info.topology.thread_count &&
|
||||
num_enabled_cpus % cpuid_info.topology.thread_count == 0) {
|
||||
|
||||
num_cpu_sockets = num_enabled_cpus / cpuid_info.topology.thread_count;
|
||||
}
|
||||
|
||||
// Temporary workaround for Hybrid CPUs.
|
||||
// TODO: run cpuid on each core to get correct P+E topology
|
||||
if(cpuid_info.topology.is_hybrid) {
|
||||
printf(7, 5, "%u Threads (%s)", cpuid_info.topology.thread_count,
|
||||
cpuid_info.flags.lm ? "X64" : "PAE");
|
||||
return;
|
||||
}
|
||||
|
||||
if(num_cpu_sockets < 2) {
|
||||
printf(7, 5, "%uC/%uT (%s)", cpuid_info.topology.core_count,
|
||||
cpuid_info.topology.thread_count,
|
||||
cpuid_info.flags.lm ? "X64" : "PAE");
|
||||
} else {
|
||||
printf(7, 5, "%uS/%uC/%uT (%s)", num_cpu_sockets,
|
||||
num_cpu_sockets * cpuid_info.topology.core_count,
|
||||
num_cpu_sockets * cpuid_info.topology.thread_count,
|
||||
cpuid_info.flags.lm ? "X64" : "PAE");
|
||||
}
|
||||
}
|
||||
|
||||
void post_display_init(void)
|
||||
{
|
||||
print_smbios_startup_info();
|
||||
|
|
|
@ -38,9 +38,6 @@
|
|||
#define display_cpu_clk(freq) \
|
||||
printf(1, 10, "%i MHz", freq)
|
||||
|
||||
#define display_cpu_addr_mode(str) \
|
||||
prints(1, 20, str)
|
||||
|
||||
#define display_l1_cache_size(size) \
|
||||
printf(2, 9, "%6kB", (uintptr_t)(size));
|
||||
|
||||
|
@ -72,21 +69,12 @@
|
|||
dmicol = prints(23, dmicol, sys_man); \
|
||||
prints(23, dmicol + 1, sys_sku);
|
||||
|
||||
#define display_available_cpus(count) \
|
||||
printi(7, 10, count, 4, false, false)
|
||||
|
||||
#define display_enabled_cpus(count) \
|
||||
printi(7, 25, count, 4, false, false)
|
||||
|
||||
#define display_cpu_mode(str) \
|
||||
prints(8, 11, str)
|
||||
|
||||
#define display_active_cpu(cpu_num) \
|
||||
prints(8, 25, "core #"); \
|
||||
printi(8, 31, cpu_num, 3, false, true)
|
||||
prints(8, 7, "Core #"); \
|
||||
printi(8, 13, cpu_num, 3, false, true)
|
||||
|
||||
#define display_all_active \
|
||||
prints(8, 25, "all cores")
|
||||
prints(8, 7, "All Cores")
|
||||
|
||||
#define display_spinner(spin_state) \
|
||||
printc(7, 76, spin_state)
|
||||
|
@ -196,6 +184,8 @@ extern int scroll_message_row;
|
|||
|
||||
void display_init(void);
|
||||
|
||||
void display_cpu_topology(void);
|
||||
|
||||
void post_display_init(void);
|
||||
|
||||
void display_start_run(void);
|
||||
|
|
|
@ -67,8 +67,6 @@
|
|||
|
||||
static volatile int init_state = 0;
|
||||
|
||||
static int num_enabled_cpus = 1;
|
||||
|
||||
static uintptr_t low_load_addr;
|
||||
static uintptr_t high_load_addr;
|
||||
|
||||
|
@ -100,6 +98,7 @@ efi_info_t saved_efi_info;
|
|||
uint8_t chunk_index[MAX_CPUS];
|
||||
|
||||
int num_active_cpus = 0;
|
||||
int num_enabled_cpus = 1;
|
||||
|
||||
int master_cpu = 0;
|
||||
|
||||
|
@ -230,8 +229,6 @@ static void global_init(void)
|
|||
|
||||
clear_message_area();
|
||||
|
||||
display_available_cpus(num_available_cpus);
|
||||
|
||||
num_enabled_cpus = 0;
|
||||
for (int i = 0; i < num_available_cpus; i++) {
|
||||
if (cpu_state[i] == CPU_STATE_ENABLED) {
|
||||
|
@ -239,7 +236,7 @@ static void global_init(void)
|
|||
num_enabled_cpus++;
|
||||
}
|
||||
}
|
||||
display_enabled_cpus(num_enabled_cpus);
|
||||
display_cpu_topology();
|
||||
|
||||
master_cpu = 0;
|
||||
|
||||
|
|
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
*
|
||||
*//*
|
||||
* 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>
|
||||
|
@ -133,6 +133,14 @@ typedef union {
|
|||
};
|
||||
} cpuid_custom_features;
|
||||
|
||||
typedef struct {
|
||||
int core_count;
|
||||
int thread_count;
|
||||
int is_hybrid;
|
||||
int ecore_count;
|
||||
int pcore_count;
|
||||
} topology_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t max_cpuid;
|
||||
uint32_t max_xcpuid;
|
||||
|
@ -144,6 +152,7 @@ typedef struct {
|
|||
cpuid_brand_string_t brand_id;
|
||||
cpuid_cache_info_t cache_info;
|
||||
cpuid_custom_features custom;
|
||||
topology_t topology;
|
||||
} cpuid_info_t;
|
||||
|
||||
typedef union {
|
||||
|
|
Loading…
Reference in New Issue