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 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 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