diff --git a/xtoskrnl/ar/amd64/cpufunc.cc b/xtoskrnl/ar/amd64/cpufunc.cc index 9a3db05..2a7fbe9 100644 --- a/xtoskrnl/ar/amd64/cpufunc.cc +++ b/xtoskrnl/ar/amd64/cpufunc.cc @@ -573,6 +573,33 @@ AR::CpuFunc::ReadTimeStampCounter(VOID) return ((ULONGLONG)High << 32) | Low; } +/** + * Reads the current value of the CPU's time-stamp counter and processor ID. + * + * @param TscAux + * Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX). + * + * @return This routine returns the current instruction cycle count since the processor was last reset. + * + * @since XT 1.0 + */ +XTCDECL +ULONGLONG +AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux) +{ + ULONG Low, High; + + /* Execute the RDTSCP instruction */ + __asm__ volatile("rdtscp" + : "=a" (Low), + "=d" (High), + "=c" (*TscAux) + ); + + /* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */ + return ((ULONGLONG)High << 32) | Low; +} + /** * Orders memory accesses as seen by other processors, without fence. * diff --git a/xtoskrnl/ar/i686/cpufunc.cc b/xtoskrnl/ar/i686/cpufunc.cc index bdbbe65..ca2a8a4 100644 --- a/xtoskrnl/ar/i686/cpufunc.cc +++ b/xtoskrnl/ar/i686/cpufunc.cc @@ -255,7 +255,7 @@ AR::CpuFunc::LoadLocalDescriptorTable(IN USHORT Source) XTCDECL VOID AR::CpuFunc::LoadSegment(IN USHORT Segment, - IN ULONG Source) + IN ULONG Source) { switch(Segment) { @@ -543,6 +543,33 @@ AR::CpuFunc::ReadTimeStampCounter(VOID) return Value; } +/** + * Reads the current value of the CPU's time-stamp counter and processor ID. + * + * @param TscAux + * Supplies a pointer to a variable that receives the auxiliary TSC information (IA32_TSC_AUX). + * + * @return This routine returns the current instruction cycle count since the processor was last reset. + * + * @since XT 1.0 + */ +XTCDECL +ULONGLONG +AR::CpuFunc::ReadTimeStampCounterProcessor(OUT PULONG TscAux) +{ + ULONG Low, High; + + /* Execute the RDTSCP instruction */ + __asm__ volatile("rdtscp" + : "=a" (Low), + "=d" (High), + "=c" (*TscAux) + ); + + /* Combine the two 32-bit registers into a single 64-bit unsigned integer and return the value */ + return ((ULONGLONG)High << 32) | Low; +} + /** * Orders memory accesses as seen by other processors, without fence. * @@ -650,7 +677,7 @@ AR::CpuFunc::StoreLocalDescriptorTable(OUT PVOID Destination) XTCDECL VOID AR::CpuFunc::StoreSegment(IN USHORT Segment, - OUT PVOID Destination) + OUT PVOID Destination) { switch(Segment) { diff --git a/xtoskrnl/includes/ar/amd64/cpufunc.hh b/xtoskrnl/includes/ar/amd64/cpufunc.hh index 856d3d2..b684b4d 100644 --- a/xtoskrnl/includes/ar/amd64/cpufunc.hh +++ b/xtoskrnl/includes/ar/amd64/cpufunc.hh @@ -40,6 +40,7 @@ namespace AR STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register); STATIC XTCDECL UINT ReadMxCsrRegister(VOID); STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID); + STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux); STATIC XTCDECL VOID ReadWriteBarrier(VOID); STATIC XTCDECL VOID SetInterruptFlag(VOID); STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination); diff --git a/xtoskrnl/includes/ar/i686/cpufunc.hh b/xtoskrnl/includes/ar/i686/cpufunc.hh index b05c696..046936b 100644 --- a/xtoskrnl/includes/ar/i686/cpufunc.hh +++ b/xtoskrnl/includes/ar/i686/cpufunc.hh @@ -39,6 +39,7 @@ namespace AR STATIC XTCDECL ULONGLONG ReadModelSpecificRegister(IN ULONG Register); STATIC XTCDECL UINT ReadMxCsrRegister(VOID); STATIC XTCDECL ULONGLONG ReadTimeStampCounter(VOID); + STATIC XTCDECL ULONGLONG ReadTimeStampCounterProcessor(OUT PULONG TscAux); STATIC XTCDECL VOID ReadWriteBarrier(VOID); STATIC XTCDECL VOID SetInterruptFlag(VOID); STATIC XTCDECL VOID StoreGlobalDescriptorTable(OUT PVOID Destination);