12ec1df41SThomas Gleixner #include <linux/init.h> 22ec1df41SThomas Gleixner #include <linux/mm.h> 32ec1df41SThomas Gleixner #include <asm/mtrr.h> 42ec1df41SThomas Gleixner #include <asm/msr.h> 52ec1df41SThomas Gleixner #include <asm/io.h> 62ec1df41SThomas Gleixner #include <asm/processor-cyrix.h> 72ec1df41SThomas Gleixner #include "mtrr.h" 82ec1df41SThomas Gleixner 92ec1df41SThomas Gleixner int arr3_protected; 102ec1df41SThomas Gleixner 112ec1df41SThomas Gleixner static void 122ec1df41SThomas Gleixner cyrix_get_arr(unsigned int reg, unsigned long *base, 132ec1df41SThomas Gleixner unsigned long *size, mtrr_type * type) 142ec1df41SThomas Gleixner { 152ec1df41SThomas Gleixner unsigned long flags; 162ec1df41SThomas Gleixner unsigned char arr, ccr3, rcr, shift; 172ec1df41SThomas Gleixner 182ec1df41SThomas Gleixner arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ 192ec1df41SThomas Gleixner 202ec1df41SThomas Gleixner /* Save flags and disable interrupts */ 212ec1df41SThomas Gleixner local_irq_save(flags); 222ec1df41SThomas Gleixner 232ec1df41SThomas Gleixner ccr3 = getCx86(CX86_CCR3); 242ec1df41SThomas Gleixner setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ 252ec1df41SThomas Gleixner ((unsigned char *) base)[3] = getCx86(arr); 262ec1df41SThomas Gleixner ((unsigned char *) base)[2] = getCx86(arr + 1); 272ec1df41SThomas Gleixner ((unsigned char *) base)[1] = getCx86(arr + 2); 282ec1df41SThomas Gleixner rcr = getCx86(CX86_RCR_BASE + reg); 292ec1df41SThomas Gleixner setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ 302ec1df41SThomas Gleixner 312ec1df41SThomas Gleixner /* Enable interrupts if it was enabled previously */ 322ec1df41SThomas Gleixner local_irq_restore(flags); 332ec1df41SThomas Gleixner shift = ((unsigned char *) base)[1] & 0x0f; 342ec1df41SThomas Gleixner *base >>= PAGE_SHIFT; 352ec1df41SThomas Gleixner 362ec1df41SThomas Gleixner /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7 372ec1df41SThomas Gleixner * Note: shift==0xf means 4G, this is unsupported. 382ec1df41SThomas Gleixner */ 392ec1df41SThomas Gleixner if (shift) 402ec1df41SThomas Gleixner *size = (reg < 7 ? 0x1UL : 0x40UL) << (shift - 1); 412ec1df41SThomas Gleixner else 422ec1df41SThomas Gleixner *size = 0; 432ec1df41SThomas Gleixner 442ec1df41SThomas Gleixner /* Bit 0 is Cache Enable on ARR7, Cache Disable on ARR0-ARR6 */ 452ec1df41SThomas Gleixner if (reg < 7) { 462ec1df41SThomas Gleixner switch (rcr) { 472ec1df41SThomas Gleixner case 1: 482ec1df41SThomas Gleixner *type = MTRR_TYPE_UNCACHABLE; 492ec1df41SThomas Gleixner break; 502ec1df41SThomas Gleixner case 8: 512ec1df41SThomas Gleixner *type = MTRR_TYPE_WRBACK; 522ec1df41SThomas Gleixner break; 532ec1df41SThomas Gleixner case 9: 542ec1df41SThomas Gleixner *type = MTRR_TYPE_WRCOMB; 552ec1df41SThomas Gleixner break; 562ec1df41SThomas Gleixner case 24: 572ec1df41SThomas Gleixner default: 582ec1df41SThomas Gleixner *type = MTRR_TYPE_WRTHROUGH; 592ec1df41SThomas Gleixner break; 602ec1df41SThomas Gleixner } 612ec1df41SThomas Gleixner } else { 622ec1df41SThomas Gleixner switch (rcr) { 632ec1df41SThomas Gleixner case 0: 642ec1df41SThomas Gleixner *type = MTRR_TYPE_UNCACHABLE; 652ec1df41SThomas Gleixner break; 662ec1df41SThomas Gleixner case 8: 672ec1df41SThomas Gleixner *type = MTRR_TYPE_WRCOMB; 682ec1df41SThomas Gleixner break; 692ec1df41SThomas Gleixner case 9: 702ec1df41SThomas Gleixner *type = MTRR_TYPE_WRBACK; 712ec1df41SThomas Gleixner break; 722ec1df41SThomas Gleixner case 25: 732ec1df41SThomas Gleixner default: 742ec1df41SThomas Gleixner *type = MTRR_TYPE_WRTHROUGH; 752ec1df41SThomas Gleixner break; 762ec1df41SThomas Gleixner } 772ec1df41SThomas Gleixner } 782ec1df41SThomas Gleixner } 792ec1df41SThomas Gleixner 802ec1df41SThomas Gleixner static int 812ec1df41SThomas Gleixner cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) 822ec1df41SThomas Gleixner /* [SUMMARY] Get a free ARR. 832ec1df41SThomas Gleixner <base> The starting (base) address of the region. 842ec1df41SThomas Gleixner <size> The size (in bytes) of the region. 852ec1df41SThomas Gleixner [RETURNS] The index of the region on success, else -1 on error. 862ec1df41SThomas Gleixner */ 872ec1df41SThomas Gleixner { 882ec1df41SThomas Gleixner int i; 892ec1df41SThomas Gleixner mtrr_type ltype; 902ec1df41SThomas Gleixner unsigned long lbase, lsize; 912ec1df41SThomas Gleixner 922ec1df41SThomas Gleixner switch (replace_reg) { 932ec1df41SThomas Gleixner case 7: 942ec1df41SThomas Gleixner if (size < 0x40) 952ec1df41SThomas Gleixner break; 962ec1df41SThomas Gleixner case 6: 972ec1df41SThomas Gleixner case 5: 982ec1df41SThomas Gleixner case 4: 992ec1df41SThomas Gleixner return replace_reg; 1002ec1df41SThomas Gleixner case 3: 1012ec1df41SThomas Gleixner if (arr3_protected) 1022ec1df41SThomas Gleixner break; 1032ec1df41SThomas Gleixner case 2: 1042ec1df41SThomas Gleixner case 1: 1052ec1df41SThomas Gleixner case 0: 1062ec1df41SThomas Gleixner return replace_reg; 1072ec1df41SThomas Gleixner } 1082ec1df41SThomas Gleixner /* If we are to set up a region >32M then look at ARR7 immediately */ 1092ec1df41SThomas Gleixner if (size > 0x2000) { 1102ec1df41SThomas Gleixner cyrix_get_arr(7, &lbase, &lsize, <ype); 1112ec1df41SThomas Gleixner if (lsize == 0) 1122ec1df41SThomas Gleixner return 7; 1132ec1df41SThomas Gleixner /* Else try ARR0-ARR6 first */ 1142ec1df41SThomas Gleixner } else { 1152ec1df41SThomas Gleixner for (i = 0; i < 7; i++) { 1162ec1df41SThomas Gleixner cyrix_get_arr(i, &lbase, &lsize, <ype); 1172ec1df41SThomas Gleixner if ((i == 3) && arr3_protected) 1182ec1df41SThomas Gleixner continue; 1192ec1df41SThomas Gleixner if (lsize == 0) 1202ec1df41SThomas Gleixner return i; 1212ec1df41SThomas Gleixner } 1222ec1df41SThomas Gleixner /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */ 1232ec1df41SThomas Gleixner cyrix_get_arr(i, &lbase, &lsize, <ype); 1242ec1df41SThomas Gleixner if ((lsize == 0) && (size >= 0x40)) 1252ec1df41SThomas Gleixner return i; 1262ec1df41SThomas Gleixner } 1272ec1df41SThomas Gleixner return -ENOSPC; 1282ec1df41SThomas Gleixner } 1292ec1df41SThomas Gleixner 1302ec1df41SThomas Gleixner static u32 cr4 = 0; 1312ec1df41SThomas Gleixner static u32 ccr3; 1322ec1df41SThomas Gleixner 1332ec1df41SThomas Gleixner static void prepare_set(void) 1342ec1df41SThomas Gleixner { 1352ec1df41SThomas Gleixner u32 cr0; 1362ec1df41SThomas Gleixner 1372ec1df41SThomas Gleixner /* Save value of CR4 and clear Page Global Enable (bit 7) */ 1382ec1df41SThomas Gleixner if ( cpu_has_pge ) { 1392ec1df41SThomas Gleixner cr4 = read_cr4(); 1402ec1df41SThomas Gleixner write_cr4(cr4 & ~X86_CR4_PGE); 1412ec1df41SThomas Gleixner } 1422ec1df41SThomas Gleixner 1432ec1df41SThomas Gleixner /* Disable and flush caches. Note that wbinvd flushes the TLBs as 1442ec1df41SThomas Gleixner a side-effect */ 1452ec1df41SThomas Gleixner cr0 = read_cr0() | 0x40000000; 1462ec1df41SThomas Gleixner wbinvd(); 1472ec1df41SThomas Gleixner write_cr0(cr0); 1482ec1df41SThomas Gleixner wbinvd(); 1492ec1df41SThomas Gleixner 150*27b46d76SSimon Arlott /* Cyrix ARRs - everything else was excluded at the top */ 1512ec1df41SThomas Gleixner ccr3 = getCx86(CX86_CCR3); 1522ec1df41SThomas Gleixner 153*27b46d76SSimon Arlott /* Cyrix ARRs - everything else was excluded at the top */ 1542ec1df41SThomas Gleixner setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); 1552ec1df41SThomas Gleixner 1562ec1df41SThomas Gleixner } 1572ec1df41SThomas Gleixner 1582ec1df41SThomas Gleixner static void post_set(void) 1592ec1df41SThomas Gleixner { 1602ec1df41SThomas Gleixner /* Flush caches and TLBs */ 1612ec1df41SThomas Gleixner wbinvd(); 1622ec1df41SThomas Gleixner 1632ec1df41SThomas Gleixner /* Cyrix ARRs - everything else was excluded at the top */ 1642ec1df41SThomas Gleixner setCx86(CX86_CCR3, ccr3); 1652ec1df41SThomas Gleixner 1662ec1df41SThomas Gleixner /* Enable caches */ 1672ec1df41SThomas Gleixner write_cr0(read_cr0() & 0xbfffffff); 1682ec1df41SThomas Gleixner 1692ec1df41SThomas Gleixner /* Restore value of CR4 */ 1702ec1df41SThomas Gleixner if ( cpu_has_pge ) 1712ec1df41SThomas Gleixner write_cr4(cr4); 1722ec1df41SThomas Gleixner } 1732ec1df41SThomas Gleixner 1742ec1df41SThomas Gleixner static void cyrix_set_arr(unsigned int reg, unsigned long base, 1752ec1df41SThomas Gleixner unsigned long size, mtrr_type type) 1762ec1df41SThomas Gleixner { 1772ec1df41SThomas Gleixner unsigned char arr, arr_type, arr_size; 1782ec1df41SThomas Gleixner 1792ec1df41SThomas Gleixner arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */ 1802ec1df41SThomas Gleixner 1812ec1df41SThomas Gleixner /* count down from 32M (ARR0-ARR6) or from 2G (ARR7) */ 1822ec1df41SThomas Gleixner if (reg >= 7) 1832ec1df41SThomas Gleixner size >>= 6; 1842ec1df41SThomas Gleixner 1852ec1df41SThomas Gleixner size &= 0x7fff; /* make sure arr_size <= 14 */ 1862ec1df41SThomas Gleixner for (arr_size = 0; size; arr_size++, size >>= 1) ; 1872ec1df41SThomas Gleixner 1882ec1df41SThomas Gleixner if (reg < 7) { 1892ec1df41SThomas Gleixner switch (type) { 1902ec1df41SThomas Gleixner case MTRR_TYPE_UNCACHABLE: 1912ec1df41SThomas Gleixner arr_type = 1; 1922ec1df41SThomas Gleixner break; 1932ec1df41SThomas Gleixner case MTRR_TYPE_WRCOMB: 1942ec1df41SThomas Gleixner arr_type = 9; 1952ec1df41SThomas Gleixner break; 1962ec1df41SThomas Gleixner case MTRR_TYPE_WRTHROUGH: 1972ec1df41SThomas Gleixner arr_type = 24; 1982ec1df41SThomas Gleixner break; 1992ec1df41SThomas Gleixner default: 2002ec1df41SThomas Gleixner arr_type = 8; 2012ec1df41SThomas Gleixner break; 2022ec1df41SThomas Gleixner } 2032ec1df41SThomas Gleixner } else { 2042ec1df41SThomas Gleixner switch (type) { 2052ec1df41SThomas Gleixner case MTRR_TYPE_UNCACHABLE: 2062ec1df41SThomas Gleixner arr_type = 0; 2072ec1df41SThomas Gleixner break; 2082ec1df41SThomas Gleixner case MTRR_TYPE_WRCOMB: 2092ec1df41SThomas Gleixner arr_type = 8; 2102ec1df41SThomas Gleixner break; 2112ec1df41SThomas Gleixner case MTRR_TYPE_WRTHROUGH: 2122ec1df41SThomas Gleixner arr_type = 25; 2132ec1df41SThomas Gleixner break; 2142ec1df41SThomas Gleixner default: 2152ec1df41SThomas Gleixner arr_type = 9; 2162ec1df41SThomas Gleixner break; 2172ec1df41SThomas Gleixner } 2182ec1df41SThomas Gleixner } 2192ec1df41SThomas Gleixner 2202ec1df41SThomas Gleixner prepare_set(); 2212ec1df41SThomas Gleixner 2222ec1df41SThomas Gleixner base <<= PAGE_SHIFT; 2232ec1df41SThomas Gleixner setCx86(arr, ((unsigned char *) &base)[3]); 2242ec1df41SThomas Gleixner setCx86(arr + 1, ((unsigned char *) &base)[2]); 2252ec1df41SThomas Gleixner setCx86(arr + 2, (((unsigned char *) &base)[1]) | arr_size); 2262ec1df41SThomas Gleixner setCx86(CX86_RCR_BASE + reg, arr_type); 2272ec1df41SThomas Gleixner 2282ec1df41SThomas Gleixner post_set(); 2292ec1df41SThomas Gleixner } 2302ec1df41SThomas Gleixner 2312ec1df41SThomas Gleixner typedef struct { 2322ec1df41SThomas Gleixner unsigned long base; 2332ec1df41SThomas Gleixner unsigned long size; 2342ec1df41SThomas Gleixner mtrr_type type; 2352ec1df41SThomas Gleixner } arr_state_t; 2362ec1df41SThomas Gleixner 2372ec1df41SThomas Gleixner static arr_state_t arr_state[8] = { 2382ec1df41SThomas Gleixner {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, 2392ec1df41SThomas Gleixner {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} 2402ec1df41SThomas Gleixner }; 2412ec1df41SThomas Gleixner 2422ec1df41SThomas Gleixner static unsigned char ccr_state[7] = { 0, 0, 0, 0, 0, 0, 0 }; 2432ec1df41SThomas Gleixner 2442ec1df41SThomas Gleixner static void cyrix_set_all(void) 2452ec1df41SThomas Gleixner { 2462ec1df41SThomas Gleixner int i; 2472ec1df41SThomas Gleixner 2482ec1df41SThomas Gleixner prepare_set(); 2492ec1df41SThomas Gleixner 2502ec1df41SThomas Gleixner /* the CCRs are not contiguous */ 2512ec1df41SThomas Gleixner for (i = 0; i < 4; i++) 2522ec1df41SThomas Gleixner setCx86(CX86_CCR0 + i, ccr_state[i]); 2532ec1df41SThomas Gleixner for (; i < 7; i++) 2542ec1df41SThomas Gleixner setCx86(CX86_CCR4 + i, ccr_state[i]); 2552ec1df41SThomas Gleixner for (i = 0; i < 8; i++) 2562ec1df41SThomas Gleixner cyrix_set_arr(i, arr_state[i].base, 2572ec1df41SThomas Gleixner arr_state[i].size, arr_state[i].type); 2582ec1df41SThomas Gleixner 2592ec1df41SThomas Gleixner post_set(); 2602ec1df41SThomas Gleixner } 2612ec1df41SThomas Gleixner 2622ec1df41SThomas Gleixner #if 0 2632ec1df41SThomas Gleixner /* 2642ec1df41SThomas Gleixner * On Cyrix 6x86(MX) and M II the ARR3 is special: it has connection 2652ec1df41SThomas Gleixner * with the SMM (System Management Mode) mode. So we need the following: 2662ec1df41SThomas Gleixner * Check whether SMI_LOCK (CCR3 bit 0) is set 2672ec1df41SThomas Gleixner * if it is set, write a warning message: ARR3 cannot be changed! 2682ec1df41SThomas Gleixner * (it cannot be changed until the next processor reset) 2692ec1df41SThomas Gleixner * if it is reset, then we can change it, set all the needed bits: 2702ec1df41SThomas Gleixner * - disable access to SMM memory through ARR3 range (CCR1 bit 7 reset) 2712ec1df41SThomas Gleixner * - disable access to SMM memory (CCR1 bit 2 reset) 2722ec1df41SThomas Gleixner * - disable SMM mode (CCR1 bit 1 reset) 2732ec1df41SThomas Gleixner * - disable write protection of ARR3 (CCR6 bit 1 reset) 2742ec1df41SThomas Gleixner * - (maybe) disable ARR3 2752ec1df41SThomas Gleixner * Just to be sure, we enable ARR usage by the processor (CCR5 bit 5 set) 2762ec1df41SThomas Gleixner */ 2772ec1df41SThomas Gleixner static void __init 2782ec1df41SThomas Gleixner cyrix_arr_init(void) 2792ec1df41SThomas Gleixner { 2802ec1df41SThomas Gleixner struct set_mtrr_context ctxt; 2812ec1df41SThomas Gleixner unsigned char ccr[7]; 2822ec1df41SThomas Gleixner int ccrc[7] = { 0, 0, 0, 0, 0, 0, 0 }; 2832ec1df41SThomas Gleixner #ifdef CONFIG_SMP 2842ec1df41SThomas Gleixner int i; 2852ec1df41SThomas Gleixner #endif 2862ec1df41SThomas Gleixner 2872ec1df41SThomas Gleixner /* flush cache and enable MAPEN */ 2882ec1df41SThomas Gleixner set_mtrr_prepare_save(&ctxt); 2892ec1df41SThomas Gleixner set_mtrr_cache_disable(&ctxt); 2902ec1df41SThomas Gleixner 2912ec1df41SThomas Gleixner /* Save all CCRs locally */ 2922ec1df41SThomas Gleixner ccr[0] = getCx86(CX86_CCR0); 2932ec1df41SThomas Gleixner ccr[1] = getCx86(CX86_CCR1); 2942ec1df41SThomas Gleixner ccr[2] = getCx86(CX86_CCR2); 2952ec1df41SThomas Gleixner ccr[3] = ctxt.ccr3; 2962ec1df41SThomas Gleixner ccr[4] = getCx86(CX86_CCR4); 2972ec1df41SThomas Gleixner ccr[5] = getCx86(CX86_CCR5); 2982ec1df41SThomas Gleixner ccr[6] = getCx86(CX86_CCR6); 2992ec1df41SThomas Gleixner 3002ec1df41SThomas Gleixner if (ccr[3] & 1) { 3012ec1df41SThomas Gleixner ccrc[3] = 1; 3022ec1df41SThomas Gleixner arr3_protected = 1; 3032ec1df41SThomas Gleixner } else { 3042ec1df41SThomas Gleixner /* Disable SMM mode (bit 1), access to SMM memory (bit 2) and 3052ec1df41SThomas Gleixner * access to SMM memory through ARR3 (bit 7). 3062ec1df41SThomas Gleixner */ 3072ec1df41SThomas Gleixner if (ccr[1] & 0x80) { 3082ec1df41SThomas Gleixner ccr[1] &= 0x7f; 3092ec1df41SThomas Gleixner ccrc[1] |= 0x80; 3102ec1df41SThomas Gleixner } 3112ec1df41SThomas Gleixner if (ccr[1] & 0x04) { 3122ec1df41SThomas Gleixner ccr[1] &= 0xfb; 3132ec1df41SThomas Gleixner ccrc[1] |= 0x04; 3142ec1df41SThomas Gleixner } 3152ec1df41SThomas Gleixner if (ccr[1] & 0x02) { 3162ec1df41SThomas Gleixner ccr[1] &= 0xfd; 3172ec1df41SThomas Gleixner ccrc[1] |= 0x02; 3182ec1df41SThomas Gleixner } 3192ec1df41SThomas Gleixner arr3_protected = 0; 3202ec1df41SThomas Gleixner if (ccr[6] & 0x02) { 3212ec1df41SThomas Gleixner ccr[6] &= 0xfd; 3222ec1df41SThomas Gleixner ccrc[6] = 1; /* Disable write protection of ARR3 */ 3232ec1df41SThomas Gleixner setCx86(CX86_CCR6, ccr[6]); 3242ec1df41SThomas Gleixner } 3252ec1df41SThomas Gleixner /* Disable ARR3. This is safe now that we disabled SMM. */ 3262ec1df41SThomas Gleixner /* cyrix_set_arr_up (3, 0, 0, 0, FALSE); */ 3272ec1df41SThomas Gleixner } 3282ec1df41SThomas Gleixner /* If we changed CCR1 in memory, change it in the processor, too. */ 3292ec1df41SThomas Gleixner if (ccrc[1]) 3302ec1df41SThomas Gleixner setCx86(CX86_CCR1, ccr[1]); 3312ec1df41SThomas Gleixner 3322ec1df41SThomas Gleixner /* Enable ARR usage by the processor */ 3332ec1df41SThomas Gleixner if (!(ccr[5] & 0x20)) { 3342ec1df41SThomas Gleixner ccr[5] |= 0x20; 3352ec1df41SThomas Gleixner ccrc[5] = 1; 3362ec1df41SThomas Gleixner setCx86(CX86_CCR5, ccr[5]); 3372ec1df41SThomas Gleixner } 3382ec1df41SThomas Gleixner #ifdef CONFIG_SMP 3392ec1df41SThomas Gleixner for (i = 0; i < 7; i++) 3402ec1df41SThomas Gleixner ccr_state[i] = ccr[i]; 3412ec1df41SThomas Gleixner for (i = 0; i < 8; i++) 3422ec1df41SThomas Gleixner cyrix_get_arr(i, 3432ec1df41SThomas Gleixner &arr_state[i].base, &arr_state[i].size, 3442ec1df41SThomas Gleixner &arr_state[i].type); 3452ec1df41SThomas Gleixner #endif 3462ec1df41SThomas Gleixner 3472ec1df41SThomas Gleixner set_mtrr_done(&ctxt); /* flush cache and disable MAPEN */ 3482ec1df41SThomas Gleixner 3492ec1df41SThomas Gleixner if (ccrc[5]) 3502ec1df41SThomas Gleixner printk(KERN_INFO "mtrr: ARR usage was not enabled, enabled manually\n"); 3512ec1df41SThomas Gleixner if (ccrc[3]) 3522ec1df41SThomas Gleixner printk(KERN_INFO "mtrr: ARR3 cannot be changed\n"); 3532ec1df41SThomas Gleixner /* 3542ec1df41SThomas Gleixner if ( ccrc[1] & 0x80) printk ("mtrr: SMM memory access through ARR3 disabled\n"); 3552ec1df41SThomas Gleixner if ( ccrc[1] & 0x04) printk ("mtrr: SMM memory access disabled\n"); 3562ec1df41SThomas Gleixner if ( ccrc[1] & 0x02) printk ("mtrr: SMM mode disabled\n"); 3572ec1df41SThomas Gleixner */ 3582ec1df41SThomas Gleixner if (ccrc[6]) 3592ec1df41SThomas Gleixner printk(KERN_INFO "mtrr: ARR3 was write protected, unprotected\n"); 3602ec1df41SThomas Gleixner } 3612ec1df41SThomas Gleixner #endif 3622ec1df41SThomas Gleixner 3632ec1df41SThomas Gleixner static struct mtrr_ops cyrix_mtrr_ops = { 3642ec1df41SThomas Gleixner .vendor = X86_VENDOR_CYRIX, 3652ec1df41SThomas Gleixner // .init = cyrix_arr_init, 3662ec1df41SThomas Gleixner .set_all = cyrix_set_all, 3672ec1df41SThomas Gleixner .set = cyrix_set_arr, 3682ec1df41SThomas Gleixner .get = cyrix_get_arr, 3692ec1df41SThomas Gleixner .get_free_region = cyrix_get_free_region, 3702ec1df41SThomas Gleixner .validate_add_page = generic_validate_add_page, 3712ec1df41SThomas Gleixner .have_wrcomb = positive_have_wrcomb, 3722ec1df41SThomas Gleixner }; 3732ec1df41SThomas Gleixner 3742ec1df41SThomas Gleixner int __init cyrix_init_mtrr(void) 3752ec1df41SThomas Gleixner { 3762ec1df41SThomas Gleixner set_mtrr_ops(&cyrix_mtrr_ops); 3772ec1df41SThomas Gleixner return 0; 3782ec1df41SThomas Gleixner } 3792ec1df41SThomas Gleixner 3802ec1df41SThomas Gleixner //arch_initcall(cyrix_init_mtrr); 381