From 9ff294c54e3d8a8e04c25067f9b9b5e276bce5ef Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Tue, 29 Nov 2005 02:40:18 +0000 Subject: [PATCH] - Implement RtlPrefectMemoryNonTemporal. Patch by Patrick Baggett and myself. svn path=/trunk/; revision=19742 --- reactos/lib/rtl/i386/mem_asm.S | 24 ++++++++++++++++++++---- reactos/lib/rtl/mem.c | 6 ++++-- reactos/ntoskrnl/ke/i386/kernel.c | 11 ++++++++++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/reactos/lib/rtl/i386/mem_asm.S b/reactos/lib/rtl/i386/mem_asm.S index 61a29124ed3..5ad5a3928d7 100644 --- a/reactos/lib/rtl/i386/mem_asm.S +++ b/reactos/lib/rtl/i386/mem_asm.S @@ -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@greatlord.com) - * UPDATE HISTORY: - * Created 27/07/2005 + * PROGRAMMERS: Patrick Baggett (baggett.patrick@gmail.com) + * Alex Ionescu (alex@relsoft.net) + * Magnus Olsen (magnusolsen@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 @@ _RtlCompareMemory@12: 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 diff --git a/reactos/lib/rtl/mem.c b/reactos/lib/rtl/mem.c index 85ceba3fec1..52c54e18d0a 100644 --- a/reactos/lib/rtl/mem.c +++ b/reactos/lib/rtl/mem.c @@ -140,7 +140,7 @@ RtlMoveMemory ( } /* -* @unimplemented +* @implemented */ VOID FASTCALL @@ -149,7 +149,9 @@ RtlPrefetchMemoryNonTemporal( IN SIZE_T Length ) { - UNIMPLEMENTED; + /* By nature of prefetch, this is non-portable. */ + (void)Source; + (void)Length; } diff --git a/reactos/ntoskrnl/ke/i386/kernel.c b/reactos/ntoskrnl/ke/i386/kernel.c index cf65530648a..8f40320ce9a 100644 --- a/reactos/ntoskrnl/ke/i386/kernel.c +++ b/reactos/ntoskrnl/ke/i386/kernel.c @@ -22,6 +22,7 @@ static ULONG Ke386CpuidFlags2, Ke386CpuidExFlags, Ke386CpuidExMisc; 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 @@ KeInit2(VOID) DPRINT("Ke386CacheAlignment: %d\n", Ke386CacheAlignment); if (Ke386L1CacheSize) { + DPRINT("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize); } if (Pcr->L2CacheSize) @@ -497,7 +499,7 @@ Ki386SetProcessorFeatures(VOID) 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 @@ Ki386SetProcessorFeatures(VOID) 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) { -- 2.17.1