--- /dev/null
+/** @file\r
+\r
+ Copyright (c) 2008-2009, Apple Inc. All rights reserved.\r
+ \r
+ All rights reserved. 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