1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/ex/exintrin.c
5 * PURPOSE: Exported kernel functions which are now intrinsics
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #undef InterlockedIncrement
16 #undef InterlockedDecrement
17 #undef InterlockedCompareExchange
18 #undef InterlockedExchangeAdd
19 #undef InterlockedExchange
20
21 //
22 // HAL Port to Inlined Port
23 //
24 #define H2I(Port) PtrToUshort(Port)
25
26 /* FUNCTIONS ******************************************************************/
27
28 /*
29 * @implemented
30 */
31 LONG
32 FASTCALL
InterlockedIncrement(IN LONG volatile * Addend)33 InterlockedIncrement(IN LONG volatile *Addend)
34 {
35 //
36 // Call the intrinsic
37 //
38 return _InterlockedIncrement(Addend);
39 }
40
41 /*
42 * @implemented
43 */
44 LONG
45 FASTCALL
InterlockedDecrement(IN LONG volatile * Addend)46 InterlockedDecrement(IN LONG volatile *Addend)
47 {
48 //
49 // Call the intrinsic
50 //
51 return _InterlockedDecrement(Addend);
52 }
53
54 /*
55 * @implemented
56 */
57 LONG
58 FASTCALL
InterlockedCompareExchange(IN OUT LONG volatile * Destination,IN LONG Exchange,IN LONG Comperand)59 InterlockedCompareExchange(IN OUT LONG volatile *Destination,
60 IN LONG Exchange,
61 IN LONG Comperand)
62 {
63 //
64 // Call the intrinsic
65 //
66 return _InterlockedCompareExchange(Destination, Exchange, Comperand);
67 }
68
69 /*
70 * @implemented
71 */
72 LONG
73 FASTCALL
InterlockedExchange(IN OUT LONG volatile * Destination,IN LONG Value)74 InterlockedExchange(IN OUT LONG volatile *Destination,
75 IN LONG Value)
76 {
77 //
78 // Call the intrinsic
79 //
80 return _InterlockedExchange(Destination, Value);
81 }
82
83 /*
84 * @implemented
85 */
86 LONG
87 FASTCALL
InterlockedExchangeAdd(IN OUT LONG volatile * Addend,IN LONG Increment)88 InterlockedExchangeAdd(IN OUT LONG volatile *Addend,
89 IN LONG Increment)
90 {
91 //
92 // Call the intrinsic
93 //
94 return _InterlockedExchangeAdd(Addend, Increment);
95 }
96
97 /*
98 * @implemented
99 */
100 VOID
101 NTAPI
ProbeForRead(IN CONST VOID * Address,IN SIZE_T Length,IN ULONG Alignment)102 ProbeForRead(IN CONST VOID *Address,
103 IN SIZE_T Length,
104 IN ULONG Alignment)
105 {
106 ULONG_PTR Last, Current = (ULONG_PTR)Address;
107 PAGED_CODE();
108
109 /* Only probe if we have a valid length */
110 if (Length != 0)
111 {
112 /* Sanity check */
113 ASSERT((Alignment == 1) ||
114 (Alignment == 2) ||
115 (Alignment == 4) ||
116 (Alignment == 8) ||
117 (Alignment == 16));
118
119 /* Check the alignment */
120 if ((Current & (Alignment - 1)) != 0)
121 {
122 /* Incorrect alignment */
123 ExRaiseDatatypeMisalignment();
124 }
125
126 /* Get the end address */
127 Last = Current + Length - 1;
128 if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress))
129 {
130 /* Raise an access violation */
131 ExRaiseAccessViolation();
132 }
133
134 /* ProbeForRead doesn't check if memory pages are readable! */
135 }
136 }
137
138 /*
139 * @implemented
140 */
141 VOID
142 NTAPI
ProbeForWrite(IN PVOID Address,IN SIZE_T Length,IN ULONG Alignment)143 ProbeForWrite(IN PVOID Address,
144 IN SIZE_T Length,
145 IN ULONG Alignment)
146 {
147 ULONG_PTR Last, Current = (ULONG_PTR)Address;
148 PAGED_CODE();
149
150 /* Only probe if we have a valid length */
151 if (Length != 0)
152 {
153 /* Sanity check */
154 ASSERT((Alignment == 1) ||
155 (Alignment == 2) ||
156 (Alignment == 4) ||
157 (Alignment == 8) ||
158 (Alignment == 16));
159
160 /* Check the alignment */
161 if ((Current & (Alignment - 1)) != 0)
162 {
163 /* Incorrect alignment */
164 ExRaiseDatatypeMisalignment();
165 }
166
167 /* Get the end address */
168 Last = Current + Length - 1;
169 if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress))
170 {
171 /* Raise an access violation */
172 ExRaiseAccessViolation();
173 }
174
175 /* Round down to the last page */
176 Last = PAGE_ROUND_DOWN(Last) + PAGE_SIZE;
177 do
178 {
179 /* Attempt a write */
180 *(volatile CHAR*)Current = *(volatile CHAR*)Current;
181
182 /* Go to the next address */
183 Current = PAGE_ROUND_DOWN(Current) + PAGE_SIZE;
184 } while (Current != Last);
185 }
186 }
187