Reactos
1/*
2 * PROJECT: ReactOS HAL
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: hal/halx86/generic/profil.c
5 * PURPOSE: System Profiling
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl
8 */
9
10/* INCLUDES ******************************************************************/
11
12#include <hal.h>
13#define NDEBUG
14#include <debug.h>
15
16/* GLOBALS *******************************************************************/
17
18BOOLEAN HalpProfilingStopped = TRUE;
19UCHAR HalpProfileRate = 8;
20
21/* FUNCTIONS *****************************************************************/
22
23/*
24 * @implemented
25 */
26VOID
27NTAPI
28HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
29{
30 UCHAR StatusB;
31
32 UNREFERENCED_PARAMETER(ProfileSource);
33
34 /* Acquire the CMOS lock */
35 HalpAcquireCmosSpinLock();
36
37 /* Read Status Register B */
38 StatusB = HalpReadCmos(RTC_REGISTER_B);
39
40 /* Disable periodic interrupts */
41 StatusB = StatusB & ~RTC_REG_B_PI;
42
43 /* Write new value into Status Register B */
44 HalpWriteCmos(RTC_REGISTER_B, StatusB);
45
46 HalpProfilingStopped = TRUE;
47
48 /* Release the CMOS lock */
49 HalpReleaseCmosSpinLock();
50}
51
52/*
53 * @unimplemented
54 */
55VOID
56NTAPI
57HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
58{
59 UCHAR StatusA, StatusB;
60
61 UNREFERENCED_PARAMETER(ProfileSource);
62
63 HalpProfilingStopped = FALSE;
64
65 /* Acquire the CMOS lock */
66 HalpAcquireCmosSpinLock();
67
68 /* Set the interval in Status Register A */
69 StatusA = HalpReadCmos(RTC_REGISTER_A);
70 StatusA = (StatusA & 0xF0) | HalpProfileRate;
71 HalpWriteCmos(RTC_REGISTER_A, StatusA);
72
73 /* Enable periodic interrupts in Status Register B */
74 StatusB = HalpReadCmos(RTC_REGISTER_B);
75 StatusB = StatusB | RTC_REG_B_PI;
76 HalpWriteCmos(RTC_REGISTER_B, StatusB);
77
78 /* Release the CMOS lock */
79 HalpReleaseCmosSpinLock();
80}
81
82/*
83 * @unimplemented
84 */
85ULONG_PTR
86NTAPI
87HalSetProfileInterval(IN ULONG_PTR Interval)
88{
89 ULONG_PTR CurrentValue, NextValue;
90 UCHAR i;
91
92 /* Normalize interval. 122100 ns is the smallest supported */
93 Interval &= ~(1 << 31);
94 if (Interval < 1221)
95 Interval = 1221;
96
97 /* Highest rate value of 15 means 500 ms */
98 CurrentValue = 5000000;
99 for (i = 15; ; i--)
100 {
101 NextValue = (CurrentValue + 1) / 2;
102 if (Interval > CurrentValue - NextValue / 2)
103 break;
104 CurrentValue = NextValue;
105 }
106
107 /* Interval as needed by RTC */
108 HalpProfileRate = i;
109
110 /* Reset the */
111 if (!HalpProfilingStopped)
112 {
113 HalStartProfileInterrupt(0);
114 }
115
116 return CurrentValue;
117}