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