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