• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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