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