1 /** @file
2   Unaligned access functions of BaseLib for IPF.
3 
4   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php.
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include "BaseLibInternals.h"
16 
17 /**
18   Reads a 16-bit value from memory that may be unaligned.
19 
20   This function returns the 16-bit value pointed to by Buffer. The function
21   guarantees that the read operation does not produce an alignment fault.
22 
23   If the Buffer is NULL, then ASSERT().
24 
25   @param  Buffer  The pointer to a 16-bit value that may be unaligned.
26 
27   @return The 16-bit value read from Buffer.
28 
29 **/
30 UINT16
31 EFIAPI
ReadUnaligned16(IN CONST UINT16 * Buffer)32 ReadUnaligned16 (
33   IN CONST UINT16              *Buffer
34   )
35 {
36   ASSERT (Buffer != NULL);
37 
38   return (UINT16)(((UINT8*)Buffer)[0] | (((UINT8*)Buffer)[1] << 8));
39 }
40 
41 /**
42   Writes a 16-bit value to memory that may be unaligned.
43 
44   This function writes the 16-bit value specified by Value to Buffer. Value is
45   returned. The function guarantees that the write operation does not produce
46   an alignment fault.
47 
48   If the Buffer is NULL, then ASSERT().
49 
50   @param  Buffer  The pointer to a 16-bit value that may be unaligned.
51   @param  Value   The 16-bit value to write to Buffer.
52 
53   @return The 16-bit value to write to Buffer.
54 
55 **/
56 UINT16
57 EFIAPI
WriteUnaligned16(OUT UINT16 * Buffer,IN UINT16 Value)58 WriteUnaligned16 (
59   OUT UINT16                    *Buffer,
60   IN  UINT16                    Value
61   )
62 {
63   ASSERT (Buffer != NULL);
64 
65   ((UINT8*)Buffer)[0] = (UINT8)Value;
66   ((UINT8*)Buffer)[1] = (UINT8)(Value >> 8);
67 
68   return Value;
69 }
70 
71 /**
72   Reads a 24-bit value from memory that may be unaligned.
73 
74   This function returns the 24-bit value pointed to by Buffer. The function
75   guarantees that the read operation does not produce an alignment fault.
76 
77   If the Buffer is NULL, then ASSERT().
78 
79   @param  Buffer  The pointer to a 24-bit value that may be unaligned.
80 
81   @return The 24-bit value read from Buffer.
82 
83 **/
84 UINT32
85 EFIAPI
ReadUnaligned24(IN CONST UINT32 * Buffer)86 ReadUnaligned24 (
87   IN CONST UINT32              *Buffer
88   )
89 {
90   ASSERT (Buffer != NULL);
91 
92   return (UINT32)(
93             ReadUnaligned16 ((UINT16*)Buffer) |
94             (((UINT8*)Buffer)[2] << 16)
95             );
96 }
97 
98 /**
99   Writes a 24-bit value to memory that may be unaligned.
100 
101   This function writes the 24-bit value specified by Value to Buffer. Value is
102   returned. The function guarantees that the write operation does not produce
103   an alignment fault.
104 
105   If the Buffer is NULL, then ASSERT().
106 
107   @param  Buffer  The pointer to a 24-bit value that may be unaligned.
108   @param  Value   The 24-bit value to write to Buffer.
109 
110   @return The 24-bit value to write to Buffer.
111 
112 **/
113 UINT32
114 EFIAPI
WriteUnaligned24(OUT UINT32 * Buffer,IN UINT32 Value)115 WriteUnaligned24 (
116   OUT UINT32                    *Buffer,
117   IN  UINT32                    Value
118   )
119 {
120   ASSERT (Buffer != NULL);
121 
122   WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);
123   *(UINT8*)((UINT16*)Buffer + 1) = (UINT8)(Value >> 16);
124   return Value;
125 }
126 
127 /**
128   Reads a 32-bit value from memory that may be unaligned.
129 
130   This function returns the 32-bit value pointed to by Buffer. The function
131   guarantees that the read operation does not produce an alignment fault.
132 
133   If the Buffer is NULL, then ASSERT().
134 
135   @param  Buffer  The pointer to a 32-bit value that may be unaligned.
136 
137   @return The 32-bit value read from Buffer.
138 
139 **/
140 UINT32
141 EFIAPI
ReadUnaligned32(IN CONST UINT32 * Buffer)142 ReadUnaligned32 (
143   IN CONST UINT32              *Buffer
144   )
145 {
146   UINT16  LowerBytes;
147   UINT16  HigherBytes;
148 
149   ASSERT (Buffer != NULL);
150 
151   LowerBytes  = ReadUnaligned16 ((UINT16*) Buffer);
152   HigherBytes = ReadUnaligned16 ((UINT16*) Buffer + 1);
153 
154   return (UINT32) (LowerBytes | (HigherBytes << 16));
155 }
156 
157 /**
158   Writes a 32-bit value to memory that may be unaligned.
159 
160   This function writes the 32-bit value specified by Value to Buffer. Value is
161   returned. The function guarantees that the write operation does not produce
162   an alignment fault.
163 
164   If the Buffer is NULL, then ASSERT().
165 
166   @param  Buffer  The pointer to a 32-bit value that may be unaligned.
167   @param  Value   The 32-bit value to write to Buffer.
168 
169   @return The 32-bit value to write to Buffer.
170 
171 **/
172 UINT32
173 EFIAPI
WriteUnaligned32(OUT UINT32 * Buffer,IN UINT32 Value)174 WriteUnaligned32 (
175   OUT UINT32                    *Buffer,
176   IN  UINT32                    Value
177   )
178 {
179   ASSERT (Buffer != NULL);
180 
181   WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);
182   WriteUnaligned16 ((UINT16*)Buffer + 1, (UINT16)(Value >> 16));
183   return Value;
184 }
185 
186 /**
187   Reads a 64-bit value from memory that may be unaligned.
188 
189   This function returns the 64-bit value pointed to by Buffer. The function
190   guarantees that the read operation does not produce an alignment fault.
191 
192   If the Buffer is NULL, then ASSERT().
193 
194   @param  Buffer  The pointer to a 64-bit value that may be unaligned.
195 
196   @return The 64-bit value read from Buffer.
197 
198 **/
199 UINT64
200 EFIAPI
ReadUnaligned64(IN CONST UINT64 * Buffer)201 ReadUnaligned64 (
202   IN CONST UINT64              *Buffer
203   )
204 {
205   UINT32  LowerBytes;
206   UINT32  HigherBytes;
207 
208   ASSERT (Buffer != NULL);
209 
210   LowerBytes  = ReadUnaligned32 ((UINT32*) Buffer);
211   HigherBytes = ReadUnaligned32 ((UINT32*) Buffer + 1);
212 
213   return (UINT64) (LowerBytes | LShiftU64 (HigherBytes, 32));
214 }
215 
216 /**
217   Writes a 64-bit value to memory that may be unaligned.
218 
219   This function writes the 64-bit value specified by Value to Buffer. Value is
220   returned. The function guarantees that the write operation does not produce
221   an alignment fault.
222 
223   If the Buffer is NULL, then ASSERT().
224 
225   @param  Buffer  The pointer to a 64-bit value that may be unaligned.
226   @param  Value   The 64-bit value to write to Buffer.
227 
228   @return The 64-bit value to write to Buffer.
229 
230 **/
231 UINT64
232 EFIAPI
WriteUnaligned64(OUT UINT64 * Buffer,IN UINT64 Value)233 WriteUnaligned64 (
234   OUT UINT64                    *Buffer,
235   IN  UINT64                    Value
236   )
237 {
238   ASSERT (Buffer != NULL);
239 
240   WriteUnaligned32 ((UINT32*)Buffer, (UINT32)Value);
241   WriteUnaligned32 ((UINT32*)Buffer + 1, (UINT32)RShiftU64 (Value, 32));
242   return Value;
243 }
244