1 /** @file
2   Implementation of the EfiSetMem routine. This function is broken
3   out into its own source file so that it can be excluded from a
4   build for a particular platform easily if an optimized version
5   is desired.
6 
7   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
8   Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
9   Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
10 
11   SPDX-License-Identifier: BSD-2-Clause-Patent
12 
13 **/
14 
15 
16 
17 
18 #include "MemLibInternals.h"
19 
20 /**
21   Set Buffer to Value for Size bytes.
22 
23   @param  Buffer   The memory to set.
24   @param  Length   The number of bytes to set.
25   @param  Value    The value of the set operation.
26 
27   @return Buffer
28 
29 **/
30 VOID *
31 EFIAPI
InternalMemSetMem(OUT VOID * Buffer,IN UINTN Length,IN UINT8 Value)32 InternalMemSetMem (
33   OUT     VOID                      *Buffer,
34   IN      UINTN                     Length,
35   IN      UINT8                     Value
36   )
37 {
38   //
39   // Declare the local variables that actually move the data elements as
40   // volatile to prevent the optimizer from replacing this function with
41   // the intrinsic memset()
42   //
43   volatile UINT8                    *Pointer8;
44   volatile UINT32                   *Pointer32;
45   volatile UINT64                   *Pointer64;
46   UINT32                            Value32;
47   UINT64                            Value64;
48 
49   if ((((UINTN)Buffer & 0x7) == 0) && (Length >= 8)) {
50     // Generate the 64bit value
51     Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
52     Value64 = LShiftU64 (Value32, 32) | Value32;
53 
54     Pointer64 = (UINT64*)Buffer;
55     while (Length >= 8) {
56       *(Pointer64++) = Value64;
57       Length -= 8;
58     }
59 
60     // Finish with bytes if needed
61     Pointer8 = (UINT8*)Pointer64;
62   } else if ((((UINTN)Buffer & 0x3) == 0) && (Length >= 4)) {
63     // Generate the 32bit value
64     Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
65 
66     Pointer32 = (UINT32*)Buffer;
67     while (Length >= 4) {
68       *(Pointer32++) = Value32;
69       Length -= 4;
70     }
71 
72     // Finish with bytes if needed
73     Pointer8 = (UINT8*)Pointer32;
74   } else {
75     Pointer8 = (UINT8*)Buffer;
76   }
77   while (Length-- > 0) {
78     *(Pointer8++) = Value;
79   }
80   return Buffer;
81 }
82