2 * Dump CPUID information
14 uint32_t eax
, ebx
, ecx
, edx
;
19 struct cpuid_data data
;
22 static void get_cpuid(uint32_t eax
, uint32_t ecx
, struct cpuid_data
*data
)
24 asm("pushl %%ebx ; cpuid ; movl %%ebx,%1 ; popl %%ebx"
25 : "=a" (data
->eax
), "=r" (data
->ebx
),
26 "=c" (data
->ecx
), "=d" (data
->edx
)
27 : "a" (eax
), "c" (ecx
));
30 #define CPUID_CHUNK 128
32 void dump_cpuid(struct backend
*be
)
34 struct cpuid_info
*buf
= NULL
;
37 struct cpuid_data base_leaf
;
38 uint32_t base
, leaf
, count
;
39 struct cpuid_data invalid_leaf
;
40 struct cpuid_data data
;
42 if (!cpu_has_eflag(EFLAGS_ID
))
45 printf("Dumping CPUID... ");
49 /* Find out what the CPU returns for invalid leaves */
50 get_cpuid(0, 0, &base_leaf
);
51 get_cpuid(base_leaf
.eax
+1, 0, &invalid_leaf
);
53 for (region
= 0 ; region
<= 0xffff ; region
++) {
56 get_cpuid(base
, 0, &base_leaf
);
57 if (region
&& !memcmp(&base_leaf
, &invalid_leaf
, sizeof base_leaf
))
60 if ((base_leaf
.eax
^ base
) & 0xffff0000)
63 for (leaf
= base
; leaf
<= base_leaf
.eax
; leaf
++) {
64 get_cpuid(leaf
, 0, &data
);
68 if (nentry
>= nalloc
) {
69 nalloc
+= CPUID_CHUNK
;
70 buf
= realloc(buf
, nalloc
*sizeof *buf
);
74 buf
[nentry
].eax
= leaf
;
75 buf
[nentry
].ecx
= count
;
76 buf
[nentry
].data
= data
;
80 get_cpuid(leaf
, count
, &data
);
81 } while (memcmp(&data
, &buf
[nentry
-1].data
, sizeof data
) &&
82 (data
.eax
| data
.ebx
| data
.ecx
| data
.edx
));
87 cpio_writefile(be
, "cpuid", buf
, nentry
*sizeof *buf
);