1 /** @file 2 I/O Library MMIO Buffer Functions. 3 The implementations are based on EFI_PEI_SERVICE->CpuIo interface. 4 5 Copyright (c) 2007 - 2009, 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 17 #include <PiPei.h> 18 19 #include <Library/IoLib.h> 20 #include <Library/DebugLib.h> 21 #include <Library/BaseLib.h> 22 #include <Library/PeiServicesTablePointerLib.h> 23 24 /** 25 Copy data from MMIO region to system memory by using 8-bit access. 26 27 Copy data from MMIO region specified by starting address StartAddress 28 to system memory specified by Buffer by using 8-bit access. The total 29 number of byte to be copied is specified by Length. Buffer is returned. 30 31 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 32 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 33 34 35 @param StartAddress The starting address for the MMIO region to be copied from. 36 @param Length The size, in bytes, of Buffer. 37 @param Buffer The pointer to a system memory buffer receiving the data read. 38 39 @return Buffer 40 41 **/ 42 UINT8 * 43 EFIAPI 44 MmioReadBuffer8 ( 45 IN UINTN StartAddress, 46 IN UINTN Length, 47 OUT UINT8 *Buffer 48 ) 49 { 50 UINT8 *ReturnBuffer; 51 52 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 53 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 54 55 ReturnBuffer = Buffer; 56 57 while (Length-- != 0) { 58 *(Buffer++) = MmioRead8 (StartAddress++); 59 } 60 61 return ReturnBuffer; 62 } 63 64 /** 65 Copy data from MMIO region to system memory by using 16-bit access. 66 67 Copy data from MMIO region specified by starting address StartAddress 68 to system memory specified by Buffer by using 16-bit access. The total 69 number of byte to be copied is specified by Length. Buffer is returned. 70 71 If StartAddress is not aligned on a 16-bit boundary, then ASSERT(). 72 73 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 74 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 75 76 If Length is not aligned on a 16-bit boundary, then ASSERT(). 77 If Buffer is not aligned on a 16-bit boundary, then ASSERT(). 78 79 @param StartAddress The starting address for the MMIO region to be copied from. 80 @param Length The size, in bytes, of Buffer. 81 @param Buffer The pointer to a system memory buffer receiving the data read. 82 83 @return Buffer 84 85 **/ 86 UINT16 * 87 EFIAPI 88 MmioReadBuffer16 ( 89 IN UINTN StartAddress, 90 IN UINTN Length, 91 OUT UINT16 *Buffer 92 ) 93 { 94 UINT16 *ReturnBuffer; 95 96 ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0); 97 98 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 99 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 100 101 ASSERT ((Length & (sizeof (UINT16) - 1)) == 0); 102 ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0); 103 104 ReturnBuffer = Buffer; 105 106 while (Length != 0) { 107 *(Buffer++) = MmioRead16 (StartAddress); 108 StartAddress += sizeof (UINT16); 109 Length -= sizeof (UINT16); 110 } 111 112 return ReturnBuffer; 113 } 114 115 /** 116 Copy data from MMIO region to system memory by using 32-bit access. 117 118 Copy data from MMIO region specified by starting address StartAddress 119 to system memory specified by Buffer by using 32-bit access. The total 120 number of byte to be copied is specified by Length. Buffer is returned. 121 122 If StartAddress is not aligned on a 32-bit boundary, then ASSERT(). 123 124 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 125 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 126 127 If Length is not aligned on a 32-bit boundary, then ASSERT(). 128 If Buffer is not aligned on a 32-bit boundary, then ASSERT(). 129 130 @param StartAddress The starting address for the MMIO region to be copied from. 131 @param Length The size, in bytes, of Buffer. 132 @param Buffer The pointer to a system memory buffer receiving the data read. 133 134 @return Buffer 135 136 **/ 137 UINT32 * 138 EFIAPI 139 MmioReadBuffer32 ( 140 IN UINTN StartAddress, 141 IN UINTN Length, 142 OUT UINT32 *Buffer 143 ) 144 { 145 UINT32 *ReturnBuffer; 146 147 ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0); 148 149 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 150 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 151 152 ASSERT ((Length & (sizeof (UINT32) - 1)) == 0); 153 ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0); 154 155 ReturnBuffer = Buffer; 156 157 while (Length != 0) { 158 *(Buffer++) = MmioRead32 (StartAddress); 159 StartAddress += sizeof (UINT32); 160 Length -= sizeof (UINT32); 161 } 162 163 return ReturnBuffer; 164 } 165 166 /** 167 Copy data from MMIO region to system memory by using 64-bit access. 168 169 Copy data from MMIO region specified by starting address StartAddress 170 to system memory specified by Buffer by using 64-bit access. The total 171 number of byte to be copied is specified by Length. Buffer is returned. 172 173 If StartAddress is not aligned on a 64-bit boundary, then ASSERT(). 174 175 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 176 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). 177 178 If Length is not aligned on a 64-bit boundary, then ASSERT(). 179 If Buffer is not aligned on a 64-bit boundary, then ASSERT(). 180 181 @param StartAddress The starting address for the MMIO region to be copied from. 182 @param Length The size, in bytes, of Buffer. 183 @param Buffer The pointer to a system memory buffer receiving the data read. 184 185 @return Buffer 186 187 **/ 188 UINT64 * 189 EFIAPI 190 MmioReadBuffer64 ( 191 IN UINTN StartAddress, 192 IN UINTN Length, 193 OUT UINT64 *Buffer 194 ) 195 { 196 UINT64 *ReturnBuffer; 197 198 ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0); 199 200 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 201 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 202 203 ASSERT ((Length & (sizeof (UINT64) - 1)) == 0); 204 ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0); 205 206 ReturnBuffer = Buffer; 207 208 while (Length != 0) { 209 *(Buffer++) = MmioRead64 (StartAddress); 210 StartAddress += sizeof (UINT64); 211 Length -= sizeof (UINT64); 212 } 213 214 return ReturnBuffer; 215 } 216 217 218 /** 219 Copy data from system memory to MMIO region by using 8-bit access. 220 221 Copy data from system memory specified by Buffer to MMIO region specified 222 by starting address StartAddress by using 8-bit access. The total number 223 of byte to be copied is specified by Length. Buffer is returned. 224 225 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 226 If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT(). 227 228 229 @param StartAddress The starting address for the MMIO region to be copied to. 230 @param Length The size, in bytes, of Buffer. 231 @param Buffer The pointer to a system memory buffer containing the data to write. 232 233 @return Buffer 234 235 **/ 236 UINT8 * 237 EFIAPI 238 MmioWriteBuffer8 ( 239 IN UINTN StartAddress, 240 IN UINTN Length, 241 IN CONST UINT8 *Buffer 242 ) 243 { 244 VOID* ReturnBuffer; 245 246 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 247 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 248 249 ReturnBuffer = (UINT8 *) Buffer; 250 251 while (Length-- != 0) { 252 MmioWrite8 (StartAddress++, *(Buffer++)); 253 } 254 255 return ReturnBuffer; 256 257 } 258 259 /** 260 Copy data from system memory to MMIO region by using 16-bit access. 261 262 Copy data from system memory specified by Buffer to MMIO region specified 263 by starting address StartAddress by using 16-bit access. The total number 264 of byte to be copied is specified by Length. Buffer is returned. 265 266 If StartAddress is not aligned on a 16-bit boundary, then ASSERT(). 267 268 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 269 If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT(). 270 271 If Length is not aligned on a 16-bit boundary, then ASSERT(). 272 273 If Buffer is not aligned on a 16-bit boundary, then ASSERT(). 274 275 @param StartAddress The starting address for the MMIO region to be copied to. 276 @param Length The size, in bytes, of Buffer. 277 @param Buffer The pointer to a system memory buffer containing the data to write. 278 279 @return Buffer 280 281 **/ 282 UINT16 * 283 EFIAPI 284 MmioWriteBuffer16 ( 285 IN UINTN StartAddress, 286 IN UINTN Length, 287 IN CONST UINT16 *Buffer 288 ) 289 { 290 UINT16 *ReturnBuffer; 291 292 ASSERT ((StartAddress & (sizeof (UINT16) - 1)) == 0); 293 294 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 295 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 296 297 ASSERT ((Length & (sizeof (UINT16) - 1)) == 0); 298 ASSERT (((UINTN) Buffer & (sizeof (UINT16) - 1)) == 0); 299 300 ReturnBuffer = (UINT16 *) Buffer; 301 302 while (Length != 0) { 303 MmioWrite16 (StartAddress, *(Buffer++)); 304 305 StartAddress += sizeof (UINT16); 306 Length -= sizeof (UINT16); 307 } 308 309 return ReturnBuffer; 310 } 311 312 313 /** 314 Copy data from system memory to MMIO region by using 32-bit access. 315 316 Copy data from system memory specified by Buffer to MMIO region specified 317 by starting address StartAddress by using 32-bit access. The total number 318 of byte to be copied is specified by Length. Buffer is returned. 319 320 If StartAddress is not aligned on a 32-bit boundary, then ASSERT(). 321 322 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 323 If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT(). 324 325 If Length is not aligned on a 32-bit boundary, then ASSERT(). 326 327 If Buffer is not aligned on a 32-bit boundary, then ASSERT(). 328 329 @param StartAddress The starting address for the MMIO region to be copied to. 330 @param Length The size, in bytes, of Buffer. 331 @param Buffer The pointer to a system memory buffer containing the data to write. 332 333 @return Buffer 334 335 **/ 336 UINT32 * 337 EFIAPI 338 MmioWriteBuffer32 ( 339 IN UINTN StartAddress, 340 IN UINTN Length, 341 IN CONST UINT32 *Buffer 342 ) 343 { 344 UINT32 *ReturnBuffer; 345 346 ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0); 347 348 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 349 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 350 351 ASSERT ((Length & (sizeof (UINT32) - 1)) == 0); 352 ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0); 353 354 ReturnBuffer = (UINT32 *) Buffer; 355 356 while (Length != 0) { 357 MmioWrite32 (StartAddress, *(Buffer++)); 358 359 StartAddress += sizeof (UINT32); 360 Length -= sizeof (UINT32); 361 } 362 363 return ReturnBuffer; 364 } 365 366 /** 367 Copy data from system memory to MMIO region by using 64-bit access. 368 369 Copy data from system memory specified by Buffer to MMIO region specified 370 by starting address StartAddress by using 64-bit access. The total number 371 of byte to be copied is specified by Length. Buffer is returned. 372 373 If StartAddress is not aligned on a 64-bit boundary, then ASSERT(). 374 375 If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT(). 376 If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT(). 377 378 If Length is not aligned on a 64-bit boundary, then ASSERT(). 379 380 If Buffer is not aligned on a 64-bit boundary, then ASSERT(). 381 382 @param StartAddress The starting address for the MMIO region to be copied to. 383 @param Length The size, in bytes, of Buffer. 384 @param Buffer The pointer to a system memory buffer containing the data to write. 385 386 @return Buffer 387 388 **/ 389 UINT64 * 390 EFIAPI 391 MmioWriteBuffer64 ( 392 IN UINTN StartAddress, 393 IN UINTN Length, 394 IN CONST UINT64 *Buffer 395 ) 396 { 397 UINT64 *ReturnBuffer; 398 399 ASSERT ((StartAddress & (sizeof (UINT64) - 1)) == 0); 400 401 ASSERT ((Length - 1) <= (MAX_ADDRESS - StartAddress)); 402 ASSERT ((Length - 1) <= (MAX_ADDRESS - (UINTN) Buffer)); 403 404 ASSERT ((Length & (sizeof (UINT64) - 1)) == 0); 405 ASSERT (((UINTN) Buffer & (sizeof (UINT64) - 1)) == 0); 406 407 ReturnBuffer = (UINT64 *) Buffer; 408 409 while (Length != 0) { 410 MmioWrite64 (StartAddress, *(Buffer++)); 411 412 StartAddress += sizeof (UINT64); 413 Length -= sizeof (UINT64); 414 } 415 416 return ReturnBuffer; 417 } 418 419