]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/CheckSum.c
Update BaseLib according to code review comments.
[mirror_edk2.git] / MdePkg / Library / BaseLib / CheckSum.c
CommitLineData
e1f414b6 1/** @file\r
2 Utility functions to generate checksum based on 2's complement\r
3 algorithm.\r
4\r
24dcb5e5 5 Copyright (c) 2007 - 2008, Intel Corporation<BR>\r
e1f414b6 6 All rights reserved. This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
e1f414b6 14**/\r
15\r
1efcc4ae 16\r
f734a10a
A
17#include <BaseLibInternals.h>\r
18\r
e1f414b6 19\r
20/**\r
21 Calculate the sum of all elements in a buffer in unit of UINT8. \r
22 During calculation, the carry bits are dropped.\r
23\r
24 This function calculates the sum of all elements in a buffer \r
25 in unit of UINT8. The carry bits in result of addition are dropped. \r
26 The result is returned as UINT8. If Length is Zero, then Zero is \r
27 returned.\r
28 \r
29 If Buffer is NULL, then ASSERT().\r
30 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
31\r
1106ffe1 32 @param Buffer Pointer to the buffer to carry out the sum operation.\r
33 @param Length The size, in bytes, of Buffer .\r
e1f414b6 34\r
35 @return Sum The sum of Buffer with carry bits dropped during additions.\r
36\r
37**/\r
38UINT8\r
39EFIAPI\r
40CalculateSum8 (\r
24dcb5e5 41 IN CONST UINT8 *Buffer,\r
42 IN UINTN Length\r
e1f414b6 43 )\r
44{\r
45 UINT8 Sum;\r
46 UINTN Count;\r
47\r
48 ASSERT (Buffer != NULL);\r
49 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
50\r
51 for (Sum = 0, Count = 0; Count < Length; Count++) {\r
52 Sum = (UINT8) (Sum + *(Buffer + Count));\r
53 }\r
54 \r
55 return Sum;\r
56}\r
57\r
58\r
59/**\r
60 Returns the two's complement checksum of all elements in a buffer \r
61 of 8-bit values.\r
62\r
63 This function first calculates the sum of the 8-bit values in the \r
64 buffer specified by Buffer and Length. The carry bits in the result \r
65 of addition are dropped. Then, the two's complement of the sum is \r
66 returned. If Length is 0, then 0 is returned.\r
67 \r
68 If Buffer is NULL, then ASSERT().\r
69 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
70\r
1106ffe1 71 @param Buffer Pointer to the buffer to carry out the checksum operation.\r
72 @param Length The size, in bytes, of Buffer.\r
e1f414b6 73\r
24dcb5e5 74 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 75\r
76**/\r
77UINT8\r
78EFIAPI\r
79CalculateCheckSum8 (\r
24dcb5e5 80 IN CONST UINT8 *Buffer,\r
81 IN UINTN Length\r
e1f414b6 82 )\r
83{\r
84 UINT8 CheckSum;\r
85\r
86 CheckSum = CalculateSum8 (Buffer, Length);\r
87\r
88 //\r
89 // Return the checksum based on 2's complement.\r
90 //\r
91 return (UINT8) (0x100 - CheckSum);\r
92}\r
93\r
94/**\r
95 Returns the sum of all elements in a buffer of 16-bit values. During \r
96 calculation, the carry bits are dropped.\r
97\r
98 This function calculates the sum of the 16-bit values in the buffer \r
99 specified by Buffer and Length. The carry bits in result of addition are dropped. \r
100 The 16-bit result is returned. If Length is 0, then 0 is returned. \r
101 \r
102 If Buffer is NULL, then ASSERT().\r
103 If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
104 If Length is not aligned on a 16-bit boundary, then ASSERT().\r
105 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
106\r
1106ffe1 107 @param Buffer Pointer to the buffer to carry out the sum operation.\r
108 @param Length The size, in bytes, of Buffer.\r
e1f414b6 109\r
110 @return Sum The sum of Buffer with carry bits dropped during additions.\r
111\r
112**/\r
113UINT16\r
114EFIAPI\r
115CalculateSum16 (\r
24dcb5e5 116 IN CONST UINT16 *Buffer,\r
117 IN UINTN Length\r
e1f414b6 118 )\r
119{\r
120 UINT16 Sum;\r
121 UINTN Count;\r
f9cea76b 122 UINTN Total;\r
e1f414b6 123\r
124 ASSERT (Buffer != NULL);\r
125 ASSERT (((UINTN) Buffer & 0x1) == 0);\r
126 ASSERT ((Length & 0x1) == 0);\r
127 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
128\r
f9cea76b 129 Total = Length / sizeof (*Buffer);\r
130 for (Sum = 0, Count = 0; Count < Total; Count++) {\r
e1f414b6 131 Sum = (UINT16) (Sum + *(Buffer + Count));\r
132 }\r
133 \r
134 return Sum;\r
135}\r
136\r
137\r
138/**\r
139 Returns the two's complement checksum of all elements in a buffer of \r
140 16-bit values.\r
141\r
142 This function first calculates the sum of the 16-bit values in the buffer \r
143 specified by Buffer and Length. The carry bits in the result of addition \r
144 are dropped. Then, the two's complement of the sum is returned. If Length \r
145 is 0, then 0 is returned.\r
146 \r
147 If Buffer is NULL, then ASSERT().\r
148 If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
149 If Length is not aligned on a 16-bit boundary, then ASSERT().\r
150 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
151\r
1106ffe1 152 @param Buffer Pointer to the buffer to carry out the checksum operation.\r
153 @param Length The size, in bytes, of Buffer.\r
e1f414b6 154\r
24dcb5e5 155 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 156\r
157**/\r
158UINT16\r
159EFIAPI\r
160CalculateCheckSum16 (\r
24dcb5e5 161 IN CONST UINT16 *Buffer,\r
162 IN UINTN Length\r
e1f414b6 163 )\r
164{\r
165 UINT16 CheckSum;\r
166\r
167 CheckSum = CalculateSum16 (Buffer, Length);\r
168\r
169 //\r
170 // Return the checksum based on 2's complement.\r
171 //\r
172 return (UINT16) (0x10000 - CheckSum);\r
173}\r
174\r
175\r
176/**\r
177 Returns the sum of all elements in a buffer of 32-bit values. During \r
178 calculation, the carry bits are dropped.\r
179\r
180 This function calculates the sum of the 32-bit values in the buffer \r
181 specified by Buffer and Length. The carry bits in result of addition are dropped. \r
182 The 32-bit result is returned. If Length is 0, then 0 is returned. \r
183 \r
184 If Buffer is NULL, then ASSERT().\r
185 If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
186 If Length is not aligned on a 32-bit boundary, then ASSERT().\r
187 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
188\r
1106ffe1 189 @param Buffer Pointer to the buffer to carry out the sum operation.\r
190 @param Length The size, in bytes, of Buffer.\r
e1f414b6 191\r
192 @return Sum The sum of Buffer with carry bits dropped during additions.\r
193\r
194**/\r
195UINT32\r
196EFIAPI\r
197CalculateSum32 (\r
24dcb5e5 198 IN CONST UINT32 *Buffer,\r
199 IN UINTN Length\r
e1f414b6 200 )\r
201{\r
202 UINT32 Sum;\r
203 UINTN Count;\r
f9cea76b 204 UINTN Total;\r
e1f414b6 205\r
206 ASSERT (Buffer != NULL);\r
207 ASSERT (((UINTN) Buffer & 0x3) == 0);\r
208 ASSERT ((Length & 0x3) == 0);\r
209 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
210\r
f9cea76b 211 Total = Length / sizeof (*Buffer);\r
212 for (Sum = 0, Count = 0; Count < Total; Count++) {\r
e1f414b6 213 Sum = Sum + *(Buffer + Count);\r
214 }\r
215 \r
216 return Sum;\r
217}\r
218\r
219\r
220/**\r
221 Returns the two's complement checksum of all elements in a buffer of \r
222 32-bit values.\r
223\r
224 This function first calculates the sum of the 32-bit values in the buffer \r
225 specified by Buffer and Length. The carry bits in the result of addition \r
226 are dropped. Then, the two's complement of the sum is returned. If Length \r
227 is 0, then 0 is returned.\r
228 \r
229 If Buffer is NULL, then ASSERT().\r
230 If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
231 If Length is not aligned on a 32-bit boundary, then ASSERT().\r
232 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
233\r
1106ffe1 234 @param Buffer Pointer to the buffer to carry out the checksum operation.\r
235 @param Length The size, in bytes, of Buffer.\r
e1f414b6 236\r
24dcb5e5 237 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 238\r
239**/\r
240UINT32\r
241EFIAPI\r
242CalculateCheckSum32 (\r
24dcb5e5 243 IN CONST UINT32 *Buffer,\r
244 IN UINTN Length\r
e1f414b6 245 )\r
246{\r
247 UINT32 CheckSum;\r
248\r
249 CheckSum = CalculateSum32 (Buffer, Length);\r
250\r
251 //\r
252 // Return the checksum based on 2's complement.\r
253 //\r
254 return (UINT32) ((UINT32)(-1) - CheckSum + 1);\r
255}\r
256\r
257\r
258/**\r
259 Returns the sum of all elements in a buffer of 64-bit values. During \r
260 calculation, the carry bits are dropped.\r
261\r
262 This function calculates the sum of the 64-bit values in the buffer \r
263 specified by Buffer and Length. The carry bits in result of addition are dropped. \r
264 The 64-bit result is returned. If Length is 0, then 0 is returned. \r
265 \r
266 If Buffer is NULL, then ASSERT().\r
267 If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
268 If Length is not aligned on a 64-bit boundary, then ASSERT().\r
269 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
270\r
1106ffe1 271 @param Buffer Pointer to the buffer to carry out the sum operation.\r
272 @param Length The size, in bytes, of Buffer.\r
e1f414b6 273\r
274 @return Sum The sum of Buffer with carry bits dropped during additions.\r
275\r
276**/\r
277UINT64\r
278EFIAPI\r
279CalculateSum64 (\r
24dcb5e5 280 IN CONST UINT64 *Buffer,\r
281 IN UINTN Length\r
e1f414b6 282 )\r
283{\r
284 UINT64 Sum;\r
285 UINTN Count;\r
f9cea76b 286 UINTN Total;\r
e1f414b6 287\r
288 ASSERT (Buffer != NULL);\r
289 ASSERT (((UINTN) Buffer & 0x7) == 0);\r
290 ASSERT ((Length & 0x7) == 0);\r
291 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
292\r
f9cea76b 293 Total = Length / sizeof (*Buffer);\r
294 for (Sum = 0, Count = 0; Count < Total; Count++) {\r
e1f414b6 295 Sum = Sum + *(Buffer + Count);\r
296 }\r
297 \r
298 return Sum;\r
299}\r
300\r
301\r
302/**\r
303 Returns the two's complement checksum of all elements in a buffer of \r
304 64-bit values.\r
305\r
306 This function first calculates the sum of the 64-bit values in the buffer \r
307 specified by Buffer and Length. The carry bits in the result of addition \r
308 are dropped. Then, the two's complement of the sum is returned. If Length \r
309 is 0, then 0 is returned.\r
310 \r
311 If Buffer is NULL, then ASSERT().\r
312 If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
313 If Length is not aligned on a 64-bit boundary, then ASSERT().\r
314 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
315\r
1106ffe1 316 @param Buffer Pointer to the buffer to carry out the checksum operation.\r
317 @param Length The size, in bytes, of Buffer.\r
e1f414b6 318\r
24dcb5e5 319 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 320\r
321**/\r
322UINT64\r
323EFIAPI\r
324CalculateCheckSum64 (\r
24dcb5e5 325 IN CONST UINT64 *Buffer,\r
326 IN UINTN Length\r
e1f414b6 327 )\r
328{\r
329 UINT64 CheckSum;\r
330\r
331 CheckSum = CalculateSum64 (Buffer, Length);\r
332\r
333 //\r
334 // Return the checksum based on 2's complement.\r
335 //\r
336 return (UINT64) ((UINT64)(-1) - CheckSum + 1);\r
337}\r
338\r
339\r