xref: /freebsd/sys/amd64/amd64/initcpu.c (revision 6593be60)
1a8e282d6SKATO Takenori /*
2a8e282d6SKATO Takenori  * Copyright (c) KATO Takenori, 1997.
3a8e282d6SKATO Takenori  *
4a8e282d6SKATO Takenori  * All rights reserved.  Unpublished rights reserved under the copyright
5a8e282d6SKATO Takenori  * laws of Japan.
6a8e282d6SKATO Takenori  *
7a8e282d6SKATO Takenori  * Redistribution and use in source and binary forms, with or without
8a8e282d6SKATO Takenori  * modification, are permitted provided that the following conditions
9a8e282d6SKATO Takenori  * are met:
10a8e282d6SKATO Takenori  *
11a8e282d6SKATO Takenori  * 1. Redistributions of source code must retain the above copyright
12a8e282d6SKATO Takenori  *    notice, this list of conditions and the following disclaimer as
13a8e282d6SKATO Takenori  *    the first lines of this file unmodified.
14a8e282d6SKATO Takenori  * 2. Redistributions in binary form must reproduce the above copyright
15a8e282d6SKATO Takenori  *    notice, this list of conditions and the following disclaimer in the
16a8e282d6SKATO Takenori  *    documentation and/or other materials provided with the distribution.
17a8e282d6SKATO Takenori  *
18a8e282d6SKATO Takenori  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19a8e282d6SKATO Takenori  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20a8e282d6SKATO Takenori  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21a8e282d6SKATO Takenori  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22a8e282d6SKATO Takenori  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23a8e282d6SKATO Takenori  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24a8e282d6SKATO Takenori  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25a8e282d6SKATO Takenori  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26a8e282d6SKATO Takenori  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27a8e282d6SKATO Takenori  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28a8e282d6SKATO Takenori  *
296593be60SKATO Takenori  *		$Id: initcpu.c,v 1.7 1997/07/24 14:19:25 kato Exp $
30a8e282d6SKATO Takenori  */
31a8e282d6SKATO Takenori 
32a8e282d6SKATO Takenori #include "opt_cpu.h"
33a8e282d6SKATO Takenori 
34a8e282d6SKATO Takenori #include <sys/param.h>
35a8e282d6SKATO Takenori #include <sys/kernel.h>
36a8e282d6SKATO Takenori #include <sys/systm.h>
37a8e282d6SKATO Takenori 
38a8e282d6SKATO Takenori #include <machine/cpu.h>
39a8e282d6SKATO Takenori #include <machine/cputypes.h>
40a8e282d6SKATO Takenori #include <machine/md_var.h>
41a8e282d6SKATO Takenori #include <machine/specialreg.h>
42a8e282d6SKATO Takenori 
43a8e282d6SKATO Takenori void initializecpu(void);
44a8e282d6SKATO Takenori #ifdef I486_CPU
45a8e282d6SKATO Takenori static void init_5x86(void);
46a8e282d6SKATO Takenori static void init_bluelightning(void);
47a8e282d6SKATO Takenori static void init_486dlc(void);
489ca82267SKATO Takenori static void init_cy486dx(void);
49a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
50a8e282d6SKATO Takenori static void init_i486_on_386(void);
51a8e282d6SKATO Takenori #endif
52a8e282d6SKATO Takenori static void init_6x86(void);
53a8e282d6SKATO Takenori #endif /* I486_CPU */
54a8e282d6SKATO Takenori 
554877e978SKATO Takenori #ifdef I686_CPU
5620916c1fSKATO Takenori static void	init_6x86MX(void);
5720916c1fSKATO Takenori #endif
5820916c1fSKATO Takenori 
59a8e282d6SKATO Takenori #ifdef I486_CPU
60a8e282d6SKATO Takenori /*
61a8e282d6SKATO Takenori  * IBM Blue Lightning
62a8e282d6SKATO Takenori  */
63a8e282d6SKATO Takenori static void
64a8e282d6SKATO Takenori init_bluelightning(void)
65a8e282d6SKATO Takenori {
66a8e282d6SKATO Takenori 	u_long	eflags;
67a8e282d6SKATO Takenori 
68a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
69a8e282d6SKATO Takenori 	need_post_dma_flush = 1;
70a8e282d6SKATO Takenori #endif
71a8e282d6SKATO Takenori 
72a8e282d6SKATO Takenori 	eflags = read_eflags();
73a8e282d6SKATO Takenori 	disable_intr();
74a8e282d6SKATO Takenori 
75a8e282d6SKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
76a8e282d6SKATO Takenori 	invd();
77a8e282d6SKATO Takenori 
78a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
79a8e282d6SKATO Takenori 	wrmsr(0x1000, 0x9c92LL);	/* FP operand can be cacheable on Cyrix FPU */
80a8e282d6SKATO Takenori #else
81a8e282d6SKATO Takenori 	wrmsr(0x1000, 0x1c92LL);	/* Intel FPU */
82a8e282d6SKATO Takenori #endif
83a8e282d6SKATO Takenori 	/* Enables 13MB and 0-640KB cache. */
84a8e282d6SKATO Takenori 	wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
85a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_3X
86a8e282d6SKATO Takenori 	wrmsr(0x1002, 0x04000000LL);	/* Enables triple-clock mode. */
87a8e282d6SKATO Takenori #else
88a8e282d6SKATO Takenori 	wrmsr(0x1002, 0x03000000LL);	/* Enables double-clock mode. */
89a8e282d6SKATO Takenori #endif
90a8e282d6SKATO Takenori 
91a8e282d6SKATO Takenori 	/* Enable caching in CR0. */
92a8e282d6SKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
93a8e282d6SKATO Takenori 	invd();
94a8e282d6SKATO Takenori 	write_eflags(eflags);
95a8e282d6SKATO Takenori }
96a8e282d6SKATO Takenori 
97a8e282d6SKATO Takenori /*
989ca82267SKATO Takenori  * Cyrix 486SLC/DLC/SR/DR series
99a8e282d6SKATO Takenori  */
100a8e282d6SKATO Takenori static void
101a8e282d6SKATO Takenori init_486dlc(void)
102a8e282d6SKATO Takenori {
103a8e282d6SKATO Takenori 	u_long	eflags;
104a8e282d6SKATO Takenori 	u_char	ccr0;
105a8e282d6SKATO Takenori 
106a8e282d6SKATO Takenori 	eflags = read_eflags();
107a8e282d6SKATO Takenori 	disable_intr();
108a8e282d6SKATO Takenori 	invd();
109a8e282d6SKATO Takenori 
110a8e282d6SKATO Takenori 	ccr0 = read_cyrix_reg(CCR0);
111a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_WORKS
112a8e282d6SKATO Takenori 	ccr0 |= CCR0_NC1 | CCR0_BARB;
113a8e282d6SKATO Takenori 	write_cyrix_reg(CCR0, ccr0);
114a8e282d6SKATO Takenori 	invd();
115a8e282d6SKATO Takenori #else
116a8e282d6SKATO Takenori 	ccr0 &= ~CCR0_NC0;
117a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_REALLY_WORKS
118a8e282d6SKATO Takenori 	ccr0 |= CCR0_NC1 | CCR0_BARB;
119a8e282d6SKATO Takenori #else
120a8e282d6SKATO Takenori 	ccr0 |= CCR0_NC1;
121a8e282d6SKATO Takenori #endif
1224962d938SKATO Takenori #ifdef CPU_DIRECT_MAPPED_CACHE
1234962d938SKATO Takenori 	ccr0 |= CCR0_CO;			/* Direct mapped mode. */
1244962d938SKATO Takenori #endif
125a8e282d6SKATO Takenori 	write_cyrix_reg(CCR0, ccr0);
126a8e282d6SKATO Takenori 
127a8e282d6SKATO Takenori 	/* Clear non-cacheable region. */
128a8e282d6SKATO Takenori 	write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
129a8e282d6SKATO Takenori 	write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
130a8e282d6SKATO Takenori 	write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
131a8e282d6SKATO Takenori 	write_cyrix_reg(NCR4+2, NCR_SIZE_0K);
132a8e282d6SKATO Takenori 
133a8e282d6SKATO Takenori 	write_cyrix_reg(0, 0);	/* dummy write */
134a8e282d6SKATO Takenori 
135a8e282d6SKATO Takenori 	/* Enable caching in CR0. */
136a8e282d6SKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
137a8e282d6SKATO Takenori 	invd();
138a8e282d6SKATO Takenori #endif /* !CYRIX_CACHE_WORKS */
139a8e282d6SKATO Takenori 	write_eflags(eflags);
140a8e282d6SKATO Takenori }
141a8e282d6SKATO Takenori 
142a8e282d6SKATO Takenori 
143a8e282d6SKATO Takenori /*
1449ca82267SKATO Takenori  * Cyrix 486S/DX series
1459ca82267SKATO Takenori  */
1469ca82267SKATO Takenori static void
1479ca82267SKATO Takenori init_cy486dx(void)
1489ca82267SKATO Takenori {
1499ca82267SKATO Takenori 	u_long	eflags;
1509ca82267SKATO Takenori 	u_char	ccr2;
1519ca82267SKATO Takenori 
1529ca82267SKATO Takenori 	eflags = read_eflags();
1539ca82267SKATO Takenori 	disable_intr();
1549ca82267SKATO Takenori 	invd();
1559ca82267SKATO Takenori 
1569ca82267SKATO Takenori 	ccr2 = read_cyrix_reg(CCR2);
1579ca82267SKATO Takenori #ifdef SUSP_HLT
1589ca82267SKATO Takenori 	ccr2 |= CCR2_SUSP_HTL;
1599ca82267SKATO Takenori #endif
1609ca82267SKATO Takenori 	write_cyrix_reg(CCR2, ccr2);
1619ca82267SKATO Takenori 	write_eflags(eflags);
1629ca82267SKATO Takenori }
1639ca82267SKATO Takenori 
1649ca82267SKATO Takenori 
1659ca82267SKATO Takenori /*
166a8e282d6SKATO Takenori  * Cyrix 5x86
167a8e282d6SKATO Takenori  */
168a8e282d6SKATO Takenori static void
169a8e282d6SKATO Takenori init_5x86(void)
170a8e282d6SKATO Takenori {
171a8e282d6SKATO Takenori 	u_long	eflags;
172a8e282d6SKATO Takenori 	u_char	ccr2, ccr3, ccr4, pcr0;
173a8e282d6SKATO Takenori 
174a8e282d6SKATO Takenori 	eflags = read_eflags();
175a8e282d6SKATO Takenori 	disable_intr();
176a8e282d6SKATO Takenori 
177a8e282d6SKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
178a8e282d6SKATO Takenori 	wbinvd();
179a8e282d6SKATO Takenori 
180a8e282d6SKATO Takenori 	(void)read_cyrix_reg(CCR3);		/* dummy */
181a8e282d6SKATO Takenori 
182a8e282d6SKATO Takenori 	/* Initialize CCR2. */
183a8e282d6SKATO Takenori 	ccr2 = read_cyrix_reg(CCR2);
184a8e282d6SKATO Takenori 	ccr2 |= CCR2_WB;
185a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT
186a8e282d6SKATO Takenori 	ccr2 |= CCR2_SUSP_HLT;
187a8e282d6SKATO Takenori #else
188a8e282d6SKATO Takenori 	ccr2 &= ~CCR2_SUSP_HLT;
189a8e282d6SKATO Takenori #endif
190a8e282d6SKATO Takenori 	ccr2 |= CCR2_WT1;
191a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, ccr2);
192a8e282d6SKATO Takenori 
193a8e282d6SKATO Takenori 	/* Initialize CCR4. */
194a8e282d6SKATO Takenori 	ccr3 = read_cyrix_reg(CCR3);
195a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
196a8e282d6SKATO Takenori 
197a8e282d6SKATO Takenori 	ccr4 = read_cyrix_reg(CCR4);
198a8e282d6SKATO Takenori 	ccr4 |= CCR4_DTE;
199a8e282d6SKATO Takenori 	ccr4 |= CCR4_MEM;
200a8e282d6SKATO Takenori #ifdef CPU_FASTER_5X86_FPU
201a8e282d6SKATO Takenori 	ccr4 |= CCR4_FASTFPE;
202a8e282d6SKATO Takenori #else
203a8e282d6SKATO Takenori 	ccr4 &= ~CCR4_FASTFPE;
204a8e282d6SKATO Takenori #endif
205a8e282d6SKATO Takenori 	ccr4 &= ~CCR4_IOMASK;
206a8e282d6SKATO Takenori 	/********************************************************************
207a8e282d6SKATO Takenori 	 * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
208a8e282d6SKATO Takenori 	 * should be 0 for errata fix.
209a8e282d6SKATO Takenori 	 ********************************************************************/
210a8e282d6SKATO Takenori #ifdef CPU_IORT
211a8e282d6SKATO Takenori 	ccr4 |= CPU_IORT & CCR4_IOMASK;
212a8e282d6SKATO Takenori #endif
213a8e282d6SKATO Takenori 	write_cyrix_reg(CCR4, ccr4);
214a8e282d6SKATO Takenori 
215a8e282d6SKATO Takenori 	/* Initialize PCR0. */
216a8e282d6SKATO Takenori 	/****************************************************************
217a8e282d6SKATO Takenori 	 * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
218a8e282d6SKATO Takenori 	 * BTB_EN might make your system unstable.
219a8e282d6SKATO Takenori 	 ****************************************************************/
220a8e282d6SKATO Takenori 	pcr0 = read_cyrix_reg(PCR0);
221a8e282d6SKATO Takenori #ifdef CPU_RSTK_EN
222a8e282d6SKATO Takenori 	pcr0 |= PCR0_RSTK;
223a8e282d6SKATO Takenori #else
224a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_RSTK;
225a8e282d6SKATO Takenori #endif
226a8e282d6SKATO Takenori #ifdef CPU_BTB_EN
227a8e282d6SKATO Takenori 	pcr0 |= PCR0_BTB;
228a8e282d6SKATO Takenori #else
229a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_BTB;
230a8e282d6SKATO Takenori #endif
231a8e282d6SKATO Takenori #ifdef CPU_LOOP_EN
232a8e282d6SKATO Takenori 	pcr0 |= PCR0_LOOP;
233a8e282d6SKATO Takenori #else
234a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_LOOP;
235a8e282d6SKATO Takenori #endif
236a8e282d6SKATO Takenori 
237a8e282d6SKATO Takenori 	/****************************************************************
238a8e282d6SKATO Takenori 	 * WARNING: if you use a memory mapped I/O device, don't use
239a8e282d6SKATO Takenori 	 * DISABLE_5X86_LSSER option, which may reorder memory mapped
240a8e282d6SKATO Takenori 	 * I/O access.
241a8e282d6SKATO Takenori 	 * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
242a8e282d6SKATO Takenori 	 ****************************************************************/
243a8e282d6SKATO Takenori #ifdef CPU_DISABLE_5X86_LSSER
244a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_LSSER;
245a8e282d6SKATO Takenori #else
246a8e282d6SKATO Takenori 	pcr0 |= PCR0_LSSER;
247a8e282d6SKATO Takenori #endif
248a8e282d6SKATO Takenori 	write_cyrix_reg(PCR0, pcr0);
249a8e282d6SKATO Takenori 
250a8e282d6SKATO Takenori 	/* Restore CCR3. */
251a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, ccr3);
252a8e282d6SKATO Takenori 
253a8e282d6SKATO Takenori 	(void)read_cyrix_reg(0x80);		/* dummy */
254a8e282d6SKATO Takenori 
255a8e282d6SKATO Takenori 	/* Unlock NW bit in CR0. */
256a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
257a8e282d6SKATO Takenori 	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
258a8e282d6SKATO Takenori 	/* Lock NW bit in CR0. */
259a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
260a8e282d6SKATO Takenori 
261a8e282d6SKATO Takenori 	write_eflags(eflags);
262a8e282d6SKATO Takenori }
263a8e282d6SKATO Takenori 
264a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
265a8e282d6SKATO Takenori /*
266a8e282d6SKATO Takenori  * There are i486 based upgrade products for i386 machines.
267a8e282d6SKATO Takenori  * In this case, BIOS doesn't enables CPU cache.
268a8e282d6SKATO Takenori  */
269a8e282d6SKATO Takenori void
270a8e282d6SKATO Takenori init_i486_on_386(void)
271a8e282d6SKATO Takenori {
272a8e282d6SKATO Takenori 	u_long	eflags;
273a8e282d6SKATO Takenori 
274a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
275a8e282d6SKATO Takenori 	need_post_dma_flush = 1;
276a8e282d6SKATO Takenori #endif
277a8e282d6SKATO Takenori 
278a8e282d6SKATO Takenori 	eflags = read_eflags();
279a8e282d6SKATO Takenori 	disable_intr();
280a8e282d6SKATO Takenori 
281a8e282d6SKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0, NW = 0 */
282a8e282d6SKATO Takenori 
2835fa4a058SKATO Takenori 	write_eflags(eflags);
284a8e282d6SKATO Takenori }
285a8e282d6SKATO Takenori #endif
286a8e282d6SKATO Takenori 
287a8e282d6SKATO Takenori /*
288a8e282d6SKATO Takenori  * Cyrix 6x86
289a8e282d6SKATO Takenori  *
290a8e282d6SKATO Takenori  * XXX - What should I do here?  Please let me know.
291a8e282d6SKATO Takenori  */
292a8e282d6SKATO Takenori static void
293a8e282d6SKATO Takenori init_6x86(void)
294a8e282d6SKATO Takenori {
295a8e282d6SKATO Takenori 	u_long	eflags;
296a8e282d6SKATO Takenori 	u_char	ccr3, ccr4;
297a8e282d6SKATO Takenori 
298a8e282d6SKATO Takenori 	eflags = read_eflags();
299a8e282d6SKATO Takenori 	disable_intr();
300a8e282d6SKATO Takenori 
301a8e282d6SKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
302a8e282d6SKATO Takenori 	wbinvd();
303a8e282d6SKATO Takenori 
304a8e282d6SKATO Takenori 	/* Initialize CCR0. */
305a8e282d6SKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
306a8e282d6SKATO Takenori 
3076593be60SKATO Takenori 	/* Initialize CCR1. */
3086593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK
3096593be60SKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR1_NO_LOCK);
3106593be60SKATO Takenori #else
3116593be60SKATO Takenori #ifdef FAILSAFE
3126593be60SKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) & ~CCR1_NO_LOCK);
3136593be60SKATO Takenori #endif
3146593be60SKATO Takenori #endif
3156593be60SKATO Takenori 
316a8e282d6SKATO Takenori 	/* Initialize CCR2. */
317a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT
318a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
319a8e282d6SKATO Takenori #else
320a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
321a8e282d6SKATO Takenori #endif
322a8e282d6SKATO Takenori 
323a8e282d6SKATO Takenori 	ccr3 = read_cyrix_reg(CCR3);
324a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
325a8e282d6SKATO Takenori 
326a8e282d6SKATO Takenori 	/* Initialize CCR4. */
327a8e282d6SKATO Takenori 	ccr4 = read_cyrix_reg(CCR4);
328a8e282d6SKATO Takenori 	ccr4 |= CCR4_DTE;
329a8e282d6SKATO Takenori 	ccr4 &= ~CCR4_IOMASK;
330a8e282d6SKATO Takenori #ifdef CPU_IORT
331a8e282d6SKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
332a8e282d6SKATO Takenori #else
333a8e282d6SKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | 7);
334a8e282d6SKATO Takenori #endif
335a8e282d6SKATO Takenori 
3366593be60SKATO Takenori 	/* Initialize CCR5. */
3376593be60SKATO Takenori #ifdef CPU_WT_ALLOC
3386593be60SKATO Takenori 	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
3396593be60SKATO Takenori #endif
3406593be60SKATO Takenori 
341a8e282d6SKATO Takenori 	/* Restore CCR3. */
342a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, ccr3);
343a8e282d6SKATO Takenori 
344a8e282d6SKATO Takenori 	/* Unlock NW bit in CR0. */
345a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
346a8e282d6SKATO Takenori 
347a8e282d6SKATO Takenori 	/*
348a8e282d6SKATO Takenori 	 * Earlier revision of the 6x86 CPU could crash the system if
349a8e282d6SKATO Takenori 	 * L1 cache is in write-back mode.
350a8e282d6SKATO Takenori 	 */
351a8e282d6SKATO Takenori 	if ((cyrix_did & 0xff00) > 0x1600)
352a8e282d6SKATO Takenori 		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
353a8e282d6SKATO Takenori 	else {
354a8e282d6SKATO Takenori 		/* Revision 2.6 and lower. */
355a8e282d6SKATO Takenori #ifdef CYRIX_CACHE_REALLY_WORKS
356a8e282d6SKATO Takenori 		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
357a8e282d6SKATO Takenori #else
358a8e282d6SKATO Takenori 		load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0 and NW = 1 */
359a8e282d6SKATO Takenori #endif
360a8e282d6SKATO Takenori 	}
361a8e282d6SKATO Takenori 
362a8e282d6SKATO Takenori 	/* Lock NW bit in CR0. */
363a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
364a8e282d6SKATO Takenori 
365a8e282d6SKATO Takenori 	write_eflags(eflags);
366a8e282d6SKATO Takenori }
367a8e282d6SKATO Takenori #endif /* I486_CPU */
368a8e282d6SKATO Takenori 
3694877e978SKATO Takenori #ifdef I686_CPU
37020916c1fSKATO Takenori /*
37120916c1fSKATO Takenori  * Cyrix 6x86MX (code-named M2)
37220916c1fSKATO Takenori  *
37320916c1fSKATO Takenori  * XXX - What should I do here?  Please let me know.
37420916c1fSKATO Takenori  */
37520916c1fSKATO Takenori static void
37620916c1fSKATO Takenori init_6x86MX(void)
37720916c1fSKATO Takenori {
37820916c1fSKATO Takenori 	u_long	eflags;
37920916c1fSKATO Takenori 	u_char	ccr3, ccr4;
38020916c1fSKATO Takenori 
38120916c1fSKATO Takenori 	eflags = read_eflags();
38220916c1fSKATO Takenori 	disable_intr();
38320916c1fSKATO Takenori 
38420916c1fSKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
38520916c1fSKATO Takenori 	wbinvd();
38620916c1fSKATO Takenori 
38720916c1fSKATO Takenori 	/* Initialize CCR0. */
38820916c1fSKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
38920916c1fSKATO Takenori 
3906593be60SKATO Takenori 	/* Initialize CCR1. */
3916593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK
3926593be60SKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR1_NO_LOCK);
3936593be60SKATO Takenori #else
3946593be60SKATO Takenori #ifdef FAILSAFE
3956593be60SKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) & ~CCR1_NO_LOCK);
3966593be60SKATO Takenori #endif
3976593be60SKATO Takenori #endif
3986593be60SKATO Takenori 
39920916c1fSKATO Takenori 	/* Initialize CCR2. */
40020916c1fSKATO Takenori #ifdef CPU_SUSP_HLT
40120916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
40220916c1fSKATO Takenori #else
40320916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
40420916c1fSKATO Takenori #endif
40520916c1fSKATO Takenori 
40620916c1fSKATO Takenori 	ccr3 = read_cyrix_reg(CCR3);
40720916c1fSKATO Takenori 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
40820916c1fSKATO Takenori 
40920916c1fSKATO Takenori 	/* Initialize CCR4. */
41020916c1fSKATO Takenori 	ccr4 = read_cyrix_reg(CCR4);
41120916c1fSKATO Takenori 	ccr4 &= ~CCR4_IOMASK;
41220916c1fSKATO Takenori #ifdef CPU_IORT
41320916c1fSKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
41420916c1fSKATO Takenori #else
41520916c1fSKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | 7);
41620916c1fSKATO Takenori #endif
41720916c1fSKATO Takenori 
4186593be60SKATO Takenori 	/* Initialize CCR5. */
4196593be60SKATO Takenori #ifdef CPU_WT_ALLOC
4206593be60SKATO Takenori 	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
4216593be60SKATO Takenori #endif
4226593be60SKATO Takenori 
42320916c1fSKATO Takenori 	/* Restore CCR3. */
42420916c1fSKATO Takenori 	write_cyrix_reg(CCR3, ccr3);
42520916c1fSKATO Takenori 
42620916c1fSKATO Takenori 	/* Unlock NW bit in CR0. */
42720916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
42820916c1fSKATO Takenori 
42920916c1fSKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
43020916c1fSKATO Takenori 
43120916c1fSKATO Takenori 	/* Lock NW bit in CR0. */
43220916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
43320916c1fSKATO Takenori 
43420916c1fSKATO Takenori 	write_eflags(eflags);
43520916c1fSKATO Takenori }
4364877e978SKATO Takenori #endif /* I686_CPU */
43720916c1fSKATO Takenori 
438a8e282d6SKATO Takenori void
439a8e282d6SKATO Takenori initializecpu(void)
440a8e282d6SKATO Takenori {
441a8e282d6SKATO Takenori 
442a8e282d6SKATO Takenori 	switch (cpu) {
443a8e282d6SKATO Takenori #ifdef I486_CPU
444a8e282d6SKATO Takenori 	case CPU_BLUE:
445a8e282d6SKATO Takenori 		init_bluelightning();
446a8e282d6SKATO Takenori 		break;
447a8e282d6SKATO Takenori 	case CPU_486DLC:
448a8e282d6SKATO Takenori 		init_486dlc();
449a8e282d6SKATO Takenori 		break;
4509ca82267SKATO Takenori 	case CPU_CY486DX:
4519ca82267SKATO Takenori 		init_cy486dx();
4529ca82267SKATO Takenori 		break;
453a8e282d6SKATO Takenori 	case CPU_M1SC:
454a8e282d6SKATO Takenori 		init_5x86();
455a8e282d6SKATO Takenori 		break;
456a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
457a8e282d6SKATO Takenori 	case CPU_486:
458a8e282d6SKATO Takenori 		init_i486_on_386();
459a8e282d6SKATO Takenori 		break;
460a8e282d6SKATO Takenori #endif
461a8e282d6SKATO Takenori 	case CPU_M1:
462a8e282d6SKATO Takenori 		init_6x86();
463a8e282d6SKATO Takenori 		break;
464a8e282d6SKATO Takenori #endif /* I486_CPU */
4654877e978SKATO Takenori #ifdef I686_CPU
46620916c1fSKATO Takenori 	case CPU_M2:
46720916c1fSKATO Takenori 		init_6x86MX();
46820916c1fSKATO Takenori 		break;
46920916c1fSKATO Takenori #endif
470a8e282d6SKATO Takenori 	default:
471a8e282d6SKATO Takenori 		break;
472a8e282d6SKATO Takenori 	}
473a8e282d6SKATO Takenori 
474a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
475a8e282d6SKATO Takenori 	/*
476a8e282d6SKATO Takenori 	 * OS should flush L1 cahce by itself because no PC-98 supports
477a8e282d6SKATO Takenori 	 * non-Intel CPUs.  Use wbinvd instruction before DMA transfer
478a8e282d6SKATO Takenori 	 * when need_pre_dma_flush = 1, use invd instruction after DMA
479a8e282d6SKATO Takenori 	 * transfer when need_post_dma_flush = 1.  If your CPU upgrade
480a8e282d6SKATO Takenori 	 * product support hardware cache control, you can add
481a8e282d6SKATO Takenori 	 * UPGRADE_CPU_HW_CACHE option in your kernel configuration file.
482a8e282d6SKATO Takenori 	 * This option elminate unneeded cache flush instruction.
483a8e282d6SKATO Takenori 	 */
484a8e282d6SKATO Takenori 	if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
485a8e282d6SKATO Takenori 		switch (cpu) {
486a8e282d6SKATO Takenori #ifdef I486_CPU
487a8e282d6SKATO Takenori 		case CPU_486DLC:
488a8e282d6SKATO Takenori 			need_post_dma_flush = 1;
489a8e282d6SKATO Takenori 			break;
490a8e282d6SKATO Takenori 		case CPU_M1SC:
491a8e282d6SKATO Takenori 			need_pre_dma_flush = 1;
492a8e282d6SKATO Takenori 			break;
493a8e282d6SKATO Takenori #endif
494a8e282d6SKATO Takenori 		default:
495a8e282d6SKATO Takenori 			break;
496a8e282d6SKATO Takenori 		}
497a8e282d6SKATO Takenori 	} else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
498a8e282d6SKATO Takenori 		switch (cpu_id & 0xFF0) {
499a8e282d6SKATO Takenori 		case 0x470:		/* Enhanced Am486DX2 WB */
500a8e282d6SKATO Takenori 		case 0x490:		/* Enhanced Am486DX4 WB */
501a8e282d6SKATO Takenori 		case 0x4F0:		/* Am5x86 WB */
502a8e282d6SKATO Takenori 			need_pre_dma_flush = 1;
503a8e282d6SKATO Takenori 			break;
504a8e282d6SKATO Takenori 		}
505a8e282d6SKATO Takenori 	} else if (strcmp(cpu_vendor, "IBM") == 0) {
506a8e282d6SKATO Takenori 		need_post_dma_flush = 1;
507a8e282d6SKATO Takenori 	} else {
508a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
509a8e282d6SKATO Takenori 		need_pre_dma_flush = 1;
510a8e282d6SKATO Takenori #endif
511a8e282d6SKATO Takenori 	}
512a8e282d6SKATO Takenori #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
513a8e282d6SKATO Takenori }
514a8e282d6SKATO Takenori 
515a8e282d6SKATO Takenori #include "opt_ddb.h"
516a8e282d6SKATO Takenori #ifdef DDB
517a8e282d6SKATO Takenori #include <ddb/ddb.h>
518a8e282d6SKATO Takenori 
519a8e282d6SKATO Takenori DB_SHOW_COMMAND(cyrixreg, cyrixreg)
520a8e282d6SKATO Takenori {
521a8e282d6SKATO Takenori 	u_long	eflags;
522a8e282d6SKATO Takenori 	u_int	cr0;
523a8e282d6SKATO Takenori 	u_char	ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, pcr0;
524a8e282d6SKATO Takenori 
525a8e282d6SKATO Takenori 	cr0 = rcr0();
526a8e282d6SKATO Takenori 	if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
527a8e282d6SKATO Takenori 		eflags = read_eflags();
528a8e282d6SKATO Takenori 		disable_intr();
529a8e282d6SKATO Takenori 
530a8e282d6SKATO Takenori 
5319ca82267SKATO Takenori 		if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) {
532a8e282d6SKATO Takenori 			ccr0 = read_cyrix_reg(CCR0);
533a8e282d6SKATO Takenori 		}
534a8e282d6SKATO Takenori 		ccr1 = read_cyrix_reg(CCR1);
535a8e282d6SKATO Takenori 		ccr2 = read_cyrix_reg(CCR2);
536a8e282d6SKATO Takenori 		ccr3 = read_cyrix_reg(CCR3);
5376593be60SKATO Takenori 		if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
538a8e282d6SKATO Takenori 			write_cyrix_reg(CCR3, CCR3_MAPEN0);
539a8e282d6SKATO Takenori 			ccr4 = read_cyrix_reg(CCR4);
5406593be60SKATO Takenori 			if ((cpu == CPU_M1) || (cpu == CPU_M2))
541a8e282d6SKATO Takenori 				ccr5 = read_cyrix_reg(CCR5);
542a8e282d6SKATO Takenori 			else
543a8e282d6SKATO Takenori 				pcr0 = read_cyrix_reg(PCR0);
544a8e282d6SKATO Takenori 			write_cyrix_reg(CCR3, ccr3);		/* Restore CCR3. */
545a8e282d6SKATO Takenori 		}
546a8e282d6SKATO Takenori 		write_eflags(eflags);
547a8e282d6SKATO Takenori 
5489ca82267SKATO Takenori 		if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX))
549a8e282d6SKATO Takenori 			printf("CCR0=%x, ", (u_int)ccr0);
550a8e282d6SKATO Takenori 
551a8e282d6SKATO Takenori 		printf("CCR1=%x, CCR2=%x, CCR3=%x",
552a8e282d6SKATO Takenori 			(u_int)ccr1, (u_int)ccr2, (u_int)ccr3);
5536593be60SKATO Takenori 		if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
554a8e282d6SKATO Takenori 			printf(", CCR4=%x, ", (u_int)ccr4);
5556593be60SKATO Takenori 			if (cpu == CPU_M1SC)
556a8e282d6SKATO Takenori 				printf("PCR0=%x\n", pcr0);
5576593be60SKATO Takenori 			else
5586593be60SKATO Takenori 				printf("CCR5=%x\n", ccr5);
559a8e282d6SKATO Takenori 		}
560a8e282d6SKATO Takenori 	}
561a8e282d6SKATO Takenori 	printf("CR0=%x\n", cr0);
562a8e282d6SKATO Takenori }
563a8e282d6SKATO Takenori #endif /* DDB */
564