2008-03-11 04:42:54 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
2008-06-29 02:58:05 +00:00
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
|
|
* FILE: ntoskrnl/ex/exintrin.c
|
2008-03-11 04:42:54 +00:00
|
|
|
* PURPOSE: Exported kernel functions which are now intrinsics
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
#undef InterlockedIncrement
|
|
|
|
#undef InterlockedDecrement
|
|
|
|
#undef InterlockedCompareExchange
|
|
|
|
#undef InterlockedExchangeAdd
|
|
|
|
#undef InterlockedExchange
|
|
|
|
|
2008-03-12 18:17:55 +00:00
|
|
|
//
|
|
|
|
// HAL Port to Inlined Port
|
|
|
|
//
|
|
|
|
#define H2I(Port) PtrToUshort(Port)
|
|
|
|
|
2008-03-11 04:42:54 +00:00
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
2008-04-24 21:26:01 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-03-11 04:42:54 +00:00
|
|
|
LONG
|
|
|
|
FASTCALL
|
|
|
|
InterlockedIncrement(IN LONG volatile *Addend)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Call the intrinsic
|
|
|
|
//
|
2021-06-11 12:29:21 +00:00
|
|
|
return _InterlockedIncrement(Addend);
|
2008-03-11 04:42:54 +00:00
|
|
|
}
|
|
|
|
|
2008-04-24 21:26:01 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-03-11 04:42:54 +00:00
|
|
|
LONG
|
|
|
|
FASTCALL
|
|
|
|
InterlockedDecrement(IN LONG volatile *Addend)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Call the intrinsic
|
|
|
|
//
|
|
|
|
return _InterlockedDecrement(Addend);
|
|
|
|
}
|
|
|
|
|
2008-04-24 21:26:01 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-03-11 04:42:54 +00:00
|
|
|
LONG
|
|
|
|
FASTCALL
|
|
|
|
InterlockedCompareExchange(IN OUT LONG volatile *Destination,
|
|
|
|
IN LONG Exchange,
|
|
|
|
IN LONG Comperand)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Call the intrinsic
|
|
|
|
//
|
|
|
|
return _InterlockedCompareExchange(Destination, Exchange, Comperand);
|
|
|
|
}
|
|
|
|
|
2008-04-24 21:26:01 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-03-11 04:42:54 +00:00
|
|
|
LONG
|
|
|
|
FASTCALL
|
|
|
|
InterlockedExchange(IN OUT LONG volatile *Destination,
|
|
|
|
IN LONG Value)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Call the intrinsic
|
|
|
|
//
|
|
|
|
return _InterlockedExchange(Destination, Value);
|
|
|
|
}
|
|
|
|
|
2008-04-24 21:26:01 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-03-11 04:42:54 +00:00
|
|
|
LONG
|
|
|
|
FASTCALL
|
|
|
|
InterlockedExchangeAdd(IN OUT LONG volatile *Addend,
|
|
|
|
IN LONG Increment)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Call the intrinsic
|
|
|
|
//
|
|
|
|
return _InterlockedExchangeAdd(Addend, Increment);
|
|
|
|
}
|
2008-04-24 21:26:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
ProbeForRead(IN CONST VOID *Address,
|
2008-10-11 09:42:44 +00:00
|
|
|
IN SIZE_T Length,
|
2008-04-24 21:26:01 +00:00
|
|
|
IN ULONG Alignment)
|
|
|
|
{
|
2015-04-24 19:40:38 +00:00
|
|
|
ULONG_PTR Last, Current = (ULONG_PTR)Address;
|
2008-04-24 21:26:01 +00:00
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
/* Only probe if we have a valid length */
|
|
|
|
if (Length != 0)
|
|
|
|
{
|
|
|
|
/* Sanity check */
|
|
|
|
ASSERT((Alignment == 1) ||
|
|
|
|
(Alignment == 2) ||
|
|
|
|
(Alignment == 4) ||
|
|
|
|
(Alignment == 8) ||
|
|
|
|
(Alignment == 16));
|
|
|
|
|
2011-03-21 14:43:56 +00:00
|
|
|
/* Check the alignment */
|
|
|
|
if ((Current & (Alignment - 1)) != 0)
|
2008-04-24 21:26:01 +00:00
|
|
|
{
|
|
|
|
/* Incorrect alignment */
|
|
|
|
ExRaiseDatatypeMisalignment();
|
|
|
|
}
|
2021-06-11 12:29:21 +00:00
|
|
|
|
2011-03-21 14:43:56 +00:00
|
|
|
/* Get the end address */
|
|
|
|
Last = Current + Length - 1;
|
|
|
|
if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress))
|
2008-04-24 21:26:01 +00:00
|
|
|
{
|
2011-03-21 14:43:56 +00:00
|
|
|
/* Raise an access violation */
|
|
|
|
ExRaiseAccessViolation();
|
2008-04-24 21:26:01 +00:00
|
|
|
}
|
2011-03-21 14:43:56 +00:00
|
|
|
|
2011-03-23 15:49:44 +00:00
|
|
|
/* ProbeForRead doesn't check if memory pages are readable! */
|
2008-04-24 21:26:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
ProbeForWrite(IN PVOID Address,
|
2008-10-11 09:42:44 +00:00
|
|
|
IN SIZE_T Length,
|
2008-04-24 21:26:01 +00:00
|
|
|
IN ULONG Alignment)
|
|
|
|
{
|
|
|
|
ULONG_PTR Last, Current = (ULONG_PTR)Address;
|
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
/* Only probe if we have a valid length */
|
|
|
|
if (Length != 0)
|
|
|
|
{
|
|
|
|
/* Sanity check */
|
|
|
|
ASSERT((Alignment == 1) ||
|
|
|
|
(Alignment == 2) ||
|
|
|
|
(Alignment == 4) ||
|
|
|
|
(Alignment == 8) ||
|
|
|
|
(Alignment == 16));
|
|
|
|
|
|
|
|
/* Check the alignment */
|
|
|
|
if ((Current & (Alignment - 1)) != 0)
|
|
|
|
{
|
|
|
|
/* Incorrect alignment */
|
|
|
|
ExRaiseDatatypeMisalignment();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the end address */
|
|
|
|
Last = Current + Length - 1;
|
|
|
|
if ((Last < Current) || (Last >= (ULONG_PTR)MmUserProbeAddress))
|
|
|
|
{
|
|
|
|
/* Raise an access violation */
|
|
|
|
ExRaiseAccessViolation();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Round down to the last page */
|
|
|
|
Last = PAGE_ROUND_DOWN(Last) + PAGE_SIZE;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Attempt a write */
|
|
|
|
*(volatile CHAR*)Current = *(volatile CHAR*)Current;
|
|
|
|
|
|
|
|
/* Go to the next address */
|
|
|
|
Current = PAGE_ROUND_DOWN(Current) + PAGE_SIZE;
|
|
|
|
} while (Current != Last);
|
|
|
|
}
|
|
|
|
}
|