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 ;--------------------------------------------------------------------------- 22 .686 23 .model flat,C 24 .mmx 25 .code 26 27 ;--------------------------------------------------------------------------- 28 ;VOID 29 ;EfiCommonLibZeroMem ( 30 ; IN VOID *Buffer, 31 ; IN UINTN Count 32 ; ) 33 ;/*++ 34 ; 35 ;Input: VOID *Buffer - Pointer to buffer to clear 36 ; UINTN Count - Number of bytes to clear 37 ; 38 ;Output: None. 39 ; 40 ;Saves: 41 ; 42 ;Modifies: 43 ; 44 ;Description: This function is an optimized zero-memory function. 45 ; 46 ;Notes: This function tries to zero memory 8 bytes at a time. As a result, 47 ; it first picks up any misaligned bytes, then words, before getting 48 ; in the main loop that does the 8-byte clears. 49 ; 50 ;--*/ 51 EfiCommonLibZeroMem PROC 52 ; UINT64 MmxSave; 53 push ebp 54 mov ebp, esp 55 push ecx ; Reserve space for local variable MmxSave 56 push ecx 57 push edi 58 59 mov ecx, [ebp + 0Ch] ; Count 60 mov edi, [ebp + 8]; Buffer 61 62 ; Pick up misaligned start bytes (get pointer 4-byte aligned) 63 _StartByteZero: 64 mov eax, edi 65 and al, 3 ; check lower 2 bits of address 66 test al, al 67 je _ZeroBlocks ; already aligned? 68 cmp ecx, 0 69 je _ZeroMemDone 70 71 ; Clear the byte memory location 72 mov BYTE PTR [edi], 0 73 inc edi 74 75 ; Decrement our count 76 dec ecx 77 jmp _StartByteZero ; back to top of loop 78 79 _ZeroBlocks: 80 81 ; Compute how many 64-byte blocks we can clear 82 mov edx, ecx 83 shr ecx, 6 ; convert to 64-byte count 84 shl ecx, 6 ; convert back to bytes 85 sub edx, ecx ; subtract from the original count 86 shr ecx, 6 ; and this is how many 64-byte blocks 87 88 ; If no 64-byte blocks, then skip 89 cmp ecx, 0 90 je _ZeroRemaining 91 92 ; Save mm0 93 movq [ebp - 8], mm0 ; Save mm0 to MmxSave 94 95 pxor mm0, mm0 ; Clear mm0 96 97 _B: 98 movq QWORD PTR ds:[edi], mm0 99 movq QWORD PTR ds:[edi+8], mm0 100 movq QWORD PTR ds:[edi+16], mm0 101 movq QWORD PTR ds:[edi+24], mm0 102 movq QWORD PTR ds:[edi+32], mm0 103 movq QWORD PTR ds:[edi+40], mm0 104 movq QWORD PTR ds:[edi+48], mm0 105 movq QWORD PTR ds:[edi+56], mm0 106 107 add edi, 64 108 dec ecx 109 jnz _B 110 111 ; Restore mm0 112 movq mm0, [ebp - 8] ; Restore mm0 from MmxSave 113 emms ; Exit MMX Instruction 114 115 _ZeroRemaining: 116 ; Zero out as many DWORDS as possible 117 mov ecx, edx 118 shr ecx, 2 119 xor eax, eax 120 121 rep stosd 122 123 ; Zero out remaining as bytes 124 mov ecx, edx 125 and ecx, 03 126 127 rep stosb 128 129 _ZeroMemDone: 130 131 pop edi 132 leave 133 ret 134 EfiCommonLibZeroMem ENDP 135 END 136