/* Put the processor into a state where MTRRs can be safely set */ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt) { unsigned int cr0; /* Disable interrupts locally */ local_irq_save(ctxt->flags); if (use_intel() || is_cpu(CYRIX)) { /* Save value of CR4 and clear Page Global Enable (bit 7) */ if ( cpu_has_pge ) { ctxt->cr4val = read_cr4(); write_cr4(ctxt->cr4val & ~X86_CR4_PGE); } /* Disable and flush caches. Note that wbinvd flushes the TLBs as a side-effect */ cr0 = read_cr0() | 0x40000000; wbinvd(); write_cr0(cr0); wbinvd(); if (use_intel()) /* Save MTRR state */ rdmsr(MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi); else /* Cyrix ARRs - everything else were excluded at the top */ ctxt->ccr3 = getCx86(CX86_CCR3); } }
static const char * Cx86model(void) /* We know our CPU is a Cyrix now (see bugs.h), so we can use the DIR0/DIR1 * mechanism to figure out the model, bus clock multiplier and stepping. * For the newest CPUs (GXm and MXi) we use the Extended CPUID function. */ { unsigned char nr6x86 = 0; unsigned char cx_dir0 = 0; /* Model and bus clock multiplier */ unsigned char cx_dir1 = 0; /* Stepping info */ unsigned int flags; static const char *model[] = { "unknown", "Cx486", "5x86", "MediaGX", "6x86", "6x86L", "6x86MX", "M II" }; if (x86_model == -1) { /* is this an old Cx486 without DIR0/DIR1? */ nr6x86 = 1; /* Cx486 */ Cx86_mult = 0; /* unknown multiplier */ } else { /* Get DIR0, DIR1 since all other Cyrix CPUs have them */ save_flags(flags); cli(); cx_dir0 = getCx86(CX86_DIR0); /* we use the access macros */ cx_dir1 = getCx86(CX86_DIR1); /* defined in processor.h */ restore_flags(flags); /* Now cook; the recipe is by Channing Corn, from Cyrix. * We do the same thing for each generation: we work out * the model, multiplier and stepping. */ if (cx_dir0 < 0x20) { nr6x86 = 1; /* Cx486 */ Cx86_mult = 0; /* unknown multiplier */ sprintf(Cx86_step, "%d.%d", (cx_dir1 >> 4) + 1, cx_dir1 & 0x0f); } if ((cx_dir0 > 0x20) && (cx_dir0 < 0x30)) { nr6x86 = 2; /* 5x86 */ Cx86_mult = ((cx_dir0 & 0x04) ? 5 : 3); /* either 3x or 2x */ sprintf(Cx86_step, "%d.%d", (cx_dir1 >> 4) + 1, cx_dir1 & 0x0f); }