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