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