-/** @file\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "PciEmulation.h"\r
-\r
-BOOLEAN\r
-PciRootBridgeMemAddressValid (\r
- IN PCI_ROOT_BRIDGE *Private,\r
- IN UINT64 Address\r
- )\r
-{\r
- if ((Address >= Private->MemoryStart) && (Address < (Private->MemoryStart + Private->MemorySize))) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciRootBridgeIoMemRW (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINTN Count,\r
- IN BOOLEAN InStrideFlag,\r
- IN PTR In,\r
- IN BOOLEAN OutStrideFlag,\r
- OUT PTR Out\r
- )\r
-{\r
- UINTN Stride;\r
- UINTN InStride;\r
- UINTN OutStride;\r
-\r
-\r
- Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);\r
- Stride = (UINTN)1 << Width;\r
- InStride = InStrideFlag ? Stride : 0;\r
- OutStride = OutStrideFlag ? Stride : 0;\r
-\r
- //\r
- // Loop for each iteration and move the data\r
- //\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {\r
- *In.ui8 = *Out.ui8;\r
- }\r
- break;\r
- case EfiPciWidthUint16:\r
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {\r
- *In.ui16 = *Out.ui16;\r
- }\r
- break;\r
- case EfiPciWidthUint32:\r
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {\r
- *In.ui32 = *Out.ui32;\r
- }\r
- break;\r
- default:\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciRootBridgeIoPciRW (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN BOOLEAN Write,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 UserAddress,\r
- IN UINTN Count,\r
- IN OUT VOID *UserBuffer\r
- )\r
-{\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
-\r
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @param Address The base address of the memory operations.\r
- @param Count The number of memory operations to perform.\r
- @param Buffer For read operations, the destination buffer to store the results. For write\r
- operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PciRootBridgeIoMemRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- PCI_ROOT_BRIDGE *Private;\r
- UINTN AlignMask;\r
- PTR In;\r
- PTR Out;\r
-\r
- if ( Buffer == NULL ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- if (!PciRootBridgeMemAddressValid (Private, Address)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- AlignMask = (1 << (Width & 0x03)) - 1;\r
- if (Address & AlignMask) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- In.buf = Buffer;\r
- Out.buf = (VOID *)(UINTN) Address;\r
-\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- case EfiPciWidthUint16:\r
- case EfiPciWidthUint32:\r
- case EfiPciWidthUint64:\r
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);\r
-\r
- case EfiPciWidthFifoUint8:\r
- case EfiPciWidthFifoUint16:\r
- case EfiPciWidthFifoUint32:\r
- case EfiPciWidthFifoUint64:\r
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);\r
-\r
- case EfiPciWidthFillUint8:\r
- case EfiPciWidthFillUint16:\r
- case EfiPciWidthFillUint32:\r
- case EfiPciWidthFillUint64:\r
- return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_INVALID_PARAMETER;\r
-}\r
-\r
-\r
-\r
-/**\r
- Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
-\r
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @param Address The base address of the memory operations.\r
- @param Count The number of memory operations to perform.\r
- @param Buffer For read operations, the destination buffer to store the results. For write\r
- operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PciRootBridgeIoMemWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- PCI_ROOT_BRIDGE *Private;\r
- UINTN AlignMask;\r
- PTR In;\r
- PTR Out;\r
-\r
- if ( Buffer == NULL ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);\r
-\r
- if (!PciRootBridgeMemAddressValid (Private, Address)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- AlignMask = (1 << (Width & 0x03)) - 1;\r
- if (Address & AlignMask) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- In.buf = (VOID *)(UINTN) Address;\r
- Out.buf = Buffer;\r
-\r
- switch (Width) {\r
- case EfiPciWidthUint8:\r
- case EfiPciWidthUint16:\r
- case EfiPciWidthUint32:\r
- case EfiPciWidthUint64:\r
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);\r
-\r
- case EfiPciWidthFifoUint8:\r
- case EfiPciWidthFifoUint16:\r
- case EfiPciWidthFifoUint32:\r
- case EfiPciWidthFifoUint64:\r
- return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);\r
-\r
- case EfiPciWidthFillUint8:\r
- case EfiPciWidthFillUint16:\r
- case EfiPciWidthFillUint32:\r
- case EfiPciWidthFillUint64:\r
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);\r
-\r
- default:\r
- break;\r
- }\r
-\r
- return EFI_INVALID_PARAMETER;\r
-}\r
-\r
-/**\r
- Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
-\r
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @param Address The base address of the memory operations.\r
- @param Count The number of memory operations to perform.\r
- @param Buffer For read operations, the destination buffer to store the results. For write\r
- operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PciRootBridgeIoPciRead (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);\r
-}\r
-\r
-\r
-\r
-/**\r
- Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.\r
-\r
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
- @param Width Signifies the width of the memory operations.\r
- @param Address The base address of the memory operations.\r
- @param Count The number of memory operations to perform.\r
- @param Buffer For read operations, the destination buffer to store the results. For write\r
- operations, the source buffer to write data from.\r
-\r
- @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.\r
- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.\r
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PciRootBridgeIoPciWrite (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,\r
- IN UINT64 Address,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- if (Buffer == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);\r
-}\r
-\r
-\r