📄 pentiumlib.c
字号:
{MSR_IQ_COUNTER5, "IQ_COUNTER5"}, {MSR_BPU_CCCR0, "BPU_CCCR0"}, {MSR_BPU_CCCR1, "BPU_CCCR1"}, {MSR_BPU_CCCR2, "BPU_CCCR2"}, {MSR_BPU_CCCR3, "BPU_CCCR3"}, {MSR_MS_CCCR0, "MS_CCCR0"}, {MSR_MS_CCCR1, "MS_CCCR1"}, {MSR_MS_CCCR2, "MS_CCCR2"}, {MSR_MS_CCCR3, "MS_CCCR3"}, {MSR_FLAME_CCCR0, "FLAME_CCCR0"}, {MSR_FLAME_CCCR1, "FLAME_CCCR1"}, {MSR_FLAME_CCCR2, "FLAME_CCCR2"}, {MSR_FLAME_CCCR3, "FLAME_CCCR3"}, {MSR_IQ_CCCR0, "IQ_CCCR0"}, {MSR_IQ_CCCR1, "IQ_CCCR1"}, {MSR_IQ_CCCR2, "IQ_CCCR2"}, {MSR_IQ_CCCR3, "IQ_CCCR3"}, {MSR_IQ_CCCR4, "IQ_CCCR4"}, {MSR_IQ_CCCR5, "IQ_CCCR5"}, {MSR_BSU_ESCR0, "BSU_ESCR0"}, {MSR_BSU_ESCR1, "BSU_ESCR1"}, {MSR_FSB_ESCR0, "FSB_ESCR0"}, {MSR_FSB_ESCR1, "FSB_ESCR1"}, {MSR_FIRM_ESCR0, "FIRM_ESCR0"}, {MSR_FIRM_ESCR1, "FIRM_ESCR1"}, {MSR_FLAME_ESCR0, "FLAME_ESCR0"}, {MSR_FLAME_ESCR1, "FLAME_ESCR1"}, {MSR_DAC_ESCR0, "DAC_ESCR0"}, {MSR_DAC_ESCR1, "DAC_ESCR1"}, {MSR_MOB_ESCR0, "MOB_ESCR0"}, {MSR_MOB_ESCR1, "MOB_ESCR1"}, {MSR_PMH_ESCR0, "PMH_ESCR0"}, {MSR_PMH_ESCR1, "PMH_ESCR1"}, {MSR_SAAT_ESCR0, "SAAT_ESCR0"}, {MSR_SAAT_ESCR1, "SAAT_ESCR1"}, {MSR_U2L_ESCR0, "U2L_ESCR0"}, {MSR_U2L_ESCR1, "U2L_ESCR1"}, {MSR_BPU_ESCR0, "BPU_ESCR0"}, {MSR_BPU_ESCR1, "BPU_ESCR1"}, {MSR_IS_ESCR0, "IS_ESCR0"}, {MSR_IS_ESCR1, "IS_ESCR1"}, {MSR_ITLB_ESCR0, "ITLB_ESCR0"}, {MSR_ITLB_ESCR1, "ITLB_ESCR1"}, {MSR_CRU_ESCR0, "CRU_ESCR0"}, {MSR_CRU_ESCR1, "CRU_ESCR1"}, {MSR_IQ_ESCR0, "IQ_ESCR0"}, {MSR_IQ_ESCR1, "IQ_ESCR1"}, {MSR_RAT_ESCR0, "RAT_ESCR0"}, {MSR_RAT_ESCR1, "RAT_ESCR1"}, {MSR_SSU_ESCR0, "SSU_ESCR0"}, {MSR_MS_ESCR0, "MS_ESCR0"}, {MSR_MS_ESCR1, "MS_ESCR1"}, {MSR_TBPU_ESCR0, "TBPU_ESCR0"}, {MSR_TBPU_ESCR1, "TBPU_ESCR1"}, {MSR_TC_ESCR0, "TC_ESCR0"}, {MSR_TC_ESCR1, "TC_ESCR1"}, {MSR_IX_ESCR0, "IX_ESCR0"}, {MSR_IX_ESCR1, "IX_ESCR1"}, {MSR_ALF_ESCR0, "ALF_ESCR0"}, {MSR_ALF_ESCR1, "ALF_ESCR1"}, {MSR_CRU_ESCR2, "CRU_ESCR2"}, {MSR_CRU_ESCR3, "CRU_ESCR3"}, {MSR_CRU_ESCR4, "CRU_ESCR4"}, {MSR_CRU_ESCR5, "CRU_ESCR5"}, {MSR_TC_PRECISE_EVENT, "TC_PRECISE_EVENT"}, {IA32_PEBS_ENABLE, "IA32_PEBS_ENABLE"}, {MSR_PEBS_MATRIX_VERT, "PEBS_MATRIX_VERT"}, /* use pentiumMcaEnable() or pentiumMcaShow() {IA32_MC0_CTL, "IA32_MC0_CTL"}, {IA32_MC0_STATUS, "IA32_MC0_STATUS"}, {IA32_MC0_ADDR, "IA32_MC0_ADDR"}, {IA32_MC0_MISC, "IA32_MC0_MISC"}, {IA32_MC1_CTL, "IA32_MC1_CTL"}, {IA32_MC1_STATUS, "IA32_MC1_STATUS"}, {IA32_MC1_ADDR, "IA32_MC1_ADDR"}, {IA32_MC1_MISC, "IA32_MC1_MISC"}, {IA32_MC2_CTL, "IA32_MC2_CTL"}, {IA32_MC2_STATUS, "IA32_MC2_STATUS"}, {IA32_MC2_ADDR, "IA32_MC2_ADDR"}, {IA32_MC2_MISC, "IA32_MC2_MISC"}, {IA32_MC3_CTL, "IA32_MC3_CTL"}, {IA32_MC3_STATUS, "IA32_MC3_STATUS"}, {IA32_MC3_ADDR, "IA32_MC3_ADDR"}, {IA32_MC3_MISC, "IA32_MC3_MISC"}, */ {IA32_DS_AREA, "IA32_DS_AREA"}, };INT32 pentiumMsrP7NumEnt = NELEMENTS (pentiumMsrP7);/* locals */LOCAL char mtrrBusy = FALSE; /* MTRR busy flag *//********************************************************************************* pentiumMtrrEnable - enable MTRR (Memory Type Range Register)** This routine enables the MTRR that provide a mechanism for associating the* memory types with physical address ranges in system memory.** RETURNS: N/A*/void pentiumMtrrEnable (void) { int oldLevel; int deftype[2]; int oldCr4; oldLevel = intLock (); /* LOCK INTERRUPT */ cacheFlush (DATA_CACHE, NULL, 0); /* flush cache w WBINVD */ oldCr4 = pentiumCr4Get (); /* save CR4 */ pentiumCr4Set (oldCr4 & ~CR4_PGE); /* clear PGE bit */ pentiumTlbFlush (); /* flush TLB */ pentiumMsrGet (MSR_MTRR_DEFTYPE, (LL_INT *)&deftype); deftype[0] |= (MTRR_E | MTRR_FE); /* set enable bits */ pentiumMsrSet (MSR_MTRR_DEFTYPE, (LL_INT *)&deftype); cacheFlush (DATA_CACHE, NULL, 0); /* flush cache w WBINVD */ pentiumTlbFlush (); /* flush TLB */ pentiumCr4Set (oldCr4); /* restore CR4 */ intUnlock (oldLevel); /* UNLOCK INTERRUPT */ }/********************************************************************************* pentiumMtrrDisable - disable MTRR (Memory Type Range Register)** This routine disables the MTRR that provide a mechanism for associating the* memory types with physical address ranges in system memory.** RETURNS: N/A*/void pentiumMtrrDisable (void) { int oldLevel; int deftype[2]; int oldCr4; oldLevel = intLock (); /* LOCK INTERRUPT */ cacheFlush (DATA_CACHE, NULL, 0); /* flush cache w WBINVD */ oldCr4 = pentiumCr4Get (); /* save CR4 */ pentiumCr4Set (oldCr4 & ~CR4_PGE); /* clear PGE bit */ pentiumTlbFlush (); /* flush TLB */ pentiumMsrGet (MSR_MTRR_DEFTYPE, (LL_INT *)&deftype); deftype[0] &= ~(MTRR_E | MTRR_FE); /* clear enable bits */ pentiumMsrSet (MSR_MTRR_DEFTYPE, (LL_INT *)&deftype); cacheFlush (DATA_CACHE, NULL, 0); /* flush cache w WBINVD */ pentiumTlbFlush (); /* flush TLB */ pentiumCr4Set (oldCr4); /* restore CR4 */ intUnlock (oldLevel); /* UNLOCK INTERRUPT */ }/********************************************************************************* pentiumMtrrGet - get MTRRs to a specified MTRR table** This routine gets MTRRs to a specified MTRR table with RDMSR instruction.* The read MTRRs are CAP register, DEFTYPE register, fixed range MTRRs, and* variable range MTRRs.** RETURNS: OK, or ERROR if MTRR is being accessed.*/STATUS pentiumMtrrGet ( MTRR * pMtrr /* MTRR table */ ) { int ix; int addr = MSR_MTRR_PHYS_BASE0; /* mutual exclusion ON */ if (pentiumBts (&mtrrBusy) != OK) return (ERROR); pentiumMsrGet (MSR_MTRR_CAP, (LL_INT *)&pMtrr->cap); pentiumMsrGet (MSR_MTRR_DEFTYPE, (LL_INT *)&pMtrr->deftype); if (pMtrr->cap[0] & MTRR_FIX_SUPPORT) { pentiumMsrGet (MSR_MTRR_FIX_00000, (LL_INT *)&pMtrr->fix[0].type); pentiumMsrGet (MSR_MTRR_FIX_80000, (LL_INT *)&pMtrr->fix[1].type); pentiumMsrGet (MSR_MTRR_FIX_A0000, (LL_INT *)&pMtrr->fix[2].type); pentiumMsrGet (MSR_MTRR_FIX_C0000, (LL_INT *)&pMtrr->fix[3].type); pentiumMsrGet (MSR_MTRR_FIX_C8000, (LL_INT *)&pMtrr->fix[4].type); pentiumMsrGet (MSR_MTRR_FIX_D0000, (LL_INT *)&pMtrr->fix[5].type); pentiumMsrGet (MSR_MTRR_FIX_D8000, (LL_INT *)&pMtrr->fix[6].type); pentiumMsrGet (MSR_MTRR_FIX_E0000, (LL_INT *)&pMtrr->fix[7].type); pentiumMsrGet (MSR_MTRR_FIX_E8000, (LL_INT *)&pMtrr->fix[8].type); pentiumMsrGet (MSR_MTRR_FIX_F0000, (LL_INT *)&pMtrr->fix[9].type); pentiumMsrGet (MSR_MTRR_FIX_F8000, (LL_INT *)&pMtrr->fix[10].type); } for (ix = 0; ix < (pMtrr->cap[0] & MTRR_VCNT); ix++) { pentiumMsrGet (addr++, &pMtrr->var[ix].base); pentiumMsrGet (addr++, &pMtrr->var[ix].mask); } /* mutual exclusion OFF */ (void) pentiumBtc (&mtrrBusy); return (OK); }/********************************************************************************* pentiumMtrrSet - set MTRRs from specified MTRR table with WRMSR instruction.** This routine sets MTRRs from specified MTRR table with WRMSR instruction.* The written MTRRs are DEFTYPE register, fixed range MTRRs, and variable* range MTRRs.** RETURNS: OK, or ERROR if MTRR is enabled or being accessed.*/STATUS pentiumMtrrSet ( MTRR * pMtrr /* MTRR table */ ) { int ix; int addr = MSR_MTRR_PHYS_BASE0; /* MTRR should be disabled */ pentiumMsrGet (MSR_MTRR_DEFTYPE, (LL_INT *)&pMtrr->deftype); if ((pMtrr->deftype[0] & (MTRR_E | MTRR_FE)) != 0) return (ERROR); /* mutual exclusion ON */ if (pentiumBts (&mtrrBusy) != OK) return (ERROR); pentiumMsrSet (MSR_MTRR_DEFTYPE, (LL_INT *)&pMtrr->deftype); pentiumMsrGet (MSR_MTRR_CAP, (LL_INT *)&pMtrr->cap); if (pMtrr->cap[0] & MTRR_FIX_SUPPORT) { pentiumMsrSet (MSR_MTRR_FIX_00000, (LL_INT *)&pMtrr->fix[0].type); pentiumMsrSet (MSR_MTRR_FIX_80000, (LL_INT *)&pMtrr->fix[1].type); pentiumMsrSet (MSR_MTRR_FIX_A0000, (LL_INT *)&pMtrr->fix[2].type); pentiumMsrSet (MSR_MTRR_FIX_C0000, (LL_INT *)&pMtrr->fix[3].type); pentiumMsrSet (MSR_MTRR_FIX_C8000, (LL_INT *)&pMtrr->fix[4].type); pentiumMsrSet (MSR_MTRR_FIX_D0000, (LL_INT *)&pMtrr->fix[5].type); pentiumMsrSet (MSR_MTRR_FIX_D8000, (LL_INT *)&pMtrr->fix[6].type); pentiumMsrSet (MSR_MTRR_FIX_E0000, (LL_INT *)&pMtrr->fix[7].type); pentiumMsrSet (MSR_MTRR_FIX_E8000, (LL_INT *)&pMtrr->fix[8].type); pentiumMsrSet (MSR_MTRR_FIX_F0000, (LL_INT *)&pMtrr->fix[9].type); pentiumMsrSet (MSR_MTRR_FIX_F8000, (LL_INT *)&pMtrr->fix[10].type); } for (ix = 0; ix < (pMtrr->cap[0] & MTRR_VCNT); ix++) { pentiumMsrSet (addr++, &pMtrr->var[ix].base); pentiumMsrSet (addr++, &pMtrr->var[ix].mask); } /* mutual exclusion OFF */ (void) pentiumBtc (&mtrrBusy); return (OK); }/********************************************************************************* pentiumPmcStart - start both PMC0 and PMC1** SYNOPSIS* \ss* STATUS pentiumPmcStart (pmcEvtSel0, pmcEvtSel1)* int pmcEvtSel0; /@ Performance Event Select Register 0 @/* int pmcEvtSel1; /@ Performance Event Select Register 1 @/* \se* * This routine starts both PMC0 (Performance Monitoring Counter 0) and PMC1* by writing specified events to Performance Event Select Registers. * The first parameter is a content of Performance Event Select Register 0,* and the second parameter is for the Performance Event Select Register 1.** RETURNS: OK or ERROR if PMC is already started.*/STATUS pentiumPmcStart ( int pmcEvtSel0, int pmcEvtSel1 ) { STATUS retVal; retVal = ERROR; if (sysCpuId.featuresEdx & CPUID_MSR) { if (sysProcessor == X86CPU_PENTIUM) { if(pentiumP5PmcStart0(pmcEvtSel0) == OK && pentiumP5PmcStart1(pmcEvtSel1) == OK) retVal = OK; } else if (sysProcessor == X86CPU_PENTIUMPRO) retVal = pentiumP6PmcStart(pmcEvtSel0, pmcEvtSel1); } return (retVal); } /********************************************************************************* pentiumPmcStart0 - start PMC0** SYNOPSIS* \ss* STATUS pentiumPmcStart0 (pmcEvtSel0)* int pmcEvtSel0; /@ PMC0 control and event select @/* \se** This routine starts PMC0 (Performance Monitoring Counter 0) * by writing specified PMC0 events to Performance Event Select Registers. * The only parameter is the content of Performance Event Select Register.** RETURNS: OK or ERROR if PMC is already started.*/STATUS pentiumPmcStart0 ( int pmcEvtSel0 ) { if ((sysCpuId.featuresEdx & CPUID_MSR) && (sysProcessor == X86CPU_PENTIUM)) return (pentiumP5PmcStart0(pmcEvtSel0)); else return (ERROR); }/********************************************************************************* pentiumPmcStart1 - start PMC1** SYNOPSIS* \ss* STATUS pentiumPmcStart1 (pmcEvtSel1)* int pmcEvtSel1; /@ PMC1 control and event select @/* \se** This routine starts PMC1 (Performance Monitoring Counter 0) * by writing specified PMC1 events to Performance Event Select Registers. * The only parameter is the content of Performance Event Select Register.** RETURNS: OK or ERROR if PMC1 is already started.*/STATUS pentiumPmcStart1 ( int pmcEvtSel1 ) { if ((sysCpuId.featuresEdx & CPUID_MSR) && (sysProcessor == X86CPU_PENTIUM)) return (pentiumP5PmcStart1(pmcEvtSel1)); else return (ERROR); }/********************************************************************************* pentiumPmcStop - stop both PMC0 and PMC1** SYNOPSIS* \ss* void pentiumPmcStop (void)* \se** This routine stops both PMC0 (Performance Monitoring Counter 0)* and PMC1 by clearing two Performance Event Select Registers.** RETURNS: N/A*/void pentiumPmcStop (void) { if (sysCpuId.featuresEdx & CPUID_MSR) { if (sysProcessor == X86CPU_PENTIUM) { pentiumP5PmcStop0(); pentiumP5PmcStop1(); } else if (sysProcessor == X86CPU_PENTIUMPRO) pentiumP6PmcStop(); } }/********************************************************************************* pentiumPmcStop0 - stop PMC0** SYNOPSIS* \ss* void pentiumPmcStop0 (void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -