xref: /reactos/hal/halx86/generic/profil.c (revision dc0433f0)
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 
18 BOOLEAN HalpProfilingStopped = TRUE;
19 UCHAR HalpProfileRate = 8;
20 
21 /* FUNCTIONS *****************************************************************/
22 
23 /*
24  * @implemented
25  */
26 VOID
27 NTAPI
28 HalStopProfileInterrupt(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  */
55 VOID
56 NTAPI
57 HalStartProfileInterrupt(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  */
85 ULONG_PTR
86 NTAPI
87 HalSetProfileInterval(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 }
118