📄 pentiumalib.s
字号:
FUNC_LABEL(pentiumP5PmcGet) movl $ MSR_CTR0,%ecx /* specify PMC0 */ rdmsr /* read PMC0 to %edx:%eax */ movl SP_ARG1(%esp),%ecx movl %eax,(%ecx) /* save low-order 32 bits */ movl %edx,4(%ecx) /* save high-order 32 bits */ movl $ MSR_CTR1,%ecx /* specify PMC1 */ rdmsr /* read PMC1 to %edx:%eax */ movl SP_ARG2(%esp),%ecx movl %eax,(%ecx) /* save low-order 32 bits */ movl %edx,4(%ecx) /* save high-order 32 bits */ ret/********************************************************************************* pentiumP5PmcGet0 - get the contents of P5 PMC0** SYNOPSIS* \ss* void pentiumP5PmcGet0 (pPmc0)* long long int * pPmc0; /@ Performance Monitoring Counter 0 @/* \se** This routine gets the contents of PMC0 (Performance Monitoring Counter 0).* The parameter is a pointer of 64Bit variable to store the content of* the Counter.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumP5PmcGet0) movl $ MSR_CTR0,%ecx /* specify PMC0 */ rdmsr /* read PMC0 to %edx:%eax */ movl SP_ARG1(%esp),%ecx movl %eax,(%ecx) /* save low-order 32 bits */ movl %edx,4(%ecx) /* save high-order 32 bits */ ret/********************************************************************************* pentiumP5PmcGet1 - get the contents of P5 PMC1** SYNOPSIS* \ss* void pentiumP5PmcGet1 (pPmc1)* long long int * pPmc1; /@ Performance Monitoring Counter 1 @/* \se** This routine gets a content of PMC1 (Performance Monitoring Counter 1).* Parameter is a pointer of 64Bit variable to store the content of the Counter.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumP5PmcGet1) movl $ MSR_CTR1,%ecx /* specify PMC1 */ rdmsr /* read PMC1 to %edx:%eax */ movl SP_ARG1(%esp),%ecx movl %eax,(%ecx) /* save low-order 32 bits */ movl %edx,4(%ecx) /* save high-order 32 bits */ ret/********************************************************************************* pentiumP5PmcReset - reset both PMC0 and PMC1** SYNOPSIS* \ss* void pentiumP5PmcReset (void)* \se** This routine resets both PMC0 (Performance Monitoring Counter 0) and PMC1.** RETURNS: N/A */ .balign 16,0x90FUNC_LABEL(pentiumP5PmcReset) xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_CTR0,%ecx /* specify MSR_CTR0 */ wrmsr /* write %edx:%eax to MSR_CTR0 */ movl $ MSR_CTR1,%ecx /* specify MSR_CRT1 */ wrmsr /* write %edx:%eax to MSR_CTR1 */ ret/********************************************************************************* pentiumP5PmcReset0 - reset PMC0** SYNOPSIS* \ss* void pentiumP5PmcReset0 (void)* \se** This routine resets PMC0 (Performance Monitoring Counter 0).** RETURNS: N/A */ .balign 16,0x90FUNC_LABEL(pentiumP5PmcReset0) xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_CTR0,%ecx /* specify MSR_CTR0 */ wrmsr /* write %edx:%eax to MSR_CTR1 */ ret/********************************************************************************* pentiumP5PmcReset1 - reset PMC1** SYNOPSIS* \ss* void pentiumP5PmcReset1 (void)* \se** This routine resets PMC1 (Performance Monitoring Counter 1).** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumP5PmcReset1) xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_CTR1,%ecx /* specify MSR_CTR1 */ wrmsr /* write %edx:%eax to MSR_CTR1 */ ret/********************************************************************************* pentiumTscGet64 - get 64Bit TSC (Timestamp Counter)** SYNOPSIS* \ss* void pentiumTscGet64 (pTsc)* long long int * pTsc; /@ Timestamp Counter @/* \se* * This routine gets 64Bit TSC by RDTSC instruction.* Parameter is a pointer of 64Bit variable to store the content of the Counter.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumTscGet64) movl SP_ARG1(%esp),%ecx rdtsc /* read TSC to %edx:%eax */ movl %eax,(%ecx) /* save low-order 32 bits */ movl %edx,4(%ecx) /* save high-order 32 bits */ ret/********************************************************************************* pentiumTscGet32 - get the lower half of the 64Bit TSC (Timestamp Counter)** SYNOPSIS* \ss* UINT32 pentiumTscGet32 (void)* \se* * This routine gets a lower half of the 64Bit TSC by RDTSC instruction.* RDTSC instruction saves the lower 32Bit in EAX register, so this routine* simply returns after executing RDTSC instruction.** RETURNS: Lower half of the 64Bit TSC (Timestamp Counter)*/ .balign 16,0x90FUNC_LABEL(pentiumTscGet32) rdtsc /* read TSC to %edx:%eax */ ret/********************************************************************************* pentiumTscReset - reset the TSC (Timestamp Counter)** SYNOPSIS* \ss* void pentiumTscReset (void)* \se* * This routine resets the TSC by writing zero to the TSC with WRMSR* instruction. ** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumTscReset) xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_TSC,%ecx /* specify MSR_TSC */ wrmsr /* write %edx:%eax to TSC */ ret/********************************************************************************* pentiumMsrGet - get the contents of the specified MSR (Model Specific Register)** SYNOPSIS* \ss* void pentiumMsrGet (addr, pData)* int addr; /@ MSR address @/* long long int * pData; /@ MSR data @/* \se* * This routine gets the contents of the specified MSR. The first parameter is* an address of the MSR. The second parameter is a pointer of 64Bit variable.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumMsrGet) movl SP_ARG1(%esp),%ecx /* specify MSR to read */ rdmsr /* read the MSR to %edx:%eax */ movl SP_ARG2(%esp),%ecx movl %eax,(%ecx) /* save low-order 32 bits */ movl %edx,4(%ecx) /* save high-order 32 bits */ ret/********************************************************************************* pentiumMsrSet - set a value to the specified MSR (Model Specific Registers)** SYNOPSIS* \ss* void pentiumMsrSet (addr, pData)* int addr; /@ MSR address @/* long long int * pData; /@ MSR data @/* \se* * This routine sets a value to a specified MSR. The first parameter is an* address of the MSR. The second parameter is a pointer of 64Bit variable.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumMsrSet) movl SP_ARG2(%esp),%ecx movl (%ecx),%eax /* low-order 32 bits */ movl 4(%ecx),%edx /* high-order 32 bits */ movl SP_ARG1(%esp),%ecx /* specify MSR to read */ wrmsr /* write %edx:%eax to the MSR */ ret/********************************************************************************* pentiumTlbFlush - flush TLBs (Translation Lookaside Buffers)** SYNOPSIS* \ss* void pentiumTlbFlush (void)* \se* * This routine flushes TLBs by loading the CR3 register.* All of the TLBs are automatically invalidated any time the CR3 register is* loaded. The page global enable (PGE) flag in register CR4 and the global* flag in a page-directory or page-table entry can be used to frequently used* pages from being automatically invalidated in the TLBs on a load of CR3* register. The only way to deterministically invalidate global page entries* is to clear the PGE flag and then invalidate the TLBs.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumTlbFlush) movl %cr3,%eax movl %eax,%cr3 /* flush the TLB */ jmp pentiumTlbFlush0 /* flush the prefetch queue */pentiumTlbFlush0: ret/********************************************************************************* pentiumSerialize - execute a serializing instruction CPUID** SYNOPSIS* \ss* void pentiumSerialize (void)* \se* * This routine executes a serializing instruction CPUID.* Serialization means that all modifications to flags, registers, and memory* by previous instructions are completed before the next instruction is fetched* and executed and all buffered writes have drained to memory.** RETURNS: N/A*/ .balign 16,0x90FUNC_LABEL(pentiumSerialize) pushl %ebx /* save ebx which is used by cpuid */ cpuid /* serializing instruction */ popl %ebx /* restore ebx */ ret/********************************************************************************* pentiumBts - execute atomic compare-and-exchange instruction to set a bit** SYNOPSIS* \ss* STATUS pentiumBts (pFlag)* char * pFlag; /@ flag address @/* \se* * This routine compares a byte specified by the first parameter with 0.* If it is 0, it changes it to TRUE and returns OK.* If it is not 0, it returns ERROR. LOCK and CMPXCHGB are used to get * the atomic memory access.** RETURNS: OK or ERROR if the specified flag is not zero.*/ .balign 16,0x90FUNC_LABEL(pentiumBts) movl SP_ARG1(%esp),%ecx xorl %eax,%eax movl $ TRUE,%edx lock /* lock the BUS */ cmpxchgb %dl,(%ecx) /* if (flag == 0) */ jnz pentiumBts0 /* {ZF = 1; flag = TRUE;} */ retpentiumBts0: movl $ ERROR,%eax ret/********************************************************************************* pentiumBtc - execute atomic compare-and-exchange instruction to clear a bit** SYNOPSIS* \ss* STATUS pentiumBtc (pFlag)* char * pFlag; /@ flag address @/* \se* * This routine compares a byte specified by the first parameter with TRUE.* If it is TRUE, it changes it to 0 and returns OK.* If it is not TRUE, it returns ERROR. LOCK and CMPXCHGB are used to get * the atomic memory access.** RETURNS: OK or ERROR if the specified flag is not TRUE*/ .balign 16,0x90FUNC_LABEL(pentiumBtc) movl SP_ARG1(%esp),%ecx movl $ TRUE,%eax xorl %edx,%edx lock /* lock the BUS */ cmpxchgb %dl,(%ecx) /* if (flag == TRUE) */ jnz pentiumBtc0 /* {ZF = 1; flag = 0;} */ xorl %eax,%eax retpentiumBtc0: movl $ ERROR,%eax ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -