1 /*
2 * Copyright (c) KATO Takenori, 1997.
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.5.2.8 1999/09/05 08:11:09 peter Exp $
30 */
31
32 #include "opt_cpu.h"
33
34 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/systm.h>
37
38 #include <machine/cpu.h>
39 #include <machine/cputypes.h>
40 #include <machine/md_var.h>
41 #include <machine/specialreg.h>
42
43 void initializecpu(void);
44 #ifdef I486_CPU
45 static void init_5x86(void);
46 static void init_bluelightning(void);
47 static void init_486dlc(void);
48 static void init_cy486dx(void);
49 #ifdef CPU_I486_ON_386
50 static void init_i486_on_386(void);
51 #endif
52 static void init_6x86(void);
53 #endif /* I486_CPU */
54
55 #ifdef I686_CPU
56 static void init_6x86MX(void);
57 static void init_ppro(void);
58 #endif
59
60 #ifdef I486_CPU
61 /*
62 * IBM Blue Lightning
63 */
64 static void
65 init_bluelightning(void)
66 {
67 u_long eflags;
68
69 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
70 need_post_dma_flush = 1;
71 #endif
72
73 eflags = read_eflags();
74 disable_intr();
75
76 load_cr0(rcr0() | CR0_CD | CR0_NW);
77 invd();
78
79 #ifdef CPU_BLUELIGHTNING_FPU_OP_CACHE
80 wrmsr(0x1000, 0x9c92LL); /* FP operand can be cacheable on Cyrix FPU */
81 #else
82 wrmsr(0x1000, 0x1c92LL); /* Intel FPU */
83 #endif
84 /* Enables 13MB and 0-640KB cache. */
85 wrmsr(0x1001, (0xd0LL << 32) | 0x3ff);
86 #ifdef CPU_BLUELIGHTNING_3X
87 wrmsr(0x1002, 0x04000000LL); /* Enables triple-clock mode. */
88 #else
89 wrmsr(0x1002, 0x03000000LL); /* Enables double-clock mode. */
90 #endif
91
92 /* Enable caching in CR0. */
93 load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */
94 invd();
95 write_eflags(eflags);
96 }
97
98 /*
99 * Cyrix 486SLC/DLC/SR/DR series
100 */
101 static void
102 init_486dlc(void)
103 {
104 u_long eflags;
105 u_char ccr0;
106
107 eflags = read_eflags();
108 disable_intr();
109 invd();
110
111 ccr0 = read_cyrix_reg(CCR0);
112 #ifndef CYRIX_CACHE_WORKS
113 ccr0 |= CCR0_NC1 | CCR0_BARB;
114 write_cyrix_reg(CCR0, ccr0);
115 invd();
116 #else
117 ccr0 &= ~CCR0_NC0;
118 #ifndef CYRIX_CACHE_REALLY_WORKS
119 ccr0 |= CCR0_NC1 | CCR0_BARB;
120 #else
121 ccr0 |= CCR0_NC1;
122 #endif
123 #ifdef CPU_DIRECT_MAPPED_CACHE
124 ccr0 |= CCR0_CO; /* Direct mapped mode. */
125 #endif
126 write_cyrix_reg(CCR0, ccr0);
127
128 /* Clear non-cacheable region. */
129 write_cyrix_reg(NCR1+2, NCR_SIZE_0K);
130 write_cyrix_reg(NCR2+2, NCR_SIZE_0K);
131 write_cyrix_reg(NCR3+2, NCR_SIZE_0K);
132 write_cyrix_reg(NCR4+2, NCR_SIZE_0K);
133
134 write_cyrix_reg(0, 0); /* dummy write */
135
136 /* Enable caching in CR0. */
137 load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */
138 invd();
139 #endif /* !CYRIX_CACHE_WORKS */
140 write_eflags(eflags);
141 }
142
143
144 /*
145 * Cyrix 486S/DX series
146 */
147 static void
148 init_cy486dx(void)
149 {
150 u_long eflags;
151 u_char ccr2;
152
153 eflags = read_eflags();
154 disable_intr();
155 invd();
156
157 ccr2 = read_cyrix_reg(CCR2);
158 #ifdef CPU_SUSP_HLT
159 ccr2 |= CCR2_SUSP_HLT;
160 #endif
161 write_cyrix_reg(CCR2, ccr2);
162 write_eflags(eflags);
163 }
164
165
166 /*
167 * Cyrix 5x86
168 */
169 static void
170 init_5x86(void)
171 {
172 u_long eflags;
173 u_char ccr2, ccr3, ccr4, pcr0;
174
175 eflags = read_eflags();
176 disable_intr();
177
178 load_cr0(rcr0() | CR0_CD | CR0_NW);
179 wbinvd();
180
181 (void)read_cyrix_reg(CCR3); /* dummy */
182
183 /* Initialize CCR2. */
184 ccr2 = read_cyrix_reg(CCR2);
185 ccr2 |= CCR2_WB;
186 #ifdef CPU_SUSP_HLT
187 ccr2 |= CCR2_SUSP_HLT;
188 #else
189 ccr2 &= ~CCR2_SUSP_HLT;
190 #endif
191 ccr2 |= CCR2_WT1;
192 write_cyrix_reg(CCR2, ccr2);
193
194 /* Initialize CCR4. */
195 ccr3 = read_cyrix_reg(CCR3);
196 write_cyrix_reg(CCR3, CCR3_MAPEN0);
197
198 ccr4 = read_cyrix_reg(CCR4);
199 ccr4 |= CCR4_DTE;
200 ccr4 |= CCR4_MEM;
201 #ifdef CPU_FASTER_5X86_FPU
202 ccr4 |= CCR4_FASTFPE;
203 #else
204 ccr4 &= ~CCR4_FASTFPE;
205 #endif
206 ccr4 &= ~CCR4_IOMASK;
207 /********************************************************************
208 * WARNING: The "BIOS Writers Guide" mentions that I/O recovery time
209 * should be 0 for errata fix.
210 ********************************************************************/
211 #ifdef CPU_IORT
212 ccr4 |= CPU_IORT & CCR4_IOMASK;
213 #endif
214 write_cyrix_reg(CCR4, ccr4);
215
216 /* Initialize PCR0. */
217 /****************************************************************
218 * WARNING: RSTK_EN and LOOP_EN could make your system unstable.
219 * BTB_EN might make your system unstable.
220 ****************************************************************/
221 pcr0 = read_cyrix_reg(PCR0);
222 #ifdef CPU_RSTK_EN
223 pcr0 |= PCR0_RSTK;
224 #else
225 pcr0 &= ~PCR0_RSTK;
226 #endif
227 #ifdef CPU_BTB_EN
228 pcr0 |= PCR0_BTB;
229 #else
230 pcr0 &= ~PCR0_BTB;
231 #endif
232 #ifdef CPU_LOOP_EN
233 pcr0 |= PCR0_LOOP;
234 #else
235 pcr0 &= ~PCR0_LOOP;
236 #endif
237
238 /****************************************************************
239 * WARNING: if you use a memory mapped I/O device, don't use
240 * DISABLE_5X86_LSSER option, which may reorder memory mapped
241 * I/O access.
242 * IF YOUR MOTHERBOARD HAS PCI BUS, DON'T DISABLE LSSER.
243 ****************************************************************/
244 #ifdef CPU_DISABLE_5X86_LSSER
245 pcr0 &= ~PCR0_LSSER;
246 #else
247 pcr0 |= PCR0_LSSER;
248 #endif
249 write_cyrix_reg(PCR0, pcr0);
250
251 /* Restore CCR3. */
252 write_cyrix_reg(CCR3, ccr3);
253
254 (void)read_cyrix_reg(0x80); /* dummy */
255
256 /* Unlock NW bit in CR0. */
257 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
258 load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0, NW = 1 */
259 /* Lock NW bit in CR0. */
260 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
261
262 write_eflags(eflags);
263 }
264
265 #ifdef CPU_I486_ON_386
266 /*
267 * There are i486 based upgrade products for i386 machines.
268 * In this case, BIOS doesn't enables CPU cache.
269 */
270 void
271 init_i486_on_386(void)
272 {
273 u_long eflags;
274
275 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
276 need_post_dma_flush = 1;
277 #endif
278
279 eflags = read_eflags();
280 disable_intr();
281
282 load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0, NW = 0 */
283
284 write_eflags(eflags);
285 }
286 #endif
287
288 /*
289 * Cyrix 6x86
290 *
291 * XXX - What should I do here? Please let me know.
292 */
293 static void
294 init_6x86(void)
295 {
296 u_long eflags;
297 u_char ccr3, ccr4;
298
299 eflags = read_eflags();
300 disable_intr();
301
302 load_cr0(rcr0() | CR0_CD | CR0_NW);
303 wbinvd();
304
305 /* Initialize CCR0. */
306 write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
307
308 /* Initialize CCR1. */
309 #ifdef CPU_CYRIX_NO_LOCK
310 write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
311 #else
312 #ifdef FAILSAFE
313 write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
314 #endif
315 #endif
316
317 /* Initialize CCR2. */
318 #ifdef CPU_SUSP_HLT
319 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
320 #else
321 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
322 #endif
323
324 ccr3 = read_cyrix_reg(CCR3);
325 write_cyrix_reg(CCR3, CCR3_MAPEN0);
326
327 /* Initialize CCR4. */
328 ccr4 = read_cyrix_reg(CCR4);
329 ccr4 |= CCR4_DTE;
330 ccr4 &= ~CCR4_IOMASK;
331 #ifdef CPU_IORT
332 write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
333 #else
334 write_cyrix_reg(CCR4, ccr4 | 7);
335 #endif
336
337 /* Initialize CCR5. */
338 #ifdef CPU_WT_ALLOC
339 write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
340 #endif
341
342 /* Restore CCR3. */
343 write_cyrix_reg(CCR3, ccr3);
344
345 /* Unlock NW bit in CR0. */
346 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
347
348 /*
349 * Earlier revision of the 6x86 CPU could crash the system if
350 * L1 cache is in write-back mode.
351 */
352 if ((cyrix_did & 0xff00) > 0x1600)
353 load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */
354 else {
355 /* Revision 2.6 and lower. */
356 #ifdef CYRIX_CACHE_REALLY_WORKS
357 load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */
358 #else
359 load_cr0((rcr0() & ~CR0_CD) | CR0_NW); /* CD = 0 and NW = 1 */
360 #endif
361 }
362
363 /* Lock NW bit in CR0. */
364 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
365
366 write_eflags(eflags);
367 }
368 #endif /* I486_CPU */
369
370 #ifdef I686_CPU
371 /*
372 * Cyrix 6x86MX (code-named M2)
373 *
374 * XXX - What should I do here? Please let me know.
375 */
376 static void
377 init_6x86MX(void)
378 {
379 u_long eflags;
380 u_char ccr3, ccr4;
381
382 eflags = read_eflags();
383 disable_intr();
384
385 load_cr0(rcr0() | CR0_CD | CR0_NW);
386 wbinvd();
387
388 /* Initialize CCR0. */
389 write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);
390
391 /* Initialize CCR1. */
392 #ifdef CPU_CYRIX_NO_LOCK
393 write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
394 #else
395 #ifdef FAILSAFE
396 write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
397 #endif
398 #endif
399
400 /* Initialize CCR2. */
401 #ifdef CPU_SUSP_HLT
402 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_SUSP_HLT);
403 #else
404 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_SUSP_HLT);
405 #endif
406
407 ccr3 = read_cyrix_reg(CCR3);
408 write_cyrix_reg(CCR3, CCR3_MAPEN0);
409
410 /* Initialize CCR4. */
411 ccr4 = read_cyrix_reg(CCR4);
412 ccr4 &= ~CCR4_IOMASK;
413 #ifdef CPU_IORT
414 write_cyrix_reg(CCR4, ccr4 | (CPU_IORT & CCR4_IOMASK));
415 #else
416 write_cyrix_reg(CCR4, ccr4 | 7);
417 #endif
418
419 /* Initialize CCR5. */
420 #ifdef CPU_WT_ALLOC
421 write_cyrix_reg(CCR5, read_cyrix_reg(CCR5) | CCR5_WT_ALLOC);
422 #endif
423
424 /* Restore CCR3. */
425 write_cyrix_reg(CCR3, ccr3);
426
427 /* Unlock NW bit in CR0. */
428 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) & ~CCR2_LOCK_NW);
429
430 load_cr0(rcr0() & ~(CR0_CD | CR0_NW)); /* CD = 0 and NW = 0 */
431
432 /* Lock NW bit in CR0. */
433 write_cyrix_reg(CCR2, read_cyrix_reg(CCR2) | CCR2_LOCK_NW);
434
435 write_eflags(eflags);
436 }
437
438 static void
439 init_ppro(void)
440 {
441 quad_t apicbase;
442
443 /*
444 * Local APIC should be diabled in UP kernel.
445 */
446 apicbase = rdmsr(0x1b);
447 apicbase &= ~0x800LL;
448 wrmsr(0x1b, apicbase);
449 }
450 #endif /* I686_CPU */
451
452 void
453 initializecpu(void)
454 {
455
456 switch (cpu) {
457 #ifdef I486_CPU
458 case CPU_BLUE:
459 init_bluelightning();
460 break;
461 case CPU_486DLC:
462 init_486dlc();
463 break;
464 case CPU_CY486DX:
465 init_cy486dx();
466 break;
467 case CPU_M1SC:
468 init_5x86();
469 break;
470 #ifdef CPU_I486_ON_386
471 case CPU_486:
472 init_i486_on_386();
473 break;
474 #endif
475 case CPU_M1:
476 init_6x86();
477 break;
478 #endif /* I486_CPU */
479 #ifdef I686_CPU
480 case CPU_M2:
481 init_6x86MX();
482 break;
483 case CPU_686:
484 if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
485 (cpu_id & 0xff0) == 0x610)
486 init_ppro();
487 break;
488 #endif
489 default:
490 break;
491 }
492
493 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE)
494 /*
495 * OS should flush L1 cahce by itself because no PC-98 supports
496 * non-Intel CPUs. Use wbinvd instruction before DMA transfer
497 * when need_pre_dma_flush = 1, use invd instruction after DMA
498 * transfer when need_post_dma_flush = 1. If your CPU upgrade
499 * product support hardware cache control, you can add
500 * UPGRADE_CPU_HW_CACHE option in your kernel configuration file.
501 * This option elminate unneeded cache flush instruction.
502 */
503 if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
504 switch (cpu) {
505 #ifdef I486_CPU
506 case CPU_486DLC:
507 need_post_dma_flush = 1;
508 break;
509 case CPU_M1SC:
510 need_pre_dma_flush = 1;
511 break;
512 #endif
513 default:
514 break;
515 }
516 } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
517 switch (cpu_id & 0xFF0) {
518 case 0x470: /* Enhanced Am486DX2 WB */
519 case 0x490: /* Enhanced Am486DX4 WB */
520 case 0x4F0: /* Am5x86 WB */
521 need_pre_dma_flush = 1;
522 break;
523 }
524 } else if (strcmp(cpu_vendor, "IBM") == 0) {
525 need_post_dma_flush = 1;
526 } else {
527 #ifdef CPU_I486_ON_386
528 need_pre_dma_flush = 1;
529 #endif
530 }
531 #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
532 }
533
534 #include "opt_ddb.h"
535 #ifdef DDB
536 #include <ddb/ddb.h>
537
538 DB_SHOW_COMMAND(cyrixreg, cyrixreg)
539 {
540 u_long eflags;
541 u_int cr0;
542 u_char ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, pcr0;
543
544 cr0 = rcr0();
545 if (strcmp(cpu_vendor,"CyrixInstead") == 0) {
546 eflags = read_eflags();
547 disable_intr();
548
549
550 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) {
551 ccr0 = read_cyrix_reg(CCR0);
552 }
553 ccr1 = read_cyrix_reg(CCR1);
554 ccr2 = read_cyrix_reg(CCR2);
555 ccr3 = read_cyrix_reg(CCR3);
556 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
557 write_cyrix_reg(CCR3, CCR3_MAPEN0);
558 ccr4 = read_cyrix_reg(CCR4);
559 if ((cpu == CPU_M1) || (cpu == CPU_M2))
560 ccr5 = read_cyrix_reg(CCR5);
561 else
562 pcr0 = read_cyrix_reg(PCR0);
563 write_cyrix_reg(CCR3, ccr3); /* Restore CCR3. */
564 }
565 write_eflags(eflags);
566
567 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX))
568 printf("CCR0=%x, ", (u_int)ccr0);
569
570 printf("CCR1=%x, CCR2=%x, CCR3=%x",
571 (u_int)ccr1, (u_int)ccr2, (u_int)ccr3);
572 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) {
573 printf(", CCR4=%x, ", (u_int)ccr4);
574 if (cpu == CPU_M1SC)
575 printf("PCR0=%x\n", pcr0);
576 else
577 printf("CCR5=%x\n", ccr5);
578 }
579 }
580 printf("CR0=%x\n", cr0);
581 }
582 #endif /* DDB */
Cache object: 5dcc70ff3ab47ec3ddb1302332843b9d
|