1 /** @file 2 I/O Library. 3 The implementation of I/O operation for this library instance 4 are based on EFI_CPU_IO_PROTOCOL. 5 6 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> 7 This program and the accompanying materials 8 are licensed and made available under the terms and conditions of the BSD License 9 which accompanies this distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15 Module Name: IoLib.c 16 17 **/ 18 19 20 #include "DxeCpuIoLibInternal.h" 21 22 // 23 // Globle varible to cache pointer to CpuIo protocol. 24 // 25 EFI_CPU_IO_PROTOCOL *mCpuIo = NULL; 26 27 /** 28 The constructor function caches the pointer to CpuIo protocol. 29 30 The constructor function locates CpuIo protocol from protocol database. 31 It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. 32 33 @param ImageHandle The firmware allocated handle for the EFI image. 34 @param SystemTable A pointer to the EFI System Table. 35 36 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. 37 38 **/ 39 EFI_STATUS 40 EFIAPI 41 IoLibConstructor ( 42 IN EFI_HANDLE ImageHandle, 43 IN EFI_SYSTEM_TABLE *SystemTable 44 ) 45 { 46 EFI_STATUS Status; 47 48 Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, (VOID **) &mCpuIo); 49 ASSERT_EFI_ERROR (Status); 50 51 return Status; 52 } 53 54 /** 55 Reads registers in the EFI CPU I/O space. 56 57 Reads the I/O port specified by Port with registers width specified by Width. 58 The read value is returned. If such operations are not supported, then ASSERT(). 59 This function must guarantee that all I/O read and write operations are serialized. 60 61 @param Port The base address of the I/O operation. 62 The caller is responsible for aligning the Address if required. 63 @param Width The width of the I/O operation. 64 65 @return Data read from registers in the EFI CPU I/O space. 66 67 **/ 68 UINT64 69 EFIAPI 70 IoReadWorker ( 71 IN UINTN Port, 72 IN EFI_CPU_IO_PROTOCOL_WIDTH Width 73 ) 74 { 75 EFI_STATUS Status; 76 UINT64 Data; 77 78 Status = mCpuIo->Io.Read (mCpuIo, Width, Port, 1, &Data); 79 ASSERT_EFI_ERROR (Status); 80 81 return Data; 82 } 83 84 /** 85 Writes registers in the EFI CPU I/O space. 86 87 Writes the I/O port specified by Port with registers width and value specified by Width 88 and Data respectively. Data is returned. If such operations are not supported, then ASSERT(). 89 This function must guarantee that all I/O read and write operations are serialized. 90 91 @param Port The base address of the I/O operation. 92 The caller is responsible for aligning the Address if required. 93 @param Width The width of the I/O operation. 94 @param Data The value to write to the I/O port. 95 96 @return The paramter of Data. 97 98 **/ 99 UINT64 100 EFIAPI 101 IoWriteWorker ( 102 IN UINTN Port, 103 IN EFI_CPU_IO_PROTOCOL_WIDTH Width, 104 IN UINT64 Data 105 ) 106 { 107 EFI_STATUS Status; 108 109 Status = mCpuIo->Io.Write (mCpuIo, Width, Port, 1, &Data); 110 ASSERT_EFI_ERROR (Status); 111 112 return Data; 113 } 114 115 /** 116 Reads memory-mapped registers in the EFI system memory space. 117 118 Reads the MMIO registers specified by Address with registers width specified by Width. 119 The read value is returned. If such operations are not supported, then ASSERT(). 120 This function must guarantee that all MMIO read and write operations are serialized. 121 122 @param Address The MMIO register to read. 123 The caller is responsible for aligning the Address if required. 124 @param Width The width of the I/O operation. 125 126 @return Data read from registers in the EFI system memory space. 127 128 **/ 129 UINT64 130 EFIAPI 131 MmioReadWorker ( 132 IN UINTN Address, 133 IN EFI_CPU_IO_PROTOCOL_WIDTH Width 134 ) 135 { 136 EFI_STATUS Status; 137 UINT64 Data; 138 139 Status = mCpuIo->Mem.Read (mCpuIo, Width, Address, 1, &Data); 140 ASSERT_EFI_ERROR (Status); 141 142 return Data; 143 } 144 145 /** 146 Writes memory-mapped registers in the EFI system memory space. 147 148 Writes the MMIO registers specified by Address with registers width and value specified by Width 149 and Data respectively. Data is returned. If such operations are not supported, then ASSERT(). 150 This function must guarantee that all MMIO read and write operations are serialized. 151 152 @param Address The MMIO register to read. 153 The caller is responsible for aligning the Address if required. 154 @param Width The width of the I/O operation. 155 @param Data The value to write to the I/O port. 156 157 @return Data read from registers in the EFI system memory space. 158 159 **/ 160 UINT64 161 EFIAPI 162 MmioWriteWorker ( 163 IN UINTN Address, 164 IN EFI_CPU_IO_PROTOCOL_WIDTH Width, 165 IN UINT64 Data 166 ) 167 { 168 EFI_STATUS Status; 169 170 Status = mCpuIo->Mem.Write (mCpuIo, Width, Address, 1, &Data); 171 ASSERT_EFI_ERROR (Status); 172 173 return Data; 174 } 175 176 /** 177 Reads an 8-bit I/O port. 178 179 Reads the 8-bit I/O port specified by Port. The 8-bit read value is returned. 180 This function must guarantee that all I/O read and write operations are 181 serialized. 182 183 If 8-bit I/O port operations are not supported, then ASSERT(). 184 185 @param Port The I/O port to read. 186 187 @return The value read. 188 189 **/ 190 UINT8 191 EFIAPI 192 IoRead8 ( 193 IN UINTN Port 194 ) 195 { 196 return (UINT8)IoReadWorker (Port, EfiCpuIoWidthUint8); 197 } 198 199 /** 200 Writes an 8-bit I/O port. 201 202 Writes the 8-bit I/O port specified by Port with the value specified by Value 203 and returns Value. This function must guarantee that all I/O read and write 204 operations are serialized. 205 206 If 8-bit I/O port operations are not supported, then ASSERT(). 207 208 @param Port The I/O port to write. 209 @param Value The value to write to the I/O port. 210 211 @return The value written the I/O port. 212 213 **/ 214 UINT8 215 EFIAPI 216 IoWrite8 ( 217 IN UINTN Port, 218 IN UINT8 Value 219 ) 220 { 221 return (UINT8)IoWriteWorker (Port, EfiCpuIoWidthUint8, Value); 222 } 223 224 /** 225 Reads a 16-bit I/O port. 226 227 Reads the 16-bit I/O port specified by Port. The 16-bit read value is returned. 228 This function must guarantee that all I/O read and write operations are 229 serialized. 230 231 If Port is not aligned on a 16-bit boundary, then ASSERT(). 232 233 If 16-bit I/O port operations are not supported, then ASSERT(). 234 235 @param Port The I/O port to read. 236 237 @return The value read. 238 239 **/ 240 UINT16 241 EFIAPI 242 IoRead16 ( 243 IN UINTN Port 244 ) 245 { 246 // 247 // Make sure Port is aligned on a 16-bit boundary. 248 // 249 ASSERT ((Port & 1) == 0); 250 return (UINT16)IoReadWorker (Port, EfiCpuIoWidthUint16); 251 } 252 253 /** 254 Writes a 16-bit I/O port. 255 256 Writes the 16-bit I/O port specified by Port with the value specified by Value 257 and returns Value. This function must guarantee that all I/O read and write 258 operations are serialized. 259 260 If Port is not aligned on a 16-bit boundary, then ASSERT(). 261 262 If 16-bit I/O port operations are not supported, then ASSERT(). 263 264 @param Port The I/O port to write. 265 @param Value The value to write to the I/O port. 266 267 @return The value written the I/O port. 268 269 **/ 270 UINT16 271 EFIAPI 272 IoWrite16 ( 273 IN UINTN Port, 274 IN UINT16 Value 275 ) 276 { 277 // 278 // Make sure Port is aligned on a 16-bit boundary. 279 // 280 ASSERT ((Port & 1) == 0); 281 return (UINT16)IoWriteWorker (Port, EfiCpuIoWidthUint16, Value); 282 } 283 284 /** 285 Reads a 32-bit I/O port. 286 287 Reads the 32-bit I/O port specified by Port. The 32-bit read value is returned. 288 This function must guarantee that all I/O read and write operations are 289 serialized. 290 291 If Port is not aligned on a 32-bit boundary, then ASSERT(). 292 293 If 32-bit I/O port operations are not supported, then ASSERT(). 294 295 @param Port The I/O port to read. 296 297 @return The value read. 298 299 **/ 300 UINT32 301 EFIAPI 302 IoRead32 ( 303 IN UINTN Port 304 ) 305 { 306 // 307 // Make sure Port is aligned on a 32-bit boundary. 308 // 309 ASSERT ((Port & 3) == 0); 310 return (UINT32)IoReadWorker (Port, EfiCpuIoWidthUint32); 311 } 312 313 /** 314 Writes a 32-bit I/O port. 315 316 Writes the 32-bit I/O port specified by Port with the value specified by Value 317 and returns Value. This function must guarantee that all I/O read and write 318 operations are serialized. 319 320 If Port is not aligned on a 32-bit boundary, then ASSERT(). 321 322 If 32-bit I/O port operations are not supported, then ASSERT(). 323 324 @param Port The I/O port to write. 325 @param Value The value to write to the I/O port. 326 327 @return The value written the I/O port. 328 329 **/ 330 UINT32 331 EFIAPI 332 IoWrite32 ( 333 IN UINTN Port, 334 IN UINT32 Value 335 ) 336 { 337 // 338 // Make sure Port is aligned on a 32-bit boundary. 339 // 340 ASSERT ((Port & 3) == 0); 341 return (UINT32)IoWriteWorker (Port, EfiCpuIoWidthUint32, Value); 342 } 343 344 /** 345 Reads a 64-bit I/O port. 346 347 Reads the 64-bit I/O port specified by Port. The 64-bit read value is returned. 348 This function must guarantee that all I/O read and write operations are 349 serialized. 350 351 If Port is not aligned on a 64-bit boundary, then ASSERT(). 352 353 If 64-bit I/O port operations are not supported, then ASSERT(). 354 355 @param Port The I/O port to read. 356 357 @return The value read. 358 359 **/ 360 UINT64 361 EFIAPI 362 IoRead64 ( 363 IN UINTN Port 364 ) 365 { 366 // 367 // Make sure Port is aligned on a 64-bit boundary. 368 // 369 ASSERT ((Port & 7) == 0); 370 return IoReadWorker (Port, EfiCpuIoWidthUint64); 371 } 372 373 /** 374 Writes a 64-bit I/O port. 375 376 Writes the 64-bit I/O port specified by Port with the value specified by Value 377 and returns Value. This function must guarantee that all I/O read and write 378 operations are serialized. 379 380 If Port is not aligned on a 64-bit boundary, then ASSERT(). 381 382 If 64-bit I/O port operations are not supported, then ASSERT(). 383 384 @param Port The I/O port to write. 385 @param Value The value to write to the I/O port. 386 387 @return The value written the I/O port. 388 389 **/ 390 UINT64 391 EFIAPI 392 IoWrite64 ( 393 IN UINTN Port, 394 IN UINT64 Value 395 ) 396 { 397 // 398 // Make sure Port is aligned on a 64-bit boundary. 399 // 400 ASSERT ((Port & 7) == 0); 401 return IoWriteWorker (Port, EfiCpuIoWidthUint64, Value); 402 } 403 404 /** 405 Reads an 8-bit MMIO register. 406 407 Reads the 8-bit MMIO register specified by Address. The 8-bit read value is 408 returned. This function must guarantee that all MMIO read and write 409 operations are serialized. 410 411 If 8-bit MMIO register operations are not supported, then ASSERT(). 412 413 @param Address The MMIO register to read. 414 415 @return The value read. 416 417 **/ 418 UINT8 419 EFIAPI 420 MmioRead8 ( 421 IN UINTN Address 422 ) 423 { 424 return (UINT8)MmioReadWorker (Address, EfiCpuIoWidthUint8); 425 } 426 427 /** 428 Writes an 8-bit MMIO register. 429 430 Writes the 8-bit MMIO register specified by Address with the value specified 431 by Value and returns Value. This function must guarantee that all MMIO read 432 and write operations are serialized. 433 434 If 8-bit MMIO register operations are not supported, then ASSERT(). 435 436 @param Address The MMIO register to write. 437 @param Value The value to write to the MMIO register. 438 439 **/ 440 UINT8 441 EFIAPI 442 MmioWrite8 ( 443 IN UINTN Address, 444 IN UINT8 Value 445 ) 446 { 447 return (UINT8)MmioWriteWorker (Address, EfiCpuIoWidthUint8, Value); 448 } 449 450 /** 451 Reads a 16-bit MMIO register. 452 453 Reads the 16-bit MMIO register specified by Address. The 16-bit read value is 454 returned. This function must guarantee that all MMIO read and write 455 operations are serialized. 456 457 If Address is not aligned on a 16-bit boundary, then ASSERT(). 458 459 If 16-bit MMIO register operations are not supported, then ASSERT(). 460 461 @param Address The MMIO register to read. 462 463 @return The value read. 464 465 **/ 466 UINT16 467 EFIAPI 468 MmioRead16 ( 469 IN UINTN Address 470 ) 471 { 472 // 473 // Make sure Address is aligned on a 16-bit boundary. 474 // 475 ASSERT ((Address & 1) == 0); 476 return (UINT16)MmioReadWorker (Address, EfiCpuIoWidthUint16); 477 } 478 479 /** 480 Writes a 16-bit MMIO register. 481 482 Writes the 16-bit MMIO register specified by Address with the value specified 483 by Value and returns Value. This function must guarantee that all MMIO read 484 and write operations are serialized. 485 486 If Address is not aligned on a 16-bit boundary, then ASSERT(). 487 488 If 16-bit MMIO register operations are not supported, then ASSERT(). 489 490 @param Address The MMIO register to write. 491 @param Value The value to write to the MMIO register. 492 493 **/ 494 UINT16 495 EFIAPI 496 MmioWrite16 ( 497 IN UINTN Address, 498 IN UINT16 Value 499 ) 500 { 501 // 502 // Make sure Address is aligned on a 16-bit boundary. 503 // 504 ASSERT ((Address & 1) == 0); 505 return (UINT16)MmioWriteWorker (Address, EfiCpuIoWidthUint16, Value); 506 } 507 508 /** 509 Reads a 32-bit MMIO register. 510 511 Reads the 32-bit MMIO register specified by Address. The 32-bit read value is 512 returned. This function must guarantee that all MMIO read and write 513 operations are serialized. 514 515 If Address is not aligned on a 32-bit boundary, then ASSERT(). 516 517 If 32-bit MMIO register operations are not supported, then ASSERT(). 518 519 @param Address The MMIO register to read. 520 521 @return The value read. 522 523 **/ 524 UINT32 525 EFIAPI 526 MmioRead32 ( 527 IN UINTN Address 528 ) 529 { 530 // 531 // Make sure Address is aligned on a 32-bit boundary. 532 // 533 ASSERT ((Address & 3) == 0); 534 return (UINT32)MmioReadWorker (Address, EfiCpuIoWidthUint32); 535 } 536 537 /** 538 Writes a 32-bit MMIO register. 539 540 Writes the 32-bit MMIO register specified by Address with the value specified 541 by Value and returns Value. This function must guarantee that all MMIO read 542 and write operations are serialized. 543 544 If Address is not aligned on a 32-bit boundary, then ASSERT(). 545 546 If 32-bit MMIO register operations are not supported, then ASSERT(). 547 548 @param Address The MMIO register to write. 549 @param Value The value to write to the MMIO register. 550 551 **/ 552 UINT32 553 EFIAPI 554 MmioWrite32 ( 555 IN UINTN Address, 556 IN UINT32 Value 557 ) 558 { 559 // 560 // Make sure Address is aligned on a 32-bit boundary. 561 // 562 ASSERT ((Address & 3) == 0); 563 return (UINT32)MmioWriteWorker (Address, EfiCpuIoWidthUint32, Value); 564 } 565 566 /** 567 Reads a 64-bit MMIO register. 568 569 Reads the 64-bit MMIO register specified by Address. The 64-bit read value is 570 returned. This function must guarantee that all MMIO read and write 571 operations are serialized. 572 573 If Address is not aligned on a 64-bit boundary, then ASSERT(). 574 575 If 64-bit MMIO register operations are not supported, then ASSERT(). 576 577 @param Address The MMIO register to read. 578 579 @return The value read. 580 581 **/ 582 UINT64 583 EFIAPI 584 MmioRead64 ( 585 IN UINTN Address 586 ) 587 { 588 // 589 // Make sure Address is aligned on a 64-bit boundary. 590 // 591 ASSERT ((Address & 7) == 0); 592 return (UINT64)MmioReadWorker (Address, EfiCpuIoWidthUint64); 593 } 594 595 /** 596 Writes a 64-bit MMIO register. 597 598 Writes the 64-bit MMIO register specified by Address with the value specified 599 by Value and returns Value. This function must guarantee that all MMIO read 600 and write operations are serialized. 601 602 If Address is not aligned on a 64-bit boundary, then ASSERT(). 603 604 If 64-bit MMIO register operations are not supported, then ASSERT(). 605 606 @param Address The MMIO register to write. 607 @param Value The value to write to the MMIO register. 608 609 **/ 610 UINT64 611 EFIAPI 612 MmioWrite64 ( 613 IN UINTN Address, 614 IN UINT64 Value 615 ) 616 { 617 // 618 // Make sure Address is aligned on a 64-bit boundary. 619 // 620 ASSERT ((Address & 7) == 0); 621 return (UINT64)MmioWriteWorker (Address, EfiCpuIoWidthUint64, Value); 622 } 623