help needed - routine for reading product string from cpuid

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator:Moderators

Post Reply
User avatar
Warsome
Posts:21
Joined:Sun Nov 18, 2007 3:13 am
help needed - routine for reading product string from cpuid

Post by Warsome » Sat Nov 20, 2010 10:43 pm

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.

Hoozim
Posts:34
Joined:Sun Nov 21, 2010 6:40 pm

Re: help needed - routine for reading product string from cpuid

Post by Hoozim » Sun Nov 21, 2010 7:06 pm

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.

User avatar
Warsome
Posts:21
Joined:Sun Nov 18, 2007 3:13 am

Re: help needed - routine for reading product string from cpuid

Post by Warsome » Fri Nov 26, 2010 2:18 pm

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.

halofreak1990
Posts:92
Joined:Thu May 27, 2010 8:54 pm
Location:Netherlands

Re: help needed - routine for reading product string from cpuid

Post by halofreak1990 » Sat Nov 27, 2010 8:12 pm

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

Post Reply