From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- .../NonDiscoverableDeviceRegistrationLib.c | 208 +++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c') diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c new file mode 100644 index 00000000..e468634c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.c @@ -0,0 +1,208 @@ +/** @file + Copyright (c) 2016, Linaro, Ltd. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/** + Get Guid form the type of non-discoverable device. + + @param[in] Type The type of non-discoverable device. + + @retval Return the Guid. + +**/ +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] Type 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 + @param[in] ... The variable argument list which contains the + info about MmioResources. + + @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 = ((EFI_PHYSICAL_ADDRESS)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; +} -- cgit v1.2.3