- Implement beginnings of Ramdisk Port Driver. Planning compatibility with ISO, SDI...
[reactos.git] / reactos / ntoskrnl / ex / exintrin.c
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
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
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
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
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
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
102 ProbeForRead(IN CONST VOID *Address,
103 IN ULONG Length,
104 IN ULONG Alignment)
105 {
106 PAGED_CODE();
107
108 /* Only probe if we have a valid length */
109 if (Length != 0)
110 {
111 /* Sanity check */
112 ASSERT((Alignment == 1) ||
113 (Alignment == 2) ||
114 (Alignment == 4) ||
115 (Alignment == 8) ||
116 (Alignment == 16));
117
118 /* Check for correct alignment */
119 if (((ULONG_PTR)Address & (Alignment - 1)) != 0)
120 {
121 /* Incorrect alignment */
122 ExRaiseDatatypeMisalignment();
123 }
124 else if (((ULONG_PTR)Address + Length) < (ULONG_PTR)Address ||
125 ((ULONG_PTR)Address + Length) > (ULONG_PTR)MmUserProbeAddress)
126 {
127 /* Attempt a read */
128 *(volatile CHAR* const)MmUserProbeAddress = 0;
129 }
130 }
131 }
132
133 /*
134 * @implemented
135 */
136 VOID
137 NTAPI
138 ProbeForWrite(IN PVOID Address,
139 IN ULONG Length,
140 IN ULONG Alignment)
141 {
142 ULONG_PTR Last, Current = (ULONG_PTR)Address;
143 PAGED_CODE();
144
145 /* Only probe if we have a valid length */
146 if (Length != 0)
147 {
148 /* Sanity check */
149 ASSERT((Alignment == 1) ||
150 (Alignment == 2) ||
151 (Alignment == 4) ||
152 (Alignment == 8) ||
153 (Alignment == 16));
154
155 /* Check the alignment */
156 if ((Current & (Alignment - 1)) != 0)
157 {
158 /* Incorrect alignment */
159 ExRaiseDatatypeMisalignment();
160 }
161
162 /* Get the end address */
163 Last = Current + Length - 1;
164 if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress))
165 {
166 /* Raise an access violation */
167 ExRaiseAccessViolation();
168 }
169
170 /* Round down to the last page */
171 Last = PAGE_ROUND_DOWN(Last) + PAGE_SIZE;
172 do
173 {
174 /* Attempt a write */
175 *(volatile CHAR*)Current = *(volatile CHAR*)Current;
176
177 /* Go to the next address */
178 Current = PAGE_ROUND_DOWN(Current) + PAGE_SIZE;
179 } while (Current != Last);
180 }
181 }