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   EfiSetMem.c
15 
16 Abstract:
17 
18   This is the code that supports IA32-optimized SetMem service
19 
20 --*/
21 
22 #include "Tiano.h"
23 
24 VOID
EfiCommonLibSetMem(IN VOID * Buffer,IN UINTN Count,IN UINT8 Value)25 EfiCommonLibSetMem (
26   IN VOID   *Buffer,
27   IN UINTN  Count,
28   IN UINT8  Value
29   )
30 /*++
31 
32 Input:  VOID   *Buffer - Pointer to buffer to write
33         UINTN  Count   - Number of bytes to write
34         UINT8  Value   - Value to write
35 
36 Output: None.
37 
38 Saves:
39 
40 Modifies:
41 
42 Description:  This function is an optimized set-memory function.
43 
44 Notes:  This function tries to set memory 8 bytes at a time. As a result,
45         it first picks up any misaligned bytes, then words, before getting
46         in the main loop that does the 8-byte clears.
47 
48 --*/
49 {
50   UINT64 QWordValue;
51   UINT64 MmxSave;
52   __asm {
53     mov edx, Count
54     test edx, edx
55     je _SetMemDone
56 
57     push ebx
58 
59     mov eax, Buffer
60     mov bl, Value
61     mov edi, eax
62     mov bh, bl
63 
64     cmp edx, 256
65     jb _SetRemindingByte
66 
67     and al, 07h
68     test al, al
69     je _SetBlock
70 
71     mov eax, edi
72     shr eax, 3
73     inc eax
74     shl eax, 3
75     sub eax, edi
76     cmp eax, edx
77     jnb _SetRemindingByte
78 
79     sub edx, eax
80     mov ecx, eax
81 
82     mov al, bl
83     rep stosb
84 
85 _SetBlock:
86     mov eax, edx
87     shr eax, 6
88     test eax, eax
89     je _SetRemindingByte
90 
91     shl eax, 6
92     sub edx, eax
93     shr eax, 6
94 
95     mov WORD PTR QWordValue[0], bx
96     mov WORD PTR QWordValue[2], bx
97     mov WORD PTR QWordValue[4], bx
98     mov WORD PTR QWordValue[6], bx
99 
100 
101     movq  MmxSave, mm0
102     movq  mm0, QWordValue
103 
104 _B:
105     movq  QWORD PTR ds:[edi], mm0
106     movq  QWORD PTR ds:[edi+8], mm0
107     movq  QWORD PTR ds:[edi+16], mm0
108     movq  QWORD PTR ds:[edi+24], mm0
109     movq  QWORD PTR ds:[edi+32], mm0
110     movq  QWORD PTR ds:[edi+40], mm0
111     movq  QWORD PTR ds:[edi+48], mm0
112     movq  QWORD PTR ds:[edi+56], mm0
113     add edi, 64
114     dec eax
115     jnz _B
116 
117 ; Restore mm0
118     movq  mm0, MmxSave
119     emms                                 ; Exit MMX Instruction
120 
121 _SetRemindingByte:
122     mov ecx, edx
123 
124     mov eax, ebx
125     shl eax, 16
126     mov ax, bx
127     shr ecx, 2
128     rep stosd
129 
130     mov ecx, edx
131     and ecx, 3
132     rep stosb
133 
134     pop ebx
135 
136 _SetMemDone:
137 
138   }
139 }
140