mirror of
https://github.com/0Nera/BMOSP.git
synced 2024-12-03 21:52:04 +03:00
91 lines
3.1 KiB
C
91 lines
3.1 KiB
C
#include <system.h>
|
||
|
||
static char fxsave_region[512] __attribute__((aligned(16)));
|
||
|
||
static inline void cpuid(uint32_t leaf, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) {
|
||
asm volatile("cpuid" : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) : "a"(leaf));
|
||
}
|
||
|
||
static inline void L1_cache_size( ) {
|
||
uint32_t eax, ebx, ecx, edx;
|
||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||
if ((edx & 0xFF) == 0) {
|
||
fb_printf("L1 кэш недоступен\n");
|
||
return;
|
||
}
|
||
fb_printf("L1: Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", ecx & 0xFF, (ecx >> 12) & 0x07,
|
||
(ecx >> 16) & 0xFFff);
|
||
}
|
||
|
||
static inline void L2_cache_size( ) {
|
||
uint32_t eax, ebx, ecx, edx;
|
||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||
if ((edx & 0xFF) == 0) {
|
||
fb_printf("L2 кэш недоступен\n");
|
||
return;
|
||
}
|
||
fb_printf("L2: Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", ecx & 0xFF, (ecx >> 12) & 0x0F,
|
||
(ecx >> 16) & 0xFFFF);
|
||
}
|
||
|
||
static inline void L3_cache_size( ) {
|
||
uint32_t eax, ebx, ecx, edx;
|
||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||
if ((edx & 0xFF) == 0) {
|
||
fb_printf("L3 кэш недоступен\n");
|
||
return;
|
||
}
|
||
fb_printf("L3: Размер строки: %u B, Тип ассоциации: %u, Размер кэша: %u КБ\n", edx & 0xFF, (edx >> 12) & 0x0F,
|
||
(edx >> 16) & 0xFFFF);
|
||
}
|
||
|
||
static void cpu_info( ) {
|
||
uint32_t eax, ebx, ecx, edx;
|
||
cpuid(0x8000001E, &eax, &ebx, &ecx, &edx);
|
||
|
||
uint32_t apic_id = eax;
|
||
uint8_t compute_unit_id = ebx & 0xFF;
|
||
uint8_t cores_per_compute_unit = ((ebx >> 8) & 3) + 1;
|
||
uint8_t node_id = ecx & 0xFF;
|
||
uint8_t nodes_per_processor = ((ecx >> 8) & 3) + 1;
|
||
|
||
fb_printf("Топология процессора:\n");
|
||
fb_printf(" Идентификатор APIC: %u\n", apic_id);
|
||
fb_printf(" Идентификатор вычислительной единицы: %u\n", compute_unit_id);
|
||
fb_printf(" Ядра на вычислительную единицу: %u\n", cores_per_compute_unit);
|
||
fb_printf(" Идентификатор узла: %u\n", node_id);
|
||
fb_printf(" Узлы на процессор: %u\n", nodes_per_processor);
|
||
}
|
||
|
||
module_info_t __attribute__((section(".minit"))) init(env_t *env) {
|
||
uint32_t eax, ebx, ecx, edx;
|
||
|
||
init_env(env);
|
||
|
||
cpuid(1, &eax, &ebx, &ecx, &edx);
|
||
|
||
if (ecx & (1 << 31)) {
|
||
fb_printf("Запуск на эмуляторе\n");
|
||
} else {
|
||
fb_printf("Запуск на физическом процессоре\n");
|
||
}
|
||
|
||
L1_cache_size( );
|
||
L2_cache_size( );
|
||
L3_cache_size( );
|
||
|
||
cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||
if (eax >= 0x8000001E) { cpu_info( ); }
|
||
|
||
return (module_info_t){ .name = (char *)"CPUBENCH",
|
||
.message = (char *)"Дополнительная информация о процессоре",
|
||
.type = 0,
|
||
.data_size = 0,
|
||
.data = (void *)0,
|
||
.err_code = 0,
|
||
.module_id = 0,
|
||
.irq = 0,
|
||
.irq_handler = 0,
|
||
.get_func = 0,
|
||
.after_init = 0 };
|
||
} |