blob: 33562bec8907033137802520bd6873e5717d97e4 [file] [log] [blame]
/*
* cpuid.c --
*
* Implements CPUID querying functions
*
*/
#include "stdin.h"
#include "cpuid.h"
struct cpu_ident cpu_id;
void get_cpuid()
{
unsigned int *v, dummy[3];
char *p, *q;
/* Get the largest CPUID number and vendor ID */
cpuid(0x00000000, &cpu_id.max_cpuid, &cpu_id.vend_id.uint32_array[0],
&cpu_id.vend_id.uint32_array[2], &cpu_id.vend_id.uint32_array[1]);
cpu_id.vend_id.char_array[11] = 0;
/* Get the largest CPUID */
cpuid(0x80000000, &cpu_id.max_cpuid, &dummy[0], &dummy[1], &dummy[2]);
/* Get processor family information */
if (cpu_id.max_cpuid >= 1) {
cpuid(1, &cpu_id.vers.flat, &cpu_id.info.flat,
&cpu_id.fid.uint32_array[1], &cpu_id.fid.uint32_array[0]);
}
/* Get the brand ID */
if (cpu_id.max_cpuid >= 4) {
v = (unsigned int *)&cpu_id.brand_id;
cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);
cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);
cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
cpu_id.brand_id.char_array[47] = 0;
}
/*
* Intel chips right-justify this string for some dumb reason;
* undo that brain damage:
*/
p = q = &cpu_id.brand_id.char_array[0];
while (*p == ' ')
p++;
if (p != q) {
while (*p)
*q++ = *p++;
while (q <= &cpu_id.brand_id.char_array[48])
*q++ = '\0'; /* Zero-pad the rest */
}
/* Get cache information */
switch(cpu_id.vend_id.char_array[0]) {
case 'A':
/* AMD Processors */
/* The cache information is only in ecx and edx so only save
* those registers */
if (cpu_id.max_cpuid >= 0x80000005) {
cpuid(0x80000005, &dummy[0], &dummy[1],
&cpu_id.cache_info.uint[0], &cpu_id.cache_info.uint[1]);
}
if (cpu_id.max_cpuid >= 0x80000006) {
cpuid(0x80000006, &dummy[0], &dummy[1],
&cpu_id.cache_info.uint[2], &cpu_id.cache_info.uint[3]);
}
break;
case 'G':
/* Intel Processors, Need to do this in init.c */
break;
}
}