xref: /illumos-gate/usr/src/boot/i386/libi386/cpuid.c (revision bad082f6)
1d9256fffSToomas Soome /*
2d9256fffSToomas Soome  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3d9256fffSToomas Soome  * All rights reserved.
4d9256fffSToomas Soome  *
5d9256fffSToomas Soome  * Redistribution and use in source and binary forms, with or without
6d9256fffSToomas Soome  * modification, are permitted provided that the following conditions
7d9256fffSToomas Soome  * are met:
8d9256fffSToomas Soome  * 1. Redistributions of source code must retain the above copyright
9d9256fffSToomas Soome  *    notice, this list of conditions and the following disclaimer.
10d9256fffSToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
11d9256fffSToomas Soome  *    notice, this list of conditions and the following disclaimer in the
12d9256fffSToomas Soome  *    documentation and/or other materials provided with the distribution.
13d9256fffSToomas Soome  *
14d9256fffSToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15d9256fffSToomas Soome  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16d9256fffSToomas Soome  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17d9256fffSToomas Soome  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18d9256fffSToomas Soome  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19d9256fffSToomas Soome  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20d9256fffSToomas Soome  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21d9256fffSToomas Soome  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22d9256fffSToomas Soome  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23d9256fffSToomas Soome  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24d9256fffSToomas Soome  * SUCH DAMAGE.
25d9256fffSToomas Soome  */
26d9256fffSToomas Soome 
27d9256fffSToomas Soome #include <sys/cdefs.h>
28d9256fffSToomas Soome 
29d9256fffSToomas Soome #include <stand.h>
30d9256fffSToomas Soome #include <machine/psl.h>
31d9256fffSToomas Soome #include <machine/cpufunc.h>
32d9256fffSToomas Soome #include <machine/specialreg.h>
33d9256fffSToomas Soome 
34d9256fffSToomas Soome /*
35d9256fffSToomas Soome  * Check to see if this CPU supports long mode.
36d9256fffSToomas Soome  */
37d9256fffSToomas Soome int
bi_checkcpu(void)38d9256fffSToomas Soome bi_checkcpu(void)
39d9256fffSToomas Soome {
40d9256fffSToomas Soome 	unsigned long flags;
41d9256fffSToomas Soome 	unsigned int regs[4];
42d9256fffSToomas Soome 	unsigned int maxeax;
43d9256fffSToomas Soome 	unsigned int max_maxeax = 0x100;
44d9256fffSToomas Soome 	unsigned int stdfeatures = 0, xtdfeatures = 0;
45d9256fffSToomas Soome 	int amd64 = 0;
46d9256fffSToomas Soome 
47d9256fffSToomas Soome 	/* Check for presence of "cpuid". */
48d9256fffSToomas Soome #if defined(__LP64__)
49d9256fffSToomas Soome 	flags = read_rflags();
50d9256fffSToomas Soome 	write_rflags(flags ^ PSL_ID);
51d9256fffSToomas Soome 	if (!((flags ^ read_rflags()) & PSL_ID))
52d9256fffSToomas Soome 		return (0);
53d9256fffSToomas Soome #else
54d9256fffSToomas Soome 	flags = read_eflags();
55d9256fffSToomas Soome 	write_eflags(flags ^ PSL_ID);
56d9256fffSToomas Soome 	if (!((flags ^ read_eflags()) & PSL_ID))
57d9256fffSToomas Soome 		return (0);
58d9256fffSToomas Soome #endif /* __LP64__ */
59d9256fffSToomas Soome 
60d9256fffSToomas Soome 	/* Fetch the vendor string. */
61d9256fffSToomas Soome 	do_cpuid(0, regs);
62d9256fffSToomas Soome 	maxeax = regs[0];
63d9256fffSToomas Soome 
64d9256fffSToomas Soome 	/*
65d9256fffSToomas Soome 	 * Limit the range in case of weird hardware
66d9256fffSToomas Soome 	 */
67d9256fffSToomas Soome 	if (maxeax > max_maxeax)
68d9256fffSToomas Soome 		maxeax = max_maxeax;
69d9256fffSToomas Soome 	if (maxeax < 1)
70d9256fffSToomas Soome 		return (0);
71d9256fffSToomas Soome 	else {
72d9256fffSToomas Soome 		do_cpuid(1, regs);
73d9256fffSToomas Soome 		stdfeatures = regs[3];
74d9256fffSToomas Soome 	}
75d9256fffSToomas Soome 
76d9256fffSToomas Soome 	/* Has to support AMD features. */
77d9256fffSToomas Soome 	do_cpuid(0x80000000, regs);
78d9256fffSToomas Soome 	if (regs[0] & 0x80000000) {
79d9256fffSToomas Soome 		maxeax = regs[0];
80d9256fffSToomas Soome 		max_maxeax = 0x80000100;
81d9256fffSToomas Soome 		if (maxeax > max_maxeax)
82d9256fffSToomas Soome 			maxeax = max_maxeax;
83d9256fffSToomas Soome 		if (maxeax >= 0x80000001) {
84d9256fffSToomas Soome 			do_cpuid(0x80000001, regs);
85d9256fffSToomas Soome 			xtdfeatures = regs[3];
86d9256fffSToomas Soome 		}
87d9256fffSToomas Soome 	}
88d9256fffSToomas Soome 
89d9256fffSToomas Soome 	/* Check for long mode. */
90d9256fffSToomas Soome 	if (xtdfeatures & AMDID_LM)
91d9256fffSToomas Soome 		amd64++;
92d9256fffSToomas Soome 
93d9256fffSToomas Soome 	/* Check for FPU. */
94d9256fffSToomas Soome 	if ((stdfeatures & CPUID_FPU) == 0)
95d9256fffSToomas Soome 		amd64 = 0;
96d9256fffSToomas Soome 
97d9256fffSToomas Soome 	if ((stdfeatures & CPUID_TSC) == 0)
98d9256fffSToomas Soome 		amd64 = 0;
99d9256fffSToomas Soome 
100d9256fffSToomas Soome 	if ((stdfeatures & CPUID_MSR) == 0)
101d9256fffSToomas Soome 		amd64 = 0;
102d9256fffSToomas Soome 
103d9256fffSToomas Soome 	if ((stdfeatures & CPUID_PAE) == 0)
104d9256fffSToomas Soome 		amd64 = 0;
105d9256fffSToomas Soome 
106d9256fffSToomas Soome 	if ((stdfeatures & CPUID_CX8) == 0)
107d9256fffSToomas Soome 		amd64 = 0;
108d9256fffSToomas Soome 
109d9256fffSToomas Soome 	if ((stdfeatures & CPUID_PGE) == 0)
110d9256fffSToomas Soome 		amd64 = 0;
111d9256fffSToomas Soome 
112d9256fffSToomas Soome 	if ((stdfeatures & CPUID_CLFSH) == 0)
113d9256fffSToomas Soome 		amd64 = 0;
114d9256fffSToomas Soome 
115d9256fffSToomas Soome 	if ((stdfeatures & CPUID_MMX) == 0)
116d9256fffSToomas Soome 		amd64 = 0;
117d9256fffSToomas Soome 
118d9256fffSToomas Soome 	if ((stdfeatures & CPUID_FXSR) == 0)
119d9256fffSToomas Soome 		amd64 = 0;
120d9256fffSToomas Soome 
121d9256fffSToomas Soome 	if ((stdfeatures & CPUID_SSE) == 0)
122d9256fffSToomas Soome 		amd64 = 0;
123d9256fffSToomas Soome 
124*bad082f6SToomas Soome 	if ((stdfeatures & CPUID_SSE2) == 0)
125d9256fffSToomas Soome 		amd64 = 0;
126d9256fffSToomas Soome 
127d9256fffSToomas Soome 	return (amd64);
128d9256fffSToomas Soome }
129d9256fffSToomas Soome 
130d9256fffSToomas Soome void
bi_isadir(void)131d9256fffSToomas Soome bi_isadir(void)
132d9256fffSToomas Soome {
133d9256fffSToomas Soome 	int rc;
134d9256fffSToomas Soome 
135d9256fffSToomas Soome 	if (bi_checkcpu())
136d9256fffSToomas Soome 		rc = setenv("ISADIR", "amd64", 1);
137d9256fffSToomas Soome 	else
138d9256fffSToomas Soome 		rc = setenv("ISADIR", "", 1);
139d9256fffSToomas Soome 
140d9256fffSToomas Soome 	if (rc != 0) {
141d9256fffSToomas Soome 		printf("Warning: failed to set ISADIR environment "
142d9256fffSToomas Soome 		    "variable: %d\n", rc);
143d9256fffSToomas Soome 	}
144d9256fffSToomas Soome }
145