2 * Dump CPUID information
13 uint32_t eax
, ebx
, ecx
, edx
;
18 struct cpuid_data data
;
21 static void get_cpuid(uint32_t eax
, uint32_t ecx
, struct cpuid_data
*data
)
23 asm("pushl %%ebx ; cpuid ; movl %%ebx,%1 ; popl %%ebx"
24 : "=a" (data
->eax
), "=r" (data
->ebx
),
25 "=c" (data
->ecx
), "=d" (data
->edx
)
26 : "a" (eax
), "c" (ecx
));
29 #define CPUID_CHUNK 128
31 void dump_cpuid(struct upload_backend
*be
)
33 struct cpuid_info
*buf
= NULL
;
36 struct cpuid_data base_leaf
;
37 uint32_t base
, leaf
, count
;
38 struct cpuid_data invalid_leaf
;
39 struct cpuid_data data
;
41 if (!cpu_has_eflag(EFLAGS_ID
))
44 printf("Dumping CPUID... ");
48 /* Find out what the CPU returns for invalid leaves */
49 get_cpuid(0, 0, &base_leaf
);
50 get_cpuid(base_leaf
.eax
+1, 0, &invalid_leaf
);
52 for (region
= 0 ; region
<= 0xffff ; region
++) {
55 get_cpuid(base
, 0, &base_leaf
);
56 if (region
&& !memcmp(&base_leaf
, &invalid_leaf
, sizeof base_leaf
))
59 if ((base_leaf
.eax
^ base
) & 0xffff0000)
62 for (leaf
= base
; leaf
<= base_leaf
.eax
; leaf
++) {
63 get_cpuid(leaf
, 0, &data
);
67 if (nentry
>= nalloc
) {
68 nalloc
+= CPUID_CHUNK
;
69 buf
= realloc(buf
, nalloc
*sizeof *buf
);
73 buf
[nentry
].eax
= leaf
;
74 buf
[nentry
].ecx
= count
;
75 buf
[nentry
].data
= data
;
79 get_cpuid(leaf
, count
, &data
);
80 } while (memcmp(&data
, &buf
[nentry
-1].data
, sizeof data
) &&
81 (data
.eax
| data
.ebx
| data
.ecx
| data
.edx
));
86 cpio_writefile(be
, "cpuid", buf
, nentry
*sizeof *buf
);