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