Merge branch 'vendor/GDB' into gdb7
[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.10 2006/12/23 00:27:03 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 u_int   via_feature_rng = 0;    /* VIA RNG features */
73 u_int   via_feature_xcrypt = 0; /* VIA ACE features */
74
75 SYSCTL_UINT(_hw, OID_AUTO, via_feature_rng, CTLFLAG_RD,
76         &via_feature_rng, 0, "VIA C3/C7 RNG feature available in CPU");
77 SYSCTL_UINT(_hw, OID_AUTO, via_feature_xcrypt, CTLFLAG_RD,
78         &via_feature_xcrypt, 0, "VIA C3/C7 xcrypt feature available in CPU");
79
80 #ifndef CPU_DISABLE_SSE
81 u_int   cpu_fxsr;               /* SSE enabled */
82 #endif
83
84 #ifdef I486_CPU
85 /*
86  * IBM Blue Lightning
87  */
88 static void
89 init_bluelightning(void)
90 {
91         u_long  eflags;
92
93         eflags = read_eflags();
94         cpu_disable_intr();
95
96         load_cr0(rcr0() | CR0_CD | CR0_NW);
97         invd();
98
99 #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
100         wrmsr(0x1000, 0x9c92LL);        /* FP operand can be cacheable on Cyrix FPU */
101 #else
102         wrmsr(0x1000, 0x1c92LL);        /* Intel FPU */
103 #endif
104         /* Enables 13MB and 0-640KB cache. */
105         wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
106 #ifdef CPU_BLUELIGHTNING_3X
107         wrmsr(0x1002, 0x04000000LL);    /* Enables triple-clock mode. */
108 #else
109         wrmsr(0x1002, 0x03000000LL);    /* Enables double-clock mode. */
110 #endif
111
112         /* Enable caching in CR0. */
113         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
114         invd();
115         write_eflags(eflags);
116 }
117
118 /*
119  * Cyrix 486SLC/DLC/SR/DR series
120  */
121 static void
122 init_486dlc(void)
123 {
124         u_long  eflags;
125         u_char  ccr0;
126
127         eflags = read_eflags();
128         cpu_disable_intr();
129         invd();
130
131         ccr0 = read_cyrix_reg(CCR0);
132 #ifndef CYRIX_CACHE_WORKS
133         ccr0 |= CCR0_NC1 | CCR0_BARB;
134         write_cyrix_reg(CCR0, ccr0);
135         invd();
136 #else
137         ccr0 &= ~CCR0_NC0;
138 #ifndef CYRIX_CACHE_REALLY_WORKS
139         ccr0 |= CCR0_NC1 | CCR0_BARB;
140 #else
141         ccr0 |= CCR0_NC1;
142 #endif
143 #ifdef CPU_DIRECT_MAPPED_CACHE
144         ccr0 |= CCR0_CO;                        /* Direct mapped mode. */
145 #endif
146         write_cyrix_reg(CCR0, ccr0);
147
148         /* Clear non-cacheable region. */
149         write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
150         write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
151         write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
152         write_cyrix_reg(NCR4+2, NCR_SIZE_0K);
153
154         write_cyrix_reg(0, 0);  /* dummy write */
155
156         /* Enable caching in CR0. */
157         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
158         invd();
159 #endif /* !CYRIX_CACHE_WORKS */
160         write_eflags(eflags);
161 }
162
163
164 /*
165  * Cyrix 486S/DX series
166  */
167 static void
168 init_cy486dx(void)
169 {
170         u_long  eflags;
171         u_char  ccr2;
172
173         eflags = read_eflags();
174         cpu_disable_intr();
175         invd();
176
177         ccr2 = read_cyrix_reg(CCR2);
178 #ifdef CPU_SUSP_HLT
179         ccr2 |= CCR2_SUSP_HLT;
180 #endif
181
182         write_cyrix_reg(CCR2, ccr2);
183         write_eflags(eflags);
184 }
185
186
187 /*
188  * Cyrix 5x86
189  */
190 static void
191 init_5x86(void)
192 {
193         u_long  eflags;
194         u_char  ccr2, ccr3, ccr4, pcr0;
195
196         eflags = read_eflags();
197         cpu_disable_intr();
198
199         load_cr0(rcr0() | CR0_CD | CR0_NW);
200         wbinvd();
201
202         read_cyrix_reg(CCR3);           /* dummy */
203
204         /* Initialize CCR2. */
205         ccr2 = read_cyrix_reg(CCR2);
206         ccr2 |= CCR2_WB;
207 #ifdef CPU_SUSP_HLT
208         ccr2 |= CCR2_SUSP_HLT;
209 #else
210         ccr2 &= ~CCR2_SUSP_HLT;
211 #endif
212         ccr2 |= CCR2_WT1;
213         write_cyrix_reg(CCR2, ccr2);
214
215         /* Initialize CCR4. */
216         ccr3 = read_cyrix_reg(CCR3);
217         write_cyrix_reg(CCR3, CCR3_MAPEN0);
218
219         ccr4 = read_cyrix_reg(CCR4);
220         ccr4 |= CCR4_DTE;
221         ccr4 |= CCR4_MEM;
222 #ifdef CPU_FASTER_5X86_FPU
223         ccr4 |= CCR4_FASTFPE;
224 #else
225         ccr4 &= ~CCR4_FASTFPE;
226 #endif
227         ccr4 &= ~CCR4_IOMASK;
228         /********************************************************************
229          * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
230          * should be 0 for errata fix.
231          ********************************************************************/
232 #ifdef CPU_IORT
233         ccr4 |= CPU_IORT & CCR4_IOMASK;
234 #endif
235         write_cyrix_reg(CCR4, ccr4);
236
237         /* Initialize PCR0. */
238         /****************************************************************
239          * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
240          * BTB_EN might make your system unstable.
241          ****************************************************************/
242         pcr0 = read_cyrix_reg(PCR0);
243 #ifdef CPU_RSTK_EN
244         pcr0 |= PCR0_RSTK;
245 #else
246         pcr0 &= ~PCR0_RSTK;
247 #endif
248 #ifdef CPU_BTB_EN
249         pcr0 |= PCR0_BTB;
250 #else
251         pcr0 &= ~PCR0_BTB;
252 #endif
253 #ifdef CPU_LOOP_EN
254         pcr0 |= PCR0_LOOP;
255 #else
256         pcr0 &= ~PCR0_LOOP;
257 #endif
258
259         /****************************************************************
260          * WARNING: if you use a memory mapped I/O device, don't use
261          * DISABLE_5X86_LSSER option, which may reorder memory mapped
262          * I/O access.
263          * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
264          ****************************************************************/
265 #ifdef CPU_DISABLE_5X86_LSSER
266         pcr0 &= ~PCR0_LSSER;
267 #else
268         pcr0 |= PCR0_LSSER;
269 #endif
270         write_cyrix_reg(PCR0, pcr0);
271
272         /* Restore CCR3. */
273         write_cyrix_reg(CCR3, ccr3);
274
275         read_cyrix_reg(0x80);           /* dummy */
276
277         /* Unlock NW bit in CR0. */
278         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
279         load_cr0((rcr0() & ~CR0_CD) | CR0_NW);  /* CD = 0, NW = 1 */
280         /* Lock NW bit in CR0. */
281         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
282
283         write_eflags(eflags);
284 }
285
286 #ifdef CPU_I486_ON_386
287 /*
288  * There are i486 based upgrade products for i386 machines.
289  * In this case, BIOS doesn't enables CPU cache.
290  */
291 void
292 init_i486_on_386(void)
293 {
294         u_long  eflags;
295
296         eflags = read_eflags();
297         cpu_disable_intr();
298
299         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0, NW = 0 */
300
301         write_eflags(eflags);
302 }
303 #endif
304
305 /*
306  * Cyrix 6x86
307  *
308  * XXX - What should I do here?  Please let me know.
309  */
310 static void
311 init_6x86(void)
312 {
313         u_long  eflags;
314         u_char  ccr3, ccr4;
315
316         eflags = read_eflags();
317         cpu_disable_intr();
318
319         load_cr0(rcr0() | CR0_CD | CR0_NW);
320         wbinvd();
321
322         /* Initialize CCR0. */
323         write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
324
325         /* Initialize CCR1. */
326 #ifdef CPU_CYRIX_NO_LOCK
327         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
328 #else
329         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
330 #endif
331
332         /* Initialize CCR2. */
333 #ifdef CPU_SUSP_HLT
334         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
335 #else
336         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
337 #endif
338
339         ccr3 = read_cyrix_reg(CCR3);
340         write_cyrix_reg(CCR3, CCR3_MAPEN0);
341
342         /* Initialize CCR4. */
343         ccr4 = read_cyrix_reg(CCR4);
344         ccr4 |= CCR4_DTE;
345         ccr4 &= ~CCR4_IOMASK;
346 #ifdef CPU_IORT
347         write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
348 #else
349         write_cyrix_reg(CCR4, ccr4 | 7);
350 #endif
351
352         /* Initialize CCR5. */
353 #ifdef CPU_WT_ALLOC
354         write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
355 #endif
356
357         /* Restore CCR3. */
358         write_cyrix_reg(CCR3, ccr3);
359
360         /* Unlock NW bit in CR0. */
361         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
362
363         /*
364          * Earlier revision of the 6x86 CPU could crash the system if
365          * L1 cache is in write-back mode.
366          */
367         if ((cyrix_did & 0xff00) > 0x1600)
368                 load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
369         else {
370                 /* Revision 2.6 and lower. */
371 #ifdef CYRIX_CACHE_REALLY_WORKS
372                 load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
373 #else
374                 load_cr0((rcr0() & ~CR0_CD) | CR0_NW);  /* CD = 0 and NW = 1 */
375 #endif
376         }
377
378         /* Lock NW bit in CR0. */
379         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
380
381         write_eflags(eflags);
382 }
383 #endif /* I486_CPU */
384
385 #ifdef I686_CPU
386 /*
387  * Cyrix 6x86MX (code-named M2)
388  *
389  * XXX - What should I do here?  Please let me know.
390  */
391 static void
392 init_6x86MX(void)
393 {
394         u_long  eflags;
395         u_char  ccr3, ccr4;
396
397         eflags = read_eflags();
398         cpu_disable_intr();
399
400         load_cr0(rcr0() | CR0_CD | CR0_NW);
401         wbinvd();
402
403         /* Initialize CCR0. */
404         write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
405
406         /* Initialize CCR1. */
407 #ifdef CPU_CYRIX_NO_LOCK
408         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
409 #else
410         write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
411 #endif
412
413         /* Initialize CCR2. */
414 #ifdef CPU_SUSP_HLT
415         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
416 #else
417         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
418 #endif
419
420         ccr3 = read_cyrix_reg(CCR3);
421         write_cyrix_reg(CCR3, CCR3_MAPEN0);
422
423         /* Initialize CCR4. */
424         ccr4 = read_cyrix_reg(CCR4);
425         ccr4 &= ~CCR4_IOMASK;
426 #ifdef CPU_IORT
427         write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
428 #else
429         write_cyrix_reg(CCR4, ccr4 | 7);
430 #endif
431
432         /* Initialize CCR5. */
433 #ifdef CPU_WT_ALLOC
434         write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
435 #endif
436
437         /* Restore CCR3. */
438         write_cyrix_reg(CCR3, ccr3);
439
440         /* Unlock NW bit in CR0. */
441         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
442
443         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));  /* CD = 0 and NW = 0 */
444
445         /* Lock NW bit in CR0. */
446         write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
447
448         write_eflags(eflags);
449 }
450
451 static void
452 init_ppro(void)
453 {
454 #ifndef SMP
455         u_int64_t       apicbase;
456
457         /*
458          * Local APIC should be diabled in UP kernel.
459          */
460         apicbase = rdmsr(0x1b);
461         apicbase &= ~0x800LL;
462         wrmsr(0x1b, apicbase);
463 #endif
464 }
465
466 /*
467  * Initialize BBL_CR_CTL3 (Control register 3: used to configure the
468  * L2 cache).
469  */
470 void
471 init_mendocino(void)
472 {
473 #ifdef CPU_PPRO2CELERON
474         u_long  eflags;
475         u_int64_t       bbl_cr_ctl3;
476
477         eflags = read_eflags();
478         cpu_disable_intr();
479
480         load_cr0(rcr0() | CR0_CD | CR0_NW);
481         wbinvd();
482
483         bbl_cr_ctl3 = rdmsr(0x11e);
484
485         /* If the L2 cache is configured, do nothing. */
486         if (!(bbl_cr_ctl3 & 1)) {
487                 bbl_cr_ctl3 = 0x134052bLL;
488
489                 /* Set L2 Cache Latency (Default: 5). */
490 #ifdef  CPU_CELERON_L2_LATENCY
491 #if CPU_L2_LATENCY > 15
492 #error invalid CPU_L2_LATENCY.
493 #endif
494                 bbl_cr_ctl3 |= CPU_L2_LATENCY << 1;
495 #else
496                 bbl_cr_ctl3 |= 5 << 1;
497 #endif
498                 wrmsr(0x11e, bbl_cr_ctl3);
499         }
500
501         load_cr0(rcr0() & ~(CR0_CD | CR0_NW));
502         write_eflags(eflags);
503 #endif /* CPU_PPRO2CELERON */
504 }
505
506 /*
507  * Initialize special VIA C3/C7 features
508  */
509 static void
510 init_via(void)
511 {
512         u_int regs[4], val;
513         u_int64_t msreg;
514
515         do_cpuid(0xc0000000, regs);
516         val = regs[0];
517         if (val >= 0xc0000001) {
518                 do_cpuid(0xc0000001, regs);
519                 val = regs[3];
520         } else
521                 val = 0;
522
523         /* Enable RNG if present and disabled */
524         if (val & VIA_CPUID_HAS_RNG) {
525                 if (!(val & VIA_CPUID_DO_RNG)) {
526                         msreg = rdmsr(0x110B);
527                         msreg |= 0x40;
528                         wrmsr(0x110B, msreg);
529                 }
530                 via_feature_rng = VIA_HAS_RNG;
531         }
532         /* Enable AES engine if present and disabled */
533         if (val & VIA_CPUID_HAS_ACE) {
534                 if (!(val & VIA_CPUID_DO_ACE)) {
535                         msreg = rdmsr(0x1107);
536                         msreg |= (0x01 << 28);
537                         wrmsr(0x1107, msreg);
538                 }
539                 via_feature_xcrypt |= VIA_HAS_AES;
540         }
541         /* Enable ACE2 engine if present and disabled */
542         if (val & VIA_CPUID_HAS_ACE2) {
543                 if (!(val & VIA_CPUID_DO_ACE2)) {
544                         msreg = rdmsr(0x1107);
545                         msreg |= (0x01 << 28);
546                         wrmsr(0x1107, msreg);
547                 }
548                 via_feature_xcrypt |= VIA_HAS_AESCTR;
549         }
550         /* Enable SHA engine if present and disabled */
551         if (val & VIA_CPUID_HAS_PHE) {
552                 if (!(val & VIA_CPUID_DO_PHE)) {
553                         msreg = rdmsr(0x1107);
554                         msreg |= (0x01 << 28/**/);
555                         wrmsr(0x1107, msreg);
556                 }
557                 via_feature_xcrypt |= VIA_HAS_SHA;
558         }
559         /* Enable MM engine if present and disabled */
560         if (val & VIA_CPUID_HAS_PMM) {
561                 if (!(val & VIA_CPUID_DO_PMM)) {
562                         msreg = rdmsr(0x1107);
563                         msreg |= (0x01 << 28/**/);
564                         wrmsr(0x1107, msreg);
565                 }
566                 via_feature_xcrypt |= VIA_HAS_MM;
567         }
568 }
569
570 #endif /* I686_CPU */
571
572 /*
573  * Initialize CR4 (Control register 4) to enable SSE instructions.
574  */
575 void
576 enable_sse(void)
577 {
578 #ifndef CPU_DISABLE_SSE
579         if ((cpu_feature & CPUID_SSE) && (cpu_feature & CPUID_FXSR)) {
580                 load_cr4(rcr4() | CR4_FXSR | CR4_XMM);
581                 cpu_fxsr = hw_instruction_sse = 1;
582         }
583 #endif
584 }
585
586 static
587 void
588 init_686_amd(void)
589 {
590 #if defined(I686_CPU) && defined(CPU_ATHLON_SSE_HACK)
591         /*
592          * Sometimes the BIOS doesn't enable SSE instructions.
593          * According to AMD document 20734, the mobile
594          * Duron, the (mobile) Athlon 4 and the Athlon MP
595          * support SSE. These correspond to cpu_id 0x66X
596          * or 0x67X.
597          */
598         if ((cpu_feature & CPUID_XMM) == 0 &&
599             ((cpu_id & ~0xf) == 0x660 ||
600              (cpu_id & ~0xf) == 0x670 ||
601              (cpu_id & ~0xf) == 0x680)) {
602                 u_int regs[4];
603                 wrmsr(0xC0010015, rdmsr(0xC0010015) & ~0x08000);
604                 do_cpuid(1, regs);
605                 cpu_feature = regs[3];
606         }
607 #endif
608 #if defined(I686_CPU) && defined(CPU_AMD64X2_INTR_SPAM)
609         /*
610          * Set the LINTEN bit in the HyperTransport Transaction
611          * Control Register.
612          *
613          * This will cause EXTINT and NMI interrupts routed over the
614          * hypertransport bus to be fed into the LAPIC LINT0/LINT1.  If
615          * the bit isn't set, the interrupts will go to the general cpu
616          * INTR/NMI pins.  On a dual-core cpu the interrupt winds up
617          * going to BOTH cpus.  The first cpu that does the interrupt ack
618          * cycle will get the correct interrupt.  The second cpu that does
619          * it will get a spurious interrupt vector (typically IRQ 7).
620          */
621         if ((cpu_id & 0xff0) == 0xf30) {
622             int32_t tcr;
623             outl(0x0cf8,
624                     (1 << 31) | /* enable */
625                     (0 << 16) | /* bus */
626                     (24 << 11) |        /* dev (cpu + 24) */
627                     (0 << 8) |  /* func */
628                     0x68                /* reg */
629             );
630             tcr = inl(0xcfc);
631             if ((tcr & 0x00010000) == 0) {
632                     outl(0xcfc, tcr|0x00010000);
633                     additional_cpu_info("AMD: Rerouting HyperTransport "
634                                         "EXTINT/NMI to APIC");
635             }
636             outl(0x0cf8, 0);
637         }
638 #endif
639 }
640
641 void
642 initializecpu(void)
643 {
644         switch (cpu) {
645 #ifdef I486_CPU
646         case CPU_BLUE:
647                 init_bluelightning();
648                 break;
649         case CPU_486DLC:
650                 init_486dlc();
651                 break;
652         case CPU_CY486DX:
653                 init_cy486dx();
654                 break;
655         case CPU_M1SC:
656                 init_5x86();
657                 break;
658 #ifdef CPU_I486_ON_386
659         case CPU_486:
660                 init_i486_on_386();
661                 break;
662 #endif
663         case CPU_M1:
664                 init_6x86();
665                 break;
666 #endif /* I486_CPU */
667 #ifdef I686_CPU
668         case CPU_M2:
669                 init_6x86MX();
670                 break;
671         case CPU_686:
672                 if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
673                         switch (cpu_id & 0xff0) {
674                         case 0x610:
675                                 init_ppro();
676                                 break;
677                         case 0x660:
678                                 init_mendocino();
679                                 break;
680                         }
681                 } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
682                         init_686_amd();
683                 } else if (strcmp(cpu_vendor, "CentaurHauls") == 0) {
684                         switch (cpu_id & 0xff0) {
685                         case 0x690:
686                                 if ((cpu_id & 0xf) < 3)
687                                         break;
688                                 /* fall through. */
689                         case 0x6a0:
690                         case 0x6d0:
691                         case 0x6f0:
692                                 init_via();
693                                 break;
694                         default:
695                                 break;
696                         }
697                 }
698                 break;
699 #endif
700         default:
701                 break;
702         }
703         enable_sse();
704 }
705
706 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
707 /*
708  * Enable write allocate feature of AMD processors.
709  * Following two functions require the Maxmem variable being set.
710  */
711 void
712 enable_K5_wt_alloc(void)
713 {
714         u_int64_t       msr;
715
716         /*
717          * Write allocate is supported only on models 1, 2, and 3, with
718          * a stepping of 4 or greater.
719          */
720         if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) {
721                 cpu_disable_intr();
722                 msr = rdmsr(0x83);              /* HWCR */
723                 wrmsr(0x83, msr & !(0x10));
724
725                 /*
726                  * We have to tell the chip where the top of memory is,
727                  * since video cards could have frame bufferes there,
728                  * memory-mapped I/O could be there, etc.
729                  */
730                 if(Maxmem > 0)
731                   msr = Maxmem / 16;
732                 else
733                   msr = 0;
734                 msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
735
736                 /*
737                  * There is no way to know wheter 15-16M hole exists or not. 
738                  * Therefore, we disable write allocate for this range.
739                  */
740                 wrmsr(0x86, 0x0ff00f0);
741                 msr |= AMD_WT_ALLOC_PRE;
742                 wrmsr(0x85, msr);
743
744                 msr=rdmsr(0x83);
745                 wrmsr(0x83, msr|0x10); /* enable write allocate */
746
747                 cpu_enable_intr();
748         }
749 }
750
751 void
752 enable_K6_wt_alloc(void)
753 {
754         quad_t  size;
755         u_int64_t       whcr;
756         u_long  eflags;
757
758         eflags = read_eflags();
759         cpu_disable_intr();
760         wbinvd();
761
762 #ifdef CPU_DISABLE_CACHE
763         /*
764          * Certain K6-2 box becomes unstable when write allocation is
765          * enabled.
766          */
767         /*
768          * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
769          * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
770          * All other bits in TR12 have no effect on the processer's operation.
771          * The I/O Trap Restart function (bit 9 of TR12) is always enabled
772          * on the AMD-K6.
773          */
774         wrmsr(0x0000000e, (u_int64_t)0x0008);
775 #endif
776         /* Don't assume that memory size is aligned with 4M. */
777         if (Maxmem > 0)
778           size = ((Maxmem >> 8) + 3) >> 2;
779         else
780           size = 0;
781
782         /* Limit is 508M bytes. */
783         if (size > 0x7f)
784                 size = 0x7f;
785         whcr = (rdmsr(0xc0000082) & ~(0x7fLL << 1)) | (size << 1);
786
787 #if defined(NO_MEMORY_HOLE)
788         if (whcr & (0x7fLL << 1))
789                 whcr |=  0x0001LL;
790 #else
791         /*
792          * There is no way to know wheter 15-16M hole exists or not. 
793          * Therefore, we disable write allocate for this range.
794          */
795         whcr &= ~0x0001LL;
796 #endif
797         wrmsr(0x0c0000082, whcr);
798
799         write_eflags(eflags);
800 }
801
802 void
803 enable_K6_2_wt_alloc(void)
804 {
805         quad_t  size;
806         u_int64_t       whcr;
807         u_long  eflags;
808
809         eflags = read_eflags();
810         cpu_disable_intr();
811         wbinvd();
812
813 #ifdef CPU_DISABLE_CACHE
814         /*
815          * Certain K6-2 box becomes unstable when write allocation is
816          * enabled.
817          */
818         /*
819          * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
820          * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
821          * All other bits in TR12 have no effect on the processer's operation.
822          * The I/O Trap Restart function (bit 9 of TR12) is always enabled
823          * on the AMD-K6.
824          */
825         wrmsr(0x0000000e, (u_int64_t)0x0008);
826 #endif
827         /* Don't assume that memory size is aligned with 4M. */
828         if (Maxmem > 0)
829           size = ((Maxmem >> 8) + 3) >> 2;
830         else
831           size = 0;
832
833         /* Limit is 4092M bytes. */
834         if (size > 0x3fff)
835                 size = 0x3ff;
836         whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22);
837
838 #if defined(NO_MEMORY_HOLE)
839         if (whcr & (0x3ffLL << 22))
840                 whcr |=  1LL << 16;
841 #else
842         /*
843          * There is no way to know wheter 15-16M hole exists or not. 
844          * Therefore, we disable write allocate for this range.
845          */
846         whcr &= ~(1LL << 16);
847 #endif
848         wrmsr(0x0c0000082, whcr);
849
850         write_eflags(eflags);
851 }
852 #endif /* I585_CPU && CPU_WT_ALLOC */
853
854 #include "opt_ddb.h"
855 #ifdef DDB
856 #include <ddb/ddb.h>
857
858 DB_SHOW_COMMAND(cyrixreg, cyrixreg)
859 {
860         u_long  eflags;
861         u_int   cr0;
862         u_char  ccr1, ccr2, ccr3;
863         u_char  ccr0 = 0, ccr4 = 0, ccr5 = 0, pcr0 = 0;
864
865         cr0 = rcr0();
866         if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
867                 eflags = read_eflags();
868                 cpu_disable_intr();
869
870
871                 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) {
872                         ccr0 = read_cyrix_reg(CCR0);
873                 }
874                 ccr1 = read_cyrix_reg(CCR1);
875                 ccr2 = read_cyrix_reg(CCR2);
876                 ccr3 = read_cyrix_reg(CCR3);
877                 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
878                         write_cyrix_reg(CCR3, CCR3_MAPEN0);
879                         ccr4 = read_cyrix_reg(CCR4);
880                         if ((cpu == CPU_M1) || (cpu == CPU_M2))
881                                 ccr5 = read_cyrix_reg(CCR5);
882                         else
883                                 pcr0 = read_cyrix_reg(PCR0);
884                         write_cyrix_reg(CCR3, ccr3);            /* Restore CCR3. */
885                 }
886                 write_eflags(eflags);
887
888                 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX))
889                         kprintf("CCR0=%x, ", (u_int)ccr0);
890
891                 kprintf("CCR1=%x, CCR2=%x, CCR3=%x",
892                         (u_int)ccr1, (u_int)ccr2, (u_int)ccr3);
893                 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
894                         kprintf(", CCR4=%x, ", (u_int)ccr4);
895                         if (cpu == CPU_M1SC)
896                                 kprintf("PCR0=%x\n", pcr0);
897                         else
898                                 kprintf("CCR5=%x\n", ccr5);
899                 }
900         }
901         kprintf("CR0=%x\n", cr0);
902 }
903 #endif /* DDB */