Page 1 of 1
help needed - routine for reading product string from cpuid
Posted: Sat Nov 20, 2010 10:43 pm
by Warsome
I created this routine in cpu.cpp as an addition to the routine i86_cpu_get_vender
Code: Select all
PCHAR
i86_cpu_get_product () {
static CHAR product[48] = {0};
#ifdef _MSC_VER
_asm {
mov eax, 80000000h
cpuid
mov eax, 80000002h
cpuid
mov dword ptr [product+0], eax
mov dword ptr [product+4], ebx
mov dword ptr [product+8], ecx
mov dword ptr [product+12], edx
mov eax, 80000003h
cpuid
mov dword ptr [product+16], eax
mov dword ptr [product+20], ebx
mov dword ptr [product+24], ecx
mov dword ptr [product+28], edx
mov eax, 80000004h
cpuid
mov dword ptr [product+32], eax
mov dword ptr [product+36], ebx
mov dword ptr [product+40], ecx
mov dword ptr [product+44], edx
}
#endif
return product;
}
This routine does work, but it does not contain sanity checks for support and errors because the tutorials i was working from did not provide that information. Any help completing this routine would be great.
Re: help needed - routine for reading product string from cpuid
Posted: Sun Nov 21, 2010 7:06 pm
by Hoozim
Your problem is actually a lot more complex than you may think. It has to do with the stack. You are returning a pointer to a string declared on the method stack. When you return from this method, the string is deleted from the stack and the pointer points to nothing. To solve this issue (it's actually very simple), have the method accept the pointer to the string as a parameter and just return void. The string will actually be located in the stack for the calling method and hence will not get deleted on a return. Just return void. Here is the modified code:
Code: Select all
void GetProduct (char* product) {
#ifdef _MSC_VER
_asm {
mov eax, 80000000h
cpuid
mov eax, 80000002h
cpuid
mov dword ptr [product+0], eax
mov dword ptr [product+4], ebx
mov dword ptr [product+8], ecx
mov dword ptr [product+12], edx
mov eax, 80000003h
cpuid
mov dword ptr [product+16], eax
mov dword ptr [product+20], ebx
mov dword ptr [product+24], ecx
mov dword ptr [product+28], edx
mov eax, 80000004h
cpuid
mov dword ptr [product+32], eax
mov dword ptr [product+36], ebx
mov dword ptr [product+40], ecx
mov dword ptr [product+44], edx
}
#endif
return
}
Finally, place everything in namespaces. It is a great way to organize everything and prevents ambiguousies. It also makes everything look much neater because you don't need these huge method names.
Re: help needed - routine for reading product string from cpuid
Posted: Fri Nov 26, 2010 2:18 pm
by Warsome
Thank you for your reply, but I think you misunderstood my question, my function does correctly return the information from cpuid.
What I was requesting was help with the assembly code. The assembly code does not check for cpuid support, for the moment it assumes that the information is there and available.
Re: help needed - routine for reading product string from cpuid
Posted: Sat Nov 27, 2010 8:12 pm
by halofreak1990
Warsome wrote:What I was requesting was help with the assembly code. The assembly code does not check for cpuid support, for the moment it assumes that the information is there and available.
My kernel can check for many CPU features using this function:
Code: Select all
static int eflag_supported(unsigned long flag)
{
unsigned long f1, f2;
_asm
{
// save eflags
pushfd
// get eflags into eax
pushfd
pop eax
// store eflags in f1
mov f1, eax
// toggle the flag we are testing
xor eax, flag
// load eax into eflags
push eax
popfd
// get eflags into eax
pushfd
pop eax
// save in f2
mov f2, eax
// restore eflags
popfd
}
return ((f1 ^ f2) & flag) != 0;
}
This function tests whether the CPU supports the function specified in flag.
Checking for cpuid can be done by passing 0x00200000 to the function