/** @file\r
\r
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ Copyright (c) 2016, Linaro, Ltd. 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
\r
**/\r
\r
-#include "PciEmulation.h"\r
+#include <PiDxe.h>\r
\r
-EMBEDDED_EXTERNAL_DEVICE *gTPS65950;\r
-\r
-#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
\r
-typedef struct {\r
- ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
- PCI_DEVICE_PATH PciDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
-} EFI_PCI_IO_DEVICE_PATH;\r
+#include <Protocol/EmbeddedExternalDevice.h>\r
\r
-typedef struct {\r
- UINT32 Signature;\r
- EFI_PCI_IO_DEVICE_PATH DevicePath;\r
- EFI_PCI_IO_PROTOCOL PciIoProtocol;\r
- PCI_TYPE00 *ConfigSpace;\r
- PCI_ROOT_BRIDGE RootBridge;\r
- UINTN Segment;\r
-} EFI_PCI_IO_PRIVATE_DATA;\r
+#include <TPS65950.h>\r
+#include <Omap3530/Omap3530.h>\r
\r
-#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o')\r
-#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE)\r
+EMBEDDED_EXTERNAL_DEVICE *gTPS65950;\r
\r
-EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplate =\r
-{\r
- {\r
- { ACPI_DEVICE_PATH, ACPI_DP, { sizeof (ACPI_HID_DEVICE_PATH), 0 } },\r
- EISA_PNP_ID(0x0A03), // HID\r
- 0 // UID\r
- },\r
- {\r
- { HARDWARE_DEVICE_PATH, HW_PCI_DP, { sizeof (PCI_DEVICE_PATH), 0 } },\r
- 0,\r
- 0\r
- },\r
- { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }\r
-};\r
+#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44\r
\r
STATIC\r
-VOID\r
+EFI_STATUS\r
ConfigureUSBHost (\r
- VOID\r
+ NON_DISCOVERABLE_DEVICE *Device\r
)\r
{\r
EFI_STATUS Status;\r
\r
Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);\r
ASSERT_EFI_ERROR (Status);\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciIoPollMem (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoPollIo (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINT64 Mask,\r
- IN UINT64 Value,\r
- IN UINT64 Delay,\r
- OUT UINT64 *Result\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoMemRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- return PciRootBridgeIoMemRead (&Private->RootBridge.Io,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Private->ConfigSpace->Device.Bar[BarIndex] + Offset,\r
- Count,\r
- Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-PciIoMemWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- return PciRootBridgeIoMemWrite (&Private->RootBridge.Io,\r
- (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Private->ConfigSpace->Device.Bar[BarIndex] + Offset,\r
- Count,\r
- Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-PciIoIoRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoIoWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 BarIndex,\r
- IN UINT64 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoPciRead (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,\r
- Count,\r
- TRUE,\r
- (PTR)(UINTN)Buffer,\r
- TRUE,\r
- (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset)\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-PciIoPciWrite (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT32 Offset,\r
- IN UINTN Count,\r
- IN OUT VOID *Buffer\r
- )\r
-{\r
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,\r
- Count,\r
- TRUE,\r
- (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset),\r
- TRUE,\r
- (PTR)(UINTN)Buffer\r
- );\r
-}\r
-\r
-EFI_STATUS\r
-PciIoCopyMem (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_WIDTH Width,\r
- IN UINT8 DestBarIndex,\r
- IN UINT64 DestOffset,\r
- IN UINT8 SrcBarIndex,\r
- IN UINT64 SrcOffset,\r
- IN UINTN Count\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoMap (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,\r
- IN VOID *HostAddress,\r
- IN OUT UINTN *NumberOfBytes,\r
- OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
- OUT VOID **Mapping\r
- )\r
-{\r
- DMA_MAP_OPERATION DmaOperation;\r
-\r
- if (Operation == EfiPciIoOperationBusMasterRead) {\r
- DmaOperation = MapOperationBusMasterRead;\r
- } else if (Operation == EfiPciIoOperationBusMasterWrite) {\r
- DmaOperation = MapOperationBusMasterWrite;\r
- } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {\r
- DmaOperation = MapOperationBusMasterCommonBuffer;\r
- } else {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);\r
-}\r
-\r
-EFI_STATUS\r
-PciIoUnmap (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN VOID *Mapping\r
- )\r
-{\r
- return DmaUnmap (Mapping);\r
-}\r
-\r
-EFI_STATUS\r
-PciIoAllocateBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_ALLOCATE_TYPE Type,\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Pages,\r
- OUT VOID **HostAddress,\r
- IN UINT64 Attributes\r
- )\r
-{\r
- if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {\r
- // Check this\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- return DmaAllocateBuffer (MemoryType, Pages, HostAddress);\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciIoFreeBuffer (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINTN Pages,\r
- IN VOID *HostAddress\r
- )\r
-{\r
- return DmaFreeBuffer (Pages, HostAddress);\r
-}\r
-\r
-\r
-EFI_STATUS\r
-PciIoFlush (\r
- IN EFI_PCI_IO_PROTOCOL *This\r
- )\r
-{\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoGetLocation (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- OUT UINTN *SegmentNumber,\r
- OUT UINTN *BusNumber,\r
- OUT UINTN *DeviceNumber,\r
- OUT UINTN *FunctionNumber\r
- )\r
-{\r
- EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);\r
-\r
- if (SegmentNumber != NULL) {\r
- *SegmentNumber = Private->Segment;\r
- }\r
-\r
- if (BusNumber != NULL) {\r
- *BusNumber = 0xff;\r
- }\r
-\r
- if (DeviceNumber != NULL) {\r
- *DeviceNumber = 0;\r
- }\r
-\r
- if (FunctionNumber != NULL) {\r
- *FunctionNumber = 0;\r
- }\r
\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-PciIoAttributes (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,\r
- IN UINT64 Attributes,\r
- OUT UINT64 *Result OPTIONAL\r
- )\r
-{\r
- switch (Operation) {\r
- case EfiPciIoAttributeOperationGet:\r
- case EfiPciIoAttributeOperationSupported:\r
- if (Result == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- // We are not a real PCI device so just say things we kind of do\r
- *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE;\r
- break;\r
-\r
- case EfiPciIoAttributeOperationSet:\r
- case EfiPciIoAttributeOperationEnable:\r
- case EfiPciIoAttributeOperationDisable:\r
- // Since we are not a real PCI device no enable/set or disable operations exist.\r
- return EFI_SUCCESS;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- return EFI_INVALID_PARAMETER;\r
- };\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoGetBarAttributes (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINT8 BarIndex,\r
- OUT UINT64 *Supports, OPTIONAL\r
- OUT VOID **Resources OPTIONAL\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-PciIoSetBarAttributes (\r
- IN EFI_PCI_IO_PROTOCOL *This,\r
- IN UINT64 Attributes,\r
- IN UINT8 BarIndex,\r
- IN OUT UINT64 *Offset,\r
- IN OUT UINT64 *Length\r
- )\r
-{\r
- ASSERT (FALSE);\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_PCI_IO_PROTOCOL PciIoTemplate =\r
-{\r
- PciIoPollMem,\r
- PciIoPollIo,\r
- { PciIoMemRead, PciIoMemWrite },\r
- { PciIoIoRead, PciIoIoWrite },\r
- { PciIoPciRead, PciIoPciWrite },\r
- PciIoCopyMem,\r
- PciIoMap,\r
- PciIoUnmap,\r
- PciIoAllocateBuffer,\r
- PciIoFreeBuffer,\r
- PciIoFlush,\r
- PciIoGetLocation,\r
- PciIoAttributes,\r
- PciIoGetBarAttributes,\r
- PciIoSetBarAttributes,\r
- 0,\r
- 0\r
-};\r
-\r
EFI_STATUS\r
EFIAPI\r
PciEmulationEntryPoint (\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_HANDLE Handle;\r
- EFI_PCI_IO_PRIVATE_DATA *Private;\r
UINT8 CapabilityLength;\r
UINT8 PhysicalPorts;\r
- UINTN Count;\r
-\r
-\r
- //Configure USB host for OMAP3530.\r
- ConfigureUSBHost();\r
-\r
- // Create a private structure\r
- Private = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));\r
- if (Private == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- return Status;\r
- }\r
-\r
- Private->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature\r
- Private->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too\r
- Private->RootBridge.MemoryStart = USB_EHCI_HCCAPBASE; // Get the USB capability register base\r
- Private->Segment = 0; // Default to segment zero\r
-\r
- // Find out the capability register length and number of physical ports.\r
- CapabilityLength = MmioRead8(Private->RootBridge.MemoryStart);\r
- PhysicalPorts = (MmioRead32 (Private->RootBridge.MemoryStart + 0x4)) & 0x0000000F;\r
-\r
- // Calculate the total size of the USB registers.\r
- Private->RootBridge.MemorySize = CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1));\r
-\r
- // Enable Port Power bit in Port status and control registers in EHCI register space.\r
- // Port Power Control (PPC) bit in the HCSPARAMS register is already set which indicates\r
- // host controller implementation includes port power control.\r
- for (Count = 0; Count < PhysicalPorts; Count++) {\r
- MmioOr32 ((Private->RootBridge.MemoryStart + CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE + 4*Count), 0x00001000);\r
- }\r
-\r
- // Create fake PCI config space.\r
- Private->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));\r
- if (Private->ConfigSpace == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- FreePool(Private);\r
- return Status;\r
- }\r
-\r
- // Configure PCI config space\r
- Private->ConfigSpace->Hdr.VendorId = 0x3530;\r
- Private->ConfigSpace->Hdr.DeviceId = 0x3530;\r
- Private->ConfigSpace->Hdr.ClassCode[0] = 0x20;\r
- Private->ConfigSpace->Hdr.ClassCode[1] = 0x03;\r
- Private->ConfigSpace->Hdr.ClassCode[2] = 0x0C;\r
- Private->ConfigSpace->Device.Bar[0] = Private->RootBridge.MemoryStart;\r
-\r
- Handle = NULL;\r
-\r
- // Unique device path.\r
- CopyMem(&Private->DevicePath, &PciIoDevicePathTemplate, sizeof(PciIoDevicePathTemplate));\r
- Private->DevicePath.AcpiDevicePath.UID = 0;\r
-\r
- // Copy protocol structure\r
- CopyMem(&Private->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));\r
-\r
- Status = gBS->InstallMultipleProtocolInterfaces(&Handle,\r
- &gEfiPciIoProtocolGuid, &Private->PciIoProtocol,\r
- &gEfiDevicePathProtocolGuid, &Private->DevicePath,\r
- NULL);\r
- if (EFI_ERROR(Status)) {\r
- DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n"));\r
- }\r
-\r
- return Status;\r
+ UINTN MemorySize;\r
+\r
+ CapabilityLength = MmioRead8 (USB_EHCI_HCCAPBASE);\r
+ PhysicalPorts = MmioRead32 (USB_EHCI_HCCAPBASE + 0x4) & 0x0000000F;\r
+ MemorySize = CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE +\r
+ 4 * PhysicalPorts - 1;\r
+\r
+ return RegisterNonDiscoverableMmioDevice (\r
+ NonDiscoverableDeviceTypeEhci,\r
+ NonDiscoverableDeviceDmaTypeNonCoherent,\r
+ ConfigureUSBHost,\r
+ NULL,\r
+ 1,\r
+ USB_EHCI_HCCAPBASE, MemorySize\r
+ );\r
}\r
-\r