On 2009-03-12 Piotr Roszatycki <[email protected]> wrote:
> I read the source for kernel 2.6.24 and found that it uses similar
> technic for CPUID detection. I've copied to one simple test program
> (attached) and I worried why it doesn't work on Vortex correcty:
> $ ./cpuid
> This CPU has CPUID opcode
> Illegal instruction
>> Any ideas? Would anyone be so kind and compare it to the Linux code?
There is a second, slightly diffeent instance of the same code in
boot/cpucheck.c. Does this one also prodecue the Illegal instruction
error?
cu and- doesn't speak ASM -reas
--
`What a good friend you are to him, Dr. Maturin. His other friends are
so grateful to you.'
`I sew his ears on from time to time, sure'
#include <stdio.h>
#define __cold __attribute__((__cold__))
#define __section(S) __attribute__ ((__section__(#S)))
#define __cpuinit __section(.cpuinit.text) __cold
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
typedef unsigned int u32;
static int has_eflag(u32 mask)
{
u32 f0, f1;
asm("pushfl ; "
"pushfl ; "
"popl %0 ; "
"movl %0,%1 ; "
"xorl %2,%1 ; "
"pushl %1 ; "
"popfl ; "
"pushfl ; "
"popl %1 ; "
"popfl"
: "=&r" (f0), "=&r" (f1)
: "ri" (mask));
return !!((f0^f1) & mask);
}
/* Probe for the CPUID instruction */
static int __cpuinit have_cpuid_p(void)
{
return has_eflag(X86_EFLAGS_ID);
}
/* Generix CPUID */
static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
{
__asm__("cpuid"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (op), "c"(0));
}
int main() {
int id0, id1, id2, id3;
printf("This CPU %s CPUID opcode\n", (have_cpuid_p ? "has" : "has not"));
/* Get vendor name and crash on Vortex86SX */
cpuid(0x00000000, &id0, (int *)&id1, (int *)&id2, (int *)&id3);
printf("%d %d %d\n", id0 , id1 , id2);
}