xref: /freebsd/sys/amd64/amd64/initcpu.c (revision 380a989b3223d455375b4fae70fd0b9bdd43bafb)
1 /*
2  * Copyright (c) KATO Takenori, 1997, 1998.
3  *
4  * All rights reserved.  Unpublished rights reserved under the copyright
5  * laws of Japan.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer as
13  *    the first lines of this file unmodified.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *		$Id: initcpu.c,v 1.15 1998/12/14 06:16:13 dillon Exp $
30  */
31 
32 #include "opt_cpu.h"
33 #include "opt_failsafe.h"
34 
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/systm.h>
38 
39 #include <machine/cputypes.h>
40 #include <machine/md_var.h>
41 #include <machine/specialreg.h>
42 
43 void initializecpu(void);
44 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
45 void	enable_K5_wt_alloc(void);
46 void	enable_K6_wt_alloc(void);
47 void	enable_K6_2_wt_alloc(void);
48 #endif
49 
50 #ifdef I486_CPU
51 static void init_5x86(void);
52 static void init_bluelightning(void);
53 static void init_486dlc(void);
54 static void init_cy486dx(void);
55 #ifdef CPU_I486_ON_386
56 static void init_i486_on_386(void);
57 #endif
58 static void init_6x86(void);
59 #endif /* I486_CPU */
60 
61 #ifdef I686_CPU
62 static void	init_6x86MX(void);
63 static void	init_ppro(void);
64 #endif
65 
66 #ifdef I486_CPU
67 /*
68  * IBM Blue Lightning
69  */
70 static void
71 init_bluelightning(void)
72 {
73 	u_long	eflags;
74 
75 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
76 	need_post_dma_flush = 1;
77 #endif
78 
79 	eflags = read_eflags();
80 	disable_intr();
81 
82 	load_cr0(rcr0() | CR0_CD | CR0_NW);
83 	invd();
84 
85 #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
86 	wrmsr(0x1000, 0x9c92LL);	/* FP operand can be cacheable on Cyrix FPU */
87 #else
88 	wrmsr(0x1000, 0x1c92LL);	/* Intel FPU */
89 #endif
90 	/* Enables 13MB and 0-640KB cache. */
91 	wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
92 #ifdef CPU_BLUELIGHTNING_3X
93 	wrmsr(0x1002, 0x04000000LL);	/* Enables triple-clock mode. */
94 #else
95 	wrmsr(0x1002, 0x03000000LL);	/* Enables double-clock mode. */
96 #endif
97 
98 	/* Enable caching in CR0. */
99 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
100 	invd();
101 	write_eflags(eflags);
102 }
103 
104 /*
105  * Cyrix 486SLC/DLC/SR/DR series
106  */
107 static void
108 init_486dlc(void)
109 {
110 	u_long	eflags;
111 	u_char	ccr0;
112 
113 	eflags = read_eflags();
114 	disable_intr();
115 	invd();
116 
117 	ccr0 = read_cyrix_reg(CCR0);
118 #ifndef CYRIX_CACHE_WORKS
119 	ccr0 |= CCR0_NC1 | CCR0_BARB;
120 	write_cyrix_reg(CCR0, ccr0);
121 	invd();
122 #else
123 	ccr0 &= ~CCR0_NC0;
124 #ifndef CYRIX_CACHE_REALLY_WORKS
125 	ccr0 |= CCR0_NC1 | CCR0_BARB;
126 #else
127 	ccr0 |= CCR0_NC1;
128 #endif
129 #ifdef CPU_DIRECT_MAPPED_CACHE
130 	ccr0 |= CCR0_CO;			/* Direct mapped mode. */
131 #endif
132 	write_cyrix_reg(CCR0, ccr0);
133 
134 	/* Clear non-cacheable region. */
135 	write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
136 	write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
137 	write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
138 	write_cyrix_reg(NCR4+2, NCR_SIZE_0K);
139 
140 	write_cyrix_reg(0, 0);	/* dummy write */
141 
142 	/* Enable caching in CR0. */
143 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
144 	invd();
145 #endif /* !CYRIX_CACHE_WORKS */
146 	write_eflags(eflags);
147 }
148 
149 
150 /*
151  * Cyrix 486S/DX series
152  */
153 static void
154 init_cy486dx(void)
155 {
156 	u_long	eflags;
157 	u_char	ccr2;
158 
159 	eflags = read_eflags();
160 	disable_intr();
161 	invd();
162 
163 	ccr2 = read_cyrix_reg(CCR2);
164 #ifdef CPU_SUSP_HLT
165 	ccr2 |= CCR2_SUSP_HLT;
166 #endif
167 	write_cyrix_reg(CCR2, ccr2);
168 	write_eflags(eflags);
169 }
170 
171 
172 /*
173  * Cyrix 5x86
174  */
175 static void
176 init_5x86(void)
177 {
178 	u_long	eflags;
179 	u_char	ccr2, ccr3, ccr4, pcr0;
180 
181 	eflags = read_eflags();
182 	disable_intr();
183 
184 	load_cr0(rcr0() | CR0_CD | CR0_NW);
185 	wbinvd();
186 
187 	(void)read_cyrix_reg(CCR3);		/* dummy */
188 
189 	/* Initialize CCR2. */
190 	ccr2 = read_cyrix_reg(CCR2);
191 	ccr2 |= CCR2_WB;
192 #ifdef CPU_SUSP_HLT
193 	ccr2 |= CCR2_SUSP_HLT;
194 #else
195 	ccr2 &= ~CCR2_SUSP_HLT;
196 #endif
197 	ccr2 |= CCR2_WT1;
198 	write_cyrix_reg(CCR2, ccr2);
199 
200 	/* Initialize CCR4. */
201 	ccr3 = read_cyrix_reg(CCR3);
202 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
203 
204 	ccr4 = read_cyrix_reg(CCR4);
205 	ccr4 |= CCR4_DTE;
206 	ccr4 |= CCR4_MEM;
207 #ifdef CPU_FASTER_5X86_FPU
208 	ccr4 |= CCR4_FASTFPE;
209 #else
210 	ccr4 &= ~CCR4_FASTFPE;
211 #endif
212 	ccr4 &= ~CCR4_IOMASK;
213 	/********************************************************************
214 	 * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
215 	 * should be 0 for errata fix.
216 	 ********************************************************************/
217 #ifdef CPU_IORT
218 	ccr4 |= CPU_IORT & CCR4_IOMASK;
219 #endif
220 	write_cyrix_reg(CCR4, ccr4);
221 
222 	/* Initialize PCR0. */
223 	/****************************************************************
224 	 * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
225 	 * BTB_EN might make your system unstable.
226 	 ****************************************************************/
227 	pcr0 = read_cyrix_reg(PCR0);
228 #ifdef CPU_RSTK_EN
229 	pcr0 |= PCR0_RSTK;
230 #else
231 	pcr0 &= ~PCR0_RSTK;
232 #endif
233 #ifdef CPU_BTB_EN
234 	pcr0 |= PCR0_BTB;
235 #else
236 	pcr0 &= ~PCR0_BTB;
237 #endif
238 #ifdef CPU_LOOP_EN
239 	pcr0 |= PCR0_LOOP;
240 #else
241 	pcr0 &= ~PCR0_LOOP;
242 #endif
243 
244 	/****************************************************************
245 	 * WARNING: if you use a memory mapped I/O device, don't use
246 	 * DISABLE_5X86_LSSER option, which may reorder memory mapped
247 	 * I/O access.
248 	 * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
249 	 ****************************************************************/
250 #ifdef CPU_DISABLE_5X86_LSSER
251 	pcr0 &= ~PCR0_LSSER;
252 #else
253 	pcr0 |= PCR0_LSSER;
254 #endif
255 	write_cyrix_reg(PCR0, pcr0);
256 
257 	/* Restore CCR3. */
258 	write_cyrix_reg(CCR3, ccr3);
259 
260 	(void)read_cyrix_reg(0x80);		/* dummy */
261 
262 	/* Unlock NW bit in CR0. */
263 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
264 	load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0, NW = 1 */
265 	/* Lock NW bit in CR0. */
266 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
267 
268 	write_eflags(eflags);
269 }
270 
271 #ifdef CPU_I486_ON_386
272 /*
273  * There are i486 based upgrade products for i386 machines.
274  * In this case, BIOS doesn't enables CPU cache.
275  */
276 void
277 init_i486_on_386(void)
278 {
279 	u_long	eflags;
280 
281 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
282 	need_post_dma_flush = 1;
283 #endif
284 
285 	eflags = read_eflags();
286 	disable_intr();
287 
288 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0, NW = 0 */
289 
290 	write_eflags(eflags);
291 }
292 #endif
293 
294 /*
295  * Cyrix 6x86
296  *
297  * XXX - What should I do here?  Please let me know.
298  */
299 static void
300 init_6x86(void)
301 {
302 	u_long	eflags;
303 	u_char	ccr3, ccr4;
304 
305 	eflags = read_eflags();
306 	disable_intr();
307 
308 	load_cr0(rcr0() | CR0_CD | CR0_NW);
309 	wbinvd();
310 
311 	/* Initialize CCR0. */
312 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
313 
314 	/* Initialize CCR1. */
315 #ifdef CPU_CYRIX_NO_LOCK
316 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
317 #else
318 #ifdef FAILSAFE
319 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
320 #endif
321 #endif
322 
323 	/* Initialize CCR2. */
324 #ifdef CPU_SUSP_HLT
325 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
326 #else
327 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
328 #endif
329 
330 	ccr3 = read_cyrix_reg(CCR3);
331 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
332 
333 	/* Initialize CCR4. */
334 	ccr4 = read_cyrix_reg(CCR4);
335 	ccr4 |= CCR4_DTE;
336 	ccr4 &= ~CCR4_IOMASK;
337 #ifdef CPU_IORT
338 	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
339 #else
340 	write_cyrix_reg(CCR4, ccr4 | 7);
341 #endif
342 
343 	/* Initialize CCR5. */
344 #ifdef CPU_WT_ALLOC
345 	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
346 #endif
347 
348 	/* Restore CCR3. */
349 	write_cyrix_reg(CCR3, ccr3);
350 
351 	/* Unlock NW bit in CR0. */
352 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
353 
354 	/*
355 	 * Earlier revision of the 6x86 CPU could crash the system if
356 	 * L1 cache is in write-back mode.
357 	 */
358 	if ((cyrix_did & 0xff00) > 0x1600)
359 		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
360 	else {
361 		/* Revision 2.6 and lower. */
362 #ifdef CYRIX_CACHE_REALLY_WORKS
363 		load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
364 #else
365 		load_cr0((rcr0() & ~CR0_CD) | CR0_NW);	/* CD = 0 and NW = 1 */
366 #endif
367 	}
368 
369 	/* Lock NW bit in CR0. */
370 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
371 
372 	write_eflags(eflags);
373 }
374 #endif /* I486_CPU */
375 
376 #ifdef I686_CPU
377 /*
378  * Cyrix 6x86MX (code-named M2)
379  *
380  * XXX - What should I do here?  Please let me know.
381  */
382 static void
383 init_6x86MX(void)
384 {
385 	u_long	eflags;
386 	u_char	ccr3, ccr4;
387 
388 	eflags = read_eflags();
389 	disable_intr();
390 
391 	load_cr0(rcr0() | CR0_CD | CR0_NW);
392 	wbinvd();
393 
394 	/* Initialize CCR0. */
395 	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
396 
397 	/* Initialize CCR1. */
398 #ifdef CPU_CYRIX_NO_LOCK
399 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
400 #else
401 #ifdef FAILSAFE
402 	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
403 #endif
404 #endif
405 
406 	/* Initialize CCR2. */
407 #ifdef CPU_SUSP_HLT
408 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
409 #else
410 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
411 #endif
412 
413 	ccr3 = read_cyrix_reg(CCR3);
414 	write_cyrix_reg(CCR3, CCR3_MAPEN0);
415 
416 	/* Initialize CCR4. */
417 	ccr4 = read_cyrix_reg(CCR4);
418 	ccr4 &= ~CCR4_IOMASK;
419 #ifdef CPU_IORT
420 	write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
421 #else
422 	write_cyrix_reg(CCR4, ccr4 | 7);
423 #endif
424 
425 	/* Initialize CCR5. */
426 #ifdef CPU_WT_ALLOC
427 	write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
428 #endif
429 
430 	/* Restore CCR3. */
431 	write_cyrix_reg(CCR3, ccr3);
432 
433 	/* Unlock NW bit in CR0. */
434 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
435 
436 	load_cr0(rcr0() & ~(CR0_CD | CR0_NW));	/* CD = 0 and NW = 0 */
437 
438 	/* Lock NW bit in CR0. */
439 	write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
440 
441 	write_eflags(eflags);
442 }
443 
444 static void
445 init_ppro(void)
446 {
447 #ifndef SMP
448 	u_int64_t	apicbase;
449 
450 	/*
451 	 * Local APIC should be diabled in UP kernel.
452 	 */
453 	apicbase = rdmsr(0x1b);
454 	apicbase &= ~0x800LL;
455 	wrmsr(0x1b, apicbase);
456 #endif
457 }
458 #endif /* I686_CPU */
459 
460 void
461 initializecpu(void)
462 {
463 
464 	switch (cpu) {
465 #ifdef I486_CPU
466 	case CPU_BLUE:
467 		init_bluelightning();
468 		break;
469 	case CPU_486DLC:
470 		init_486dlc();
471 		break;
472 	case CPU_CY486DX:
473 		init_cy486dx();
474 		break;
475 	case CPU_M1SC:
476 		init_5x86();
477 		break;
478 #ifdef CPU_I486_ON_386
479 	case CPU_486:
480 		init_i486_on_386();
481 		break;
482 #endif
483 	case CPU_M1:
484 		init_6x86();
485 		break;
486 #endif /* I486_CPU */
487 #ifdef I686_CPU
488 	case CPU_M2:
489 		init_6x86MX();
490 		break;
491 	case CPU_686:
492 		if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
493 			(cpu_id & 0xff0) == 0x610)
494 			init_ppro();
495 		break;
496 #endif
497 	default:
498 		break;
499 	}
500 
501 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
502 	/*
503 	 * OS should flush L1 cahce by itself because no PC-98 supports
504 	 * non-Intel CPUs.  Use wbinvd instruction before DMA transfer
505 	 * when need_pre_dma_flush = 1, use invd instruction after DMA
506 	 * transfer when need_post_dma_flush = 1.  If your CPU upgrade
507 	 * product support hardware cache control, you can add
508 	 * UPGRADE_CPU_HW_CACHE option in your kernel configuration file.
509 	 * This option elminate unneeded cache flush instruction.
510 	 */
511 	if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
512 		switch (cpu) {
513 #ifdef I486_CPU
514 		case CPU_486DLC:
515 			need_post_dma_flush = 1;
516 			break;
517 		case CPU_M1SC:
518 			need_pre_dma_flush = 1;
519 			break;
520 #endif
521 		default:
522 			break;
523 		}
524 	} else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
525 		switch (cpu_id & 0xFF0) {
526 		case 0x470:		/* Enhanced Am486DX2 WB */
527 		case 0x490:		/* Enhanced Am486DX4 WB */
528 		case 0x4F0:		/* Am5x86 WB */
529 			need_pre_dma_flush = 1;
530 			break;
531 		}
532 	} else if (strcmp(cpu_vendor, "IBM") == 0) {
533 		need_post_dma_flush = 1;
534 	} else {
535 #ifdef CPU_I486_ON_386
536 		need_pre_dma_flush = 1;
537 #endif
538 	}
539 #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
540 }
541 
542 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
543 /*
544  * Enable write allocate feature of AMD processors.
545  * Following two functions require the Maxmem variable being set.
546  */
547 void
548 enable_K5_wt_alloc(void)
549 {
550 	u_int64_t	msr;
551 
552 	/*
553 	 * Write allocate is supported only on models 1, 2, and 3, with
554 	 * a stepping of 4 or greater.
555 	 */
556 	if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) {
557 		disable_intr();
558 		msr = rdmsr(0x83);		/* HWCR */
559 		wrmsr(0x83, msr & !(0x10));
560 
561 		/*
562 		 * We have to tell the chip where the top of memory is,
563 		 * since video cards could have frame bufferes there,
564 		 * memory-mapped I/O could be there, etc.
565 		 */
566 		if(Maxmem > 0)
567 		  msr = Maxmem / 16;
568 		else
569 		  msr = 0;
570 		msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
571 #ifdef PC98
572 		if (!(inb(0x43b) & 4)) {
573 			wrmsr(0x86, 0x0ff00f0);
574 			msr |= AMD_WT_ALLOC_PRE;
575 		}
576 #else
577 		/*
578 		 * There is no way to know wheter 15-16M hole exists or not.
579 		 * Therefore, we disable write allocate for this range.
580 		 */
581 			wrmsr(0x86, 0x0ff00f0);
582 			msr |= AMD_WT_ALLOC_PRE;
583 #endif
584 		wrmsr(0x85, msr);
585 
586 		msr=rdmsr(0x83);
587 		wrmsr(0x83, msr|0x10); /* enable write allocate */
588 
589 		enable_intr();
590 	}
591 }
592 
593 void
594 enable_K6_wt_alloc(void)
595 {
596 	quad_t	size;
597 	u_int64_t	whcr;
598 	u_long	eflags;
599 
600 	eflags = read_eflags();
601 	disable_intr();
602 	wbinvd();
603 
604 #ifdef CPU_DISABLE_CACHE
605 	/*
606 	 * Certain K6-2 box becomes unstable when write allocation is
607 	 * enabled.
608 	 */
609 	/*
610 	 * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
611 	 * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
612 	 * All other bits in TR12 have no effect on the processer's operation.
613 	 * The I/O Trap Restart function (bit 9 of TR12) is always enabled
614 	 * on the AMD-K6.
615 	 */
616 	wrmsr(0x0000000e, (u_int64_t)0x0008);
617 #endif
618 	/* Don't assume that memory size is aligned with 4M. */
619 	if (Maxmem > 0)
620 	  size = Maxmem / 256;
621 	else
622 	  size = 0;
623 	size = (size + 3) / 4;
624 
625 	/* Limit is 508M bytes. */
626 	if (size > 127)
627 		size = 127;
628 	whcr = rdmsr(0xc0000082);
629 	whcr &= ~0x00feLL;
630 	whcr |= (size << 1);
631 
632 #if defined(PC98) || defined(NO_MEMORY_HOLE)
633 	if (whcr & 0x00feLL) {
634 #ifdef PC98
635 		/*
636 		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
637 		 * 15-16M range.
638 		 */
639 		if (!(inb(0x43b) & 4))
640 			whcr &= ~0x0001LL;
641 		else
642 #endif
643 			whcr |=  0x0001LL;
644 	}
645 #else
646 	/*
647 	 * There is no way to know wheter 15-16M hole exists or not.
648 	 * Therefore, we disable write allocate for this range.
649 	 */
650 	whcr &= ~0x0001LL;
651 #endif
652 	wrmsr(0x0c0000082, whcr);
653 
654 	write_eflags(eflags);
655 	enable_intr();
656 }
657 
658 void
659 enable_K6_2_wt_alloc(void)
660 {
661 	quad_t	size;
662 	u_int64_t	whcr;
663 	u_long	eflags;
664 
665 	eflags = read_eflags();
666 	disable_intr();
667 	wbinvd();
668 
669 #ifdef CPU_DISABLE_CACHE
670 	/*
671 	 * Certain K6-2 box becomes unstable when write allocation is
672 	 * enabled.
673 	 */
674 	/*
675 	 * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
676 	 * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
677 	 * All other bits in TR12 have no effect on the processer's operation.
678 	 * The I/O Trap Restart function (bit 9 of TR12) is always enabled
679 	 * on the AMD-K6.
680 	 */
681 	wrmsr(0x0000000e, (u_int64_t)0x0008);
682 #endif
683 	/* Don't assume that memory size is aligned with 4M. */
684 	if (Maxmem > 0)
685 	  size = ((Maxmem >> 8) + 3) >> 2;
686 	else
687 	  size = 0;
688 
689 	/* Limit is 4092M bytes. */
690 	size &= 0x3ff;
691 	whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22);
692 
693 #if defined(PC98) || defined(NO_MEMORY_HOLE)
694 	if (whcr & (0x3ffLL << 22)) {
695 #ifdef PC98
696 		/*
697 		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
698 		 * 15-16M range.
699 		 */
700 		if (!(inb(0x43b) & 4))
701 			whcr &= ~(1LL << 16);
702 		else
703 #endif
704 			whcr |=  1LL << 16;
705 	}
706 #else
707 	/*
708 	 * There is no way to know wheter 15-16M hole exists or not.
709 	 * Therefore, we disable write allocate for this range.
710 	 */
711 	whcr &= ~(1LL << 16);
712 #endif
713 	wrmsr(0x0c0000082, whcr);
714 
715 	write_eflags(eflags);
716 	enable_intr();
717 }
718 #endif /* I585_CPU && CPU_WT_ALLOC */
719 
720 #include "opt_ddb.h"
721 #ifdef DDB
722 #include <ddb/ddb.h>
723 
724 DB_SHOW_COMMAND(cyrixreg, cyrixreg)
725 {
726 	u_long	eflags;
727 	u_int	cr0;
728 	u_char	ccr1, ccr2, ccr3;
729 	u_char	ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0;
730 
731 	cr0 = rcr0();
732 	if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
733 		eflags = read_eflags();
734 		disable_intr();
735 
736 
737 		if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) {
738 			ccr0 = read_cyrix_reg(CCR0);
739 		}
740 		ccr1 = read_cyrix_reg(CCR1);
741 		ccr2 = read_cyrix_reg(CCR2);
742 		ccr3 = read_cyrix_reg(CCR3);
743 		if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
744 			write_cyrix_reg(CCR3, CCR3_MAPEN0);
745 			ccr4 = read_cyrix_reg(CCR4);
746 			if ((cpu == CPU_M1) || (cpu == CPU_M2))
747 				ccr5 = read_cyrix_reg(CCR5);
748 			else
749 				pcr0 = read_cyrix_reg(PCR0);
750 			write_cyrix_reg(CCR3, ccr3);		/* Restore CCR3. */
751 		}
752 		write_eflags(eflags);
753 
754 		if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX))
755 			printf("CCR0=%x, ", (u_int)ccr0);
756 
757 		printf("CCR1=%x, CCR2=%x, CCR3=%x",
758 			(u_int)ccr1, (u_int)ccr2, (u_int)ccr3);
759 		if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
760 			printf(", CCR4=%x, ", (u_int)ccr4);
761 			if (cpu == CPU_M1SC)
762 				printf("PCR0=%x\n", pcr0);
763 			else
764 				printf("CCR5=%x\n", ccr5);
765 		}
766 	}
767 	printf("CR0=%x\n", cr0);
768 }
769 #endif /* DDB */
770