FreeBSD/sys/i386/i386/i686_mem.c
/*
 * Update the current CPU's MTRRs with those represented in the
 * descriptor list.  Note that we do this wholesale rather than just
 * stuffing one entry; this is simpler (but slower, of course).
 */
Update the current CPU's MTRRs with those represented in the
descriptor list.  Note that we do this wholesale rather than just
stuffing one entry; this is simpler (but slower, of course).
Update the current CPU ' s MTRRs with those represented in the descriptor list . Note that we do this wholesale rather than just stuffing one entry ; this is simpler ( but slower of course ) .
static void
i686_mrstoreone(void *arg)
{
	struct mem_range_softc *sc = arg;
	struct mem_range_desc *mrd;
	u_int64_t omsrv, msrv;
	int i, j, msr;
	u_long cr0, cr4;
	mrd = sc->mr_desc;
	critical_enter();
	cr4 = rcr4();
	load_cr4(cr4 & ~CR4_PGE);
	cr0 = rcr0();
	load_cr0((cr0 & ~CR0_NW) | CR0_CD);
	wbinvd();
	invltlb();
	wrmsr(MSR_MTRRdefType, rdmsr(MSR_MTRRdefType) & ~MTRR_DEF_ENABLE);
	if (sc->mr_cap & MR686_FIXMTRR) {
		msr = MSR_MTRR64kBase;
		for (i = 0; i < (MTRR_N64K / 8); i++, msr++) {
			msrv = 0;
			omsrv = rdmsr(msr);
			for (j = 7; j >= 0; j--) {
				msrv = msrv << 8;
				msrv |= i686_mrt2mtrr((mrd + j)->mr_flags,
				    omsrv >> (j * 8));
			}
			wrmsr(msr, msrv);
			mrd += 8;
		}
		msr = MSR_MTRR16kBase;
		for (i = 0; i < (MTRR_N16K / 8); i++, msr++) {
			msrv = 0;
			omsrv = rdmsr(msr);
			for (j = 7; j >= 0; j--) {
				msrv = msrv << 8;
				msrv |= i686_mrt2mtrr((mrd + j)->mr_flags,
				    omsrv >> (j * 8));
			}
			wrmsr(msr, msrv);
			mrd += 8;
		}
		msr = MSR_MTRR4kBase;
		for (i = 0; i < (MTRR_N4K / 8); i++, msr++) {
			msrv = 0;
			omsrv = rdmsr(msr);
			for (j = 7; j >= 0; j--) {
				msrv = msrv << 8;
				msrv |= i686_mrt2mtrr((mrd + j)->mr_flags,
				    omsrv >> (j * 8));
			}
			wrmsr(msr, msrv);
			mrd += 8;
		}
	}
	msr = MSR_MTRRVarBase;
	for (; (mrd - sc->mr_desc) < sc->mr_ndesc; msr += 2, mrd++) {
		omsrv = rdmsr(msr);
		if (mrd->mr_flags & MDF_ACTIVE) {
			msrv = mrd->mr_base & mtrr_physmask;
			msrv |= i686_mrt2mtrr(mrd->mr_flags, omsrv);
		} else {
			msrv = 0;
		}
		wrmsr(msr, msrv);
		if (mrd->mr_flags & MDF_ACTIVE) {
			msrv = MTRR_PHYSMASK_VALID |
			    rounddown2(mtrr_physmask, mrd->mr_len);
		} else {
			msrv = 0;
		}
		wrmsr(msr + 1, msrv);
	}
	wbinvd();
	invltlb();
	wrmsr(MSR_MTRRdefType, rdmsr(MSR_MTRRdefType) | MTRR_DEF_ENABLE);
	load_cr0(cr0);
	load_cr4(cr4);
	critical_exit();
}
static void i686_mrstoreone ( void * arg ) { struct mem_range_softc * sc = arg ; struct mem_range_desc * mrd ; u_int64_t omsrv , msrv ; int i , j , msr ; u_long cr0 , cr4 ; mrd = sc -> mr_desc ; critical_enter ( ) ; cr4 = rcr4 ( ) ; load_cr4 ( cr4 & ~ CR4_PGE ) ; cr0 = rcr0 ( ) ; load_cr0 ( ( cr0 & ~ CR0_NW ) | CR0_CD ) ; wbinvd ( ) ; invltlb ( ) ; wrmsr ( MSR_MTRRdefType , rdmsr ( MSR_MTRRdefType ) & ~ MTRR_DEF_ENABLE ) ; if ( sc -> mr_cap & MR686_FIXMTRR ) { msr = MSR_MTRR64kBase ; for ( i = 0 ; i < ( MTRR_N64K / 8 ) ; i ++ , msr ++ ) { msrv = 0 ; omsrv = rdmsr ( msr ) ; for ( j = 7 ; j >= 0 ; j -- ) { msrv = msrv << 8 ; msrv |= i686_mrt2mtrr ( ( mrd + j ) -> mr_flags , omsrv >> ( j * 8 ) ) ; } wrmsr ( msr , msrv ) ; mrd += 8 ; } msr = MSR_MTRR16kBase ; for ( i = 0 ; i < ( MTRR_N16K / 8 ) ; i ++ , msr ++ ) { msrv = 0 ; omsrv = rdmsr ( msr ) ; for ( j = 7 ; j >= 0 ; j -- ) { msrv = msrv << 8 ; msrv |= i686_mrt2mtrr ( ( mrd + j ) -> mr_flags , omsrv >> ( j * 8 ) ) ; } wrmsr ( msr , msrv ) ; mrd += 8 ; } msr = MSR_MTRR4kBase ; for ( i = 0 ; i < ( MTRR_N4K / 8 ) ; i ++ , msr ++ ) { msrv = 0 ; omsrv = rdmsr ( msr ) ; for ( j = 7 ; j >= 0 ; j -- ) { msrv = msrv << 8 ; msrv |= i686_mrt2mtrr ( ( mrd + j ) -> mr_flags , omsrv >> ( j * 8 ) ) ; } wrmsr ( msr , msrv ) ; mrd += 8 ; } } msr = MSR_MTRRVarBase ; for ( ; ( mrd - sc -> mr_desc ) < sc -> mr_ndesc ; msr += 2 , mrd ++ ) { omsrv = rdmsr ( msr ) ; if ( mrd -> mr_flags & MDF_ACTIVE ) { msrv = mrd -> mr_base & mtrr_physmask ; msrv |= i686_mrt2mtrr ( mrd -> mr_flags , omsrv ) ; } else { msrv = 0 ; } wrmsr ( msr , msrv ) ; if ( mrd -> mr_flags & MDF_ACTIVE ) { msrv = MTRR_PHYSMASK_VALID | rounddown2 ( mtrr_physmask , mrd -> mr_len ) ; } else { msrv = 0 ; } wrmsr ( msr + 1 , msrv ) ; } wbinvd ( ) ; invltlb ( ) ; wrmsr ( MSR_MTRRdefType , rdmsr ( MSR_MTRRdefType ) | MTRR_DEF_ENABLE ) ; load_cr0 ( cr0 ) ; load_cr4 ( cr4 ) ; critical_exit ( ) ; }
Update the current CPU's MTRRs with those represented in the
 descriptor list.
Update the current CPU ' s MTRRs with those represented in the descriptor list .
/* Disable PGE. */ /* Disable caches (CD = 1, NW = 0). */ /* Flushes caches and TLBs. */ /* Disable MTRRs (E = 0). */ /* Set fixed-range MTRRs. */ /* Set remainder which must be variable MTRRs. */ /* base/type register */ /* mask/active register */ /* Flush caches and TLBs. */ /* Enable MTRRs. */ /* Restore caches and PGE. */