Hello Marcin,
On 28 October 2016 at 16:42, Marcin Wojtas mw@semihalf.com wrote:
From: Jan Dąbroś jsd@semihalf.com
In order to use numerous UEFI drivers based on PCI bus, PciEmulation driver is implemented. This solution is based on Chips/TexasInstruments/Omap35xx/PciEmulation/ Configuring fake devices is performed via PCD.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jan Dabros jsd@semihalf.com Signed-off-by: Marcin Wojtas mw@semihalf.com
.../Marvell/PortingGuide/PciEmulation.txt | 53 ++ Platforms/Marvell/Marvell.dec | 8 + Platforms/Marvell/PciEmulation/PciEmulation.c | 678 +++++++++++++++++++++ Platforms/Marvell/PciEmulation/PciEmulation.h | 271 ++++++++ Platforms/Marvell/PciEmulation/PciEmulation.inf | 65 ++ Platforms/Marvell/PciEmulation/PciRootBridgeIo.c | 314 ++++++++++ 6 files changed, 1389 insertions(+) create mode 100644 Documentation/Marvell/PortingGuide/PciEmulation.txt create mode 100644 Platforms/Marvell/PciEmulation/PciEmulation.c create mode 100644 Platforms/Marvell/PciEmulation/PciEmulation.h create mode 100644 Platforms/Marvell/PciEmulation/PciEmulation.inf create mode 100644 Platforms/Marvell/PciEmulation/PciRootBridgeIo.c
diff --git a/Documentation/Marvell/PortingGuide/PciEmulation.txt b/Documentation/Marvell/PortingGuide/PciEmulation.txt new file mode 100644 index 0000000..5bb812a --- /dev/null +++ b/Documentation/Marvell/PortingGuide/PciEmulation.txt @@ -0,0 +1,53 @@ +PciEmulation configuration +-------------------------- +Instalation of various Pci devices via PciEmulation driver is performed via set +of PCDs. Following are available:
- gMarvellTokenSpaceGuid.PcdPciEDevCount
+Indicates how many fake Pci devices are placed on board.
+Next five PCDs are in unicode string, format containing settings for all devices +separated with semicolon.
- gMarvellTokenSpaceGuid.PcdPciEDevBaseAddress
I must say, I quite dislike this way of putting ; delimited strings into PCDs and then parsing them at runtime. But I don't have anything better to propose, so this is OK for now. We do intend to improve the situation somewhat around PCI I/O emulation (which is a terrible name as well, by the way) but for now this is fine.
+Indicates base address of Pci device register space.
- gMarvellTokenSpaceGuid.PcdPciEDevRegSize
+Indicates size of Pci device register space.
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode1
+Indicates device subclass code.
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode2
+Indicates device class code.
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode3
+Indicates Pci device class code.
+Examples +-------- +Assuming that there are two fake Pci xHCI controllers with register space +0xF2500000 - 0xF2510000 and 0xF2510000 - 0xF2520000 following PCD values should +be set:
- gMarvellTokenSpaceGuid.PcdPciEDevCount|2
- gMarvellTokenSpaceGuid.PcdPciEDevBaseAddress|L"0xF2500000;0xF2510000"
- gMarvellTokenSpaceGuid.PcdPciEDevRegSize|L"0x10000;0x10000"
- ## XHCI subclass
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode1|L"0x30;0x30"
- ## USB controller class
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode2|L"0x03;0x03"
- ## Serial bus controller Pci device class
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode3|L"0x0C;0x0C"
+Notes +----- +1.In order to find proper values for Pci class codes, please refer to
- PCI Local Bus Specification.
+2.PCDs are configured via UNICODE strings - remember to add L marker. diff --git a/Platforms/Marvell/Marvell.dec b/Platforms/Marvell/Marvell.dec index db99230..f56987d 100644 --- a/Platforms/Marvell/Marvell.dec +++ b/Platforms/Marvell/Marvell.dec @@ -209,6 +209,14 @@ gMarvellTokenSpaceGuid.PcdPp2XlgBaseAddress|0|UINT64|0x3000031 gMarvellTokenSpaceGuid.PcdPp2XlgDevSize|0|UINT32|0x3000032
+#PciEmulation
- gMarvellTokenSpaceGuid.PcdPciEDevBaseAddress|{ 0x0 }|VOID*|0x30000058
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode1|{ 0x0 }|VOID*|0x30000059
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode2|{ 0x0 }|VOID*|0x30000060
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode3|{ 0x0 }|VOID*|0x30000061
- gMarvellTokenSpaceGuid.PcdPciEDevCount|0|UINT32|0x30000062
- gMarvellTokenSpaceGuid.PcdPciEDevRegSize|{ 0x0 }|VOID*|0x30000063
One potential issue with covering all PCI I/O emulated devices by a single driver is that they must all be coherent or non-coherent. There is no way for a single device to deviate in this respect. Did you take that into account for your platform?
#ResetLib gMarvellTokenSpaceGuid.PcdResetRegAddress|0|UINT64|0x40000050 gMarvellTokenSpaceGuid.PcdResetRegMask|0|UINT32|0x4000051 diff --git a/Platforms/Marvell/PciEmulation/PciEmulation.c b/Platforms/Marvell/PciEmulation/PciEmulation.c new file mode 100644 index 0000000..a800bcb --- /dev/null +++ b/Platforms/Marvell/PciEmulation/PciEmulation.c @@ -0,0 +1,678 @@ +/** @file
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2016, Marvell. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD
- License which accompanies this distribution. The full text of the license
- may be found at http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include "PciEmulation.h"
+typedef struct {
- ACPI_HID_DEVICE_PATH AcpiDevicePath;
- PCI_DEVICE_PATH PciDevicePath;
- EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_IO_DEVICE_PATH;
+typedef struct {
- UINT32 Signature;
- EFI_PCI_IO_DEVICE_PATH DevicePath;
- EFI_PCI_IO_PROTOCOL PciIoProtocol;
- PCI_TYPE00 *ConfigSpace;
- PCI_ROOT_BRIDGE RootBridge;
- UINTN Segment;
+} EFI_PCI_IO_PRIVATE_DATA;
+#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o') +#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, \
PciIoProtocol, \EFI_PCI_IO_PRIVATE_DATA_SIGNATURE)+EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate = +{
- {
- {
ACPI_DEVICE_PATH,ACPI_DP,{sizeof (ACPI_HID_DEVICE_PATH),0}- },
- EISA_PNP_ID(0x0A03), // HID
- 0 // UID
- },
- {
- {
HARDWARE_DEVICE_PATH,HW_PCI_DP,{sizeof (PCI_DEVICE_PATH),0}- },
- 0,
- 0
- },
- {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
sizeof (EFI_DEVICE_PATH_PROTOCOL),0- }
- }
+};
+EFI_STATUS +PciIoPollMem (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 BarIndex,
- IN UINT64 Offset,
- IN UINT64 Mask,
- IN UINT64 Value,
- IN UINT64 Delay,
- OUT UINT64 *Result
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+EFI_STATUS +PciIoPollIo (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 BarIndex,
- IN UINT64 Offset,
- IN UINT64 Mask,
- IN UINT64 Value,
- IN UINT64 Delay,
- OUT UINT64 *Result
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+EFI_STATUS +PciIoMemRead (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 BarIndex,
- IN UINT64 Offset,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
- return PciRootBridgeIoMemRead (
&Private->RootBridge.Io,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,Private->ConfigSpace->Device.Bar[BarIndex] + Offset,Count,Buffer);+}
+EFI_STATUS +PciIoMemWrite (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 BarIndex,
- IN UINT64 Offset,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
- return PciRootBridgeIoMemWrite (
&Private->RootBridge.Io,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,Private->ConfigSpace->Device.Bar[BarIndex] + Offset,Count,Buffer);+}
+EFI_STATUS +PciIoIoRead (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 BarIndex,
- IN UINT64 Offset,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+EFI_STATUS +PciIoIoWrite (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 BarIndex,
- IN UINT64 Offset,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+/**
- Enable a PCI driver to read PCI controller registers in
- PCI configuration space.
- @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.
- @param[in] Width Signifies the width of the memory operations.
- @param[in] Offset The offset within the PCI configuration space for
the PCI controller.- @param[in] Count The number of PCI configuration operations to
perform. Bytes moved is Width size * Count,starting at Offset.- @param[in out] Buffer The destination buffer to store the results.
- @retval EFI_SUCCESS The data was read from the PCI controller.
- @retval EFI_INVALID_PARAMETER "Width" is invalid.
- @retval EFI_INVALID_PARAMETER "Buffer" is NULL.
+**/ +EFI_STATUS +PciIoPciRead (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT32 Offset,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
- if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- return PciRootBridgeIoMemRW (
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,Count,TRUE,(PTR)(UINTN)Buffer,TRUE,(PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset));+}
+/**
- Enable a PCI driver to write PCI controller registers in
- PCI configuration space.
- @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.
- @param[in] Width Signifies the width of the memory operations.
- @param[in] Offset The offset within the PCI configuration space for
the PCI controller.- @param[in] Count The number of PCI configuration operations to
perform. Bytes moved is Width size * Count,starting at Offset.- @param[in out] Buffer The source buffer to write data from.
- @retval EFI_SUCCESS The data was read from the PCI controller.
- @retval EFI_INVALID_PARAMETER "Width" is invalid.
- @retval EFI_INVALID_PARAMETER "Buffer" is NULL.
+**/ +EFI_STATUS +PciIoPciWrite (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT32 Offset,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
- if ((Width < 0) || (Width >= EfiPciIoWidthMaximum) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- return PciRootBridgeIoMemRW (
(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,Count,TRUE,(PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset),TRUE,(PTR)(UINTN)Buffer);+}
+EFI_STATUS +PciIoCopyMem (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
- IN UINT8 DestBarIndex,
- IN UINT64 DestOffset,
- IN UINT8 SrcBarIndex,
- IN UINT64 SrcOffset,
- IN UINTN Count
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+EFI_STATUS +PciIoMap (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
- IN VOID *HostAddress,
- IN OUT UINTN *NumberOfBytes,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
- OUT VOID **Mapping
- )
+{
- DMA_MAP_OPERATION DmaOperation;
- if (Operation == EfiPciIoOperationBusMasterRead) {
- DmaOperation = MapOperationBusMasterRead;
- } else if (Operation == EfiPciIoOperationBusMasterWrite) {
- DmaOperation = MapOperationBusMasterWrite;
- } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {
- DmaOperation = MapOperationBusMasterCommonBuffer;
- } else {
- return EFI_INVALID_PARAMETER;
- }
- return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
Are all your peripherals 64-bit DMA capable? If not, you may have a problem here, given that NullDmaLib just returns the CPU address unmodified, so you may want to check the DeviceAddress if the EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute is not set. Another complication in the non-coherent case is that the buffer may be remapped by DmaLib, in which case you have no control over the final allocation, unless you perform the bounce buffering here.
+}
+EFI_STATUS +PciIoUnmap (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN VOID *Mapping
- )
+{
- return DmaUnmap (Mapping);
+}
+/**
- Allocate pages that are suitable for an EfiPciIoOperationBusMasterCommonBuffer
- mapping.
- @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.
- @param[in] Type This parameter is not used and must be ignored.
- @param[in] MemoryType The type of memory to allocate, EfiBootServicesData
or EfiRuntimeServicesData.- @param[in] Pages The number of pages to allocate.
- @param[out] HostAddress A pointer to store the base system memory address of
the allocated range.- @param[in] Attributes The requested bit mask of attributes for the
allocated range. Only the attributes,EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE andEFI_PCI_ATTRIBUTE_MEMORY_CACHED may be used withthis function. If any other bits are set, thenEFI_UNSUPPORTED is returned. This function ignoresthis bit mask.- @retval EFI_SUCCESS The requested memory pages were allocated.
- @retval EFI_INVALID_PARAMETER HostAddress is NULL.
- @retval EFI_INVALID_PARAMETER MemoryType is invalid.
- @retval EFI_UNSUPPORTED Attributes is unsupported.
- @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+**/ +EFI_STATUS +PciIoAllocateBuffer (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_ALLOCATE_TYPE Type,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN Pages,
- OUT VOID **HostAddress,
- IN UINT64 Attributes
- )
+{
- if (Attributes & (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED))) {
- return EFI_UNSUPPORTED;
- }
- return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
Same question: are all your peripherals 64-bit DMA capable? If the EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE attribute is not set, you must ensure that you allocate below 4 GB (if your platform also has UEFI visible memory above 4 GB)
+}
+EFI_STATUS +PciIoFreeBuffer (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN UINTN Pages,
- IN VOID *HostAddress
- )
+{
- return DmaFreeBuffer (Pages, HostAddress);
+}
+EFI_STATUS +PciIoFlush (
- IN EFI_PCI_IO_PROTOCOL *This
- )
+{
- return EFI_SUCCESS;
+}
+/**
- Retrieves this PCI controller's current PCI bus number, device number, and
- function number.
- @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.
- @param[out] SegmentNumber The PCI controller's current PCI segment number.
- @param[out] BusNumber The PCI controller's current PCI bus number.
- @param[out] DeviceNumber The PCI controller's current PCI device number.
- @param[out] FunctionNumber The PCI controller’s current PCI function number.
- @retval EFI_SUCCESS The PCI controller location was returned.
- @retval EFI_INVALID_PARAMETER At least one out of the four output parameters
is a NULL pointer.+**/ +EFI_STATUS +PciIoGetLocation (
- IN EFI_PCI_IO_PROTOCOL *This,
- OUT UINTN *SegmentNumber,
- OUT UINTN *BusNumber,
- OUT UINTN *DeviceNumber,
- OUT UINTN *FunctionNumber
- )
+{
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS (This);
- if ((SegmentNumber == NULL) || (BusNumber == NULL) ||
(DeviceNumber == NULL) || (FunctionNumber == NULL)) {- return EFI_INVALID_PARAMETER;
- }
- *SegmentNumber = Private->Segment;
- *BusNumber = 0xff;
- *DeviceNumber = 0;
- *FunctionNumber = 0;
- return EFI_SUCCESS;
+}
+/**
- Performs an operation on the attributes that this PCI controller supports.
- The operations include getting the set of supported attributes, retrieving
- the current attributes, setting the current attributes, enabling attributes,
- and disabling attributes.
- @param[in] This A pointer to the EFI_PCI_IO_PROTOCOL instance.
- @param[in] Operation The operation to perform on the attributes for this
PCI controller.- @param[in] Attributes The mask of attributes that are used for Set,
Enable and Disable operations.- @param[out] Result A pointer to the result mask of attributes that are
returned for the Get and Supported operations. Thisis an optional parameter that may be NULL for theSet, Enable, and Disable operations.- @retval EFI_SUCCESS The operation on the PCI controller's
attributes was completed. If the operationwas Get or Supported, then the attribute maskis returned in Result.- @retval EFI_INVALID_PARAMETER Operation is greater than or equal to
EfiPciIoAttributeOperationMaximum.- @retval EFI_INVALID_PARAMETER Operation is Get and Result is NULL.
- @retval EFI_INVALID_PARAMETER Operation is Supported and Result is NULL.
+**/ +EFI_STATUS +PciIoAttributes (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
- IN UINT64 Attributes,
- OUT UINT64 *Result OPTIONAL
- )
+{
- switch (Operation) {
- case EfiPciIoAttributeOperationGet:
- case EfiPciIoAttributeOperationSupported:
- if (Result == NULL) {
return EFI_INVALID_PARAMETER;- }
- //
- // We are not a real PCI device so just say things we kind of do
- //
- *Result = EFI_PCI_DEVICE_ENABLE;
- break;
- case EfiPciIoAttributeOperationSet:
- case EfiPciIoAttributeOperationEnable:
- case EfiPciIoAttributeOperationDisable:
- if (Attributes & (~EFI_PCI_DEVICE_ENABLE)) {
return EFI_UNSUPPORTED;- }
- //
- // Since we are not a real PCI device no enable/set or
- // disable operations exist.
- //
- return EFI_SUCCESS;
- default:
- return EFI_INVALID_PARAMETER;
- };
- return EFI_SUCCESS;
+}
+EFI_STATUS +PciIoGetBarAttributes (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN UINT8 BarIndex,
- OUT UINT64 *Supports, OPTIONAL
- OUT VOID **Resources OPTIONAL
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+EFI_STATUS +PciIoSetBarAttributes (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN UINT64 Attributes,
- IN UINT8 BarIndex,
- IN OUT UINT64 *Offset,
- IN OUT UINT64 *Length
- )
+{
- ASSERT (FALSE);
- return EFI_UNSUPPORTED;
+}
+EFI_PCI_IO_PROTOCOL PciIoTemplate = +{
- PciIoPollMem,
- PciIoPollIo,
- { PciIoMemRead, PciIoMemWrite },
- { PciIoIoRead, PciIoIoWrite },
- { PciIoPciRead, PciIoPciWrite },
- PciIoCopyMem,
- PciIoMap,
- PciIoUnmap,
- PciIoAllocateBuffer,
- PciIoFreeBuffer,
- PciIoFlush,
- PciIoGetLocation,
- PciIoAttributes,
- PciIoGetBarAttributes,
- PciIoSetBarAttributes,
- 0,
- 0
+};
+STATIC +EFI_STATUS +EFIAPI +InstallDevices (
- IN UINTN DeviceId,
- IN UINTN BaseAddr,
- IN UINTN AddressSpaceSize,
- IN UINTN ClassCode1,
- IN UINTN ClassCode2,
- IN UINTN ClassCode3
- )
+{
- EFI_PCI_IO_PRIVATE_DATA *Private;
- EFI_STATUS Status;
- EFI_HANDLE Handle;
- // Create a private structure
- Private = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));
- if (Private == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
- }
- // Fill in signature
- Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE;
- // Fake Root Bridge structure needs a signature too
- Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE;
- // Get the register base
- Private->RootBridge.MemoryStart = BaseAddr;
- // Default to segment zero
- Private->Segment = 0;
- // Calculate the total size of device registers.
- Private->RootBridge.MemorySize = AddressSpaceSize;
- // Create fake PCI config space.
- Private->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));
- if (Private->ConfigSpace == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- FreePool(Private);
- return Status;
- }
- //
- // Configure PCI config space
- //
- // Invalid vendor Id as it is not an actual device.
- Private->ConfigSpace->Hdr.VendorId = 0xFFFF;
- // Not relevant as the vendor id is not valid.
- Private->ConfigSpace->Hdr.DeviceId = 0x0000;
- Private->ConfigSpace->Hdr.ClassCode[0] = ClassCode1;
- Private->ConfigSpace->Hdr.ClassCode[1] = ClassCode2;
- Private->ConfigSpace->Hdr.ClassCode[2] = ClassCode3;
- Private->ConfigSpace->Device.Bar[0] = Private->RootBridge.MemoryStart;
- Handle = NULL;
- // Unique device path.
- CopyMem(&Private->DevicePath, &PciIoDevicePathTemplate, sizeof(PciIoDevicePathTemplate));
- Private->DevicePath.AcpiDevicePath.UID = 0;
- Private->DevicePath.PciDevicePath.Device = DeviceId;
- // Copy protocol structure
- CopyMem(&Private->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));
- Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,&gEfiPciIoProtocolGuid,&Private->PciIoProtocol,&gEfiDevicePathProtocolGuid,&Private->DevicePath,NULL);- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "PciEmulation: InstallMultipleProtocolInterfaces failed\n"));
- }
- return Status;
+}
+// +// Below function is used to parse devices information from PCD strings. +// +EFI_STATUS +EFIAPI +PciEmulationEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
+{
- EFI_STATUS Status;
- UINT8 i, DevCount;
- UINTN BaseAddrTable[PcdGet32 (PcdPciEDevCount)];
- UINTN RegSizeTable[PcdGet32 (PcdPciEDevCount)];
- UINTN DevClass1Table[PcdGet32 (PcdPciEDevCount)];
- UINTN DevClass2Table[PcdGet32 (PcdPciEDevCount)];
- UINTN DevClass3Table[PcdGet32 (PcdPciEDevCount)];
- DevCount = PcdGet32 (PcdPciEDevCount);
- Status = ParsePcdString ((CHAR16 *) PcdGetPtr (PcdPciEDevBaseAddress), DevCount, BaseAddrTable, NULL);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "PciEmulation: Wrong PcdPciEDevBaseAddress format\n"));
- return EFI_INVALID_PARAMETER;
- }
- Status = ParsePcdString ((CHAR16 *) PcdGetPtr (PcdPciEDevRegSize), DevCount, RegSizeTable, NULL);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "PciEmulation: Wrong PcdPciEDevRegSize format\n"));
- return EFI_INVALID_PARAMETER;
- }
- Status = ParsePcdString ((CHAR16 *) PcdGetPtr (PcdPciEDevClassCode1), DevCount, DevClass1Table, NULL);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "PciEmulation: Wrong PcdPciEDevClassCode1 format\n"));
- return EFI_INVALID_PARAMETER;
- }
- Status = ParsePcdString ((CHAR16 *) PcdGetPtr (PcdPciEDevClassCode2), DevCount, DevClass2Table, NULL);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "PciEmulation: Wrong PcdPciEDevClassCode2 format\n"));
- return EFI_INVALID_PARAMETER;
- }
- Status = ParsePcdString ((CHAR16 *) PcdGetPtr (PcdPciEDevClassCode3), DevCount, DevClass3Table, NULL);
- if (EFI_ERROR(Status)) {
- DEBUG((DEBUG_ERROR, "PciEmulation: Wrong PcdPciEDevClassCode3 format\n"));
- return EFI_INVALID_PARAMETER;
- }
- for (i = 0; i < DevCount; i++) {
- Status = InstallDevices (i, BaseAddrTable[i], RegSizeTable[i],
DevClass1Table[i], DevClass2Table[i], DevClass3Table[i]);- if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, "PciEmulation: Cannot install device with ID=%d\n", i));- }
- }
- return Status;
+} diff --git a/Platforms/Marvell/PciEmulation/PciEmulation.h b/Platforms/Marvell/PciEmulation/PciEmulation.h new file mode 100644 index 0000000..4f75539 --- /dev/null +++ b/Platforms/Marvell/PciEmulation/PciEmulation.h @@ -0,0 +1,271 @@ +/** @file
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2016, Marvell. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD
- License which accompanies this distribution. The full text of the license may
- be found at http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef _PCI_ROOT_BRIDGE_H_ +#define _PCI_ROOT_BRIDGE_H_
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/Pci22.h> +#include <IndustryStandard/PciCodeId.h>
+#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/DmaLib.h> +#include <Library/DxeServicesTableLib.h> +#include <Library/IoLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/ParsePcdLib.h> +#include <Library/PcdLib.h> +#include <Library/PciLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h>
+#include <Protocol/DevicePath.h> +#include <Protocol/EmbeddedExternalDevice.h> +#include <Protocol/PciHostBridgeResourceAllocation.h> +#include <Protocol/PciIo.h> +#include <Protocol/PciRootBridgeIo.h>
+#define ACPI_CONFIG_IO 0 +#define ACPI_CONFIG_MMIO 1 +#define ACPI_CONFIG_BUS 2
+#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('P', 'c', 'i', 'F')
+typedef struct {
- ACPI_HID_DEVICE_PATH AcpiDevicePath;
- EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+typedef struct {
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Desc[3];
- EFI_ACPI_END_TAG_DESCRIPTOR EndDesc;
+} ACPI_CONFIG_INFO;
+typedef struct {
- UINT32 Signature;
- EFI_HANDLE Handle;
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
- EFI_PCI_ROOT_BRIDGE_DEVICE_PATH DevicePath;
- UINT8 StartBus;
- UINT8 EndBus;
- UINT16 Type;
- UINT32 MemoryStart;
- UINT32 MemorySize;
- UINTN IoOffset;
- UINT32 IoStart;
- UINT32 IoSize;
- UINT64 PciAttributes;
- ACPI_CONFIG_INFO *Config;
+} PCI_ROOT_BRIDGE;
+#define INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) CR (a, PCI_ROOT_BRIDGE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+typedef union {
- UINT8 volatile *buf;
- UINT8 volatile *ui8;
- UINT16 volatile *ui16;
- UINT32 volatile *ui32;
- UINT64 volatile *ui64;
- UINTN volatile ui;
+} PTR;
+EFI_STATUS +EFIAPI +PciRootBridgeIoPollMem (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINT64 Mask,
- IN UINT64 Value,
- IN UINT64 Delay,
- OUT UINT64 *Result
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoPollIo (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINT64 Mask,
- IN UINT64 Value,
- IN UINT64 Delay,
- OUT UINT64 *Result
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoMemRead (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoMemWrite (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoIoRead (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 UserAddress,
- IN UINTN Count,
- IN OUT VOID *UserBuffer
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoIoWrite (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 UserAddress,
- IN UINTN Count,
- IN OUT VOID *UserBuffer
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoCopyMem (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 DestAddress,
- IN UINT64 SrcAddress,
- IN UINTN Count
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoPciRead (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoPciWrite (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoMap (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
- IN VOID *HostAddress,
- IN OUT UINTN *NumberOfBytes,
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
- OUT VOID **Mapping
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoUnmap (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN VOID *Mapping
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoAllocateBuffer (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_ALLOCATE_TYPE Type,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN Pages,
- OUT VOID **HostAddress,
- IN UINT64 Attributes
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoFreeBuffer (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN UINTN Pages,
- OUT VOID *HostAddress
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoFlush (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoGetAttributes (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- OUT UINT64 *Supported,
- OUT UINT64 *Attributes
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoSetAttributes (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN UINT64 Attributes,
- IN OUT UINT64 *ResourceBase,
- IN OUT UINT64 *ResourceLength
- );
+EFI_STATUS +EFIAPI +PciRootBridgeIoConfiguration (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- OUT VOID **Resources
- );
+// +// Private Function Prototypes +// +EFI_STATUS +EFIAPI +PciRootBridgeIoMemRW (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINTN Count,
- IN BOOLEAN InStrideFlag,
- IN PTR In,
- IN BOOLEAN OutStrideFlag,
- OUT PTR Out
- );
+BOOLEAN +PciIoMemAddressValid (
- IN EFI_PCI_IO_PROTOCOL *This,
- IN UINT64 Address
- );
+#endif diff --git a/Platforms/Marvell/PciEmulation/PciEmulation.inf b/Platforms/Marvell/PciEmulation/PciEmulation.inf new file mode 100644 index 0000000..30ddfc2 --- /dev/null +++ b/Platforms/Marvell/PciEmulation/PciEmulation.inf @@ -0,0 +1,65 @@ +/** @file
- Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2016, Marvell. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD
- License which accompanies this distribution. The full text of the license may
- be found at http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+[Defines]
- INF_VERSION = 0x00010019
- BASE_NAME = PciEmulation
- FILE_GUID = 3dfa08da-923b-4841-9435-c77a604d7493
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = PciEmulationEntryPoint
+[Sources.common]
- PciEmulation.c
- PciRootBridgeIo.c
+[Packages]
- ArmPkg/ArmPkg.dec
- EmbeddedPkg/EmbeddedPkg.dec
- IntelFrameworkPkg/IntelFrameworkPkg.dec
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
- OpenPlatformPkg/Platforms/Marvell/Marvell.dec
- ShellPkg/ShellPkg.dec
Why on earth do you need the ShellPkg in a DXE_DRIVER module?
+[LibraryClasses]
- BaseLib
- DmaLib
- DxeServicesTableLib
- IoLib
- ParsePcdLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- UefiLib
- UefiRuntimeServicesTableLib
+[Protocols]
- gEfiDevicePathProtocolGuid
- gEfiPciHostBridgeResourceAllocationProtocolGuid
- gEfiPciIoProtocolGuid
- gEfiPciRootBridgeIoProtocolGuid
- gEmbeddedExternalDeviceProtocolGuid
+[Pcd]
- gMarvellTokenSpaceGuid.PcdPciEDevBaseAddress
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode1
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode2
- gMarvellTokenSpaceGuid.PcdPciEDevClassCode3
- gMarvellTokenSpaceGuid.PcdPciEDevCount
- gMarvellTokenSpaceGuid.PcdPciEDevRegSize
+[Depex]
- TRUE
diff --git a/Platforms/Marvell/PciEmulation/PciRootBridgeIo.c b/Platforms/Marvell/PciEmulation/PciRootBridgeIo.c new file mode 100644 index 0000000..dab26b6 --- /dev/null +++ b/Platforms/Marvell/PciEmulation/PciRootBridgeIo.c @@ -0,0 +1,314 @@ +/** @file
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
- Copyright (c) 2016, Marvell. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD
- License which accompanies this distribution. The full text of the license may
- be found at http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#include "PciEmulation.h"
+BOOLEAN +PciRootBridgeMemAddressValid (
- IN PCI_ROOT_BRIDGE *Private,
- IN UINT64 Address
- )
+{
- if ((Address >= Private->MemoryStart) &&
(Address < (Private->MemoryStart + Private->MemorySize))) {- return TRUE;
- }
- return FALSE;
+}
+EFI_STATUS +PciRootBridgeIoMemRW (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINTN Count,
- IN BOOLEAN InStrideFlag,
- IN PTR In,
- IN BOOLEAN OutStrideFlag,
- OUT PTR Out
- )
+{
- UINTN Stride;
- UINTN InStride;
- UINTN OutStride;
- Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
- Stride = (UINTN)1 << Width;
- InStride = InStrideFlag ? Stride : 0;
- OutStride = OutStrideFlag ? Stride : 0;
- //
- // Loop for each iteration and move the data
- //
- switch (Width) {
- case EfiPciWidthUint8:
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
*In.ui8 = *Out.ui8;- }
- break;
- case EfiPciWidthUint16:
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
*In.ui16 = *Out.ui16;- }
- break;
- case EfiPciWidthUint32:
- for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
*In.ui32 = *Out.ui32;- }
- break;
- default:
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
+}
+EFI_STATUS +PciRootBridgeIoPciRW (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN BOOLEAN Write,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 UserAddress,
- IN UINTN Count,
- IN OUT VOID *UserBuffer
- )
+{
- return EFI_SUCCESS;
+}
+/**
- Enables a PCI driver to access PCI controller registers in the PCI root bridge
- memory space.
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
- @param Width Signifies the width of the memory operations.
- @param Address The base address of the memory operations.
- @param Count The number of memory operations to perform.
- @param Buffer For read operations, the destination buffer to
store the results. For write operations, thesource buffer to write data from.- @retval EFI_SUCCESS The data was read from or written to the PCI
root bridge.- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
of resources.- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+**/ +EFI_STATUS +EFIAPI +PciRootBridgeIoMemRead (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- PCI_ROOT_BRIDGE *Private;
- UINTN AlignMask;
- PTR In;
- PTR Out;
- if ( Buffer == NULL ) {
- return EFI_INVALID_PARAMETER;
- }
- Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
- if (!PciRootBridgeMemAddressValid (Private, Address)) {
- return EFI_INVALID_PARAMETER;
- }
- AlignMask = (1 << (Width & 0x03)) - 1;
- if (Address & AlignMask) {
- return EFI_INVALID_PARAMETER;
- }
- In.buf = Buffer;
- Out.buf = (VOID *)(UINTN) Address;
- switch (Width) {
- case EfiPciWidthUint8:
- case EfiPciWidthUint16:
- case EfiPciWidthUint32:
- case EfiPciWidthUint64:
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
- case EfiPciWidthFifoUint8:
- case EfiPciWidthFifoUint16:
- case EfiPciWidthFifoUint32:
- case EfiPciWidthFifoUint64:
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
- case EfiPciWidthFillUint8:
- case EfiPciWidthFillUint16:
- case EfiPciWidthFillUint32:
- case EfiPciWidthFillUint64:
- return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
- default:
- break;
- }
- return EFI_INVALID_PARAMETER;
+}
+/**
- Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
- @param Width Signifies the width of the memory operations.
- @param Address The base address of the memory operations.
- @param Count The number of memory operations to perform.
- @param Buffer For read operations, the destination buffer to
store the results. For write operations, thesource buffer to write data from.- @retval EFI_SUCCESS The data was read from or written to the PCI
root bridge.- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
of resources.- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+**/ +EFI_STATUS +EFIAPI +PciRootBridgeIoMemWrite (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- PCI_ROOT_BRIDGE *Private;
- UINTN AlignMask;
- PTR In;
- PTR Out;
- if (Buffer == NULL ) {
- return EFI_INVALID_PARAMETER;
- }
- Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
- if (!PciRootBridgeMemAddressValid (Private, Address)) {
- return EFI_INVALID_PARAMETER;
- }
- AlignMask = (1 << (Width & 0x03)) - 1;
- if (Address & AlignMask) {
- return EFI_INVALID_PARAMETER;
- }
- In.buf = (VOID *)(UINTN) Address;
- Out.buf = Buffer;
- switch (Width) {
- case EfiPciWidthUint8:
- case EfiPciWidthUint16:
- case EfiPciWidthUint32:
- case EfiPciWidthUint64:
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
- case EfiPciWidthFifoUint8:
- case EfiPciWidthFifoUint16:
- case EfiPciWidthFifoUint32:
- case EfiPciWidthFifoUint64:
- return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
- case EfiPciWidthFillUint8:
- case EfiPciWidthFillUint16:
- case EfiPciWidthFillUint32:
- case EfiPciWidthFillUint64:
- return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
- default:
- break;
- }
- return EFI_INVALID_PARAMETER;
+}
+/**
- Enables a PCI driver to access PCI controller registers in the PCI root bridge
- memory space.
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
- @param Width Signifies the width of the memory operations.
- @param Address The base address of the memory operations.
- @param Count The number of memory operations to perform.
- @param Buffer For read operations, the destination buffer to
store the results. For write operations, thesource buffer to write data from.- @retval EFI_SUCCESS The data was read from or written to the PCI
root bridge.- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
of resources.- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+**/ +EFI_STATUS +EFIAPI +PciRootBridgeIoPciRead (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+}
+/**
- Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
- @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
- @param Width Signifies the width of the memory operations.
- @param Address The base address of the memory operations.
- @param Count The number of memory operations to perform.
- @param Buffer For read operations, the destination buffer to
store the results. For write operations, thesource buffer to write data from.- @retval EFI_SUCCESS The data was read from or written to the PCI
root bridge.- @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
- @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+**/ +EFI_STATUS +EFIAPI +PciRootBridgeIoPciWrite (
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
- IN UINT64 Address,
- IN UINTN Count,
- IN OUT VOID *Buffer
- )
+{
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+}
1.8.3.1