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