From 0591696eff9962b52b3b0137e865198096353573 Mon Sep 17 00:00:00 2001 From: Feng Tian Date: Wed, 29 Apr 2015 02:42:58 +0000 Subject: MdeModulePkg: Add UFS (Universal Flash Storage) Stack It includes 4 drivers: 1. UfsPassThruDxe, which is a UEFI driver and consumes EFI_UFS_HOST_CONTROLLER_PROTOCOL and produces EFI_EXT_SCSI_PASS_THRU_PROTOCOL 2. UfsPciHcDxe, which is specific for pci-based UFS HC implementation and is a UEFI driver to produce EFI_UFS_HOST_CONTROLLER_PROTOCOL. 3. UfsBlockIoPei, which is a PEI driver and consumes EFI_UFS_HOST_CONTROLLER_PPI and produces EFI_PEI_VIRTUAL_BLOCK_IO_PPI. 4. UfsPciHcPei, which is specific for pci-based UFS HC implementation and is a PEI driver to produce EFI_UFS_HOST_CONTROLLER_PPI. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Feng Tian Reviewed-by: Star Zeng git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17246 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c | 225 +++++++ MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c | 699 +++++++++++++++++++++ MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h | 453 +++++++++++++ MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf | 56 ++ MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni | Bin 0 -> 1980 bytes .../Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni | Bin 0 -> 1336 bytes 6 files changed, 1433 insertions(+) create mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c create mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c create mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h create mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf create mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni create mode 100644 MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni (limited to 'MdeModulePkg/Bus/Pci/UfsPciHcDxe') diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c new file mode 100644 index 0000000000..1e2db1a876 --- /dev/null +++ b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/ComponentName.c @@ -0,0 +1,225 @@ +/** @file + UfsHcDxe driver produces EFI_UFS_HOST_CONTROLLER_PROTOCOL. The upper layer module + uses it to query the MMIO base address of the UFS host controller. + + Copyright (c) 2014, Intel Corporation. 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 "UfsPciHcDxe.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUfsHcComponentName = { + UfsHcComponentNameGetDriverName, + UfsHcComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUfsHcComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UfsHcComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UfsHcComponentNameGetControllerName, + "en" +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUfsHcDriverNameTable[] = { + { + "eng;en", + L"Universal Flash Storage (UFS) Pci Host Controller Driver" + }, + { + NULL, + NULL + } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUfsHcControllerNameTable[] = { + { + "eng;en", + L"Universal Flash Storage (UFS) Pci Host Controller" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UfsHcComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mUfsHcDriverNameTable, + DriverName, + (BOOLEAN)(This == &gUfsHcComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UfsHcComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + + if (Language == NULL || ControllerName == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // This is a device driver, so ChildHandle must be NULL. + // + if (ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Make sure this driver is currently managing Controller Handle + // + Status = EfiTestManagedDevice ( + ControllerHandle, + gUfsHcDriverBinding.DriverBindingHandle, + &gEfiPciIoProtocolGuid + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mUfsHcControllerNameTable, + ControllerName, + (BOOLEAN)(This == &gUfsHcComponentName) + ); + +} diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c new file mode 100644 index 0000000000..586a52b380 --- /dev/null +++ b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.c @@ -0,0 +1,699 @@ +/** @file + UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller + MMIO base, to upper layer UFS drivers. + + Copyright (c) 2014, Intel Corporation. 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 "UfsPciHcDxe.h" + +// +// NVM Express Driver Binding Protocol Instance +// +EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding = { + UfsHcDriverBindingSupported, + UfsHcDriverBindingStart, + UfsHcDriverBindingStop, + 0x10, + NULL, + NULL +}; + +// +// Template for Ufs host controller private data. +// +UFS_HOST_CONTROLLER_PRIVATE_DATA gUfsHcTemplate = { + UFS_HC_PRIVATE_DATA_SIGNATURE, // Signature + NULL, // Handle + { // UfsHcProtocol + UfsHcGetMmioBar, + UfsHcAllocateBuffer, + UfsHcFreeBuffer, + UfsHcMap, + UfsHcUnmap, + UfsHcFlush + }, + NULL, // PciIo + 0 // PciAttributes +}; + +/** + Get the MMIO base of the UFS host controller. + + @param[in] This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param[out] MmioBar The MMIO base address of UFS host controller. + + @retval EFI_SUCCESS The operation succeeds. + @retval others The operation fails. +**/ +EFI_STATUS +EFIAPI +UfsHcGetMmioBar ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + OUT UINTN *MmioBar + ) +{ + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + if ((This == NULL) || (MmioBar == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); + PciIo = Private->PciIo; + + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + PCI_BASE_ADDRESSREG_OFFSET, + sizeof (UINT32), + MmioBar + ); + + if (!EFI_ERROR (Status)) { + *MmioBar &= (UINTN)~0xF; + } + return Status; +} + +/** + Provides the UFS controller-specific addresses needed to access system memory. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the UFS controller. + @param NumberOfBytes On input the number of bytes to map. On output the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus master UFS controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +EFI_STATUS +EFIAPI +UfsHcMap ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN EDKII_UFS_HOST_CONTROLLER_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ) +{ + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + if ((This == NULL) || (HostAddress == NULL) || (NumberOfBytes == NULL) || (DeviceAddress == NULL) || (Mapping == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); + PciIo = Private->PciIo; + + Status = PciIo->Map (PciIo, Operation, HostAddress, NumberOfBytes, DeviceAddress, Mapping); + return Status; +} + +/** + Completes the Map() operation and releases any corresponding resources. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Mapping The mapping value returned from Map(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. + +**/ +EFI_STATUS +EFIAPI +UfsHcUnmap ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN VOID *Mapping + ) +{ + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + if ((This == NULL) || (Mapping == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); + PciIo = Private->PciIo; + + Status = PciIo->Unmap (PciIo, Mapping); + return Status; +} + +/** + Allocates pages that are suitable for an EfiUfsHcOperationBusMasterCommonBuffer + mapping. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Type This parameter is not used and must be ignored. + @param MemoryType The type of memory to allocate, EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of the + allocated range. + @param Attributes The requested bit mask of attributes for the allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +UfsHcAllocateBuffer ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ) +{ + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + if ((This == NULL) || (HostAddress == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); + PciIo = Private->PciIo; + + Status = PciIo->AllocateBuffer (PciIo, Type, MemoryType, Pages, HostAddress, Attributes); + return Status; +} + +/** + Frees memory that was allocated with AllocateBuffer(). + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated range. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages + was not allocated with AllocateBuffer(). + +**/ +EFI_STATUS +EFIAPI +UfsHcFreeBuffer ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ) +{ + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + if ((This == NULL) || (HostAddress == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); + PciIo = Private->PciIo; + + Status = PciIo->FreeBuffer (PciIo, Pages, HostAddress); + return Status; +} + +/** + Flushes all posted write transactions from the UFS bus to attached UFS device. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + + @retval EFI_SUCCESS The posted write transactions were flushed from the UFS bus + to attached UFS device. + @retval EFI_DEVICE_ERROR The posted write transactions were not flushed from the UFS + bus to attached UFS device due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +UfsHcFlush ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This + ) +{ + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_STATUS Status; + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (This); + PciIo = Private->PciIo; + + Status = PciIo->Flush (PciIo); + return Status; +} + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Since ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +UfsHcDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + BOOLEAN UfsHcFound; + EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 PciData; + + PciIo = NULL; + ParentDevicePath = NULL; + UfsHcFound = FALSE; + + // + // UfsHcDxe is a device driver, and should ingore the + // "RemainingDevicePath" according to EFI spec + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID *) &ParentDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + // + // EFI_ALREADY_STARTED is also an error + // + return Status; + } + // + // Close the protocol because we don't use it here + // + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Now test the EfiPciIoProtocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Now further check the PCI header: Base class (offset 0x0B) and + // Sub Class (offset 0x0A). This controller should be an UFS controller + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + 0, + sizeof (PciData), + &PciData + ); + if (EFI_ERROR (Status)) { + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + return EFI_UNSUPPORTED; + } + // + // Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points. + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Examine UFS Host Controller PCI Configuration table fields + // + if (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE) { + if (PciData.Hdr.ClassCode[1] == 0x09 ) { //UFS Controller Subclass + UfsHcFound = TRUE; + } + } + + if (!UfsHcFound) { + return EFI_UNSUPPORTED; + } + + return Status; +} + + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +UfsHcDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + UINT64 Supports; + + PciIo = NULL; + Private = NULL; + Supports = 0; + + // + // Now test and open the EfiPciIoProtocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + // + // Status == 0 - A normal execution flow, SUCCESS and the program proceeds. + // Status == ALREADY_STARTED - A non-zero Status code returned. It indicates + // that the protocol has been opened and should be treated as a + // normal condition and the program proceeds. The Protocol will not + // opened 'again' by this call. + // Status != ALREADY_STARTED - Error status, terminate program execution + // + if (EFI_ERROR (Status)) { + // + // EFI_ALREADY_STARTED is also an error + // + return Status; + } + + Private = AllocateCopyPool (sizeof (UFS_HOST_CONTROLLER_PRIVATE_DATA), &gUfsHcTemplate); + if (Private == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Private->PciIo = PciIo; + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationGet, + 0, + &Private->PciAttributes + ); + + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSupported, + 0, + &Supports + ); + + if (!EFI_ERROR (Status)) { + Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE; + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + Supports, + NULL + ); + } else { + goto Done; + } + + /// + /// Install UFS_HOST_CONTROLLER protocol + /// + Status = gBS->InstallProtocolInterface ( + &Controller, + &gEdkiiUfsHostControllerProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID*)&(Private->UfsHc) + ); + +Done: + if (EFI_ERROR (Status)) { + if ((Private != NULL) && (Private->PciAttributes != 0)) { + // + // Restore original PCI attributes + // + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + Private->PciAttributes, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + if (Private != NULL) { + FreePool (Private); + } + } + + return Status; +} + + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +UfsHcDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + UFS_HOST_CONTROLLER_PRIVATE_DATA *Private; + EDKII_UFS_HOST_CONTROLLER_PROTOCOL *UfsHc; + + /// + /// Get private data + /// + Status = gBS->OpenProtocol ( + Controller, + &gEdkiiUfsHostControllerProtocolGuid, + (VOID **) &UfsHc, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Private = UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC (UfsHc); + + Status = gBS->UninstallProtocolInterface ( + Controller, + &gEdkiiUfsHostControllerProtocolGuid, + &(Private->UfsHc) + ); + if (!EFI_ERROR (Status)) { + // + // Restore original PCI attributes + // + Status = Private->PciIo->Attributes ( + Private->PciIo, + EfiPciIoAttributeOperationSet, + Private->PciAttributes, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Close protocols opened by UFS host controller driver + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + FreePool (Private); + } + + return Status; +} + +/** + The entry point for UFS host controller driver, used to install this driver on the ImageHandle. + + @param[in] ImageHandle The firmware allocated handle for this driver image. + @param[in] SystemTable Pointer to the EFI system table. + + @retval EFI_SUCCESS Driver loaded. + @retval other Driver not loaded. + +**/ +EFI_STATUS +EFIAPI +UfsHcDriverEntry ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gUfsHcDriverBinding, + ImageHandle, + &gUfsHcComponentName, + &gUfsHcComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h new file mode 100644 index 0000000000..f3b7eab24a --- /dev/null +++ b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.h @@ -0,0 +1,453 @@ +/** @file + UfsHcDxe driver is used to provide platform-dependent info, mainly UFS host controller + MMIO base, to upper layer UFS drivers. + + Copyright (c) 2014, Intel Corporation. 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 _EFI_UFS_HOST_CONTROLLER_H_ +#define _EFI_UFS_HOST_CONTROLLER_H_ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern EFI_DRIVER_BINDING_PROTOCOL gUfsHcDriverBinding; +extern EFI_COMPONENT_NAME_PROTOCOL gUfsHcComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gUfsHcComponentName2; + +// +// Unique signature for private data structure. +// +#define UFS_HC_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('U','F','S','H') + +typedef struct _UFS_HOST_CONTROLLER_PRIVATE_DATA UFS_HOST_CONTROLLER_PRIVATE_DATA; + +// +// Nvme private data structure. +// +struct _UFS_HOST_CONTROLLER_PRIVATE_DATA { + UINT32 Signature; + EFI_HANDLE Handle; + + EDKII_UFS_HOST_CONTROLLER_PROTOCOL UfsHc; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 PciAttributes; +}; + +#define UFS_HOST_CONTROLLER_PRIVATE_DATA_FROM_UFSHC(a) \ + CR (a, \ + UFS_HOST_CONTROLLER_PRIVATE_DATA, \ + UfsHc, \ + UFS_HC_PRIVATE_DATA_SIGNATURE \ + ) + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UfsHcComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +UfsHcComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Since ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +UfsHcDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +UfsHcDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ); + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +UfsHcDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ); + +/** + Get the MMIO base of the UFS host controller. + + @param[in] This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param[out] MmioBar The MMIO base address of UFS host controller. + + @retval EFI_SUCCESS The operation succeeds. + @retval others The operation fails. +**/ +EFI_STATUS +EFIAPI +UfsHcGetMmioBar ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + OUT UINTN *MmioBar + ); + +/** + Provides the UFS controller-specific addresses needed to access system memory. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Operation Indicates if the bus master is going to read or write to system memory. + @param HostAddress The system memory address to map to the UFS controller. + @param NumberOfBytes On input the number of bytes to map. On output the number of bytes + that were mapped. + @param DeviceAddress The resulting map address for the bus master UFS controller to use to + access the hosts HostAddress. + @param Mapping A resulting value to pass to Unmap(). + + @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. + @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. + +**/ +EFI_STATUS +EFIAPI +UfsHcMap ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN EDKII_UFS_HOST_CONTROLLER_OPERATION Operation, + IN VOID *HostAddress, + IN OUT UINTN *NumberOfBytes, + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, + OUT VOID **Mapping + ); + +/** + Completes the Map() operation and releases any corresponding resources. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Mapping The mapping value returned from Map(). + + @retval EFI_SUCCESS The range was unmapped. + @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. + +**/ +EFI_STATUS +EFIAPI +UfsHcUnmap ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN VOID *Mapping + ); + +/** + Allocates pages that are suitable for an EfiUfsHcOperationBusMasterCommonBuffer + mapping. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Type This parameter is not used and must be ignored. + @param MemoryType The type of memory to allocate, EfiBootServicesData or + EfiRuntimeServicesData. + @param Pages The number of pages to allocate. + @param HostAddress A pointer to store the base system memory address of the + allocated range. + @param Attributes The requested bit mask of attributes for the allocated range. + + @retval EFI_SUCCESS The requested memory pages were allocated. + @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are + MEMORY_WRITE_COMBINE and MEMORY_CACHED. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +UfsHcAllocateBuffer ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT VOID **HostAddress, + IN UINT64 Attributes + ); + +/** + Frees memory that was allocated with AllocateBuffer(). + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + @param Pages The number of pages to free. + @param HostAddress The base system memory address of the allocated range. + + @retval EFI_SUCCESS The requested memory pages were freed. + @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages + was not allocated with AllocateBuffer(). + +**/ +EFI_STATUS +EFIAPI +UfsHcFreeBuffer ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This, + IN UINTN Pages, + IN VOID *HostAddress + ); + +/** + Flushes all posted write transactions from the UFS bus to attached UFS device. + + @param This A pointer to the EFI_UFS_HOST_CONTROLLER_PROTOCOL instance. + + @retval EFI_SUCCESS The posted write transactions were flushed from the UFS bus + to attached UFS device. + @retval EFI_DEVICE_ERROR The posted write transactions were not flushed from the UFS + bus to attached UFS device due to a hardware error. + +**/ +EFI_STATUS +EFIAPI +UfsHcFlush ( + IN EDKII_UFS_HOST_CONTROLLER_PROTOCOL *This + ); + +#endif diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf new file mode 100644 index 0000000000..c1ce9ea851 --- /dev/null +++ b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.inf @@ -0,0 +1,56 @@ +## @file +# Component Description File For Universal Flash Storage Pci Host Controller Module. +# +# Copyright (c) 2014 - 2015, Intel Corporation. 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 = 0x00010005 + BASE_NAME = UfsPciHcDxe + MODULE_UNI_FILE = UfsPciHcDxe.uni + FILE_GUID = AF43E178-C2E9-4712-A7CD-08BFDAC7482C + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 0.9 + ENTRY_POINT = UfsHcDriverEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# +# DRIVER_BINDING = gUfsHcDriverBinding +# COMPONENT_NAME = gUfsHcComponentName +# COMPONENT_NAME2 = gUfsHcComponentName2 + +[Sources] + ComponentName.c + UfsPciHcDxe.c + UfsPciHcDxe.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + DevicePathLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiPciIoProtocolGuid ## TO_START + gEfiDevicePathProtocolGuid ## TO_START + gEdkiiUfsHostControllerProtocolGuid ## BY_START + +[UserExtensions.TianoCore."ExtraFiles"] + UfsPciHcDxeExtra.uni \ No newline at end of file diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni new file mode 100644 index 0000000000..5b3a137d80 Binary files /dev/null and b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxe.uni differ diff --git a/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni new file mode 100644 index 0000000000..fb359fd615 Binary files /dev/null and b/MdeModulePkg/Bus/Pci/UfsPciHcDxe/UfsPciHcDxeExtra.uni differ -- cgit v1.2.3