1 /++ 2 $(H2 Intel 64 and IA-32 CPUID Information) 3 4 $(GREEN This module is available for betterC compilation mode.) 5 6 References: 7 Intel® 64 and IA-32 Architectures Software Developer’s Manual 8 9 License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 10 11 Authors: Ilia Ki 12 +/ 13 module cpuid.intel; 14 15 version(X86) 16 version = X86_Any; 17 else 18 version(X86_64) 19 version = X86_Any; 20 21 version(X86_Any): 22 23 public import cpuid.x86_any; 24 25 /++ 26 TLB and Cache information. 27 28 For convinient Cache information see also $(MREF Leaf4Information). 29 30 Specification: Intel 31 +/ 32 struct Leaf2Information 33 { 34 /// Level-1 instuciton cache 35 Cache il1; 36 /// Level-2 data cache 37 Cache l1; 38 /// Level-2 unified cache 39 Cache l2; 40 /// Level-2 unified cache 41 Cache l3; 42 /// Intruction TLB 43 Tlb itlb; 44 /// Intruction TLB, huge pages 45 Tlb hitlb; 46 /// Data TLB 47 Tlb dtlb; 48 /// Data TLB, huge pages 49 Tlb hdtlb; 50 /// Data TLB, giant pages 51 Tlb gdtlb; 52 /// Data TLB1 53 Tlb dtlb1; 54 /// Data TLB1, huge pages 55 Tlb hdtlb1; 56 /// Second-level unified TLB 57 Tlb utlb; 58 /// Second-level unified TLB, huge pages 59 Tlb hutlb; 60 /// Second-level unified TLB, giant pages 61 Tlb gutlb; 62 /// prefetch line size 63 int prefetch; 64 /// Cache trace 65 int trace; 66 /// `true` if CPUID leaf 2 does not report cache descriptor information. use CPUID leaf 4 to query cache parameters. 67 bool noCacheInfo; 68 // No 2nd-level cache or, if processor contains a valid 2nd-level cache, no 3rd-level cache 69 bool noL2Or3; 70 71 /+ 72 Dencoding of CPUID Leaf 2 Descriptors. 73 74 Note: 75 76 Specification: Intel 77 +/ 78 nothrow @nogc pure 79 this()(CpuInfo info) 80 { 81 version(BigEndian) static assert(0, "Leaf2Information is not implemented for BigEndian."); 82 83 foreach(i, b; (*(cast(ubyte[16]*)&info))[1..$]) 84 switch(b) 85 { 86 default: 87 break; 88 case 0x00: 89 // General Null descriptor, this byte contains no information 90 break; 91 case 0x01: 92 itlb.page = 4; 93 itlb.associative = 4; 94 itlb.entries = 32; 95 break; 96 case 0x02: 97 hitlb.page = 4 * 1024; 98 hitlb.associative = hitlb.associative.max; 99 hitlb.entries = 2; 100 break; 101 case 0x03: 102 dtlb.page = 4; 103 dtlb.associative = 4; 104 dtlb.entries = 64; 105 break; 106 case 0x04: 107 hdtlb.page = 4 * 1024; 108 hdtlb.associative = 4; 109 hdtlb.entries = 8; 110 break; 111 case 0x05: 112 hdtlb1.page = 4 * 1024; 113 hdtlb1.associative = 4; 114 hdtlb1.entries = 32; 115 break; 116 case 0x06: 117 il1.size = 8; 118 il1.associative = 4; 119 il1.line = 32; 120 break; 121 case 0x08: 122 il1.size = 16; 123 il1.associative = 4; 124 il1.line = 32; 125 break; 126 case 0x09: 127 il1.size = 32; 128 il1.associative = 4; 129 il1.line = 64; 130 break; 131 case 0x0A: 132 l1.size = 8; 133 l1.associative = 2; 134 l1.line = 32; 135 break; 136 case 0x0B: 137 hitlb.page = 4 * 1024; 138 hitlb.associative = 4; 139 hitlb.entries = 4; 140 break; 141 case 0x0C: 142 l1.size = 16; 143 l1.associative = 4; 144 l1.line = 32; 145 break; 146 case 0x0D: 147 l1.size = 16; 148 l1.associative = 4; 149 l1.line = 64; 150 break; 151 case 0x0E: 152 l1.size = 24; 153 l1.associative = 6; 154 l1.line = 64; 155 break; 156 case 0x1D: 157 l2.size = 128; 158 l2.associative = 2; 159 l2.line = 64; 160 break; 161 case 0x21: 162 l2.size = 256; 163 l2.associative = 8; 164 l2.line = 64; 165 break; 166 case 0x22: 167 l3.size = 512; 168 l3.associative = 4; 169 l3.line = 64; 170 break; 171 case 0x23: 172 l3.size = 1 * 1024; 173 l3.associative = 8; 174 l3.line = 64; 175 break; 176 case 0x24: 177 l2.size = 1 * 1024; 178 l2.associative = 16; 179 l2.line = 64; 180 break; 181 case 0x25: 182 l3.size = 2 * 1024; 183 l3.associative = 8; 184 l3.line = 64; 185 break; 186 case 0x29: 187 l3.size = 4 * 1024; 188 l3.associative = 8; 189 l3.line = 64; 190 break; 191 case 0x2C: 192 l1.size = 32; 193 l1.associative = 8; 194 l1.line = 64; 195 break; 196 case 0x30: 197 il1.size = 32; 198 il1.associative = 8; 199 il1.line = 64; 200 break; 201 case 0x40: 202 noL2Or3 = true; 203 break; 204 case 0x41: 205 l2.size = 128; 206 l2.associative = 4; 207 l2.line = 32; 208 break; 209 case 0x42: 210 l2.size = 256; 211 l2.associative = 4; 212 l2.line = 32; 213 break; 214 case 0x43: 215 l2.size = 512; 216 l2.associative = 4; 217 l2.line = 32; 218 break; 219 case 0x44: 220 l2.size = 1 * 1024; 221 l2.associative = 4; 222 l2.line = 32; 223 break; 224 case 0x45: 225 l2.size = 2 * 1024; 226 l2.associative = 4; 227 l2.line = 32; 228 break; 229 case 0x46: 230 l3.size = 4 * 1024; 231 l3.associative = 4; 232 l3.line = 64; 233 break; 234 case 0x47: 235 l3.size = 8 * 1024; 236 l3.associative = 8; 237 l3.line = 64; 238 break; 239 case 0x48: 240 l2.size = 3 * 1024; 241 l2.associative = 12; 242 l2.line = 64; 243 break; 244 case 0x49: 245 if(family == 0x0F && model == 0x06) 246 { 247 l3.size = 4 * 1024; 248 l3.associative = 16; 249 l3.line = 64; 250 break; 251 } 252 l2.size = 4 * 1024; 253 l2.associative = 16; 254 l2.line = 64; 255 break; 256 case 0x4A: 257 l3.size = 6 * 1024; 258 l3.associative = 12; 259 l3.line = 64; 260 break; 261 case 0x4B: 262 l3.size = 8 * 1024; 263 l3.associative = 16; 264 l3.line = 64; 265 break; 266 case 0x4C: 267 l3.size = 12 * 1024; 268 l3.associative = 12; 269 l3.line = 64; 270 break; 271 case 0x4D: 272 l3.size = 16 * 1024; 273 l3.associative = 16; 274 l3.line = 64; 275 break; 276 case 0x4E: 277 l2.size = 6 * 1024; 278 l2.associative = 24; 279 l2.line = 64; 280 break; 281 case 0x4F: 282 itlb.page = 4; 283 itlb.associative = 1; 284 itlb.entries = 32; 285 break; 286 case 0x50: 287 itlb.page = 4; 288 itlb.associative = 1; 289 itlb.entries = 64; 290 hitlb.page = 2 * 1024; 291 hitlb.associative = 1; 292 hitlb.entries = 64; 293 break; 294 case 0x51: 295 itlb.page = 4; 296 itlb.associative = 1; 297 itlb.entries = 128; 298 hitlb.page = 2 * 1024; 299 hitlb.associative = 1; 300 hitlb.entries = 128; 301 break; 302 case 0x52: 303 itlb.page = 4; 304 itlb.associative = 1; 305 itlb.entries = 256; 306 hitlb.page = 2 * 1024; 307 hitlb.associative = 1; 308 hitlb.entries = 256; 309 break; 310 case 0x55: 311 itlb.page = 2 * 1024; 312 itlb.associative = itlb.associative.max; 313 itlb.entries = 7; 314 break; 315 case 0x56: 316 hdtlb.page = 4 * 1024; 317 hdtlb.associative = 4; 318 hdtlb.entries = 16; 319 break; 320 case 0x57: 321 dtlb.page = 4; 322 dtlb.associative = 4; 323 dtlb.entries = 16; 324 break; 325 case 0x59: 326 dtlb.page = 4; 327 dtlb.associative = dtlb.associative.max; 328 dtlb.entries = 16; 329 break; 330 case 0x5A: 331 hdtlb.page = 2 * 1024; 332 hdtlb.associative = 4; 333 hdtlb.entries = 32; 334 break; 335 case 0x5B: 336 dtlb.page = 4; 337 dtlb.associative = 1; 338 dtlb.entries = 64; 339 hdtlb.page = 4 * 1024; 340 hdtlb.associative = 1; 341 hdtlb.entries = 64; 342 break; 343 case 0x5C: 344 dtlb.page = 4; 345 dtlb.associative = 1; 346 dtlb.entries = 128; 347 hdtlb.page = 4 * 1024; 348 hdtlb.associative = 1; 349 hdtlb.entries = 128; 350 break; 351 case 0x5D: 352 dtlb.page = 4; 353 dtlb.associative = 1; 354 dtlb.entries = 256; 355 hdtlb.page = 4 * 1024; 356 hdtlb.associative = 1; 357 hdtlb.entries = 256; 358 break; 359 case 0x60: 360 l1.size = 16; 361 l1.associative = 8; 362 l1.line = 64; 363 break; 364 case 0x61: 365 itlb.page = 4; 366 itlb.associative = itlb.associative.max; 367 itlb.entries = 48; 368 break; 369 case 0x63: 370 hdtlb.page = 2 * 1024; 371 hdtlb.associative = 4; 372 hdtlb.entries = 32; 373 gdtlb.page = 1024 * 1024; 374 gdtlb.associative = 4; 375 gdtlb.entries = 4; 376 break; 377 case 0x64: 378 dtlb.page = 4; 379 dtlb.associative = 4; 380 dtlb.entries = 512; 381 break; 382 case 0x66: 383 l1.size = 8; 384 l1.associative = 4; 385 l1.line = 64; 386 break; 387 case 0x67: 388 l1.size = 16; 389 l1.associative = 4; 390 l1.line = 64; 391 break; 392 case 0x68: 393 l1.size = 32; 394 l1.associative = 4; 395 l1.line = 64; 396 break; 397 case 0x6A: 398 dtlb.page = 4; 399 dtlb.associative = 8; 400 dtlb.entries = 64; 401 break; 402 case 0x6B: 403 dtlb.page = 4; 404 dtlb.associative = 8; 405 dtlb.entries = 256; 406 break; 407 case 0x6C: 408 hdtlb.page = 2 * 1024; 409 hdtlb.associative = 8; 410 hdtlb.entries = 128; 411 break; 412 case 0x6D: 413 gdtlb.page = 1024 * 1024; 414 gdtlb.associative = gdtlb.associative.max; 415 gdtlb.entries = 16; 416 break; 417 case 0x70: 418 trace = 12; 419 break; 420 case 0x71: 421 trace = 16; 422 break; 423 case 0x72: 424 trace = 32; 425 break; 426 case 0x76: 427 itlb.page = 2 * 1024; 428 itlb.associative = itlb.associative.max; 429 itlb.entries = 8; 430 break; 431 case 0x78: 432 l2.size = 1 * 1024; 433 l2.associative = 4; 434 l2.line = 6; 435 break; 436 case 0x79: 437 l2.size = 128; 438 l2.associative = 8; 439 l2.line = 64; 440 break; 441 case 0x7A: 442 l2.size = 256; 443 l2.associative = 8; 444 l2.line = 64; 445 break; 446 case 0x7B: 447 l2.size = 512; 448 l2.associative = 8; 449 l2.line = 64; 450 break; 451 case 0x7C: 452 l2.size = 1 * 1024; 453 l2.associative = 8; 454 l2.line = 64; 455 break; 456 case 0x7D: 457 l2.size = 2 * 1024; 458 l2.associative = 8; 459 l2.line = 6; 460 break; 461 case 0x7F: 462 l2.size = 512; 463 l2.associative = 2; 464 l2.line = 64; 465 break; 466 case 0x80: 467 l2.size = 512; 468 l2.associative = 8; 469 l2.line = 64; 470 break; 471 case 0x82: 472 l2.size = 256; 473 l2.associative = 8; 474 l2.line = 32; 475 break; 476 case 0x83: 477 l2.size = 512; 478 l2.associative = 8; 479 l2.line = 32; 480 break; 481 case 0x84: 482 l2.size = 1 * 1024; 483 l2.associative = 8; 484 l2.line = 32; 485 break; 486 case 0x85: 487 l2.size = 2 * 1024; 488 l2.associative = 8; 489 l2.line = 32; 490 break; 491 case 0x86: 492 l2.size = 512; 493 l2.associative = 4; 494 l2.line = 64; 495 break; 496 case 0x87: 497 l2.size = 1 * 1024; 498 l2.associative = 8; 499 l2.line = 64; 500 break; 501 case 0xA0: 502 dtlb.page = 4; 503 dtlb.associative = dtlb.associative.max; 504 dtlb.entries = 32; 505 break; 506 case 0xB0: 507 itlb.page = 4; 508 itlb.associative = 4; 509 itlb.entries = 128; 510 break; 511 case 0xB1: 512 itlb.page = 2 * 1024; 513 itlb.associative = 4; 514 itlb.entries = 8; 515 break; 516 case 0xB2: 517 itlb.page = 4; 518 itlb.associative = 4; 519 itlb.entries = 64; 520 break; 521 case 0xB3: 522 dtlb.page = 4; 523 dtlb.associative = 4; 524 dtlb.entries = 128; 525 break; 526 case 0xB4: 527 dtlb1.page = 4; 528 dtlb1.associative = 4; 529 dtlb1.entries = 256; 530 break; 531 case 0xB5: 532 itlb.page = 4; 533 itlb.associative = 8; 534 itlb.entries = 64; 535 break; 536 case 0xB6: 537 itlb.page = 4; 538 itlb.associative = 8; 539 itlb.entries = 128; 540 break; 541 case 0xBA: 542 dtlb1.page = 4; 543 dtlb1.associative = 4; 544 dtlb1.entries = 64; 545 break; 546 case 0xC0: 547 dtlb.page = 4; 548 dtlb.associative = 4; 549 dtlb.entries = 8; 550 hdtlb.page = 4 * 1024; 551 hdtlb.associative = 4; 552 hdtlb.entries = 8; 553 break; 554 case 0xC1: 555 utlb.page = 4; 556 utlb.associative = 8; 557 utlb.entries = 1024; 558 hutlb.page = 2 * 1024; 559 hutlb.associative = 8; 560 hutlb.entries = 1024; 561 break; 562 case 0xC2: 563 dtlb.page = 4; 564 dtlb.associative = 4; 565 dtlb.entries = 16; 566 hdtlb.page = 2 * 1024; 567 hdtlb.associative = 4; 568 hdtlb.entries = 16; 569 break; 570 case 0xC3: 571 utlb.page = 4; 572 utlb.associative = 6; 573 utlb.entries = 1536; 574 hutlb.page = 2 * 1024; 575 hutlb.associative = 6; 576 hutlb.entries = 1536; 577 gutlb.page = 1024 * 1024; 578 gutlb.associative = 4; 579 gutlb.entries = 16; 580 break; 581 case 0xC4: 582 hdtlb.page = 2 * 1024; 583 hdtlb.associative = 4; 584 hdtlb.entries = 32; 585 break; 586 case 0xCA: 587 utlb.page = 4; 588 utlb.associative = 4; 589 utlb.entries = 512; 590 break; 591 case 0xD0: 592 l3.size = 512; 593 l3.associative = 4; 594 l3.line = 64; 595 break; 596 case 0xD1: 597 l3.size = 1 * 1024; 598 l3.associative = 4; 599 l3.line = 64; 600 break; 601 case 0xD2: 602 l3.size = 2 * 1024; 603 l3.associative = 4; 604 l3.line = 64; 605 break; 606 case 0xD6: 607 l3.size = 1 * 1024; 608 l3.associative = 8; 609 l3.line = 64; 610 break; 611 case 0xD7: 612 l3.size = 2 * 1024; 613 l3.associative = 8; 614 l3.line = 64; 615 break; 616 case 0xD8: 617 l3.size = 4 * 1024; 618 l3.associative = 8; 619 l3.line = 64; 620 break; 621 case 0xDC: 622 l3.size = 1536; 623 l3.associative = 12; 624 l3.line = 64; 625 break; 626 case 0xDD: 627 l3.size = 3 * 1024; 628 l3.associative = 12; 629 l3.line = 64; 630 break; 631 case 0xDE: 632 l3.size = 6 * 1024; 633 l3.associative = 12; 634 l3.line = 64; 635 break; 636 case 0xE2: 637 l3.size = 2 * 1024; 638 l3.associative = 16; 639 l3.line = 64; 640 break; 641 case 0xE3: 642 l3.size = 4 * 1024; 643 l3.associative = 16; 644 l3.line = 64; 645 break; 646 case 0xE4: 647 l3.size = 8 * 1024; 648 l3.associative = 16; 649 l3.line = 64; 650 break; 651 case 0xEA: 652 l3.size = 12 * 1024; 653 l3.associative = 24; 654 l3.line = 64; 655 break; 656 case 0xEB: 657 l3.size = 18 * 1024; 658 l3.associative = 24; 659 l3.line = 64; 660 break; 661 case 0xEC: 662 l3.size = 24 * 1024; 663 l3.associative = 24; 664 l3.line = 64; 665 break; 666 case 0xF0: 667 // Prefetch 64-B prefetching 668 prefetch = 64; 669 break; 670 case 0xF1: 671 // Prefetch 128-B prefetching 672 prefetch = 128; 673 break; 674 case 0xFF: 675 // General CPUID leaf 2 does not report cache descriptor information, use CPUID leaf 4 to query cache parameters 676 noCacheInfo = true; 677 break; 678 } 679 } 680 } 681 682 683 ///// 684 unittest 685 { 686 auto leaf2 = Leaf2Information(_cpuid(2)); 687 } 688 689 /++ 690 Deterministic Cache Parameters for Each Level. 691 692 ** - Add one to the return value to get the result. 693 694 Specification: Intel 695 +/ 696 union Leaf4Information 697 { 698 import mir.bitmanip: bitfields; 699 700 /// CPUID payload 701 CpuInfo info; 702 703 /// 704 struct 705 { 706 /// 707 enum Type 708 { 709 /// 710 noMoreCaches, 711 /// 712 data, 713 /// 714 instruction, 715 /// 716 unified, 717 } 718 719 version(D_Ddoc) 720 { 721 @trusted @property pure nothrow @nogc const: 722 /// Cache Type Field. 723 Type type(); 724 /// Cache Level (starts at 1). 725 uint level(); 726 /// Self Initializing cache level (does not need SW initialization). 727 bool selfInitializing(); 728 /// Fully Associative cache. 729 bool fullyAssociative(); 730 /// Maximum number of addressable IDs for logical processors sharing this cache. ** 731 uint maxThreadsPerCache(); 732 /// Maximum number of addressable IDs for processor cores in the physical package ** 733 uint maxCorePerCPU(); 734 /// System Coherency Line Size **. 735 uint l(); 736 /// Physical Line partitions **. 737 uint p(); 738 /// Ways of associativity **. 739 uint w(); 740 /// Number of Sets **. 741 uint s; 742 /// Write-Back Invalidate/Invalidate. 743 /// `false` if WBINVD/INVD from threads sharing this cache acts upon lower level caches for threads sharing this cache. 744 /// `true` if WBINVD/INVD is not guaranteed to act upon lower level caches of non-originating threads sharing this cache. 745 bool invalidate(); 746 /// `true` - Cache is not inclusive of lower cache levels. `false` - Cache is inclusive of lower cache levels. 747 bool inclusive(); 748 /// `false` - Direct mapped cache. `true` A complex function is used to index the cache, potentially using all address bits. 749 bool complex(); 750 } 751 else 752 { 753 @trusted @property pure nothrow @nogc: 754 /// EAX 755 mixin(bitfields!( 756 Type, "type", 5, 757 uint, "level", 3, 758 bool, "selfInitializing", 1, 759 bool, "fullyAssociative", 1, 760 uint, "", 4, 761 uint, "maxThreadsPerCache", 12, 762 uint, "maxCorePerCPU", 6, 763 )); 764 765 /// EBX 766 mixin(bitfields!( 767 uint, "l", 12, 768 uint, "p", 10, 769 uint, "w", 10, 770 )); 771 772 /// Number of Sets**. 773 uint s; 774 775 /// EDX 776 mixin(bitfields!( 777 bool, "invalidate", 1, 778 bool, "inclusive", 1, 779 bool, "complex", 1, 780 uint, "", 29, 781 )); 782 } 783 784 /// Compute cache size in KBs. 785 pure nothrow @nogc 786 uint size()() @property 787 { 788 return cast(uint) ( 789 size_t(l + 1) * 790 size_t(p + 1) * 791 size_t(w + 1) * 792 size_t(s + 1) >> 10); 793 } 794 795 /// 796 pure nothrow @nogc 797 void fill()(ref Cache cache) @property 798 { 799 cache.size = size; 800 cache.line = cast(typeof(cache.line))(l + 1); 801 cache.inclusive = inclusive; 802 cache.associative = cast(typeof(cache.associative)) (w + 1); 803 if(fullyAssociative) 804 cache.associative = cache.associative.max; 805 } 806 } 807 } 808 809 /// 810 unittest 811 { 812 if(maxBasicLeaf >= 4 && vendorIndex == VendorIndex.intel) 813 { 814 Cache cache = void; 815 Leaf4Information leaf4 = void; 816 foreach(ecx; 0..12) 817 { 818 leaf4.info = _cpuid(4, ecx); 819 if(!leaf4.type) 820 break; 821 leaf4.fill(cache); 822 debug(cpuid) import std.stdio; 823 debug(cpuid) writefln("Cache #%s has type '%s' and %s KB size", ecx, leaf4.type, leaf4.size); 824 } 825 } 826 }