📄 pentiumalib.s
字号:
.align 4,0x90_pentiumPmcGet: movl $0,%ecx /* specify PMC0 */ rdpmc /* 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 $1,%ecx /* specify PMC1 */ rdpmc /* 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/********************************************************************************* pentiumPmcGet0 - get the contents of PMC0** 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* void pentiumPmcGet0 (pPmc0)* long long int * pPmc0; /@ Performance Monitoring Counter 0 @/ */ .align 4,0x90_pentiumPmcGet0: movl $0,%ecx /* specify PMC0 */ rdpmc /* 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/********************************************************************************* pentiumPmcGet1 - get the contents of PMC1** 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* void pentiumPmcGet1 (pPmc1)* long long int * pPmc1; /@ Performance Monitoring Counter 1 @/ */ .align 4,0x90_pentiumPmcGet1: movl $1,%ecx /* specify PMC1 */ rdpmc /* 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/********************************************************************************* pentiumPmcReset - reset both PMC0 and PMC1** This routine resets both PMC0 (Performance Monitoring Counter 0) and PMC1.** RETURNS: N/A* void pentiumPmcReset (void) */ .align 4,0x90_pentiumPmcReset: xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_PERFCTR0,%ecx /* specify MSR_PERFCTR0 */ wrmsr /* write %edx:%eax to MSR_PERFCTR0 */ movl $ MSR_PERFCTR1,%ecx /* specify MSR_PERFCTR1 */ wrmsr /* write %edx:%eax to MSR_PERFCTR1 */ ret/********************************************************************************* pentiumPmcReset0 - reset PMC0** This routine resets PMC0 (Performance Monitoring Counter 0).** RETURNS: N/A* void pentiumPmcReset0 (void) */ .align 4,0x90_pentiumPmcReset0: xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_PERFCTR0,%ecx /* specify MSR_PERFCTR0 */ wrmsr /* write %edx:%eax to MSR_PERFCTR0 */ ret/********************************************************************************* pentiumPmcReset1 - reset PMC1** This routine resets PMC1 (Performance Monitoring Counter 1).** RETURNS: N/A* void pentiumPmcReset1 (void) */ .align 4,0x90_pentiumPmcReset1: xorl %eax,%eax /* zero low-order 32 bits */ xorl %edx,%edx /* zero high-order 32 bits */ movl $ MSR_PERFCTR1,%ecx /* specify MSR_PERFCTR1 */ wrmsr /* write %edx:%eax to MSR_PERFCTR1 */ ret/********************************************************************************* pentiumTscGet64 - get 64Bit TSC (Timestamp Counter)** 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* void pentiumTscGet64 (pTsc)* long long int * pTsc; /@ Timestamp Counter @/ */ .align 4,0x90_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)** 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)* UINT32 pentiumTscGet32 (void) */ .align 4,0x90_pentiumTscGet32: rdtsc /* read TSC to %edx:%eax */ ret/********************************************************************************* pentiumTscReset - reset the TSC (Timestamp Counter)** This routine resets the TSC by writing zero to the TSC with WRMSR* instruction. ** RETURNS: N/A* void pentiumTscReset (void) */ .align 4,0x90_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)** 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* void pentiumMsrGet (addr, pData)* int addr; /@ MSR address @/* long long int * pData; /@ MSR data @/ */ .align 4,0x90_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)** 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* void pentiumMsrSet (addr, pData)* int addr; /@ MSR address @/* long long int * pData; /@ MSR data @/ */ .align 4,0x90_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)** 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* void pentiumTlbFlush (void) */ .align 4,0x90_pentiumTlbFlush: movl %cr3,%eax movl %eax,%cr3 /* flush the TLB */ jmp pentiumTlbFlush0 /* flush the prefetch queue */pentiumTlbFlush0: ret/********************************************************************************* pentiumSerialize - execute a serializing instruction CPUID** 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* void pentiumSerialize (void) */ .align 4,0x90_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** 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.* STATUS pentiumBts (pFlag)* char * pFlag; /@ flag address @/ */ .align 4,0x90_pentiumBts: movl SP_ARG1(%esp),%ecx xorl %eax,%eax movl $ TRUE,%edx lock /* lock the BUS */ cmpxchgb %edx,(%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** 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* STATUS pentiumBtc (pFlag)* char * pFlag; /@ flag address @/ */ .align 4,0x90_pentiumBtc: movl SP_ARG1(%esp),%ecx movl $ TRUE,%eax xorl %edx,%edx lock /* lock the BUS */ cmpxchgb %edx,(%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 + -