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