Home | History | Annotate | Download | only in Ia32
      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
     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