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