git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10683 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			338 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			338 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Utility functions to generate checksum based on 2's complement
 | |
|   algorithm.
 | |
| 
 | |
|   Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
 | |
|   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.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "BaseLibInternals.h"
 | |
| 
 | |
| /**
 | |
|   Returns 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      The 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      The 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      The 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;
 | |
|   UINTN     Total;
 | |
| 
 | |
|   ASSERT (Buffer != NULL);
 | |
|   ASSERT (((UINTN) Buffer & 0x1) == 0);
 | |
|   ASSERT ((Length & 0x1) == 0);
 | |
|   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
 | |
| 
 | |
|   Total = Length / sizeof (*Buffer);
 | |
|   for (Sum = 0, Count = 0; Count < Total; 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      The 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      The 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;
 | |
|   UINTN     Total;
 | |
| 
 | |
|   ASSERT (Buffer != NULL);
 | |
|   ASSERT (((UINTN) Buffer & 0x3) == 0);
 | |
|   ASSERT ((Length & 0x3) == 0);
 | |
|   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
 | |
| 
 | |
|   Total = Length / sizeof (*Buffer);
 | |
|   for (Sum = 0, Count = 0; Count < Total; 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      The 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      The 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;
 | |
|   UINTN     Total;
 | |
| 
 | |
|   ASSERT (Buffer != NULL);
 | |
|   ASSERT (((UINTN) Buffer & 0x7) == 0);
 | |
|   ASSERT ((Length & 0x7) == 0);
 | |
|   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
 | |
| 
 | |
|   Total = Length / sizeof (*Buffer);
 | |
|   for (Sum = 0, Count = 0; Count < Total; 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      The 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);
 | |
| }
 | |
| 
 | |
| 
 |