1 /*++ 2 3 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> 4 This program and the accompanying materials 5 are licensed and made available under the terms and conditions of the BSD License 6 which accompanies this distribution. The full text of the license may be found at 7 http://opensource.org/licenses/bsd-license.php 8 9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11 12 Module Name: 13 14 DeviceIo.c 15 16 Abstract: 17 18 EFI PC-AT PCI Device IO driver 19 20 --*/ 21 #include "PcatPciRootBridge.h" 22 #include "DeviceIo.h" 23 24 EFI_STATUS 25 DeviceIoConstructor ( 26 IN EFI_HANDLE Handle, 27 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo, 28 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 29 IN UINT16 PrimaryBus, 30 IN UINT16 SubordinateBus 31 ) 32 /*++ 33 34 Routine Description: 35 36 Initialize and install a Device IO protocol on a empty device path handle. 37 38 Arguments: 39 40 Handle - Handle of PCI RootBridge IO instance 41 PciRootBridgeIo - PCI RootBridge IO instance 42 DevicePath - Device Path of PCI RootBridge IO instance 43 PrimaryBus - Primary Bus 44 SubordinateBus - Subordinate Bus 45 46 Returns: 47 48 EFI_SUCCESS - This driver is added to ControllerHandle. 49 EFI_ALREADY_STARTED - This driver is already running on ControllerHandle. 50 Others - This driver does not support this device. 51 52 --*/ 53 { 54 EFI_STATUS Status; 55 DEVICE_IO_PRIVATE_DATA *Private; 56 57 // 58 // Initialize the Device IO device instance. 59 // 60 Private = AllocateZeroPool (sizeof (DEVICE_IO_PRIVATE_DATA)); 61 if (Private == NULL) { 62 return EFI_OUT_OF_RESOURCES; 63 } 64 65 Private->Signature = DEVICE_IO_PRIVATE_DATA_SIGNATURE; 66 Private->Handle = Handle; 67 Private->PciRootBridgeIo = PciRootBridgeIo; 68 Private->DevicePath = DevicePath; 69 Private->PrimaryBus = PrimaryBus; 70 Private->SubordinateBus = SubordinateBus; 71 72 Private->DeviceIo.Mem.Read = DeviceIoMemRead; 73 Private->DeviceIo.Mem.Write = DeviceIoMemWrite; 74 Private->DeviceIo.Io.Read = DeviceIoIoRead; 75 Private->DeviceIo.Io.Write = DeviceIoIoWrite; 76 Private->DeviceIo.Pci.Read = DeviceIoPciRead; 77 Private->DeviceIo.Pci.Write = DeviceIoPciWrite; 78 Private->DeviceIo.PciDevicePath = DeviceIoPciDevicePath; 79 Private->DeviceIo.Map = DeviceIoMap; 80 Private->DeviceIo.Unmap = DeviceIoUnmap; 81 Private->DeviceIo.AllocateBuffer = DeviceIoAllocateBuffer; 82 Private->DeviceIo.Flush = DeviceIoFlush; 83 Private->DeviceIo.FreeBuffer = DeviceIoFreeBuffer; 84 85 // 86 // Install protocol interfaces for the Device IO device. 87 // 88 Status = gBS->InstallMultipleProtocolInterfaces ( 89 &Private->Handle, 90 &gEfiDeviceIoProtocolGuid, 91 &Private->DeviceIo, 92 NULL 93 ); 94 ASSERT_EFI_ERROR (Status); 95 96 return Status; 97 } 98 99 EFI_STATUS 100 EFIAPI 101 DeviceIoMemRead ( 102 IN EFI_DEVICE_IO_PROTOCOL *This, 103 IN EFI_IO_WIDTH Width, 104 IN UINT64 Address, 105 IN UINTN Count, 106 IN OUT VOID *Buffer 107 ) 108 /*++ 109 110 Routine Description: 111 112 Perform reading memory mapped I/O space of device. 113 114 Arguments: 115 116 This - A pointer to EFI_DEVICE_IO protocol instance. 117 Width - Width of I/O operations. 118 Address - The base address of I/O operations. 119 Count - The number of I/O operations to perform. 120 Bytes moves is Width size * Count, starting at Address. 121 Buffer - The destination buffer to store results. 122 123 Returns: 124 125 EFI_SUCCESS - The data was read from the device. 126 EFI_INVALID_PARAMETER - Width is invalid. 127 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. 128 129 --*/ 130 { 131 EFI_STATUS Status; 132 DEVICE_IO_PRIVATE_DATA *Private; 133 134 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 135 136 if (Width > MMIO_COPY_UINT64) { 137 return EFI_INVALID_PARAMETER; 138 } 139 if (Width >= MMIO_COPY_UINT8) { 140 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8); 141 Status = Private->PciRootBridgeIo->CopyMem ( 142 Private->PciRootBridgeIo, 143 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 144 (UINT64)(UINTN) Buffer, 145 Address, 146 Count 147 ); 148 } else { 149 Status = Private->PciRootBridgeIo->Mem.Read ( 150 Private->PciRootBridgeIo, 151 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 152 Address, 153 Count, 154 Buffer 155 ); 156 } 157 158 return Status; 159 } 160 161 162 163 EFI_STATUS 164 EFIAPI 165 DeviceIoMemWrite ( 166 IN EFI_DEVICE_IO_PROTOCOL *This, 167 IN EFI_IO_WIDTH Width, 168 IN UINT64 Address, 169 IN UINTN Count, 170 IN OUT VOID *Buffer 171 ) 172 /*++ 173 174 Routine Description: 175 176 Perform writing memory mapped I/O space of device. 177 178 Arguments: 179 180 This - A pointer to EFI_DEVICE_IO protocol instance. 181 Width - Width of I/O operations. 182 Address - The base address of I/O operations. 183 Count - The number of I/O operations to perform. 184 Bytes moves is Width size * Count, starting at Address. 185 Buffer - The source buffer of data to be written. 186 187 Returns: 188 189 EFI_SUCCESS - The data was written to the device. 190 EFI_INVALID_PARAMETER - Width is invalid. 191 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. 192 193 --*/ 194 { 195 EFI_STATUS Status; 196 DEVICE_IO_PRIVATE_DATA *Private; 197 198 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 199 200 if (Width > MMIO_COPY_UINT64) { 201 return EFI_INVALID_PARAMETER; 202 } 203 if (Width >= MMIO_COPY_UINT8) { 204 Width = (EFI_IO_WIDTH) (Width - MMIO_COPY_UINT8); 205 Status = Private->PciRootBridgeIo->CopyMem ( 206 Private->PciRootBridgeIo, 207 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 208 Address, 209 (UINT64)(UINTN) Buffer, 210 Count 211 ); 212 } else { 213 Status = Private->PciRootBridgeIo->Mem.Write ( 214 Private->PciRootBridgeIo, 215 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 216 Address, 217 Count, 218 Buffer 219 ); 220 } 221 222 return Status; 223 } 224 225 EFI_STATUS 226 EFIAPI 227 DeviceIoIoRead ( 228 IN EFI_DEVICE_IO_PROTOCOL *This, 229 IN EFI_IO_WIDTH Width, 230 IN UINT64 Address, 231 IN UINTN Count, 232 IN OUT VOID *Buffer 233 ) 234 /*++ 235 236 Routine Description: 237 238 Perform reading I/O space of device. 239 240 Arguments: 241 242 This - A pointer to EFI_DEVICE_IO protocol instance. 243 Width - Width of I/O operations. 244 Address - The base address of I/O operations. 245 Count - The number of I/O operations to perform. 246 Bytes moves is Width size * Count, starting at Address. 247 Buffer - The destination buffer to store results. 248 249 Returns: 250 251 EFI_SUCCESS - The data was read from the device. 252 EFI_INVALID_PARAMETER - Width is invalid. 253 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. 254 255 --*/ 256 { 257 EFI_STATUS Status; 258 DEVICE_IO_PRIVATE_DATA *Private; 259 260 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 261 262 if (Width >= MMIO_COPY_UINT8) { 263 return EFI_INVALID_PARAMETER; 264 } 265 266 Status = Private->PciRootBridgeIo->Io.Read ( 267 Private->PciRootBridgeIo, 268 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 269 Address, 270 Count, 271 Buffer 272 ); 273 274 return Status; 275 } 276 277 EFI_STATUS 278 EFIAPI 279 DeviceIoIoWrite ( 280 IN EFI_DEVICE_IO_PROTOCOL *This, 281 IN EFI_IO_WIDTH Width, 282 IN UINT64 Address, 283 IN UINTN Count, 284 IN OUT VOID *Buffer 285 ) 286 /*++ 287 288 Routine Description: 289 290 Perform writing I/O space of device. 291 292 Arguments: 293 294 This - A pointer to EFI_DEVICE_IO protocol instance. 295 Width - Width of I/O operations. 296 Address - The base address of I/O operations. 297 Count - The number of I/O operations to perform. 298 Bytes moves is Width size * Count, starting at Address. 299 Buffer - The source buffer of data to be written. 300 301 Returns: 302 303 EFI_SUCCESS - The data was written to the device. 304 EFI_INVALID_PARAMETER - Width is invalid. 305 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. 306 307 --*/ 308 { 309 EFI_STATUS Status; 310 DEVICE_IO_PRIVATE_DATA *Private; 311 312 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 313 314 if (Width >= MMIO_COPY_UINT8) { 315 return EFI_INVALID_PARAMETER; 316 } 317 318 Status = Private->PciRootBridgeIo->Io.Write ( 319 Private->PciRootBridgeIo, 320 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 321 Address, 322 Count, 323 Buffer 324 ); 325 326 return Status; 327 } 328 329 EFI_STATUS 330 EFIAPI 331 DeviceIoPciRead ( 332 IN EFI_DEVICE_IO_PROTOCOL *This, 333 IN EFI_IO_WIDTH Width, 334 IN UINT64 Address, 335 IN UINTN Count, 336 IN OUT VOID *Buffer 337 ) 338 /*++ 339 340 Routine Description: 341 342 Perform reading PCI configuration space of device 343 344 Arguments: 345 346 This - A pointer to EFI_DEVICE_IO protocol instance. 347 Width - Width of I/O operations. 348 Address - The base address of I/O operations. 349 Count - The number of I/O operations to perform. 350 Bytes moves is Width size * Count, starting at Address. 351 Buffer - The destination buffer to store results. 352 353 Returns: 354 355 EFI_SUCCESS - The data was read from the device. 356 EFI_INVALID_PARAMETER - Width is invalid. 357 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. 358 359 --*/ 360 { 361 EFI_STATUS Status; 362 DEVICE_IO_PRIVATE_DATA *Private; 363 364 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 365 366 if ((UINT32)Width >= MMIO_COPY_UINT8) { 367 return EFI_INVALID_PARAMETER; 368 } 369 370 Status = Private->PciRootBridgeIo->Pci.Read ( 371 Private->PciRootBridgeIo, 372 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 373 Address, 374 Count, 375 Buffer 376 ); 377 378 return Status; 379 } 380 381 EFI_STATUS 382 EFIAPI 383 DeviceIoPciWrite ( 384 IN EFI_DEVICE_IO_PROTOCOL *This, 385 IN EFI_IO_WIDTH Width, 386 IN UINT64 Address, 387 IN UINTN Count, 388 IN OUT VOID *Buffer 389 ) 390 /*++ 391 392 Routine Description: 393 394 Perform writing PCI configuration space of device. 395 396 Arguments: 397 398 This - A pointer to EFI_DEVICE_IO protocol instance. 399 Width - Width of I/O operations. 400 Address - The base address of I/O operations. 401 Count - The number of I/O operations to perform. 402 Bytes moves is Width size * Count, starting at Address. 403 Buffer - The source buffer of data to be written. 404 405 Returns: 406 407 EFI_SUCCESS - The data was written to the device. 408 EFI_INVALID_PARAMETER - Width is invalid. 409 EFI_OUT_OF_RESOURCES - The request could not be completed due to lack of resources. 410 411 --*/ 412 { 413 EFI_STATUS Status; 414 DEVICE_IO_PRIVATE_DATA *Private; 415 416 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 417 418 if ((UINT32)Width >= MMIO_COPY_UINT8) { 419 return EFI_INVALID_PARAMETER; 420 } 421 422 Status = Private->PciRootBridgeIo->Pci.Write ( 423 Private->PciRootBridgeIo, 424 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width, 425 Address, 426 Count, 427 Buffer 428 ); 429 430 return Status; 431 } 432 433 EFI_DEVICE_PATH_PROTOCOL * 434 AppendPciDevicePath ( 435 IN DEVICE_IO_PRIVATE_DATA *Private, 436 IN UINT8 Bus, 437 IN UINT8 Device, 438 IN UINT8 Function, 439 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, 440 IN OUT UINT16 *BridgePrimaryBus, 441 IN OUT UINT16 *BridgeSubordinateBus 442 ) 443 /*++ 444 445 Routine Description: 446 447 Append a PCI device path node to another device path. 448 449 Arguments: 450 451 Private - A pointer to DEVICE_IO_PRIVATE_DATA instance. 452 Bus - PCI bus number of the device. 453 Device - PCI device number of the device. 454 Function - PCI function number of the device. 455 DevicePath - Original device path which will be appended a PCI device path node. 456 BridgePrimaryBus - Primary bus number of the bridge. 457 BridgeSubordinateBus - Subordinate bus number of the bridge. 458 459 Returns: 460 461 Pointer to the appended PCI device path. 462 463 --*/ 464 { 465 UINT16 ThisBus; 466 UINT8 ThisDevice; 467 UINT8 ThisFunc; 468 UINT64 Address; 469 PCI_TYPE01 PciBridge; 470 PCI_TYPE01 *PciPtr; 471 EFI_DEVICE_PATH_PROTOCOL *ReturnDevicePath; 472 PCI_DEVICE_PATH PciNode; 473 474 PciPtr = &PciBridge; 475 for (ThisBus = *BridgePrimaryBus; ThisBus <= *BridgeSubordinateBus; ThisBus++) { 476 for (ThisDevice = 0; ThisDevice <= PCI_MAX_DEVICE; ThisDevice++) { 477 for (ThisFunc = 0; ThisFunc <= PCI_MAX_FUNC; ThisFunc++) { 478 Address = EFI_PCI_ADDRESS (ThisBus, ThisDevice, ThisFunc, 0); 479 ZeroMem (PciPtr, sizeof (PCI_TYPE01)); 480 Private->DeviceIo.Pci.Read ( 481 &Private->DeviceIo, 482 IO_UINT32, 483 Address, 484 1, 485 &(PciPtr->Hdr.VendorId) 486 ); 487 if ((PciPtr->Hdr.VendorId == 0xffff) && (ThisFunc == 0)) { 488 break; 489 } 490 if (PciPtr->Hdr.VendorId == 0xffff) { 491 continue; 492 } 493 494 Private->DeviceIo.Pci.Read ( 495 &Private->DeviceIo, 496 IO_UINT32, 497 Address, 498 sizeof (PCI_TYPE01) / sizeof (UINT32), 499 PciPtr 500 ); 501 if (IS_PCI_BRIDGE (PciPtr)) { 502 if (Bus >= PciPtr->Bridge.SecondaryBus && Bus <= PciPtr->Bridge.SubordinateBus) { 503 504 PciNode.Header.Type = HARDWARE_DEVICE_PATH; 505 PciNode.Header.SubType = HW_PCI_DP; 506 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); 507 508 PciNode.Device = ThisDevice; 509 PciNode.Function = ThisFunc; 510 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header); 511 512 *BridgePrimaryBus = PciPtr->Bridge.SecondaryBus; 513 *BridgeSubordinateBus = PciPtr->Bridge.SubordinateBus; 514 return ReturnDevicePath; 515 } 516 } 517 518 if ((ThisFunc == 0) && ((PciPtr->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x0)) { 519 // 520 // Skip sub functions, this is not a multi function device 521 // 522 break; 523 } 524 } 525 } 526 } 527 528 ZeroMem (&PciNode, sizeof (PciNode)); 529 PciNode.Header.Type = HARDWARE_DEVICE_PATH; 530 PciNode.Header.SubType = HW_PCI_DP; 531 SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode)); 532 PciNode.Device = Device; 533 PciNode.Function = Function; 534 535 ReturnDevicePath = AppendDevicePathNode (DevicePath, &PciNode.Header); 536 537 *BridgePrimaryBus = 0xffff; 538 *BridgeSubordinateBus = 0xffff; 539 return ReturnDevicePath; 540 } 541 542 EFI_STATUS 543 EFIAPI 544 DeviceIoPciDevicePath ( 545 IN EFI_DEVICE_IO_PROTOCOL *This, 546 IN UINT64 Address, 547 IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath 548 ) 549 /*++ 550 551 Routine Description: 552 553 Provides an EFI Device Path for a PCI device with the given PCI configuration space address. 554 555 Arguments: 556 557 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. 558 Address - The PCI configuration space address of the device whose Device Path 559 is going to be returned. 560 PciDevicePath - A pointer to the pointer for the EFI Device Path for PciAddress. 561 Memory for the Device Path is allocated from the pool. 562 563 Returns: 564 565 EFI_SUCCESS - The PciDevicePath returns a pointer to a valid EFI Device Path. 566 EFI_UNSUPPORTED - The PciAddress does not map to a valid EFI Device Path. 567 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources. 568 569 --*/ 570 { 571 DEVICE_IO_PRIVATE_DATA *Private; 572 UINT16 PrimaryBus; 573 UINT16 SubordinateBus; 574 UINT8 Bus; 575 UINT8 Device; 576 UINT8 Func; 577 578 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 579 580 Bus = (UINT8) (((UINT32) Address >> 24) & 0xff); 581 Device = (UINT8) (((UINT32) Address >> 16) & 0xff); 582 Func = (UINT8) (((UINT32) Address >> 8) & 0xff); 583 584 if (Bus < Private->PrimaryBus || Bus > Private->SubordinateBus) { 585 return EFI_UNSUPPORTED; 586 } 587 588 *PciDevicePath = Private->DevicePath; 589 PrimaryBus = Private->PrimaryBus; 590 SubordinateBus = Private->SubordinateBus; 591 do { 592 *PciDevicePath = AppendPciDevicePath ( 593 Private, 594 Bus, 595 Device, 596 Func, 597 *PciDevicePath, 598 &PrimaryBus, 599 &SubordinateBus 600 ); 601 if (*PciDevicePath == NULL) { 602 return EFI_OUT_OF_RESOURCES; 603 } 604 } while (PrimaryBus != 0xffff); 605 606 return EFI_SUCCESS; 607 } 608 609 EFI_STATUS 610 EFIAPI 611 DeviceIoMap ( 612 IN EFI_DEVICE_IO_PROTOCOL *This, 613 IN EFI_IO_OPERATION_TYPE Operation, 614 IN EFI_PHYSICAL_ADDRESS *HostAddress, 615 IN OUT UINTN *NumberOfBytes, 616 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 617 OUT VOID **Mapping 618 ) 619 /*++ 620 621 Routine Description: 622 623 Provides the device-specific addresses needed to access system memory. 624 625 Arguments: 626 627 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. 628 Operation - Indicates if the bus master is going to read or write to system memory. 629 HostAddress - The system memory address to map to the device. 630 NumberOfBytes - On input the number of bytes to map. On output the number of bytes 631 that were mapped. 632 DeviceAddress - The resulting map address for the bus master device to use to access the 633 hosts HostAddress. 634 Mapping - A resulting value to pass to Unmap(). 635 636 Returns: 637 638 EFI_SUCCESS - The range was mapped for the returned NumberOfBytes. 639 EFI_INVALID_PARAMETER - The Operation or HostAddress is undefined. 640 EFI_UNSUPPORTED - The HostAddress cannot be mapped as a common buffer. 641 EFI_DEVICE_ERROR - The system hardware could not map the requested address. 642 EFI_OUT_OF_RESOURCES - The request could not be completed due to a lack of resources. 643 644 --*/ 645 { 646 EFI_STATUS Status; 647 DEVICE_IO_PRIVATE_DATA *Private; 648 649 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 650 651 if ((UINT32)Operation > EfiBusMasterCommonBuffer) { 652 return EFI_INVALID_PARAMETER; 653 } 654 655 if (((UINTN) (*HostAddress) != (*HostAddress)) && Operation == EfiBusMasterCommonBuffer) { 656 return EFI_UNSUPPORTED; 657 } 658 659 Status = Private->PciRootBridgeIo->Map ( 660 Private->PciRootBridgeIo, 661 (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION) Operation, 662 (VOID *) (UINTN) (*HostAddress), 663 NumberOfBytes, 664 DeviceAddress, 665 Mapping 666 ); 667 668 return Status; 669 } 670 671 EFI_STATUS 672 EFIAPI 673 DeviceIoUnmap ( 674 IN EFI_DEVICE_IO_PROTOCOL *This, 675 IN VOID *Mapping 676 ) 677 /*++ 678 679 Routine Description: 680 681 Completes the Map() operation and releases any corresponding resources. 682 683 Arguments: 684 685 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. 686 Mapping - The mapping value returned from Map(). 687 688 Returns: 689 690 EFI_SUCCESS - The range was unmapped. 691 EFI_DEVICE_ERROR - The data was not committed to the target system memory. 692 693 --*/ 694 { 695 EFI_STATUS Status; 696 DEVICE_IO_PRIVATE_DATA *Private; 697 698 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 699 700 Status = Private->PciRootBridgeIo->Unmap ( 701 Private->PciRootBridgeIo, 702 Mapping 703 ); 704 705 return Status; 706 } 707 708 EFI_STATUS 709 EFIAPI 710 DeviceIoAllocateBuffer ( 711 IN EFI_DEVICE_IO_PROTOCOL *This, 712 IN EFI_ALLOCATE_TYPE Type, 713 IN EFI_MEMORY_TYPE MemoryType, 714 IN UINTN Pages, 715 IN OUT EFI_PHYSICAL_ADDRESS *PhysicalAddress 716 ) 717 /*++ 718 719 Routine Description: 720 721 Allocates pages that are suitable for an EFIBusMasterCommonBuffer mapping. 722 723 Arguments: 724 725 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. 726 Type - The type allocation to perform. 727 MemoryType - The type of memory to allocate, EfiBootServicesData or 728 EfiRuntimeServicesData. 729 Pages - The number of pages to allocate. 730 PhysicalAddress - A pointer to store the base address of the allocated range. 731 732 Returns: 733 734 EFI_SUCCESS - The requested memory pages were allocated. 735 EFI_OUT_OF_RESOURCES - The memory pages could not be allocated. 736 EFI_INVALID_PARAMETER - The requested memory type is invalid. 737 EFI_UNSUPPORTED - The requested PhysicalAddress is not supported on 738 this platform. 739 740 --*/ 741 { 742 EFI_STATUS Status; 743 EFI_PHYSICAL_ADDRESS HostAddress; 744 745 HostAddress = *PhysicalAddress; 746 747 if ((MemoryType != EfiBootServicesData) && (MemoryType != EfiRuntimeServicesData)) { 748 return EFI_INVALID_PARAMETER; 749 } 750 751 if ((UINT32)Type >= MaxAllocateType) { 752 return EFI_INVALID_PARAMETER; 753 } 754 755 if ((Type == AllocateAddress) && (HostAddress + EFI_PAGES_TO_SIZE (Pages) - 1 > MAX_COMMON_BUFFER)) { 756 return EFI_UNSUPPORTED; 757 } 758 759 if ((AllocateAnyPages == Type) || (AllocateMaxAddress == Type && HostAddress > MAX_COMMON_BUFFER)) { 760 Type = AllocateMaxAddress; 761 HostAddress = MAX_COMMON_BUFFER; 762 } 763 764 Status = gBS->AllocatePages ( 765 Type, 766 MemoryType, 767 Pages, 768 &HostAddress 769 ); 770 if (EFI_ERROR (Status)) { 771 return Status; 772 } 773 774 775 *PhysicalAddress = HostAddress; 776 777 return EFI_SUCCESS; 778 } 779 780 EFI_STATUS 781 EFIAPI 782 DeviceIoFlush ( 783 IN EFI_DEVICE_IO_PROTOCOL *This 784 ) 785 /*++ 786 787 Routine Description: 788 789 Flushes any posted write data to the device. 790 791 Arguments: 792 793 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. 794 795 Returns: 796 797 EFI_SUCCESS - The buffers were flushed. 798 EFI_DEVICE_ERROR - The buffers were not flushed due to a hardware error. 799 800 --*/ 801 { 802 EFI_STATUS Status; 803 DEVICE_IO_PRIVATE_DATA *Private; 804 805 Private = DEVICE_IO_PRIVATE_DATA_FROM_THIS (This); 806 807 Status = Private->PciRootBridgeIo->Flush (Private->PciRootBridgeIo); 808 809 return Status; 810 } 811 812 EFI_STATUS 813 EFIAPI 814 DeviceIoFreeBuffer ( 815 IN EFI_DEVICE_IO_PROTOCOL *This, 816 IN UINTN Pages, 817 IN EFI_PHYSICAL_ADDRESS HostAddress 818 ) 819 /*++ 820 821 Routine Description: 822 823 Frees pages that were allocated with AllocateBuffer(). 824 825 Arguments: 826 827 This - A pointer to the EFI_DEVICE_IO_INTERFACE instance. 828 Pages - The number of pages to free. 829 HostAddress - The base address of the range to free. 830 831 Returns: 832 833 EFI_SUCCESS - The requested memory pages were freed. 834 EFI_NOT_FOUND - The requested memory pages were not allocated with 835 AllocateBuffer(). 836 EFI_INVALID_PARAMETER - HostAddress is not page aligned or Pages is invalid. 837 838 --*/ 839 { 840 if (((HostAddress & EFI_PAGE_MASK) != 0) || (Pages <= 0)) { 841 return EFI_INVALID_PARAMETER; 842 } 843 844 return gBS->FreePages (HostAddress, Pages); 845 } 846