--- /dev/null
+/** @file\r
+ Utility functions to generate checksum based on 2's complement\r
+ algorithm.\r
+\r
+ Copyright (c) 2007, Intel Corporation<BR>\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+ Module Name: CheckSum.c\r
+\r
+**/\r
+\r
+/**\r
+ Calculate the sum of all elements in a buffer in unit of UINT8. \r
+ During calculation, the carry bits are dropped.\r
+\r
+ This function calculates the sum of all elements in a buffer \r
+ in unit of UINT8. The carry bits in result of addition are dropped. \r
+ The result is returned as UINT8. If Length is Zero, then Zero is \r
+ returned.\r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
+\r
+ @param Buffer Pointer to the buffer to carry out the sum operation.\r
+ @param Length The size, in bytes, of Buffer .\r
+\r
+ @return Sum The sum of Buffer with carry bits dropped during additions.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+CalculateSum8 (\r
+ IN CONST UINT8 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT8 Sum;\r
+ UINTN Count;\r
+\r
+ ASSERT (Buffer != NULL);\r
+ ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
+\r
+ for (Sum = 0, Count = 0; Count < Length; Count++) {\r
+ Sum = (UINT8) (Sum + *(Buffer + Count));\r
+ }\r
+ \r
+ return Sum;\r
+}\r
+\r
+\r
+/**\r
+ Returns the two's complement checksum of all elements in a buffer \r
+ of 8-bit values.\r
+\r
+ This function first calculates the sum of the 8-bit values in the \r
+ buffer specified by Buffer and Length. The carry bits in the result \r
+ of addition are dropped. Then, the two's complement of the sum is \r
+ returned. If Length is 0, then 0 is returned.\r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+\r
+ @param Buffer Pointer to the buffer to carry out the checksum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Checksum The 2's complement checksum of Buffer.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+CalculateCheckSum8 (\r
+ IN CONST UINT8 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT8 CheckSum;\r
+\r
+ CheckSum = CalculateSum8 (Buffer, Length);\r
+\r
+ //\r
+ // Return the checksum based on 2's complement.\r
+ //\r
+ return (UINT8) (0x100 - CheckSum);\r
+}\r
+\r
+/**\r
+ Returns the sum of all elements in a buffer of 16-bit values. During \r
+ calculation, the carry bits are dropped.\r
+\r
+ This function calculates the sum of the 16-bit values in the buffer \r
+ specified by Buffer and Length. The carry bits in result of addition are dropped. \r
+ The 16-bit result is returned. If Length is 0, then 0 is returned. \r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Length is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+ @param Buffer Pointer to the buffer to carry out the sum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Sum The sum of Buffer with carry bits dropped during additions.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+CalculateSum16 (\r
+ IN CONST UINT16 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT16 Sum;\r
+ UINTN Count;\r
+\r
+ ASSERT (Buffer != NULL);\r
+ ASSERT (((UINTN) Buffer & 0x1) == 0);\r
+ ASSERT ((Length & 0x1) == 0);\r
+ ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
+\r
+\r
+ for (Sum = 0, Count = 0; Count < Length; Count++) {\r
+ Sum = (UINT16) (Sum + *(Buffer + Count));\r
+ }\r
+ \r
+ return Sum;\r
+}\r
+\r
+\r
+/**\r
+ Returns the two's complement checksum of all elements in a buffer of \r
+ 16-bit values.\r
+\r
+ This function first calculates the sum of the 16-bit values in the buffer \r
+ specified by Buffer and Length. The carry bits in the result of addition \r
+ are dropped. Then, the two's complement of the sum is returned. If Length \r
+ is 0, then 0 is returned.\r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Length is not aligned on a 16-bit boundary, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
+\r
+ @param Buffer Pointer to the buffer to carry out the checksum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Checksum The 2's complement checksum of Buffer.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+CalculateCheckSum16 (\r
+ IN CONST UINT16 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT16 CheckSum;\r
+\r
+ CheckSum = CalculateSum16 (Buffer, Length);\r
+\r
+ //\r
+ // Return the checksum based on 2's complement.\r
+ //\r
+ return (UINT16) (0x10000 - CheckSum);\r
+}\r
+\r
+\r
+/**\r
+ Returns the sum of all elements in a buffer of 32-bit values. During \r
+ calculation, the carry bits are dropped.\r
+\r
+ This function calculates the sum of the 32-bit values in the buffer \r
+ specified by Buffer and Length. The carry bits in result of addition are dropped. \r
+ The 32-bit result is returned. If Length is 0, then 0 is returned. \r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
+ If Length is not aligned on a 32-bit boundary, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+ @param Buffer Pointer to the buffer to carry out the sum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Sum The sum of Buffer with carry bits dropped during additions.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+CalculateSum32 (\r
+ IN CONST UINT32 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT32 Sum;\r
+ UINTN Count;\r
+\r
+ ASSERT (Buffer != NULL);\r
+ ASSERT (((UINTN) Buffer & 0x3) == 0);\r
+ ASSERT ((Length & 0x3) == 0);\r
+ ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
+\r
+\r
+ for (Sum = 0, Count = 0; Count < Length; Count++) {\r
+ Sum = Sum + *(Buffer + Count);\r
+ }\r
+ \r
+ return Sum;\r
+}\r
+\r
+\r
+/**\r
+ Returns the two's complement checksum of all elements in a buffer of \r
+ 32-bit values.\r
+\r
+ This function first calculates the sum of the 32-bit values in the buffer \r
+ specified by Buffer and Length. The carry bits in the result of addition \r
+ are dropped. Then, the two's complement of the sum is returned. If Length \r
+ is 0, then 0 is returned.\r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
+ If Length is not aligned on a 32-bit boundary, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
+\r
+ @param Buffer Pointer to the buffer to carry out the checksum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Checksum The 2's complement checksum of Buffer.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+CalculateCheckSum32 (\r
+ IN CONST UINT32 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT32 CheckSum;\r
+\r
+ CheckSum = CalculateSum32 (Buffer, Length);\r
+\r
+ //\r
+ // Return the checksum based on 2's complement.\r
+ //\r
+ return (UINT32) ((UINT32)(-1) - CheckSum + 1);\r
+}\r
+\r
+\r
+/**\r
+ Returns the sum of all elements in a buffer of 64-bit values. During \r
+ calculation, the carry bits are dropped.\r
+\r
+ This function calculates the sum of the 64-bit values in the buffer \r
+ specified by Buffer and Length. The carry bits in result of addition are dropped. \r
+ The 64-bit result is returned. If Length is 0, then 0 is returned. \r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
+ If Length is not aligned on a 64-bit boundary, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
+\r
+ @param Buffer Pointer to the buffer to carry out the sum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Sum The sum of Buffer with carry bits dropped during additions.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+CalculateSum64 (\r
+ IN CONST UINT64 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT64 Sum;\r
+ UINTN Count;\r
+\r
+ ASSERT (Buffer != NULL);\r
+ ASSERT (((UINTN) Buffer & 0x7) == 0);\r
+ ASSERT ((Length & 0x7) == 0);\r
+ ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));\r
+\r
+ for (Sum = 0, Count = 0; Count < Length; Count++) {\r
+ Sum = Sum + *(Buffer + Count);\r
+ }\r
+ \r
+ return Sum;\r
+}\r
+\r
+\r
+/**\r
+ Returns the two's complement checksum of all elements in a buffer of \r
+ 64-bit values.\r
+\r
+ This function first calculates the sum of the 64-bit values in the buffer \r
+ specified by Buffer and Length. The carry bits in the result of addition \r
+ are dropped. Then, the two's complement of the sum is returned. If Length \r
+ is 0, then 0 is returned.\r
+ \r
+ If Buffer is NULL, then ASSERT().\r
+ If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
+ If Length is not aligned on a 64-bit boundary, then ASSERT().\r
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
+\r
+ @param Buffer Pointer to the buffer to carry out the checksum operation.\r
+ @param Length The size, in bytes, of Buffer.\r
+\r
+ @return Checksum The 2's complement checksum of Buffer.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+CalculateCheckSum64 (\r
+ IN CONST UINT64 *Buffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT64 CheckSum;\r
+\r
+ CheckSum = CalculateSum64 (Buffer, Length);\r
+\r
+ //\r
+ // Return the checksum based on 2's complement.\r
+ //\r
+ return (UINT64) ((UINT64)(-1) - CheckSum + 1);\r
+}\r
+\r
+\r