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