13eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++
23eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
34ea9375a2d02a43671437e0d3d808d85afb30afahhtianCopyright (c) 2006, Intel Corporation. All rights reserved.<BR>
44ea9375a2d02a43671437e0d3d808d85afb30afahhtianThis program and the accompanying materials
53eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangare licensed and made available under the terms and conditions of the BSD License
63eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangwhich accompanies this distribution.  The full text of the license may be found at
73eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwanghttp://opensource.org/licenses/bsd-license.php
83eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
93eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangModule Name:
133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  EfiZeroMem.c
153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangAbstract:
173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  This is the code that supports IA32-optimized ZeroMem service
193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/
213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang#include "Tiano.h"
233eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
243eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangVOID
253eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangEfiCommonLibZeroMem (
263eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN VOID   *Buffer,
273eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  IN UINTN  Count
283eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  )
293eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang/*++
303eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
313eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangInput:  VOID   *Buffer - Pointer to buffer to clear
323eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang        UINTN  Count  - Number of bytes to clear
333eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
343eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangOutput: None.
353eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
363eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangSaves:
373eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
383eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangModifies:
393eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
403eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangDescription:  This function is an optimized zero-memory function.
413eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
423eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwangNotes:  This function tries to zero memory 8 bytes at a time. As a result,
433eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang        it first picks up any misaligned bytes, then words, before getting
443eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang        in the main loop that does the 8-byte clears.
453eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
463eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang--*/
473eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang{
483eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  UINT64 MmxSave;
493eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  __asm {
503eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   ecx, Count
513eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   edi, Buffer
523eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
533eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Pick up misaligned start bytes (get pointer 4-byte aligned)
543eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang_StartByteZero:
553eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   eax, edi
563eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    and   al, 3                       ; check lower 2 bits of address
573eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    test  al, al
583eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    je    _ZeroBlocks                 ; already aligned?
593eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    cmp   ecx, 0
603eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    je    _ZeroMemDone
613eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
623eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Clear the byte memory location
633eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   BYTE PTR [edi], 0
643eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    inc    edi
653eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
663eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Decrement our count
673eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    dec    ecx
683eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    jmp   _StartByteZero        ; back to top of loop
693eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
703eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang_ZeroBlocks:
713eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
723eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Compute how many 64-byte blocks we can clear
733eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   edx, ecx
743eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    shr   ecx, 6                      ; convert to 64-byte count
753eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    shl   ecx, 6                      ; convert back to bytes
763eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    sub   edx, ecx                    ; subtract from the original count
773eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    shr   ecx, 6                      ; and this is how many 64-byte blocks
783eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
793eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; If no 64-byte blocks, then skip
803eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    cmp    ecx, 0
813eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    je    _ZeroRemaining
823eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
833eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Save mm0
843eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  MmxSave, mm0
853eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
863eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    pxor  mm0, mm0          ; Clear mm0
873eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
883eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang_B:
893eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi], mm0
903eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+8], mm0
913eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+16], mm0
923eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+24], mm0
933eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+32], mm0
943eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+40], mm0
953eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+48], mm0
963eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  QWORD PTR ds:[edi+56], mm0
973eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
983eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    add    edi, 64
993eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    dec    ecx
1003eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    jnz    _B
1013eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1023eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang; Restore mm0
1033eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    movq  mm0, MmxSave
1043eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    emms                                 ; Exit MMX Instruction
1053eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1063eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang_ZeroRemaining:
1073eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Zero out as many DWORDS as possible
1083eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   ecx, edx
1093eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    shr   ecx, 2
1103eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    xor   eax, eax
1113eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1123eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    rep stosd
1133eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1143eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    ; Zero out remaining as bytes
1153eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    mov   ecx, edx
1163eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    and   ecx, 03
1173eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1183eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang    rep   stosb
1193eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang
1203eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang_ZeroMemDone:
1213eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang  }
1223eb9473ea9a949badfe06ae61d2d3fcfa53651c7qwang}
123