#/*++ # #Copyright (c) 2006, Intel Corporation #All rights reserved. This program and the accompanying materials #are licensed and made available under the terms and conditions of the BSD License #which accompanies this distribution. The full text of the license may be found at #http://opensource.org/licenses/bsd-license.php # #THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, #WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # #Module Name: # # EfiSetMem.asm # #Abstract: # # This is the code that supports IA32-optimized SetMem service # #--*/ #include "EfiBind.h" #--------------------------------------------------------------------------- .686: #.MODEL flat,C .mmx: .code: #--------------------------------------------------------------------------- .globl ASM_PFX(EfiCommonLibSetMem) #VOID #EfiCommonLibSetMem ( # IN VOID *Buffer, # IN UINTN Count, # IN UINT8 Value # ) #/*++ # #Input: VOID *Buffer - Pointer to buffer to write # UINTN Count - Number of bytes to write # UINT8 Value - Value to write # #Output: None. # #Saves: # #Modifies: # #Description: This function is an optimized set-memory function. # #Notes: This function tries to set memory 8 bytes at a time. As a result, # it first picks up any misaligned bytes, then words, before getting # in the main loop that does the 8-byte clears. # #--*/ ASM_PFX(EfiCommonLibSetMem): pushl %ebp movl %esp, %ebp subl $0x10, %esp # Reserve space for local variable UINT64 QWordValue @[ebp - 10H] & UINT64 MmxSave @[ebp - 18H] pushl %ebx pushl %edi movl 0xC(%ebp), %edx # Count testl %edx, %edx je _SetMemDone pushl %ebx movl 8(%ebp), %eax # Buffer movb 0x10(%ebp), %bl # Value movl %eax, %edi movb %bl, %bh cmpl $256, %edx jb _SetRemindingByte andb $0x7, %al testb %al, %al je _SetBlock movl %edi, %eax shrl $3, %eax incl %eax shll $3, %eax subl %edi, %eax cmpl %edx, %eax jnb _SetRemindingByte subl %eax, %edx movl %eax, %ecx movb %bl, %al rep stosb _SetBlock: movl %edx, %eax shrl $6, %eax testl %eax, %eax je _SetRemindingByte shll $6, %eax subl %eax, %edx shrl $6, %eax movw %bx, -0x10(%ebp) # QWordValue[0] movw %bx, -0x10+2(%ebp) # QWordValue[2] movw %bx, -0x10+4(%ebp) # QWordValue[4] movw %bx, -0x10+6(%ebp) # QWordValue[6] movq %mm0, -8(%ebp) # Save mm0 to MmxSave movq -0x10(%ebp), %mm0 # Load QWordValue to mm0 _B: movq %mm0, %ds:(%edi) movq %mm0, %ds:8(%edi) movq %mm0, %ds:16(%edi) movq %mm0, %ds:24(%edi) movq %mm0, %ds:32(%edi) movq %mm0, %ds:40(%edi) movq %mm0, %ds:48(%edi) movq %mm0, %ds:56(%edi) addl $64, %edi decl %eax jnz _B # Restore mm0 movq -8(%ebp), %mm0 # Restore MmxSave to mm0 emms # Exit MMX Instruction _SetRemindingByte: movl %edx, %ecx movl %ebx, %eax shll $16, %eax movw %bx, %ax shrl $2, %ecx rep stosl movl %edx, %ecx andl $3, %ecx rep stosb popl %ebx _SetMemDone: popl %edi popl %ebx leave ret #EfiCommonLibSetMem ENDP