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