#include <sys/cdefs.h>
#include <stand.h>
#include <machine/psl.h>
#include <machine/cpufunc.h>
#include <machine/specialreg.h>
int
bi_checkcpu(void)
{
unsigned long flags;
unsigned int regs[4];
unsigned int maxeax;
unsigned int max_maxeax = 0x100;
unsigned int stdfeatures = 0, xtdfeatures = 0;
int amd64 = 0;
#if defined(__LP64__)
flags = read_rflags();
write_rflags(flags ^ PSL_ID);
if (!((flags ^ read_rflags()) & PSL_ID))
return (0);
#else
flags = read_eflags();
write_eflags(flags ^ PSL_ID);
if (!((flags ^ read_eflags()) & PSL_ID))
return (0);
#endif
do_cpuid(0, regs);
maxeax = regs[0];
if (maxeax > max_maxeax)
maxeax = max_maxeax;
if (maxeax < 1)
return (0);
else {
do_cpuid(1, regs);
stdfeatures = regs[3];
}
do_cpuid(0x80000000, regs);
if (regs[0] & 0x80000000) {
maxeax = regs[0];
max_maxeax = 0x80000100;
if (maxeax > max_maxeax)
maxeax = max_maxeax;
if (maxeax >= 0x80000001) {
do_cpuid(0x80000001, regs);
xtdfeatures = regs[3];
}
}
if (xtdfeatures & AMDID_LM)
amd64++;
if ((stdfeatures & CPUID_FPU) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_TSC) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_MSR) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_PAE) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_CX8) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_PGE) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_CLFSH) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_MMX) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_FXSR) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_SSE) == 0)
amd64 = 0;
if ((stdfeatures & CPUID_SSE2) == 0)
amd64 = 0;
return (amd64);
}
void
bi_isadir(void)
{
int rc;
if (bi_checkcpu())
rc = setenv("ISADIR", "amd64", 1);
else
rc = setenv("ISADIR", "", 1);
if (rc != 0) {
printf("Warning: failed to set ISADIR environment "
"variable: %d\n", rc);
}
}