1#/*++ 2# 3#Copyright (c) 2006, Intel Corporation. All rights reserved.<BR> 4#This program and the accompanying materials 5#are licensed and made available under the terms and conditions of the BSD License 6#which accompanies this distribution. The full text of the license may be found at 7#http://opensource.org/licenses/bsd-license.php 8# 9#THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10#WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11# 12#Module Name: 13# 14# EfiZeroMem.c 15# 16#Abstract: 17# 18# This is the code that supports IA32-optimized ZeroMem service 19# 20#--*/ 21#include "EfiBind.h" 22#--------------------------------------------------------------------------- 23 .686: 24 #.MODEL flat,C 25 .mmx: 26 .code: 27 28#--------------------------------------------------------------------------- 29.globl ASM_PFX(EfiCommonLibZeroMem) 30#VOID 31#EfiCommonLibZeroMem ( 32# IN VOID *Buffer, 33# IN UINTN Count 34# ) 35#/*++ 36# 37#Input: VOID *Buffer - Pointer to buffer to clear 38# UINTN Count - Number of bytes to clear 39# 40#Output: None. 41# 42#Saves: 43# 44#Modifies: 45# 46#Description: This function is an optimized zero-memory function. 47# 48#Notes: This function tries to zero memory 8 bytes at a time. As a result, 49# it first picks up any misaligned bytes, then words, before getting 50# in the main loop that does the 8-byte clears. 51# 52#--*/ 53ASM_PFX(EfiCommonLibZeroMem): 54# UINT64 MmxSave; 55 pushl %ebp 56 movl %esp, %ebp 57 pushl %ecx # Reserve space for local variable MmxSave 58 pushl %ecx 59 pushl %edi 60 61 movl 0xC(%ebp), %ecx # Count 62 movl 8(%ebp), %edi # Buffer 63 64 # Pick up misaligned start bytes (get pointer 4-byte aligned) 65_StartByteZero: 66 movl %edi, %eax 67 andb $3, %al # check lower 2 bits of address 68 testb %al, %al 69 je _ZeroBlocks # already aligned? 70 cmpl $0, %ecx 71 je _ZeroMemDone 72 73 # Clear the byte memory location 74 movb $0, (%edi) 75 incl %edi 76 77 # Decrement our count 78 decl %ecx 79 jmp _StartByteZero # back to top of loop 80 81_ZeroBlocks: 82 83 # Compute how many 64-byte blocks we can clear 84 movl %ecx, %edx 85 shrl $6, %ecx # convert to 64-byte count 86 shll $6, %ecx # convert back to bytes 87 subl %ecx, %edx # subtract from the original count 88 shrl $6, %ecx # and this is how many 64-byte blocks 89 90 # If no 64-byte blocks, then skip 91 cmpl $0, %ecx 92 je _ZeroRemaining 93 94 # Save mm0 95 movq %mm0, -8(%ebp) # Save mm0 to MmxSave 96 97 pxor %mm0, %mm0 # Clear mm0 98 99_B: 100 movq %mm0, %ds:(%edi) 101 movq %mm0, %ds:8(%edi) 102 movq %mm0, %ds:16(%edi) 103 movq %mm0, %ds:24(%edi) 104 movq %mm0, %ds:32(%edi) 105 movq %mm0, %ds:40(%edi) 106 movq %mm0, %ds:48(%edi) 107 movq %mm0, %ds:56(%edi) 108 109 addl $64, %edi 110 decl %ecx 111 jnz _B 112 113# Restore mm0 114 movq -8(%ebp), %mm0 # Restore mm0 from MmxSave 115 emms # Exit MMX Instruction 116 117_ZeroRemaining: 118 # Zero out as many DWORDS as possible 119 movl %edx, %ecx 120 shrl $2, %ecx 121 xorl %eax, %eax 122 123 rep 124 stosl 125 126 # Zero out remaining as bytes 127 movl %edx, %ecx 128 andl $03, %ecx 129 130 rep 131 stosb 132 133_ZeroMemDone: 134 135 popl %edi 136 leave 137 ret 138#EfiCommonLibZeroMem ENDP 139 140