- Implement RtlPrefectMemoryNonTemporal. Patch by Patrick Baggett
<baggett.patrick(a)gmail.com> and myself.
Modified: trunk/reactos/lib/rtl/i386/mem_asm.S
Modified: trunk/reactos/lib/rtl/mem.c
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
_____
Modified: trunk/reactos/lib/rtl/i386/mem_asm.S
--- trunk/reactos/lib/rtl/i386/mem_asm.S 2005-11-29 01:54:33 UTC
(rev 19741)
+++ trunk/reactos/lib/rtl/i386/mem_asm.S 2005-11-29 02:40:18 UTC
(rev 19742)
@@ -1,11 +1,11 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: mem.asm
+ * FILE: mem_asm.S
* PURPOSE: Memory functions
- * PROGRAMMER: Magnus Olsen (magnusolsen(a)greatlord.com)
- * UPDATE HISTORY:
- * Created 27/07/2005
+ * PROGRAMMERS: Patrick Baggett (baggett.patrick(a)gmail.com)
+ * Alex Ionescu (alex(a)relsoft.net)
+ * Magnus Olsen (magnusolsen(a)greatlord.com)
*/
.intel_syntax noprefix
@@ -17,6 +17,7 @@
.globl _RtlFillMemory@12 // [4] (no bug)
.globl _RtlCompareMemoryUlong@12 // [5] (no bug)
.globl _RtlCompareMemory@12 // [4] (no bug)
+.globl @RtlPrefetchMemoryNonTemporal@8
/* FUNCTIONS
***************************************************************/
@@ -145,3 +146,18 @@
pop edi
3:
ret 12 // return count
+
+
+@RtlPrefetchMemoryNonTemporal@8:
+ ret /* Overwritten by ntoskrnl/ke/i386/kernel.c if SSE
is supported (see Ki386SetProcessorFeatures() ) */
+
+ mov eax, [_Ke386CacheGranularity] // Get cache line size
+
+ // This is fastcall, so ecx = address, edx = size
+ fetch_next_line:
+ prefetchnta byte ptr [ecx] // prefechnta(address)
+ sub edx, eax // count = count - cache_line_size
+ add ecx, eax // address = address +
cache_line_size
+ cmp edx, 0 // if(count) <= 0
+ ja fetch_next_line // goto fetch_next_line
+ ret
_____
Modified: trunk/reactos/lib/rtl/mem.c
--- trunk/reactos/lib/rtl/mem.c 2005-11-29 01:54:33 UTC (rev 19741)
+++ trunk/reactos/lib/rtl/mem.c 2005-11-29 02:40:18 UTC (rev 19742)
@@ -140,7 +140,7 @@
}
/*
-* @unimplemented
+* @implemented
*/
VOID
FASTCALL
@@ -149,7 +149,9 @@
IN SIZE_T Length
)
{
- UNIMPLEMENTED;
+ /* By nature of prefetch, this is non-portable. */
+ (void)Source;
+ (void)Length;
}
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
--- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-11-29 01:54:33 UTC
(rev 19741)
+++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-11-29 02:40:18 UTC
(rev 19742)
@@ -22,6 +22,7 @@
ULONG Ke386CacheAlignment;
CHAR Ke386CpuidModel[49] = {0,};
ULONG Ke386L1CacheSize;
+ULONG Ke386CacheGranularity = 0x40; /* FIXME: Default to 64 bytes
for RtlPrefetchMemoryNonTemporal(), need real size */
BOOLEAN Ke386NoExecute = FALSE;
BOOLEAN Ke386Pae = FALSE;
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
@@ -476,6 +477,7 @@
DPRINT("Ke386CacheAlignment: %d\n", Ke386CacheAlignment);
if (Ke386L1CacheSize)
{
+
DPRINT("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize);
}
if (Pcr->L2CacheSize)
@@ -497,7 +499,7 @@
KEY_VALUE_PARTIAL_INFORMATION ValueData;
NTSTATUS Status;
ULONG FastSystemCallDisable = 0;
-
+
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] =
FALSE;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] =
FALSE;
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
@@ -516,6 +518,13 @@
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE]
=
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
+ /* Does the CPU Support 'prefetchnta' (SSE) */
+ if(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE)
+ {
+ /* Replace the ret by a nop */
+ *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;
+ }
+
/* Does the CPU Support Fast System Call? */
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {