diff --git a/MdeModulePkg/Include/Library/NonDiscoverableDeviceRegistrationLib.h b/MdeModulePkg/Include/Library/NonDiscoverableDeviceRegistrationLib.h new file mode 100644 index 0000000000..120d914660 --- /dev/null +++ b/MdeModulePkg/Include/Library/NonDiscoverableDeviceRegistrationLib.h @@ -0,0 +1,62 @@ +/** @file + Copyright (c) 2016, Linaro, Ltd. 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 __NON_DISCOVERABLE_DEVICE_REGISTRATION_LIB_H__ +#define __NON_DISCOVERABLE_DEVICE_REGISTRATION_LIB_H__ + +#include + +typedef enum { + NonDiscoverableDeviceTypeAhci, + NonDiscoverableDeviceTypeAmba, + NonDiscoverableDeviceTypeEhci, + NonDiscoverableDeviceTypeNvme, + NonDiscoverableDeviceTypeOhci, + NonDiscoverableDeviceTypeSdhci, + NonDiscoverableDeviceTypeUfs, + NonDiscoverableDeviceTypeUhci, + NonDiscoverableDeviceTypeXhci, + NonDiscoverableDeviceTypeMax, +} NON_DISCOVERABLE_DEVICE_TYPE; + +/** + Register a non-discoverable MMIO device + + @param[in] DeviceType The type of non-discoverable device + @param[in] DmaType Whether the device is DMA coherent + @param[in] InitFunc Initialization routine to be invoked when + the device is enabled + @param[in,out] Handle The handle onto which to install the + non-discoverable device protocol. + If Handle is NULL or *Handle is NULL, a + new handle will be allocated. + @param[in] NumMmioResources The number of UINTN base/size pairs that + follow, each describing an MMIO region + owned by the device + + @retval EFI_SUCCESS The registration succeeded. + @retval Other The registration failed. + +**/ +EFI_STATUS +EFIAPI +RegisterNonDiscoverableMmioDevice ( + IN NON_DISCOVERABLE_DEVICE_TYPE Type, + IN NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType, + IN NON_DISCOVERABLE_DEVICE_INIT InitFunc, + IN OUT EFI_HANDLE *Handle OPTIONAL, + IN UINTN NumMmioResources, + ... + ); + +#endif diff --git a/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c b/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c new file mode 100644 index 0000000000..94cd946b69 --- /dev/null +++ b/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c @@ -0,0 +1,204 @@ +/** @file + Copyright (c) 2016, Linaro, Ltd. 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 + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +STATIC +CONST EFI_GUID * +GetGuidFromType ( + IN NON_DISCOVERABLE_DEVICE_TYPE Type + ) +{ + switch (Type) { + case NonDiscoverableDeviceTypeAhci: + return &gEdkiiNonDiscoverableAhciDeviceGuid; + + case NonDiscoverableDeviceTypeAmba: + return &gEdkiiNonDiscoverableAmbaDeviceGuid; + + case NonDiscoverableDeviceTypeEhci: + return &gEdkiiNonDiscoverableEhciDeviceGuid; + + case NonDiscoverableDeviceTypeNvme: + return &gEdkiiNonDiscoverableNvmeDeviceGuid; + + case NonDiscoverableDeviceTypeOhci: + return &gEdkiiNonDiscoverableOhciDeviceGuid; + + case NonDiscoverableDeviceTypeSdhci: + return &gEdkiiNonDiscoverableSdhciDeviceGuid; + + case NonDiscoverableDeviceTypeUfs: + return &gEdkiiNonDiscoverableUfsDeviceGuid; + + case NonDiscoverableDeviceTypeUhci: + return &gEdkiiNonDiscoverableUhciDeviceGuid; + + case NonDiscoverableDeviceTypeXhci: + return &gEdkiiNonDiscoverableXhciDeviceGuid; + + default: + return NULL; + } +} + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT64 BaseAddress; + UINT8 ResourceType; + EFI_DEVICE_PATH_PROTOCOL End; +} NON_DISCOVERABLE_DEVICE_PATH; +#pragma pack () + +/** + Register a non-discoverable MMIO device + + @param[in] DeviceType The type of non-discoverable device + @param[in] DmaType Whether the device is DMA coherent + @param[in] InitFunc Initialization routine to be invoked when + the device is enabled + @param[in,out] Handle The handle onto which to install the + non-discoverable device protocol. + If Handle is NULL or *Handle is NULL, a + new handle will be allocated. + @param[in] NumMmioResources The number of UINTN base/size pairs that + follow, each describing an MMIO region + owned by the device + + @retval EFI_SUCCESS The registration succeeded. + @retval EFI_INVALID_PARAMETER An invalid argument was given + @retval Other The registration failed. + +**/ +EFI_STATUS +EFIAPI +RegisterNonDiscoverableMmioDevice ( + IN NON_DISCOVERABLE_DEVICE_TYPE Type, + IN NON_DISCOVERABLE_DEVICE_DMA_TYPE DmaType, + IN NON_DISCOVERABLE_DEVICE_INIT InitFunc, + IN OUT EFI_HANDLE *Handle OPTIONAL, + IN UINTN NumMmioResources, + ... + ) +{ + NON_DISCOVERABLE_DEVICE *Device; + NON_DISCOVERABLE_DEVICE_PATH *DevicePath; + EFI_HANDLE LocalHandle; + EFI_STATUS Status; + UINTN AllocSize; + UINTN Index; + VA_LIST Args; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Desc; + EFI_ACPI_END_TAG_DESCRIPTOR *End; + UINTN Base, Size; + + if (Type >= NonDiscoverableDeviceTypeMax || + DmaType >= NonDiscoverableDeviceDmaTypeMax || + NumMmioResources == 0) { + return EFI_INVALID_PARAMETER; + } + + if (Handle == NULL) { + Handle = &LocalHandle; + LocalHandle = NULL; + } + + AllocSize = sizeof *Device + + NumMmioResources * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR); + Device = (NON_DISCOVERABLE_DEVICE *)AllocateZeroPool (AllocSize); + if (Device == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Device->Type = GetGuidFromType (Type); + ASSERT (Device->Type != NULL); + + Device->DmaType = DmaType; + Device->Initialize = InitFunc; + Device->Resources = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(Device + 1); + + VA_START (Args, NumMmioResources); + for (Index = 0; Index < NumMmioResources; Index++) { + Desc = &Device->Resources [Index]; + Base = VA_ARG (Args, UINTN); + Size = VA_ARG (Args, UINTN); + + Desc->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR; + Desc->Len = sizeof *Desc - 3; + Desc->AddrRangeMin = Base; + Desc->AddrLen = Size; + Desc->AddrRangeMax = Base + Size - 1; + Desc->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM; + Desc->AddrSpaceGranularity = (Base + Size > SIZE_4GB) ? 64 : 32; + Desc->AddrTranslationOffset = 0; + } + VA_END (Args); + + End = (EFI_ACPI_END_TAG_DESCRIPTOR *)&Device->Resources [NumMmioResources]; + + End->Desc = ACPI_END_TAG_DESCRIPTOR; + End->Checksum = 0; + + DevicePath = (NON_DISCOVERABLE_DEVICE_PATH *)CreateDeviceNode ( + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + sizeof (*DevicePath)); + if (DevicePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto FreeDevice; + } + + CopyGuid (&DevicePath->Vendor.Guid, &gEdkiiNonDiscoverableDeviceProtocolGuid); + + // + // Use the base address and type of the first region to + // make the device path unique + // + DevicePath->BaseAddress = Device->Resources [0].AddrRangeMin; + DevicePath->ResourceType = Device->Resources [0].ResType; + + SetDevicePathNodeLength (&DevicePath->Vendor, + sizeof (*DevicePath) - sizeof (DevicePath->End)); + SetDevicePathEndNode (&DevicePath->End); + + Status = gBS->InstallMultipleProtocolInterfaces (Handle, + &gEdkiiNonDiscoverableDeviceProtocolGuid, Device, + &gEfiDevicePathProtocolGuid, DevicePath, + NULL); + if (EFI_ERROR (Status)) { + goto FreeDevicePath; + } + return EFI_SUCCESS; + +FreeDevicePath: + FreePool (DevicePath); + +FreeDevice: + FreePool (Device); + + return Status; +} diff --git a/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf b/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf new file mode 100644 index 0000000000..ba32324c30 --- /dev/null +++ b/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf @@ -0,0 +1,46 @@ +# @file +# Copyright (c) 2016, Linaro, Ltd. 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 = NonDiscoverableDeviceRegistrationLib + FILE_GUID = 8802ae41-8184-49cb-8aec-62627cd7ceb4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NonDiscoverableDeviceRegistrationLib + +[Sources] + NonDiscoverableDeviceRegistrationLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + DevicePathLib + UefiBootServicesTableLib + +[Protocols] + gEdkiiNonDiscoverableDeviceProtocolGuid + +[Guids] + gEdkiiNonDiscoverableAhciDeviceGuid + gEdkiiNonDiscoverableAmbaDeviceGuid + gEdkiiNonDiscoverableEhciDeviceGuid + gEdkiiNonDiscoverableNvmeDeviceGuid + gEdkiiNonDiscoverableOhciDeviceGuid + gEdkiiNonDiscoverableSdhciDeviceGuid + gEdkiiNonDiscoverableUfsDeviceGuid + gEdkiiNonDiscoverableUhciDeviceGuid + gEdkiiNonDiscoverableXhciDeviceGuid diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index abd5da5daa..a5eb901c4d 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -161,6 +161,10 @@ # FmpAuthenticationLib|Include/Library/FmpAuthenticationLib.h + ## @libraryclass Provides a service to register non-discoverable device + ## + NonDiscoverableDeviceRegistrationLib|Include/Library/NonDiscoverableDeviceRegistrationLib.h + [Guids] ## MdeModule package token space guid # Include/Guid/MdeModulePkgTokenSpace.h diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index d7db274cac..ada76594c5 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -102,6 +102,7 @@ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf @@ -322,6 +323,7 @@ MdeModulePkg/Library/PeiIpmiLibIpmiPpi/PeiIpmiLibIpmiPpi.inf MdeModulePkg/Library/SmmIpmiLibSmmIpmiProtocol/SmmIpmiLibSmmIpmiProtocol.inf MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf + MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf