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 * $Id: initcpu.c,v 1.12 1998/02/04 03:47:14 eivind 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 #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 #ifndef SMP 442 quad_t apicbase; 443 444 /* 445 * Local APIC should be diabled in UP kernel. 446 */ 447 apicbase = rdmsr(0x1b); 448 apicbase &= ~0x800LL; 449 wrmsr(0x1b, apicbase); 450 #endif 451 } 452 #endif /* I686_CPU */ 453 454 void 455 initializecpu(void) 456 { 457 458 switch (cpu) { 459 #ifdef I486_CPU 460 case CPU_BLUE: 461 init_bluelightning(); 462 break; 463 case CPU_486DLC: 464 init_486dlc(); 465 break; 466 case CPU_CY486DX: 467 init_cy486dx(); 468 break; 469 case CPU_M1SC: 470 init_5x86(); 471 break; 472 #ifdef CPU_I486_ON_386 473 case CPU_486: 474 init_i486_on_386(); 475 break; 476 #endif 477 case CPU_M1: 478 init_6x86(); 479 break; 480 #endif /* I486_CPU */ 481 #ifdef I686_CPU 482 case CPU_M2: 483 init_6x86MX(); 484 break; 485 case CPU_686: 486 if (strcmp(cpu_vendor, "GenuineIntel") == 0 && 487 (cpu_id & 0xff0) == 0x610) 488 init_ppro(); 489 break; 490 #endif 491 default: 492 break; 493 } 494 495 #if defined(PC98) && !defined(CPU_UPGRADE_HW_CACHE) 496 /* 497 * OS should flush L1 cahce by itself because no PC-98 supports 498 * non-Intel CPUs. Use wbinvd instruction before DMA transfer 499 * when need_pre_dma_flush = 1, use invd instruction after DMA 500 * transfer when need_post_dma_flush = 1. If your CPU upgrade 501 * product support hardware cache control, you can add 502 * UPGRADE_CPU_HW_CACHE option in your kernel configuration file. 503 * This option elminate unneeded cache flush instruction. 504 */ 505 if (strcmp(cpu_vendor, "CyrixInstead") == 0) { 506 switch (cpu) { 507 #ifdef I486_CPU 508 case CPU_486DLC: 509 need_post_dma_flush = 1; 510 break; 511 case CPU_M1SC: 512 need_pre_dma_flush = 1; 513 break; 514 #endif 515 default: 516 break; 517 } 518 } else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { 519 switch (cpu_id & 0xFF0) { 520 case 0x470: /* Enhanced Am486DX2 WB */ 521 case 0x490: /* Enhanced Am486DX4 WB */ 522 case 0x4F0: /* Am5x86 WB */ 523 need_pre_dma_flush = 1; 524 break; 525 } 526 } else if (strcmp(cpu_vendor, "IBM") == 0) { 527 need_post_dma_flush = 1; 528 } else { 529 #ifdef CPU_I486_ON_386 530 need_pre_dma_flush = 1; 531 #endif 532 } 533 #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */ 534 } 535 536 #include "opt_ddb.h" 537 #ifdef DDB 538 #include <ddb/ddb.h> 539 540 DB_SHOW_COMMAND(cyrixreg, cyrixreg) 541 { 542 u_long eflags; 543 u_int cr0; 544 u_char ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, pcr0; 545 546 cr0 = rcr0(); 547 if (strcmp(cpu_vendor,"CyrixInstead") == 0) { 548 eflags = read_eflags(); 549 disable_intr(); 550 551 552 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) { 553 ccr0 = read_cyrix_reg(CCR0); 554 } 555 ccr1 = read_cyrix_reg(CCR1); 556 ccr2 = read_cyrix_reg(CCR2); 557 ccr3 = read_cyrix_reg(CCR3); 558 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 559 write_cyrix_reg(CCR3, CCR3_MAPEN0); 560 ccr4 = read_cyrix_reg(CCR4); 561 if ((cpu == CPU_M1) || (cpu == CPU_M2)) 562 ccr5 = read_cyrix_reg(CCR5); 563 else 564 pcr0 = read_cyrix_reg(PCR0); 565 write_cyrix_reg(CCR3, ccr3); /* Restore CCR3. */ 566 } 567 write_eflags(eflags); 568 569 if ((cpu != CPU_M1SC) && (cpu != CPU_CY486DX)) 570 printf("CCR0=%x, ", (u_int)ccr0); 571 572 printf("CCR1=%x, CCR2=%x, CCR3=%x", 573 (u_int)ccr1, (u_int)ccr2, (u_int)ccr3); 574 if ((cpu == CPU_M1SC) || (cpu == CPU_M1) || (cpu == CPU_M2)) { 575 printf(", CCR4=%x, ", (u_int)ccr4); 576 if (cpu == CPU_M1SC) 577 printf("PCR0=%x\n", pcr0); 578 else 579 printf("CCR5=%x\n", ccr5); 580 } 581 } 582 printf("CR0=%x\n", cr0); 583 } 584 #endif /* DDB */ 585