cpu.c revision ae115bc77f6fcde83175c75b4206dc2e50747966
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef DEBUG
static void
{
printf("\t%8s | %8s %8s %8s %8s\n",
"eax in", "eax", "ebx", "ecx", "edx");
}
}
#else /* !DEBUG */
#ifdef lint
#else
#define cmprintf
#endif /* lint */
#endif /* DEBUG */
static int detect_target_operating_mode();
int is_amd64;
/*ARGSUSED*/
int
amd64_config_cpu(void)
{
char vendor[13];
int isamd64 = 0;
/*
* This check may seem silly, but if the C preprocesor symbol __amd64
* is #defined during compilation, something that may outwardly seem
* like a good idea, uts/common/sys/isa_defs.h will #define _LP64,
* which will cause uts/common/sys/int_types.h to typedef uint64_t as
* an unsigned long - which is only 4 bytes in size when using a 32-bit
* compiler.
*
* If that happens, all the page table translation routines will fail
* horribly, so check the size of uint64_t just to insure some degree
* of sanity in future operations.
*/
/*LINTED [sizeof result is invarient]*/
if (sizeof (uint64_t) != 8)
prom_panic("multiboot compiled improperly, unable to boot "
"64-bit AMD64 executables");
/*
* If the CPU doesn't support the CPUID instruction, it's definitely
* not an AMD64.
*/
if (amd64_cpuid_supported() == 0)
return (0);
amd64_cpuid_insn(0, vcr);
{
/*LINTED [vendor string from cpuid data]*/
}
if (maxeax > max_maxeax) {
cmprintf("cpu: warning, maxeax was 0x%x -> 0x%x\n",
maxeax, max_maxeax);
maxeax = max_maxeax;
}
if (maxeax < 1)
return (0); /* no additional functions, not an AMD64 */
else {
/*
* themselves as being in family 0xf, but for some reason
* Simics doesn't, and this may change in the future, so
* don't error out if it's not true.
*/
cmprintf("cpu: '%s' family %d model %d step %d\n",
}
#ifdef DEBUG
if (amd64_debug) {
cmprintf("cpu: standard cpuid data:\n");
amd64_dump_cpuid(0, maxeax);
}
#endif /* DEBUG */
if (xmaxeax > max_xmaxeax) {
cmprintf("amd64: warning, xmaxeax was 0x%x -> 0x%x\n",
}
#ifdef DEBUG
if (amd64_debug) {
cmprintf("amd64: extended cpuid data:\n");
}
#endif /* DEBUG */
if (xmaxeax >= 0x80000001) {
}
}
isamd64++;
else
cmprintf("amd64: CPU does NOT support long mode\n");
if (!BITX(stdfeatures, 0, 0)) {
cmprintf("amd64: CPU does NOT support FPU\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support PSE\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support TSC\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support MSRs\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support PAE\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support CX8\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support PGE\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support PSE\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support CLFSH\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support MMX\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support FXSR\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support SSE\n");
isamd64--;
}
cmprintf("amd64: CPU does NOT support SSE2\n");
isamd64--;
}
if (isamd64 < 1) {
cmprintf("amd64: CPU does not support amd64 executables.\n");
return (0);
}
if (efer & AMD_EFER_SCE)
if (efer & AMD_EFER_NXE)
cmprintf("amd64: EFER_NXE (no-exec prot) already enabled\n");
if (efer & AMD_EFER_LME)
cmprintf("amd64: EFER_LME (long mode) already enabled\n");
return (detect_target_operating_mode());
}
/*
* Issue 'Detect Target Operating Mode' callback to the BIOS
*/
static int
{
dprintf("[BIOS 'Detect Target Operating Mode' "
"callback unsupported on this platform]\n");
return (1); /* unsupported, ignore */
}
dprintf("[BIOS accepted mixed-mode target setting!]\n");
return (1); /* told the bios what we're up to */
}
printf("fatal: BIOS reports this machine CANNOT run in mixed "
"32/64-bit mode!\n");
return (0);
}
dprintf("warning: BIOS Detect Target Operating Mode callback "
return (1);
}