Why does __get_cpuid return all zeros for leaf=4?

3.1k views Asked by At

I want to write a simple program which calls __get_cpuid to get the cache information:

#include <cpuid.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int leaf = atoi(argv[1]);

    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;

    if (__get_cpuid(leaf, &eax, &ebx, &ecx, &edx))
    {
        printf("leaf=%d, eax=0x%x, ebx=0x%x, ecx=0x%x, edx=0x%x\n",
                leaf, eax, ebx, ecx, edx);
    }
    return 0;
}

First, I pass leaf as 2:

$ ./a.out 2
leaf=2, eax=0x76035a01, ebx=0xf0b2ff, ecx=0x0, edx=0xca0000

Since there is 0xff in ebx, it means I can get cache info from leaf=4 (refer here):

$ ./a.out 4
leaf=4, eax=0x0, ebx=0x0, ecx=0x0, edx=0x0

But this time, all return values are 0. Why can't I get valid information from __get_cpuid?

1

There are 1 answers

1
user786653 On BEST ANSWER

Looking at the linked reference for EAX=4 we see that ECX needs to be set to "cache level to query (e.g. 0=L1D, 1=L2, or 0=L1D, 1=L1I, 2=L2)".

I couldn't quickly find any documentation on __get_cpuid, but a search did turn up the soure code, where I noticed that you need to call __get_cpuid_count to have ecx set before the call to cpuid (otherwise you'll get random answers - mostly 0s it seems).