@@ -491,6 +491,147 @@ static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned i
491
491
}
492
492
#endif
493
493
494
+ #define TLB_INST_4K 0x01
495
+ #define TLB_INST_4M 0x02
496
+ #define TLB_INST_2M_4M 0x03
497
+
498
+ #define TLB_INST_ALL 0x05
499
+ #define TLB_INST_1G 0x06
500
+
501
+ #define TLB_DATA_4K 0x11
502
+ #define TLB_DATA_4M 0x12
503
+ #define TLB_DATA_2M_4M 0x13
504
+ #define TLB_DATA_4K_4M 0x14
505
+
506
+ #define TLB_DATA_1G 0x16
507
+
508
+ #define TLB_DATA0_4K 0x21
509
+ #define TLB_DATA0_4M 0x22
510
+ #define TLB_DATA0_2M_4M 0x23
511
+
512
+ #define STLB_4K 0x41
513
+
514
+ static const struct _tlb_table intel_tlb_table [] __cpuinitconst = {
515
+ { 0x01 , TLB_INST_4K , 32 , " TLB_INST 4 KByte pages, 4-way set associative" },
516
+ { 0x02 , TLB_INST_4M , 2 , " TLB_INST 4 MByte pages, full associative" },
517
+ { 0x03 , TLB_DATA_4K , 64 , " TLB_DATA 4 KByte pages, 4-way set associative" },
518
+ { 0x04 , TLB_DATA_4M , 8 , " TLB_DATA 4 MByte pages, 4-way set associative" },
519
+ { 0x05 , TLB_DATA_4M , 32 , " TLB_DATA 4 MByte pages, 4-way set associative" },
520
+ { 0x0b , TLB_INST_4M , 4 , " TLB_INST 4 MByte pages, 4-way set associative" },
521
+ { 0x4f , TLB_INST_4K , 32 , " TLB_INST 4 KByte pages */" },
522
+ { 0x50 , TLB_INST_ALL , 64 , " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" },
523
+ { 0x51 , TLB_INST_ALL , 128 , " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" },
524
+ { 0x52 , TLB_INST_ALL , 256 , " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" },
525
+ { 0x55 , TLB_INST_2M_4M , 7 , " TLB_INST 2-MByte or 4-MByte pages, fully associative" },
526
+ { 0x56 , TLB_DATA0_4M , 16 , " TLB_DATA0 4 MByte pages, 4-way set associative" },
527
+ { 0x57 , TLB_DATA0_4K , 16 , " TLB_DATA0 4 KByte pages, 4-way associative" },
528
+ { 0x59 , TLB_DATA0_4K , 16 , " TLB_DATA0 4 KByte pages, fully associative" },
529
+ { 0x5a , TLB_DATA0_2M_4M , 32 , " TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative" },
530
+ { 0x5b , TLB_DATA_4K_4M , 64 , " TLB_DATA 4 KByte and 4 MByte pages" },
531
+ { 0x5c , TLB_DATA_4K_4M , 128 , " TLB_DATA 4 KByte and 4 MByte pages" },
532
+ { 0x5d , TLB_DATA_4K_4M , 256 , " TLB_DATA 4 KByte and 4 MByte pages" },
533
+ { 0xb0 , TLB_INST_4K , 128 , " TLB_INST 4 KByte pages, 4-way set associative" },
534
+ { 0xb1 , TLB_INST_2M_4M , 4 , " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" },
535
+ { 0xb2 , TLB_INST_4K , 64 , " TLB_INST 4KByte pages, 4-way set associative" },
536
+ { 0xb3 , TLB_DATA_4K , 128 , " TLB_DATA 4 KByte pages, 4-way set associative" },
537
+ { 0xb4 , TLB_DATA_4K , 256 , " TLB_DATA 4 KByte pages, 4-way associative" },
538
+ { 0xba , TLB_DATA_4K , 64 , " TLB_DATA 4 KByte pages, 4-way associative" },
539
+ { 0xc0 , TLB_DATA_4K_4M , 8 , " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" },
540
+ { 0xca , STLB_4K , 512 , " STLB 4 KByte pages, 4-way associative" },
541
+ { 0x00 , 0 , 0 }
542
+ };
543
+
544
+ static void __cpuinit intel_tlb_lookup (const unsigned char desc )
545
+ {
546
+ unsigned char k ;
547
+ if (desc == 0 )
548
+ return ;
549
+
550
+ /* look up this descriptor in the table */
551
+ for (k = 0 ; intel_tlb_table [k ].descriptor != desc && \
552
+ intel_tlb_table [k ].descriptor != 0 ; k ++ )
553
+ ;
554
+
555
+ if (intel_tlb_table [k ].tlb_type == 0 )
556
+ return ;
557
+
558
+ switch (intel_tlb_table [k ].tlb_type ) {
559
+ case STLB_4K :
560
+ if (tlb_lli_4k [ENTRIES ] < intel_tlb_table [k ].entries )
561
+ tlb_lli_4k [ENTRIES ] = intel_tlb_table [k ].entries ;
562
+ if (tlb_lld_4k [ENTRIES ] < intel_tlb_table [k ].entries )
563
+ tlb_lld_4k [ENTRIES ] = intel_tlb_table [k ].entries ;
564
+ break ;
565
+ case TLB_INST_ALL :
566
+ if (tlb_lli_4k [ENTRIES ] < intel_tlb_table [k ].entries )
567
+ tlb_lli_4k [ENTRIES ] = intel_tlb_table [k ].entries ;
568
+ if (tlb_lli_2m [ENTRIES ] < intel_tlb_table [k ].entries )
569
+ tlb_lli_2m [ENTRIES ] = intel_tlb_table [k ].entries ;
570
+ if (tlb_lli_4m [ENTRIES ] < intel_tlb_table [k ].entries )
571
+ tlb_lli_4m [ENTRIES ] = intel_tlb_table [k ].entries ;
572
+ break ;
573
+ case TLB_INST_4K :
574
+ if (tlb_lli_4k [ENTRIES ] < intel_tlb_table [k ].entries )
575
+ tlb_lli_4k [ENTRIES ] = intel_tlb_table [k ].entries ;
576
+ break ;
577
+ case TLB_INST_4M :
578
+ if (tlb_lli_4m [ENTRIES ] < intel_tlb_table [k ].entries )
579
+ tlb_lli_4m [ENTRIES ] = intel_tlb_table [k ].entries ;
580
+ break ;
581
+ case TLB_INST_2M_4M :
582
+ if (tlb_lli_2m [ENTRIES ] < intel_tlb_table [k ].entries )
583
+ tlb_lli_2m [ENTRIES ] = intel_tlb_table [k ].entries ;
584
+ if (tlb_lli_4m [ENTRIES ] < intel_tlb_table [k ].entries )
585
+ tlb_lli_4m [ENTRIES ] = intel_tlb_table [k ].entries ;
586
+ break ;
587
+ case TLB_DATA_4K :
588
+ case TLB_DATA0_4K :
589
+ if (tlb_lld_4k [ENTRIES ] < intel_tlb_table [k ].entries )
590
+ tlb_lld_4k [ENTRIES ] = intel_tlb_table [k ].entries ;
591
+ break ;
592
+ case TLB_DATA_4M :
593
+ case TLB_DATA0_4M :
594
+ if (tlb_lld_4m [ENTRIES ] < intel_tlb_table [k ].entries )
595
+ tlb_lld_4m [ENTRIES ] = intel_tlb_table [k ].entries ;
596
+ break ;
597
+ case TLB_DATA_2M_4M :
598
+ case TLB_DATA0_2M_4M :
599
+ if (tlb_lld_2m [ENTRIES ] < intel_tlb_table [k ].entries )
600
+ tlb_lld_2m [ENTRIES ] = intel_tlb_table [k ].entries ;
601
+ if (tlb_lld_4m [ENTRIES ] < intel_tlb_table [k ].entries )
602
+ tlb_lld_4m [ENTRIES ] = intel_tlb_table [k ].entries ;
603
+ break ;
604
+ case TLB_DATA_4K_4M :
605
+ if (tlb_lld_4k [ENTRIES ] < intel_tlb_table [k ].entries )
606
+ tlb_lld_4k [ENTRIES ] = intel_tlb_table [k ].entries ;
607
+ if (tlb_lld_4m [ENTRIES ] < intel_tlb_table [k ].entries )
608
+ tlb_lld_4m [ENTRIES ] = intel_tlb_table [k ].entries ;
609
+ break ;
610
+ }
611
+ }
612
+
613
+ static void __cpuinit intel_detect_tlb (struct cpuinfo_x86 * c )
614
+ {
615
+ int i , j , n ;
616
+ unsigned int regs [4 ];
617
+ unsigned char * desc = (unsigned char * )regs ;
618
+ /* Number of times to iterate */
619
+ n = cpuid_eax (2 ) & 0xFF ;
620
+
621
+ for (i = 0 ; i < n ; i ++ ) {
622
+ cpuid (2 , & regs [0 ], & regs [1 ], & regs [2 ], & regs [3 ]);
623
+
624
+ /* If bit 31 is set, this is an unknown format */
625
+ for (j = 0 ; j < 3 ; j ++ )
626
+ if (regs [j ] & (1 << 31 ))
627
+ regs [j ] = 0 ;
628
+
629
+ /* Byte 0 is level count, not a descriptor */
630
+ for (j = 1 ; j < 16 ; j ++ )
631
+ intel_tlb_lookup (desc [j ]);
632
+ }
633
+ }
634
+
494
635
static const struct cpu_dev __cpuinitconst intel_cpu_dev = {
495
636
.c_vendor = "Intel" ,
496
637
.c_ident = { "GenuineIntel" },
@@ -546,6 +687,7 @@ static const struct cpu_dev __cpuinitconst intel_cpu_dev = {
546
687
},
547
688
.c_size_cache = intel_size_cache ,
548
689
#endif
690
+ .c_detect_tlb = intel_detect_tlb ,
549
691
.c_early_init = early_init_intel ,
550
692
.c_init = init_intel ,
551
693
.c_x86_vendor = X86_VENDOR_INTEL ,
0 commit comments