#define NDEBUG
#include <debug.h>
+/* GLOBALS *******************************************************************/
+
+BOOLEAN HalpProfilingStopped = TRUE;
+UCHAR HalpProfileRate = 8;
+
/* FUNCTIONS *****************************************************************/
/*
{
UCHAR StatusB;
+ UNREFERENCED_PARAMETER(ProfileSource);
+
/* Acquire the CMOS lock */
HalpAcquireCmosSpinLock();
/* Write new value into Status Register B */
HalpWriteCmos(RTC_REGISTER_B, StatusB);
+ HalpProfilingStopped = TRUE;
+
/* Release the CMOS lock */
HalpReleaseCmosSpinLock();
}
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();
}
/*
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;
}
/* 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 */
#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
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);