Home | History | Annotate | Download | only in Arm
      1 /** @file
      2   Unaligned access functions of BaseLib for ARM.
      3 
      4   volatile was added to work around optimization issues.
      5 
      6   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
      7   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
      8   This program and the accompanying materials
      9   are licensed and made available under the terms and conditions of the BSD License
     10   which accompanies this distribution.  The full text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     12 
     13   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 #include "BaseLibInternals.h"
     19 
     20 /**
     21   Reads a 16-bit value from memory that may be unaligned.
     22 
     23   This function returns the 16-bit value pointed to by Buffer. The function
     24   guarantees that the read operation does not produce an alignment fault.
     25 
     26   If the Buffer is NULL, then ASSERT().
     27 
     28   @param  Buffer  The pointer to a 16-bit value that may be unaligned.
     29 
     30   @return The 16-bit value read from Buffer.
     31 
     32 **/
     33 UINT16
     34 EFIAPI
     35 ReadUnaligned16 (
     36   IN CONST UINT16              *Buffer
     37   )
     38 {
     39   volatile UINT8 LowerByte;
     40   volatile UINT8 HigherByte;
     41 
     42   ASSERT (Buffer != NULL);
     43 
     44   LowerByte = ((UINT8*)Buffer)[0];
     45   HigherByte = ((UINT8*)Buffer)[1];
     46 
     47   return (UINT16)(LowerByte | (HigherByte << 8));
     48 }
     49 
     50 /**
     51   Writes a 16-bit value to memory that may be unaligned.
     52 
     53   This function writes the 16-bit value specified by Value to Buffer. Value is
     54   returned. The function guarantees that the write operation does not produce
     55   an alignment fault.
     56 
     57   If the Buffer is NULL, then ASSERT().
     58 
     59   @param  Buffer  The pointer to a 16-bit value that may be unaligned.
     60   @param  Value   16-bit value to write to Buffer.
     61 
     62   @return The 16-bit value to write to Buffer.
     63 
     64 **/
     65 UINT16
     66 EFIAPI
     67 WriteUnaligned16 (
     68   OUT UINT16                    *Buffer,
     69   IN  UINT16                    Value
     70   )
     71 {
     72   ASSERT (Buffer != NULL);
     73 
     74   ((volatile UINT8*)Buffer)[0] = (UINT8)Value;
     75   ((volatile UINT8*)Buffer)[1] = (UINT8)(Value >> 8);
     76 
     77   return Value;
     78 }
     79 
     80 /**
     81   Reads a 24-bit value from memory that may be unaligned.
     82 
     83   This function returns the 24-bit value pointed to by Buffer. The function
     84   guarantees that the read operation does not produce an alignment fault.
     85 
     86   If the Buffer is NULL, then ASSERT().
     87 
     88   @param  Buffer  The pointer to a 24-bit value that may be unaligned.
     89 
     90   @return The 24-bit value read from Buffer.
     91 
     92 **/
     93 UINT32
     94 EFIAPI
     95 ReadUnaligned24 (
     96   IN CONST UINT32              *Buffer
     97   )
     98 {
     99   ASSERT (Buffer != NULL);
    100 
    101   return (UINT32)(
    102             ReadUnaligned16 ((UINT16*)Buffer) |
    103             (((UINT8*)Buffer)[2] << 16)
    104             );
    105 }
    106 
    107 /**
    108   Writes a 24-bit value to memory that may be unaligned.
    109 
    110   This function writes the 24-bit value specified by Value to Buffer. Value is
    111   returned. The function guarantees that the write operation does not produce
    112   an alignment fault.
    113 
    114   If the Buffer is NULL, then ASSERT().
    115 
    116   @param  Buffer  The pointer to a 24-bit value that may be unaligned.
    117   @param  Value   24-bit value to write to Buffer.
    118 
    119   @return The 24-bit value to write to Buffer.
    120 
    121 **/
    122 UINT32
    123 EFIAPI
    124 WriteUnaligned24 (
    125   OUT UINT32                    *Buffer,
    126   IN  UINT32                    Value
    127   )
    128 {
    129   ASSERT (Buffer != NULL);
    130 
    131   WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);
    132   *(UINT8*)((UINT16*)Buffer + 1) = (UINT8)(Value >> 16);
    133   return Value;
    134 }
    135 
    136 /**
    137   Reads a 32-bit value from memory that may be unaligned.
    138 
    139   This function returns the 32-bit value pointed to by Buffer. The function
    140   guarantees that the read operation does not produce an alignment fault.
    141 
    142   If the Buffer is NULL, then ASSERT().
    143 
    144   @param  Buffer  The pointer to a 32-bit value that may be unaligned.
    145 
    146   @return The 32-bit value read from Buffer.
    147 
    148 **/
    149 UINT32
    150 EFIAPI
    151 ReadUnaligned32 (
    152   IN CONST UINT32              *Buffer
    153   )
    154 {
    155   UINT16  LowerBytes;
    156   UINT16  HigherBytes;
    157 
    158   ASSERT (Buffer != NULL);
    159 
    160   LowerBytes  = ReadUnaligned16 ((UINT16*) Buffer);
    161   HigherBytes = ReadUnaligned16 ((UINT16*) Buffer + 1);
    162 
    163   return (UINT32) (LowerBytes | (HigherBytes << 16));
    164 }
    165 
    166 /**
    167   Writes a 32-bit value to memory that may be unaligned.
    168 
    169   This function writes the 32-bit value specified by Value to Buffer. Value is
    170   returned. The function guarantees that the write operation does not produce
    171   an alignment fault.
    172 
    173   If the Buffer is NULL, then ASSERT().
    174 
    175   @param  Buffer  The pointer to a 32-bit value that may be unaligned.
    176   @param  Value   32-bit value to write to Buffer.
    177 
    178   @return The 32-bit value to write to Buffer.
    179 
    180 **/
    181 UINT32
    182 EFIAPI
    183 WriteUnaligned32 (
    184   OUT UINT32                    *Buffer,
    185   IN  UINT32                    Value
    186   )
    187 {
    188   ASSERT (Buffer != NULL);
    189 
    190   WriteUnaligned16 ((UINT16*)Buffer, (UINT16)Value);
    191   WriteUnaligned16 ((UINT16*)Buffer + 1, (UINT16)(Value >> 16));
    192   return Value;
    193 }
    194 
    195 /**
    196   Reads a 64-bit value from memory that may be unaligned.
    197 
    198   This function returns the 64-bit value pointed to by Buffer. The function
    199   guarantees that the read operation does not produce an alignment fault.
    200 
    201   If the Buffer is NULL, then ASSERT().
    202 
    203   @param  Buffer  The pointer to a 64-bit value that may be unaligned.
    204 
    205   @return The 64-bit value read from Buffer.
    206 
    207 **/
    208 UINT64
    209 EFIAPI
    210 ReadUnaligned64 (
    211   IN CONST UINT64              *Buffer
    212   )
    213 {
    214   UINT32  LowerBytes;
    215   UINT32  HigherBytes;
    216 
    217   ASSERT (Buffer != NULL);
    218 
    219   LowerBytes  = ReadUnaligned32 ((UINT32*) Buffer);
    220   HigherBytes = ReadUnaligned32 ((UINT32*) Buffer + 1);
    221 
    222   return (UINT64) (LowerBytes | LShiftU64 (HigherBytes, 32));
    223 }
    224 
    225 /**
    226   Writes a 64-bit value to memory that may be unaligned.
    227 
    228   This function writes the 64-bit value specified by Value to Buffer. Value is
    229   returned. The function guarantees that the write operation does not produce
    230   an alignment fault.
    231 
    232   If the Buffer is NULL, then ASSERT().
    233 
    234   @param  Buffer  The pointer to a 64-bit value that may be unaligned.
    235   @param  Value   64-bit value to write to Buffer.
    236 
    237   @return The 64-bit value to write to Buffer.
    238 
    239 **/
    240 UINT64
    241 EFIAPI
    242 WriteUnaligned64 (
    243   OUT UINT64                    *Buffer,
    244   IN  UINT64                    Value
    245   )
    246 {
    247   ASSERT (Buffer != NULL);
    248 
    249   WriteUnaligned32 ((UINT32*)Buffer, (UINT32)Value);
    250   WriteUnaligned32 ((UINT32*)Buffer + 1, (UINT32)RShiftU64 (Value, 32));
    251   return Value;
    252 }
    253