syscall #17
@@ -10,6 +10,10 @@ void wrmsr(uint32_t msr, uint64_t value);
|
||||
bool x86_has_msr();
|
||||
void x86_arch_init();
|
||||
|
||||
|
||||
void x86_cpu_identification();
|
||||
int cpuid_get_vendor_string(char* str);
|
||||
|
||||
/* Interrupt Descriptor Table */
|
||||
|
||||
void idt_init(void);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel.h>
|
||||
#include <string/string.h>
|
||||
|
||||
/*
|
||||
* cpuid - Wrapper for CPUID instruction
|
||||
@@ -18,4 +20,29 @@
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
* cpuid_get_vendor_string - Get the CPU vendor string
|
||||
* @str: String at least 13 bytes long (for output)
|
||||
*
|
||||
* Return:
|
||||
* %0 - on success
|
||||
*/
|
||||
int cpuid_get_vendor_string(char* str)
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
cpuid(0, &eax, &ebx, &ecx, &edx);
|
||||
char output[13] = {0};
|
||||
|
||||
uint32_t regs[3] = {ebx, edx, ecx};
|
||||
for (unsigned int j=0; j<3; j++) {
|
||||
for (unsigned int i=0; i<4; i++) {
|
||||
output[4*j+i] = (char)((regs[j] >> 8*i) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(str, output, 13);
|
||||
return 0;
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <stdint.h>
|
||||
#include <arch/x86.h>
|
||||
#include <kernel.h>
|
||||
#include <mem/utils.h>
|
||||
|
||||
/*
|
||||
* x86_overwrite_pat - Set PAT to WC
|
||||
@@ -41,6 +42,52 @@ static void x86_overwrite_pat()
|
||||
void x86_arch_init()
|
||||
{
|
||||
x86_overwrite_pat();
|
||||
x86_cpu_identification();
|
||||
idt_init();
|
||||
gdt_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* cpu_supports_brandstring - Does the CPU support brand strings?
|
||||
*
|
||||
* Return:
|
||||
* true - if it does
|
||||
* false - if it doesn't
|
||||
*/
|
||||
bool cpu_supports_brandstring() {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
if (eax < 0x80000004) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* x86_cpu_idenfitication - get info about the CPU
|
||||
*
|
||||
* This function displays the CPU vendor name or the
|
||||
* extended "brand string" if it's supported, on
|
||||
* debug output.
|
||||
*/
|
||||
void x86_cpu_identification()
|
||||
{
|
||||
if (cpu_supports_brandstring()) {
|
||||
uint32_t regs[12];
|
||||
// Some CPUs don't return null-terminated values so we do it as a failsafe default
|
||||
char str[sizeof(regs)+1] = {0};
|
||||
cpuid(0x80000002, ®s[0], ®s[1], ®s[2], ®s[3]);
|
||||
cpuid(0x80000003, ®s[4], ®s[5], ®s[6], ®s[7]);
|
||||
cpuid(0x80000004, ®s[8], ®s[9], ®s[10], ®s[11]);
|
||||
|
||||
memcpy(str, regs, sizeof(regs));
|
||||
str[sizeof(regs)] = '\0';
|
||||
DEBUG("CPU: %s", str);
|
||||
} else {
|
||||
char vendor_string[13] = {0};
|
||||
cpuid_get_vendor_string(vendor_string);
|
||||
DEBUG("CPU vendor is: %s", vendor_string);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user