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