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