- Implement HalStartProfileInterrupt, HalSetProfileInterval, and HalpProfileInterruptHandler
Now kernrate works!
CORE-10066 #resolve

svn path=/trunk/; revision=68863
This commit is contained in:
Thomas Faber 2015-08-29 16:45:00 +00:00
parent 1e34580fd6
commit a6513f80af
3 changed files with 77 additions and 7 deletions

View file

@ -13,6 +13,11 @@
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
BOOLEAN HalpProfilingStopped = TRUE;
UCHAR HalpProfileRate = 8;
/* FUNCTIONS *****************************************************************/
/*
@ -24,6 +29,8 @@ HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
{
UCHAR StatusB;
UNREFERENCED_PARAMETER(ProfileSource);
/* Acquire the CMOS lock */
HalpAcquireCmosSpinLock();
@ -36,6 +43,8 @@ HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
/* Write new value into Status Register B */
HalpWriteCmos(RTC_REGISTER_B, StatusB);
HalpProfilingStopped = TRUE;
/* Release the CMOS lock */
HalpReleaseCmosSpinLock();
}
@ -47,8 +56,27 @@ VOID
NTAPI
HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
{
UNIMPLEMENTED;
return;
UCHAR StatusA, StatusB;
UNREFERENCED_PARAMETER(ProfileSource);
HalpProfilingStopped = FALSE;
/* Acquire the CMOS lock */
HalpAcquireCmosSpinLock();
/* Set the interval in Status Register A */
StatusA = HalpReadCmos(RTC_REGISTER_A);
StatusA = (StatusA & 0xF0) | HalpProfileRate;
HalpWriteCmos(RTC_REGISTER_A, StatusA);
/* Enable periodic interrupts in Status Register B */
StatusB = HalpReadCmos(RTC_REGISTER_B);
StatusB = StatusB | RTC_REG_B_PI;
HalpWriteCmos(RTC_REGISTER_B, StatusB);
/* Release the CMOS lock */
HalpReleaseCmosSpinLock();
}
/*
@ -58,6 +86,32 @@ ULONG_PTR
NTAPI
HalSetProfileInterval(IN ULONG_PTR Interval)
{
UNIMPLEMENTED;
return Interval;
ULONG_PTR CurrentValue, NextValue;
UCHAR i;
/* Normalize interval. 122100 ns is the smallest supported */
Interval &= ~(1 << 31);
if (Interval < 1221)
Interval = 1221;
/* Highest rate value of 15 means 500 ms */
CurrentValue = 5000000;
for (i = 15; ; i--)
{
NextValue = (CurrentValue + 1) / 2;
if (Interval > CurrentValue - NextValue / 2)
break;
CurrentValue = NextValue;
}
/* Interval as needed by RTC */
HalpProfileRate = i;
/* Reset the */
if (!HalpProfilingStopped)
{
HalStartProfileInterrupt(0);
}
return CurrentValue;
}

View file

@ -188,9 +188,21 @@ HalpProfileInterruptHandler(IN PKTRAP_FRAME TrapFrame)
/* Start the interrupt */
if (HalBeginSystemInterrupt(PROFILE_LEVEL, PRIMARY_VECTOR_BASE + 8, &Irql))
{
/* Profiling isn't yet enabled */
UNIMPLEMENTED;
ASSERT(FALSE);
/* Spin until the interrupt pending bit is clear */
HalpAcquireCmosSpinLock();
while (HalpReadCmos(RTC_REGISTER_C) & RTC_REG_C_IRQ)
;
HalpReleaseCmosSpinLock();
/* If profiling is enabled, call the kernel function */
if (!HalpProfilingStopped)
{
KeProfileInterrupt(TrapFrame);
}
/* Finish the interrupt */
_disable();
HalEndSystemInterrupt(Irql, TrapFrame);
}
/* Spurious, just end the interrupt */

View file

@ -68,6 +68,7 @@ ATTRIB_NORETURN
#define RTC_REGISTER_B 0x0B
#define RTC_REG_B_PI 0x40
#define RTC_REGISTER_C 0x0C
#define RTC_REG_C_IRQ 0x80
#define RTC_REGISTER_D 0x0D
#define RTC_REGISTER_CENTURY 0x32
@ -585,6 +586,9 @@ VOID HalpDispatchInterrupt2(VOID);
DECLSPEC_NORETURN VOID FASTCALL HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
DECLSPEC_NORETURN VOID FASTCALL HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame);
/* profil.c */
extern BOOLEAN HalpProfilingStopped;
/* timer.c */
VOID NTAPI HalpInitializeClock(VOID);
VOID HalpClockInterrupt(VOID);