xref: /freebsd/sys/amd64/amd64/initcpu.c (revision 1cfd836f)
1a8e282d6SKATO Takenori /*
24536af6aSKATO Takenori  * Copyright (c) KATO Takenori, 1997, 1998.
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  *
29c3aac50fSPeter Wemm  * $FreeBSD$
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/cputypes.h>
39a8e282d6SKATO Takenori #include <machine/md_var.h>
40a8e282d6SKATO Takenori #include <machine/specialreg.h>
41a8e282d6SKATO Takenori 
42a8e282d6SKATO Takenori void initializecpu(void);
434536af6aSKATO Takenori #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
444536af6aSKATO Takenori void	enable_K5_wt_alloc(void);
454536af6aSKATO Takenori void	enable_K6_wt_alloc(void);
46925f3681SMike Smith void	enable_K6_2_wt_alloc(void);
474536af6aSKATO Takenori #endif
484536af6aSKATO Takenori 
49a8e282d6SKATO Takenori #ifdef I486_CPU
50a8e282d6SKATO Takenori static void init_5x86(void);
51a8e282d6SKATO Takenori static void init_bluelightning(void);
52a8e282d6SKATO Takenori static void init_486dlc(void);
539ca82267SKATO Takenori static void init_cy486dx(void);
54a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
55a8e282d6SKATO Takenori static void init_i486_on_386(void);
56a8e282d6SKATO Takenori #endif
57a8e282d6SKATO Takenori static void init_6x86(void);
58a8e282d6SKATO Takenori #endif /* I486_CPU */
59a8e282d6SKATO Takenori 
604877e978SKATO Takenori #ifdef I686_CPU
6120916c1fSKATO Takenori static void	init_6x86MX(void);
620d303cbaSKATO Takenori static void	init_ppro(void);
6365cbb03cSKATO Takenori static void	init_mendocino(void);
6420916c1fSKATO Takenori #endif
6520916c1fSKATO Takenori 
66a8e282d6SKATO Takenori #ifdef I486_CPU
67a8e282d6SKATO Takenori /*
68a8e282d6SKATO Takenori  * IBM Blue Lightning
69a8e282d6SKATO Takenori  */
70a8e282d6SKATO Takenori static void
71a8e282d6SKATO Takenori init_bluelightning(void)
72a8e282d6SKATO Takenori {
73a8e282d6SKATO Takenori 	u_long	eflags;
74a8e282d6SKATO Takenori 
75a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
76a8e282d6SKATO Takenori 	need_post_dma_flush = 1;
77a8e282d6SKATO Takenori #endif
78a8e282d6SKATO Takenori 
79a8e282d6SKATO Takenori 	eflags = read_eflags();
80a8e282d6SKATO Takenori 	disable_intr();
81a8e282d6SKATO Takenori 
82a8e282d6SKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
83a8e282d6SKATO Takenori 	invd();
84a8e282d6SKATO Takenori 
85a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
86a8e282d6SKATO Takenori 	wrmsr(0x1000, 0x9c92LL);	/* FP operand can be cacheable on Cyrix FPU */
87a8e282d6SKATO Takenori #else
88a8e282d6SKATO Takenori 	wrmsr(0x1000, 0x1c92LL);	/* Intel FPU */
89a8e282d6SKATO Takenori #endif
90a8e282d6SKATO Takenori 	/* Enables 13MB and 0-640KB cache. */
91a8e282d6SKATO Takenori 	wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
92a8e282d6SKATO Takenori #ifdef CPU_BLUELIGHTNING_3X
93a8e282d6SKATO Takenori 	wrmsr(0x1002, 0x04000000LL);	/* Enables triple-clock mode. */
94a8e282d6SKATO Takenori #else
95a8e282d6SKATO Takenori 	wrmsr(0x1002, 0x03000000LL);	/* Enables double-clock mode. */
96a8e282d6SKATO Takenori #endif
97a8e282d6SKATO Takenori 
98a8e282d6SKATO Takenori 	/* Enable caching in CR0. */
99a8e282d6SKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
100a8e282d6SKATO Takenori 	invd();
101a8e282d6SKATO Takenori 	write_eflags(eflags);
102a8e282d6SKATO Takenori }
103a8e282d6SKATO Takenori 
104a8e282d6SKATO Takenori /*
1059ca82267SKATO Takenori  * Cyrix 486SLC/DLC/SR/DR series
106a8e282d6SKATO Takenori  */
107a8e282d6SKATO Takenori static void
108a8e282d6SKATO Takenori init_486dlc(void)
109a8e282d6SKATO Takenori {
110a8e282d6SKATO Takenori 	u_long	eflags;
111a8e282d6SKATO Takenori 	u_char	ccr0;
112a8e282d6SKATO Takenori 
113a8e282d6SKATO Takenori 	eflags = read_eflags();
114a8e282d6SKATO Takenori 	disable_intr();
115a8e282d6SKATO Takenori 	invd();
116a8e282d6SKATO Takenori 
117a8e282d6SKATO Takenori 	ccr0 = read_cyrix_reg(CCR0);
118a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_WORKS
119a8e282d6SKATO Takenori 	ccr0 |= CCR0_NC1 | CCR0_BARB;
120a8e282d6SKATO Takenori 	write_cyrix_reg(CCR0, ccr0);
121a8e282d6SKATO Takenori 	invd();
122a8e282d6SKATO Takenori #else
123a8e282d6SKATO Takenori 	ccr0 &= ~CCR0_NC0;
124a8e282d6SKATO Takenori #ifndef CYRIX_CACHE_REALLY_WORKS
125a8e282d6SKATO Takenori 	ccr0 |= CCR0_NC1 | CCR0_BARB;
126a8e282d6SKATO Takenori #else
127a8e282d6SKATO Takenori 	ccr0 |= CCR0_NC1;
128a8e282d6SKATO Takenori #endif
1294962d938SKATO Takenori #ifdef CPU_DIRECT_MAPPED_CACHE
1304962d938SKATO Takenori 	ccr0 |= CCR0_CO;			/* Direct mapped mode. */
1314962d938SKATO Takenori #endif
132a8e282d6SKATO Takenori 	write_cyrix_reg(CCR0, ccr0);
133a8e282d6SKATO Takenori 
134a8e282d6SKATO Takenori 	/* Clear non-cacheable region. */
135a8e282d6SKATO Takenori 	write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
136a8e282d6SKATO Takenori 	write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
137a8e282d6SKATO Takenori 	write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
138a8e282d6SKATO Takenori 	write_cyrix_reg(NCR4+2, NCR_SIZE_0K);
139a8e282d6SKATO Takenori 
140a8e282d6SKATO Takenori 	write_cyrix_reg(0, 0);	/* dummy write */
141a8e282d6SKATO Takenori 
142a8e282d6SKATO Takenori 	/* Enable caching in CR0. */
143a8e282d6SKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
144a8e282d6SKATO Takenori 	invd();
145a8e282d6SKATO Takenori #endif /* !CYRIX_CACHE_WORKS */
146a8e282d6SKATO Takenori 	write_eflags(eflags);
147a8e282d6SKATO Takenori }
148a8e282d6SKATO Takenori 
149a8e282d6SKATO Takenori 
150a8e282d6SKATO Takenori /*
1519ca82267SKATO Takenori  * Cyrix 486S/DX series
1529ca82267SKATO Takenori  */
1539ca82267SKATO Takenori static void
1549ca82267SKATO Takenori init_cy486dx(void)
1559ca82267SKATO Takenori {
1569ca82267SKATO Takenori 	u_long	eflags;
1579ca82267SKATO Takenori 	u_char	ccr2;
1589ca82267SKATO Takenori 
1599ca82267SKATO Takenori 	eflags = read_eflags();
1609ca82267SKATO Takenori 	disable_intr();
1619ca82267SKATO Takenori 	invd();
1629ca82267SKATO Takenori 
1639ca82267SKATO Takenori 	ccr2 = read_cyrix_reg(CCR2);
1641ba2a543SKATO Takenori #ifdef CPU_SUSP_HLT
1651ba2a543SKATO Takenori 	ccr2 |= CCR2_SUSP_HLT;
1669ca82267SKATO Takenori #endif
1671cfd836fSKATO Takenori 
1681cfd836fSKATO Takenori #ifdef PC98
1691cfd836fSKATO Takenori 	/* Enables WB cache interface pin and Lock NW bit in CR0. */
1701cfd836fSKATO Takenori 	ccr2 |= CCR2_WB | CCR2_LOCK_NW;
1711cfd836fSKATO Takenori 	/* Unlock NW bit in CR0. */
1721cfd836fSKATO Takenori 	write_cyrix_reg(CCR2, ccr2 & ~CCR2_LOCK_NW);
1731cfd836fSKATO Takenori 	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
1741cfd836fSKATO Takenori #endif
1751cfd836fSKATO Takenori 
1769ca82267SKATO Takenori 	write_cyrix_reg(CCR2, ccr2);
1779ca82267SKATO Takenori 	write_eflags(eflags);
1789ca82267SKATO Takenori }
1799ca82267SKATO Takenori 
1809ca82267SKATO Takenori 
1819ca82267SKATO Takenori /*
182a8e282d6SKATO Takenori  * Cyrix 5x86
183a8e282d6SKATO Takenori  */
184a8e282d6SKATO Takenori static void
185a8e282d6SKATO Takenori init_5x86(void)
186a8e282d6SKATO Takenori {
187a8e282d6SKATO Takenori 	u_long	eflags;
188a8e282d6SKATO Takenori 	u_char	ccr2, ccr3, ccr4, pcr0;
189a8e282d6SKATO Takenori 
190a8e282d6SKATO Takenori 	eflags = read_eflags();
191a8e282d6SKATO Takenori 	disable_intr();
192a8e282d6SKATO Takenori 
193a8e282d6SKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
194a8e282d6SKATO Takenori 	wbinvd();
195a8e282d6SKATO Takenori 
196a8e282d6SKATO Takenori 	(void)read_cyrix_reg(CCR3);		/* dummy */
197a8e282d6SKATO Takenori 
198a8e282d6SKATO Takenori 	/* Initialize CCR2. */
199a8e282d6SKATO Takenori 	ccr2 = read_cyrix_reg(CCR2);
200a8e282d6SKATO Takenori 	ccr2 |= CCR2_WB;
201a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT
202a8e282d6SKATO Takenori 	ccr2 |= CCR2_SUSP_HLT;
203a8e282d6SKATO Takenori #else
204a8e282d6SKATO Takenori 	ccr2 &= ~CCR2_SUSP_HLT;
205a8e282d6SKATO Takenori #endif
206a8e282d6SKATO Takenori 	ccr2 |= CCR2_WT1;
207a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, ccr2);
208a8e282d6SKATO Takenori 
209a8e282d6SKATO Takenori 	/* Initialize CCR4. */
210a8e282d6SKATO Takenori 	ccr3 = read_cyrix_reg(CCR3);
211a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
212a8e282d6SKATO Takenori 
213a8e282d6SKATO Takenori 	ccr4 = read_cyrix_reg(CCR4);
214a8e282d6SKATO Takenori 	ccr4 |= CCR4_DTE;
215a8e282d6SKATO Takenori 	ccr4 |= CCR4_MEM;
216a8e282d6SKATO Takenori #ifdef CPU_FASTER_5X86_FPU
217a8e282d6SKATO Takenori 	ccr4 |= CCR4_FASTFPE;
218a8e282d6SKATO Takenori #else
219a8e282d6SKATO Takenori 	ccr4 &= ~CCR4_FASTFPE;
220a8e282d6SKATO Takenori #endif
221a8e282d6SKATO Takenori 	ccr4 &= ~CCR4_IOMASK;
222a8e282d6SKATO Takenori 	/********************************************************************
223a8e282d6SKATO Takenori 	 * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
224a8e282d6SKATO Takenori 	 * should be 0 for errata fix.
225a8e282d6SKATO Takenori 	 ********************************************************************/
226a8e282d6SKATO Takenori #ifdef CPU_IORT
227a8e282d6SKATO Takenori 	ccr4 |= CPU_IORT & CCR4_IOMASK;
228a8e282d6SKATO Takenori #endif
229a8e282d6SKATO Takenori 	write_cyrix_reg(CCR4, ccr4);
230a8e282d6SKATO Takenori 
231a8e282d6SKATO Takenori 	/* Initialize PCR0. */
232a8e282d6SKATO Takenori 	/****************************************************************
233a8e282d6SKATO Takenori 	 * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
234a8e282d6SKATO Takenori 	 * BTB_EN might make your system unstable.
235a8e282d6SKATO Takenori 	 ****************************************************************/
236a8e282d6SKATO Takenori 	pcr0 = read_cyrix_reg(PCR0);
237a8e282d6SKATO Takenori #ifdef CPU_RSTK_EN
238a8e282d6SKATO Takenori 	pcr0 |= PCR0_RSTK;
239a8e282d6SKATO Takenori #else
240a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_RSTK;
241a8e282d6SKATO Takenori #endif
242a8e282d6SKATO Takenori #ifdef CPU_BTB_EN
243a8e282d6SKATO Takenori 	pcr0 |= PCR0_BTB;
244a8e282d6SKATO Takenori #else
245a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_BTB;
246a8e282d6SKATO Takenori #endif
247a8e282d6SKATO Takenori #ifdef CPU_LOOP_EN
248a8e282d6SKATO Takenori 	pcr0 |= PCR0_LOOP;
249a8e282d6SKATO Takenori #else
250a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_LOOP;
251a8e282d6SKATO Takenori #endif
252a8e282d6SKATO Takenori 
253a8e282d6SKATO Takenori 	/****************************************************************
254a8e282d6SKATO Takenori 	 * WARNING: if you use a memory mapped I/O device, don't use
255a8e282d6SKATO Takenori 	 * DISABLE_5X86_LSSER option, which may reorder memory mapped
256a8e282d6SKATO Takenori 	 * I/O access.
257a8e282d6SKATO Takenori 	 * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
258a8e282d6SKATO Takenori 	 ****************************************************************/
259a8e282d6SKATO Takenori #ifdef CPU_DISABLE_5X86_LSSER
260a8e282d6SKATO Takenori 	pcr0 &= ~PCR0_LSSER;
261a8e282d6SKATO Takenori #else
262a8e282d6SKATO Takenori 	pcr0 |= PCR0_LSSER;
263a8e282d6SKATO Takenori #endif
264a8e282d6SKATO Takenori 	write_cyrix_reg(PCR0, pcr0);
265a8e282d6SKATO Takenori 
266a8e282d6SKATO Takenori 	/* Restore CCR3. */
267a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, ccr3);
268a8e282d6SKATO Takenori 
269a8e282d6SKATO Takenori 	(void)read_cyrix_reg(0x80);		/* dummy */
270a8e282d6SKATO Takenori 
271a8e282d6SKATO Takenori 	/* Unlock NW bit in CR0. */
272a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
273a8e282d6SKATO Takenori 	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
274a8e282d6SKATO Takenori 	/* Lock NW bit in CR0. */
275a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
276a8e282d6SKATO Takenori 
277a8e282d6SKATO Takenori 	write_eflags(eflags);
278a8e282d6SKATO Takenori }
279a8e282d6SKATO Takenori 
280a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
281a8e282d6SKATO Takenori /*
282a8e282d6SKATO Takenori  * There are i486 based upgrade products for i386 machines.
283a8e282d6SKATO Takenori  * In this case, BIOS doesn't enables CPU cache.
284a8e282d6SKATO Takenori  */
285a8e282d6SKATO Takenori void
286a8e282d6SKATO Takenori init_i486_on_386(void)
287a8e282d6SKATO Takenori {
288a8e282d6SKATO Takenori 	u_long	eflags;
289a8e282d6SKATO Takenori 
290a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
291a8e282d6SKATO Takenori 	need_post_dma_flush = 1;
292a8e282d6SKATO Takenori #endif
293a8e282d6SKATO Takenori 
294a8e282d6SKATO Takenori 	eflags = read_eflags();
295a8e282d6SKATO Takenori 	disable_intr();
296a8e282d6SKATO Takenori 
297a8e282d6SKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0, NW = 0 */
298a8e282d6SKATO Takenori 
2995fa4a058SKATO Takenori 	write_eflags(eflags);
300a8e282d6SKATO Takenori }
301a8e282d6SKATO Takenori #endif
302a8e282d6SKATO Takenori 
303a8e282d6SKATO Takenori /*
304a8e282d6SKATO Takenori  * Cyrix 6x86
305a8e282d6SKATO Takenori  *
306a8e282d6SKATO Takenori  * XXX - What should I do here?  Please let me know.
307a8e282d6SKATO Takenori  */
308a8e282d6SKATO Takenori static void
309a8e282d6SKATO Takenori init_6x86(void)
310a8e282d6SKATO Takenori {
311a8e282d6SKATO Takenori 	u_long	eflags;
312a8e282d6SKATO Takenori 	u_char	ccr3, ccr4;
313a8e282d6SKATO Takenori 
314a8e282d6SKATO Takenori 	eflags = read_eflags();
315a8e282d6SKATO Takenori 	disable_intr();
316a8e282d6SKATO Takenori 
317a8e282d6SKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
318a8e282d6SKATO Takenori 	wbinvd();
319a8e282d6SKATO Takenori 
320a8e282d6SKATO Takenori 	/* Initialize CCR0. */
321a8e282d6SKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
322a8e282d6SKATO Takenori 
3236593be60SKATO Takenori 	/* Initialize CCR1. */
3246593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK
325b20f1ceeSJonathan Lemon 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
3266593be60SKATO Takenori #else
327b20f1ceeSJonathan Lemon 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
3286593be60SKATO Takenori #endif
3296593be60SKATO Takenori 
330a8e282d6SKATO Takenori 	/* Initialize CCR2. */
331a8e282d6SKATO Takenori #ifdef CPU_SUSP_HLT
332a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
333a8e282d6SKATO Takenori #else
334a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
335a8e282d6SKATO Takenori #endif
336a8e282d6SKATO Takenori 
337a8e282d6SKATO Takenori 	ccr3 = read_cyrix_reg(CCR3);
338a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
339a8e282d6SKATO Takenori 
340a8e282d6SKATO Takenori 	/* Initialize CCR4. */
341a8e282d6SKATO Takenori 	ccr4 = read_cyrix_reg(CCR4);
342a8e282d6SKATO Takenori 	ccr4 |= CCR4_DTE;
343a8e282d6SKATO Takenori 	ccr4 &= ~CCR4_IOMASK;
344a8e282d6SKATO Takenori #ifdef CPU_IORT
345a8e282d6SKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
346a8e282d6SKATO Takenori #else
347a8e282d6SKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | 7);
348a8e282d6SKATO Takenori #endif
349a8e282d6SKATO Takenori 
3506593be60SKATO Takenori 	/* Initialize CCR5. */
3516593be60SKATO Takenori #ifdef CPU_WT_ALLOC
3526593be60SKATO Takenori 	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
3536593be60SKATO Takenori #endif
3546593be60SKATO Takenori 
355a8e282d6SKATO Takenori 	/* Restore CCR3. */
356a8e282d6SKATO Takenori 	write_cyrix_reg(CCR3, ccr3);
357a8e282d6SKATO Takenori 
358a8e282d6SKATO Takenori 	/* Unlock NW bit in CR0. */
359a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
360a8e282d6SKATO Takenori 
361a8e282d6SKATO Takenori 	/*
362a8e282d6SKATO Takenori 	 * Earlier revision of the 6x86 CPU could crash the system if
363a8e282d6SKATO Takenori 	 * L1 cache is in write-back mode.
364a8e282d6SKATO Takenori 	 */
365a8e282d6SKATO Takenori 	if ((cyrix_did & 0xff00) > 0x1600)
366a8e282d6SKATO Takenori 		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
367a8e282d6SKATO Takenori 	else {
368a8e282d6SKATO Takenori 		/* Revision 2.6 and lower. */
369a8e282d6SKATO Takenori #ifdef CYRIX_CACHE_REALLY_WORKS
370a8e282d6SKATO Takenori 		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
371a8e282d6SKATO Takenori #else
372a8e282d6SKATO Takenori 		load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0 and NW = 1 */
373a8e282d6SKATO Takenori #endif
374a8e282d6SKATO Takenori 	}
375a8e282d6SKATO Takenori 
376a8e282d6SKATO Takenori 	/* Lock NW bit in CR0. */
377a8e282d6SKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
378a8e282d6SKATO Takenori 
379a8e282d6SKATO Takenori 	write_eflags(eflags);
380a8e282d6SKATO Takenori }
381a8e282d6SKATO Takenori #endif /* I486_CPU */
382a8e282d6SKATO Takenori 
3834877e978SKATO Takenori #ifdef I686_CPU
38420916c1fSKATO Takenori /*
38520916c1fSKATO Takenori  * Cyrix 6x86MX (code-named M2)
38620916c1fSKATO Takenori  *
38720916c1fSKATO Takenori  * XXX - What should I do here?  Please let me know.
38820916c1fSKATO Takenori  */
38920916c1fSKATO Takenori static void
39020916c1fSKATO Takenori init_6x86MX(void)
39120916c1fSKATO Takenori {
39220916c1fSKATO Takenori 	u_long	eflags;
39320916c1fSKATO Takenori 	u_char	ccr3, ccr4;
39420916c1fSKATO Takenori 
39520916c1fSKATO Takenori 	eflags = read_eflags();
39620916c1fSKATO Takenori 	disable_intr();
39720916c1fSKATO Takenori 
39820916c1fSKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
39920916c1fSKATO Takenori 	wbinvd();
40020916c1fSKATO Takenori 
40120916c1fSKATO Takenori 	/* Initialize CCR0. */
40220916c1fSKATO Takenori 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
40320916c1fSKATO Takenori 
4046593be60SKATO Takenori 	/* Initialize CCR1. */
4056593be60SKATO Takenori #ifdef CPU_CYRIX_NO_LOCK
406b20f1ceeSJonathan Lemon 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
4076593be60SKATO Takenori #else
408b20f1ceeSJonathan Lemon 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
4096593be60SKATO Takenori #endif
4106593be60SKATO Takenori 
41120916c1fSKATO Takenori 	/* Initialize CCR2. */
41220916c1fSKATO Takenori #ifdef CPU_SUSP_HLT
41320916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
41420916c1fSKATO Takenori #else
41520916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
41620916c1fSKATO Takenori #endif
41720916c1fSKATO Takenori 
41820916c1fSKATO Takenori 	ccr3 = read_cyrix_reg(CCR3);
41920916c1fSKATO Takenori 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
42020916c1fSKATO Takenori 
42120916c1fSKATO Takenori 	/* Initialize CCR4. */
42220916c1fSKATO Takenori 	ccr4 = read_cyrix_reg(CCR4);
42320916c1fSKATO Takenori 	ccr4 &= ~CCR4_IOMASK;
42420916c1fSKATO Takenori #ifdef CPU_IORT
42520916c1fSKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
42620916c1fSKATO Takenori #else
42720916c1fSKATO Takenori 	write_cyrix_reg(CCR4, ccr4 | 7);
42820916c1fSKATO Takenori #endif
42920916c1fSKATO Takenori 
4306593be60SKATO Takenori 	/* Initialize CCR5. */
4316593be60SKATO Takenori #ifdef CPU_WT_ALLOC
4326593be60SKATO Takenori 	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
4336593be60SKATO Takenori #endif
4346593be60SKATO Takenori 
43520916c1fSKATO Takenori 	/* Restore CCR3. */
43620916c1fSKATO Takenori 	write_cyrix_reg(CCR3, ccr3);
43720916c1fSKATO Takenori 
43820916c1fSKATO Takenori 	/* Unlock NW bit in CR0. */
43920916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
44020916c1fSKATO Takenori 
44120916c1fSKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
44220916c1fSKATO Takenori 
44320916c1fSKATO Takenori 	/* Lock NW bit in CR0. */
44420916c1fSKATO Takenori 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
44520916c1fSKATO Takenori 
44620916c1fSKATO Takenori 	write_eflags(eflags);
44720916c1fSKATO Takenori }
4480d303cbaSKATO Takenori 
4490d303cbaSKATO Takenori static void
4500d303cbaSKATO Takenori init_ppro(void)
4510d303cbaSKATO Takenori {
4520d303cbaSKATO Takenori #ifndef SMP
4534536af6aSKATO Takenori 	u_int64_t	apicbase;
4540d303cbaSKATO Takenori 
4550d303cbaSKATO Takenori 	/*
4560d303cbaSKATO Takenori 	 * Local APIC should be diabled in UP kernel.
4570d303cbaSKATO Takenori 	 */
4580d303cbaSKATO Takenori 	apicbase = rdmsr(0x1b);
4590d303cbaSKATO Takenori 	apicbase &= ~0x800LL;
4600d303cbaSKATO Takenori 	wrmsr(0x1b, apicbase);
4610d303cbaSKATO Takenori #endif
4620d303cbaSKATO Takenori }
46365cbb03cSKATO Takenori 
46465cbb03cSKATO Takenori /*
46565cbb03cSKATO Takenori  * Initialize BBL_CR_CTL3 (Control register 3: used to configure the
46665cbb03cSKATO Takenori  * L2 cache).
46765cbb03cSKATO Takenori  */
46865cbb03cSKATO Takenori void
46965cbb03cSKATO Takenori init_mendocino(void)
47065cbb03cSKATO Takenori {
47165cbb03cSKATO Takenori #ifdef CPU_PPRO2CELERON
47265cbb03cSKATO Takenori 	u_long	eflags;
47365cbb03cSKATO Takenori 	u_int64_t	bbl_cr_ctl3;
47465cbb03cSKATO Takenori 
47565cbb03cSKATO Takenori 	eflags = read_eflags();
47665cbb03cSKATO Takenori 	disable_intr();
47765cbb03cSKATO Takenori 
47865cbb03cSKATO Takenori 	load_cr0(rcr0() | CR0_CD | CR0_NW);
47965cbb03cSKATO Takenori 	wbinvd();
48065cbb03cSKATO Takenori 
48165cbb03cSKATO Takenori 	bbl_cr_ctl3 = rdmsr(0x11e);
48265cbb03cSKATO Takenori 
48365cbb03cSKATO Takenori 	/* If the L2 cache is configured, do nothing. */
48465cbb03cSKATO Takenori 	if (!(bbl_cr_ctl3 & 1)) {
48565cbb03cSKATO Takenori 		bbl_cr_ctl3 = 0x134052bLL;
48665cbb03cSKATO Takenori 
48765cbb03cSKATO Takenori 		/* Set L2 Cache Latency (Default: 5). */
48865cbb03cSKATO Takenori #ifdef	CPU_CELERON_L2_LATENCY
48965cbb03cSKATO Takenori #if CPU_L2_LATENCY > 15
49065cbb03cSKATO Takenori #error invalid CPU_L2_LATENCY.
49165cbb03cSKATO Takenori #endif
49265cbb03cSKATO Takenori 		bbl_cr_ctl3 |= CPU_L2_LATENCY << 1;
49365cbb03cSKATO Takenori #else
49465cbb03cSKATO Takenori 		bbl_cr_ctl3 |= 5 << 1;
49565cbb03cSKATO Takenori #endif
49665cbb03cSKATO Takenori 		wrmsr(0x11e, bbl_cr_ctl3);
49765cbb03cSKATO Takenori 	}
49865cbb03cSKATO Takenori 
49965cbb03cSKATO Takenori 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));
50065cbb03cSKATO Takenori 	write_eflags(eflags);
50165cbb03cSKATO Takenori #endif /* CPU_PPRO2CELERON */
50265cbb03cSKATO Takenori }
50365cbb03cSKATO Takenori 
5044877e978SKATO Takenori #endif /* I686_CPU */
50520916c1fSKATO Takenori 
506a8e282d6SKATO Takenori void
507a8e282d6SKATO Takenori initializecpu(void)
508a8e282d6SKATO Takenori {
509a8e282d6SKATO Takenori 
510a8e282d6SKATO Takenori 	switch (cpu) {
511a8e282d6SKATO Takenori #ifdef I486_CPU
512a8e282d6SKATO Takenori 	case CPU_BLUE:
513a8e282d6SKATO Takenori 		init_bluelightning();
514a8e282d6SKATO Takenori 		break;
515a8e282d6SKATO Takenori 	case CPU_486DLC:
516a8e282d6SKATO Takenori 		init_486dlc();
517a8e282d6SKATO Takenori 		break;
5189ca82267SKATO Takenori 	case CPU_CY486DX:
5199ca82267SKATO Takenori 		init_cy486dx();
5209ca82267SKATO Takenori 		break;
521a8e282d6SKATO Takenori 	case CPU_M1SC:
522a8e282d6SKATO Takenori 		init_5x86();
523a8e282d6SKATO Takenori 		break;
524a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
525a8e282d6SKATO Takenori 	case CPU_486:
526a8e282d6SKATO Takenori 		init_i486_on_386();
527a8e282d6SKATO Takenori 		break;
528a8e282d6SKATO Takenori #endif
529a8e282d6SKATO Takenori 	case CPU_M1:
530a8e282d6SKATO Takenori 		init_6x86();
531a8e282d6SKATO Takenori 		break;
532a8e282d6SKATO Takenori #endif /* I486_CPU */
5334877e978SKATO Takenori #ifdef I686_CPU
53420916c1fSKATO Takenori 	case CPU_M2:
53520916c1fSKATO Takenori 		init_6x86MX();
53620916c1fSKATO Takenori 		break;
5370d303cbaSKATO Takenori 	case CPU_686:
53865cbb03cSKATO Takenori 		if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
53965cbb03cSKATO Takenori 			switch (cpu_id & 0xff0) {
54065cbb03cSKATO Takenori 			case 0x610:
5410d303cbaSKATO Takenori 				init_ppro();
5420d303cbaSKATO Takenori 				break;
54365cbb03cSKATO Takenori 			case 0x660:
54465cbb03cSKATO Takenori 				init_mendocino();
54565cbb03cSKATO Takenori 				break;
54665cbb03cSKATO Takenori 			}
54765cbb03cSKATO Takenori 		}
54865cbb03cSKATO Takenori 		break;
54920916c1fSKATO Takenori #endif
550a8e282d6SKATO Takenori 	default:
551a8e282d6SKATO Takenori 		break;
552a8e282d6SKATO Takenori 	}
553a8e282d6SKATO Takenori 
554a8e282d6SKATO Takenori #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
555a8e282d6SKATO Takenori 	/*
556a8e282d6SKATO Takenori 	 * OS should flush L1 cahce by itself because no PC-98 supports
557a8e282d6SKATO Takenori 	 * non-Intel CPUs.  Use wbinvd instruction before DMA transfer
558a8e282d6SKATO Takenori 	 * when need_pre_dma_flush = 1, use invd instruction after DMA
559a8e282d6SKATO Takenori 	 * transfer when need_post_dma_flush = 1.  If your CPU upgrade
560a8e282d6SKATO Takenori 	 * product support hardware cache control, you can add
561a8e282d6SKATO Takenori 	 * UPGRADE_CPU_HW_CACHE option in your kernel configuration file.
562a8e282d6SKATO Takenori 	 * This option elminate unneeded cache flush instruction.
563a8e282d6SKATO Takenori 	 */
564a8e282d6SKATO Takenori 	if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
565a8e282d6SKATO Takenori 		switch (cpu) {
566a8e282d6SKATO Takenori #ifdef I486_CPU
567a8e282d6SKATO Takenori 		case CPU_486DLC:
568a8e282d6SKATO Takenori 			need_post_dma_flush = 1;
569a8e282d6SKATO Takenori 			break;
570a8e282d6SKATO Takenori 		case CPU_M1SC:
571a8e282d6SKATO Takenori 			need_pre_dma_flush = 1;
572a8e282d6SKATO Takenori 			break;
5731cfd836fSKATO Takenori 		case CPU_CY486DX:
5741cfd836fSKATO Takenori 			need_pre_dma_flush = 1;
5751cfd836fSKATO Takenori #ifdef CPU_I486_ON_386
5761cfd836fSKATO Takenori 			need_post_dma_flush = 1;
5771cfd836fSKATO Takenori #endif
5781cfd836fSKATO Takenori 			break;
579a8e282d6SKATO Takenori #endif
580a8e282d6SKATO Takenori 		default:
581a8e282d6SKATO Takenori 			break;
582a8e282d6SKATO Takenori 		}
583a8e282d6SKATO Takenori 	} else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
584a8e282d6SKATO Takenori 		switch (cpu_id & 0xFF0) {
585a8e282d6SKATO Takenori 		case 0x470:		/* Enhanced Am486DX2 WB */
586a8e282d6SKATO Takenori 		case 0x490:		/* Enhanced Am486DX4 WB */
587a8e282d6SKATO Takenori 		case 0x4F0:		/* Am5x86 WB */
588a8e282d6SKATO Takenori 			need_pre_dma_flush = 1;
589a8e282d6SKATO Takenori 			break;
590a8e282d6SKATO Takenori 		}
591a8e282d6SKATO Takenori 	} else if (strcmp(cpu_vendor, "IBM") == 0) {
592a8e282d6SKATO Takenori 		need_post_dma_flush = 1;
593a8e282d6SKATO Takenori 	} else {
594a8e282d6SKATO Takenori #ifdef CPU_I486_ON_386
595a8e282d6SKATO Takenori 		need_pre_dma_flush = 1;
596a8e282d6SKATO Takenori #endif
597a8e282d6SKATO Takenori 	}
598a8e282d6SKATO Takenori #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
599a8e282d6SKATO Takenori }
600a8e282d6SKATO Takenori 
6014536af6aSKATO Takenori #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
6024536af6aSKATO Takenori /*
6034536af6aSKATO Takenori  * Enable write allocate feature of AMD processors.
6044536af6aSKATO Takenori  * Following two functions require the Maxmem variable being set.
6054536af6aSKATO Takenori  */
6064536af6aSKATO Takenori void
6074536af6aSKATO Takenori enable_K5_wt_alloc(void)
6084536af6aSKATO Takenori {
6094536af6aSKATO Takenori 	u_int64_t	msr;
6104536af6aSKATO Takenori 
6114536af6aSKATO Takenori 	/*
6124536af6aSKATO Takenori 	 * Write allocate is supported only on models 1, 2, and 3, with
6134536af6aSKATO Takenori 	 * a stepping of 4 or greater.
6144536af6aSKATO Takenori 	 */
6154536af6aSKATO Takenori 	if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) {
6164536af6aSKATO Takenori 		disable_intr();
6174536af6aSKATO Takenori 		msr = rdmsr(0x83);		/* HWCR */
6184536af6aSKATO Takenori 		wrmsr(0x83, msr & !(0x10));
6194536af6aSKATO Takenori 
6204536af6aSKATO Takenori 		/*
6214536af6aSKATO Takenori 		 * We have to tell the chip where the top of memory is,
6224536af6aSKATO Takenori 		 * since video cards could have frame bufferes there,
6234536af6aSKATO Takenori 		 * memory-mapped I/O could be there, etc.
6244536af6aSKATO Takenori 		 */
6254536af6aSKATO Takenori 		if(Maxmem > 0)
6264536af6aSKATO Takenori 		  msr = Maxmem / 16;
6274536af6aSKATO Takenori 		else
6284536af6aSKATO Takenori 		  msr = 0;
6294536af6aSKATO Takenori 		msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
6304536af6aSKATO Takenori #ifdef PC98
6314536af6aSKATO Takenori 		if (!(inb(0x43b) & 4)) {
6324536af6aSKATO Takenori 			wrmsr(0x86, 0x0ff00f0);
6334536af6aSKATO Takenori 			msr |= AMD_WT_ALLOC_PRE;
6344536af6aSKATO Takenori 		}
6354536af6aSKATO Takenori #else
6364536af6aSKATO Takenori 		/*
6374536af6aSKATO Takenori 		 * There is no way to know wheter 15-16M hole exists or not.
6384536af6aSKATO Takenori 		 * Therefore, we disable write allocate for this range.
6394536af6aSKATO Takenori 		 */
6404536af6aSKATO Takenori 			wrmsr(0x86, 0x0ff00f0);
6414536af6aSKATO Takenori 			msr |= AMD_WT_ALLOC_PRE;
6424536af6aSKATO Takenori #endif
6434536af6aSKATO Takenori 		wrmsr(0x85, msr);
6444536af6aSKATO Takenori 
6454536af6aSKATO Takenori 		msr=rdmsr(0x83);
6464536af6aSKATO Takenori 		wrmsr(0x83, msr|0x10); /* enable write allocate */
6474536af6aSKATO Takenori 
6484536af6aSKATO Takenori 		enable_intr();
6494536af6aSKATO Takenori 	}
6504536af6aSKATO Takenori }
6514536af6aSKATO Takenori 
6524536af6aSKATO Takenori void
6534536af6aSKATO Takenori enable_K6_wt_alloc(void)
6544536af6aSKATO Takenori {
6554536af6aSKATO Takenori 	quad_t	size;
6564536af6aSKATO Takenori 	u_int64_t	whcr;
6574536af6aSKATO Takenori 	u_long	eflags;
6584536af6aSKATO Takenori 
6594536af6aSKATO Takenori 	eflags = read_eflags();
6604536af6aSKATO Takenori 	disable_intr();
6614536af6aSKATO Takenori 	wbinvd();
6624536af6aSKATO Takenori 
6634536af6aSKATO Takenori #ifdef CPU_DISABLE_CACHE
6644536af6aSKATO Takenori 	/*
6654536af6aSKATO Takenori 	 * Certain K6-2 box becomes unstable when write allocation is
6664536af6aSKATO Takenori 	 * enabled.
6674536af6aSKATO Takenori 	 */
6684536af6aSKATO Takenori 	/*
6694536af6aSKATO Takenori 	 * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
6704536af6aSKATO Takenori 	 * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
6714536af6aSKATO Takenori 	 * All other bits in TR12 have no effect on the processer's operation.
6724536af6aSKATO Takenori 	 * The I/O Trap Restart function (bit 9 of TR12) is always enabled
6734536af6aSKATO Takenori 	 * on the AMD-K6.
6744536af6aSKATO Takenori 	 */
6754536af6aSKATO Takenori 	wrmsr(0x0000000e, (u_int64_t)0x0008);
6764536af6aSKATO Takenori #endif
6774536af6aSKATO Takenori 	/* Don't assume that memory size is aligned with 4M. */
6784536af6aSKATO Takenori 	if (Maxmem > 0)
6794b055742SKATO Takenori 	  size = ((Maxmem >> 8) + 3) >> 2;
6804536af6aSKATO Takenori 	else
6814536af6aSKATO Takenori 	  size = 0;
6824536af6aSKATO Takenori 
6834536af6aSKATO Takenori 	/* Limit is 508M bytes. */
6844b055742SKATO Takenori 	if (size > 0x7f)
6854b055742SKATO Takenori 		size = 0x7f;
6864b055742SKATO Takenori 	whcr = (rdmsr(0xc0000082) & ~(0x7fLL << 1)) | (size << 1);
6874536af6aSKATO Takenori 
688925f3681SMike Smith #if defined(PC98) || defined(NO_MEMORY_HOLE)
6894b055742SKATO Takenori 	if (whcr & (0x7fLL << 1)) {
690925f3681SMike Smith #ifdef PC98
6914536af6aSKATO Takenori 		/*
6924536af6aSKATO Takenori 		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
6934536af6aSKATO Takenori 		 * 15-16M range.
6944536af6aSKATO Takenori 		 */
6954536af6aSKATO Takenori 		if (!(inb(0x43b) & 4))
6964536af6aSKATO Takenori 			whcr &= ~0x0001LL;
6974536af6aSKATO Takenori 		else
698925f3681SMike Smith #endif
6994536af6aSKATO Takenori 			whcr |=  0x0001LL;
7004536af6aSKATO Takenori 	}
7014536af6aSKATO Takenori #else
7024536af6aSKATO Takenori 	/*
7034536af6aSKATO Takenori 	 * There is no way to know wheter 15-16M hole exists or not.
7044536af6aSKATO Takenori 	 * Therefore, we disable write allocate for this range.
7054536af6aSKATO Takenori 	 */
706925f3681SMike Smith 	whcr &= ~0x0001LL;
707925f3681SMike Smith #endif
708925f3681SMike Smith 	wrmsr(0x0c0000082, whcr);
709925f3681SMike Smith 
710925f3681SMike Smith 	write_eflags(eflags);
711925f3681SMike Smith 	enable_intr();
712925f3681SMike Smith }
713925f3681SMike Smith 
714925f3681SMike Smith void
715925f3681SMike Smith enable_K6_2_wt_alloc(void)
716925f3681SMike Smith {
717925f3681SMike Smith 	quad_t	size;
718925f3681SMike Smith 	u_int64_t	whcr;
719925f3681SMike Smith 	u_long	eflags;
720925f3681SMike Smith 
721925f3681SMike Smith 	eflags = read_eflags();
722925f3681SMike Smith 	disable_intr();
723925f3681SMike Smith 	wbinvd();
724925f3681SMike Smith 
725925f3681SMike Smith #ifdef CPU_DISABLE_CACHE
726925f3681SMike Smith 	/*
727925f3681SMike Smith 	 * Certain K6-2 box becomes unstable when write allocation is
728925f3681SMike Smith 	 * enabled.
729925f3681SMike Smith 	 */
730925f3681SMike Smith 	/*
731925f3681SMike Smith 	 * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
732925f3681SMike Smith 	 * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
733925f3681SMike Smith 	 * All other bits in TR12 have no effect on the processer's operation.
734925f3681SMike Smith 	 * The I/O Trap Restart function (bit 9 of TR12) is always enabled
735925f3681SMike Smith 	 * on the AMD-K6.
736925f3681SMike Smith 	 */
737925f3681SMike Smith 	wrmsr(0x0000000e, (u_int64_t)0x0008);
738925f3681SMike Smith #endif
739925f3681SMike Smith 	/* Don't assume that memory size is aligned with 4M. */
740925f3681SMike Smith 	if (Maxmem > 0)
741925f3681SMike Smith 	  size = ((Maxmem >> 8) + 3) >> 2;
742925f3681SMike Smith 	else
743925f3681SMike Smith 	  size = 0;
744925f3681SMike Smith 
745925f3681SMike Smith 	/* Limit is 4092M bytes. */
7464b055742SKATO Takenori 	if (size > 0x3fff)
7474b055742SKATO Takenori 		size = 0x3ff;
748925f3681SMike Smith 	whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22);
749925f3681SMike Smith 
750925f3681SMike Smith #if defined(PC98) || defined(NO_MEMORY_HOLE)
751925f3681SMike Smith 	if (whcr & (0x3ffLL << 22)) {
752925f3681SMike Smith #ifdef PC98
753925f3681SMike Smith 		/*
754925f3681SMike Smith 		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
755925f3681SMike Smith 		 * 15-16M range.
756925f3681SMike Smith 		 */
757925f3681SMike Smith 		if (!(inb(0x43b) & 4))
758925f3681SMike Smith 			whcr &= ~(1LL << 16);
759925f3681SMike Smith 		else
760925f3681SMike Smith #endif
761925f3681SMike Smith 			whcr |=  1LL << 16;
762925f3681SMike Smith 	}
763925f3681SMike Smith #else
764925f3681SMike Smith 	/*
765925f3681SMike Smith 	 * There is no way to know wheter 15-16M hole exists or not.
766925f3681SMike Smith 	 * Therefore, we disable write allocate for this range.
767925f3681SMike Smith 	 */
768925f3681SMike Smith 	whcr &= ~(1LL << 16);
7694536af6aSKATO Takenori #endif
7704536af6aSKATO Takenori 	wrmsr(0x0c0000082, whcr);
7714536af6aSKATO Takenori 
7724536af6aSKATO Takenori 	write_eflags(eflags);
7734536af6aSKATO Takenori 	enable_intr();
7744536af6aSKATO Takenori }
7754536af6aSKATO Takenori #endif /* I585_CPU && CPU_WT_ALLOC */
7764536af6aSKATO Takenori 
777a8e282d6SKATO Takenori #include "opt_ddb.h"
778a8e282d6SKATO Takenori #ifdef DDB
779a8e282d6SKATO Takenori #include <ddb/ddb.h>
780a8e282d6SKATO Takenori 
781a8e282d6SKATO Takenori DB_SHOW_COMMAND(cyrixreg, cyrixreg)
782a8e282d6SKATO Takenori {
783a8e282d6SKATO Takenori 	u_long	eflags;
784a8e282d6SKATO Takenori 	u_int	cr0;
7859402b520SMatthew Dillon 	u_char	ccr1, ccr2, ccr3;
7869402b520SMatthew Dillon 	u_char	ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0;
787a8e282d6SKATO Takenori 
788a8e282d6SKATO Takenori 	cr0 = rcr0();
789a8e282d6SKATO Takenori 	if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
790a8e282d6SKATO Takenori 		eflags = read_eflags();
791a8e282d6SKATO Takenori 		disable_intr();
792a8e282d6SKATO Takenori 
793a8e282d6SKATO Takenori 
7949ca82267SKATO Takenori 		if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) {
795a8e282d6SKATO Takenori 			ccr0 = read_cyrix_reg(CCR0);
796a8e282d6SKATO Takenori 		}
797a8e282d6SKATO Takenori 		ccr1 = read_cyrix_reg(CCR1);
798a8e282d6SKATO Takenori 		ccr2 = read_cyrix_reg(CCR2);
799a8e282d6SKATO Takenori 		ccr3 = read_cyrix_reg(CCR3);
8006593be60SKATO Takenori 		if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
801a8e282d6SKATO Takenori 			write_cyrix_reg(CCR3, CCR3_MAPEN0);
802a8e282d6SKATO Takenori 			ccr4 = read_cyrix_reg(CCR4);
8036593be60SKATO Takenori 			if ((cpu == CPU_M1) || (cpu == CPU_M2))
804a8e282d6SKATO Takenori 				ccr5 = read_cyrix_reg(CCR5);
805a8e282d6SKATO Takenori 			else
806a8e282d6SKATO Takenori 				pcr0 = read_cyrix_reg(PCR0);
807a8e282d6SKATO Takenori 			write_cyrix_reg(CCR3, ccr3);		/* Restore CCR3. */
808a8e282d6SKATO Takenori 		}
809a8e282d6SKATO Takenori 		write_eflags(eflags);
810a8e282d6SKATO Takenori 
8119ca82267SKATO Takenori 		if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX))
812a8e282d6SKATO Takenori 			printf("CCR0=%x, ", (u_int)ccr0);
813a8e282d6SKATO Takenori 
814a8e282d6SKATO Takenori 		printf("CCR1=%x, CCR2=%x, CCR3=%x",
815a8e282d6SKATO Takenori 			(u_int)ccr1, (u_int)ccr2, (u_int)ccr3);
8166593be60SKATO Takenori 		if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
817a8e282d6SKATO Takenori 			printf(", CCR4=%x, ", (u_int)ccr4);
8186593be60SKATO Takenori 			if (cpu == CPU_M1SC)
819a8e282d6SKATO Takenori 				printf("PCR0=%x\n", pcr0);
8206593be60SKATO Takenori 			else
8216593be60SKATO Takenori 				printf("CCR5=%x\n", ccr5);
822a8e282d6SKATO Takenori 		}
823a8e282d6SKATO Takenori 	}
824a8e282d6SKATO Takenori 	printf("CR0=%x\n", cr0);
825a8e282d6SKATO Takenori }
826a8e282d6SKATO Takenori #endif /* DDB */
827