From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../Universal/Disk/RamDiskDxe/RamDiskImpl.c | 758 +++++++++++++++++++++ 1 file changed, 758 insertions(+) create mode 100644 roms/edk2/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c (limited to 'roms/edk2/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c') diff --git a/roms/edk2/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c b/roms/edk2/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c new file mode 100644 index 000000000..e35b8fa22 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskImpl.c @@ -0,0 +1,758 @@ +/** @file + HII Config Access protocol implementation of RamDiskDxe driver. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ (C) Copyright 2016-2018 Hewlett Packard Enterprise Development LP
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RamDiskImpl.h" + +CHAR16 mRamDiskStorageName[] = L"RAM_DISK_CONFIGURATION"; + +RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate = { + RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE, + { + EFI_PAGE_SIZE, + RAM_DISK_BOOT_SERVICE_DATA_MEMORY + }, + { + RamDiskExtractConfig, + RamDiskRouteConfig, + RamDiskCallback + } +}; + +HII_VENDOR_DEVICE_PATH mRamDiskHiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + RAM_DISK_FORM_SET_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + + +/** + This function publish the RAM disk configuration Form. + + @param[in, out] ConfigPrivateData + Points to RAM disk configuration private data. + + @retval EFI_SUCCESS HII Form is installed successfully. + @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +InstallRamDiskConfigForm ( + IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData + ) +{ + EFI_STATUS Status; + EFI_HII_HANDLE HiiHandle; + EFI_HANDLE DriverHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + + DriverHandle = NULL; + ConfigAccess = &ConfigPrivateData->ConfigAccess; + Status = gBS->InstallMultipleProtocolInterfaces ( + &DriverHandle, + &gEfiDevicePathProtocolGuid, + &mRamDiskHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + ConfigAccess, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ConfigPrivateData->DriverHandle = DriverHandle; + + // + // Publish the HII package list + // + HiiHandle = HiiAddPackages ( + &gRamDiskFormSetGuid, + DriverHandle, + RamDiskDxeStrings, + RamDiskHiiBin, + NULL + ); + if (HiiHandle == NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + DriverHandle, + &gEfiDevicePathProtocolGuid, + &mRamDiskHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + ConfigAccess, + NULL + ); + return EFI_OUT_OF_RESOURCES; + } + + ConfigPrivateData->HiiHandle = HiiHandle; + + return EFI_SUCCESS; +} + + +/** + This function removes RAM disk configuration Form. + + @param[in, out] ConfigPrivateData + Points to RAM disk configuration private data. + +**/ +VOID +UninstallRamDiskConfigForm ( + IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData + ) +{ + // + // Uninstall HII package list + // + if (ConfigPrivateData->HiiHandle != NULL) { + HiiRemovePackages (ConfigPrivateData->HiiHandle); + ConfigPrivateData->HiiHandle = NULL; + } + + // + // Uninstall HII Config Access Protocol + // + if (ConfigPrivateData->DriverHandle != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + ConfigPrivateData->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mRamDiskHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &ConfigPrivateData->ConfigAccess, + NULL + ); + ConfigPrivateData->DriverHandle = NULL; + } + + FreePool (ConfigPrivateData); +} + + +/** + Unregister all registered RAM disks. + +**/ +VOID +UnregisterAllRamDisks ( + VOID + ) +{ + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + RAM_DISK_PRIVATE_DATA *PrivateData; + + if (!IsListEmpty(&RegisteredRamDisks)) { + BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) { + PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry); + + gBS->UninstallMultipleProtocolInterfaces ( + PrivateData->Handle, + &gEfiBlockIoProtocolGuid, + &PrivateData->BlockIo, + &gEfiBlockIo2ProtocolGuid, + &PrivateData->BlockIo2, + &gEfiDevicePathProtocolGuid, + (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath, + NULL + ); + + RemoveEntryList (&PrivateData->ThisInstance); + + if (RamDiskCreateHii == PrivateData->CreateMethod) { + // + // If a RAM disk is created within HII, then the RamDiskDxe driver + // driver is responsible for freeing the allocated memory for the + // RAM disk. + // + FreePool ((VOID *)(UINTN) PrivateData->StartingAddr); + } + + FreePool (PrivateData->DevicePath); + FreePool (PrivateData); + } + } +} + + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Request A null-terminated Unicode string in + format. + @param[out] Progress On return, points to a character in the Request + string. Points to the string's null terminator if + request was successful. Points to the most recent + '&' before the first failing name/value pair (or + the beginning of the string if the failure is in + the first name/value pair) if the request was not + successful. + @param[out] Results A null-terminated Unicode string in + format which has all values filled + in for the names in the Request string. String to + be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested + values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in + this driver. + +**/ +EFI_STATUS +EFIAPI +RamDiskExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + if (Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + *Progress = Request; + return EFI_NOT_FOUND; +} + + +/** + This function processes the results of changes in configuration. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Configuration A null-terminated Unicode string in + format. + @param[out] Progress A pointer to a string filled in with the offset of + the most recent '&' before the first failing + name/value pair (or the beginning of the string if + the failure is in the first name/value pair) or + the terminating NULL if all was successful. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in + this driver. + +**/ +EFI_STATUS +EFIAPI +RamDiskRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + if (Configuration == NULL || Progress == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Progress = Configuration; + + return EFI_NOT_FOUND; +} + + +/** + Allocate memory and register the RAM disk created within RamDiskDxe + driver HII. + + @param[in] Size If creating raw, size of the RAM disk to create. + If creating from file, zero. + @param[in] FileHandle If creating raw, NULL. If creating from file, the + file handle. + @param[in] MemoryType Type of memory to be used to create RAM Disk. + + @retval EFI_SUCCESS RAM disk is created and registered. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to match the + size required. + +**/ +EFI_STATUS +HiiCreateRamDisk ( + IN UINT64 Size, + IN EFI_FILE_HANDLE FileHandle, + IN UINT8 MemoryType + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + UINT64 *StartingAddr; + EFI_INPUT_KEY Key; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + RAM_DISK_PRIVATE_DATA *PrivateData; + EFI_FILE_INFO *FileInformation; + + FileInformation = NULL; + StartingAddr = NULL; + + if (FileHandle != NULL) { + // + // Create from file. + // + FileInformation = FileInfo (FileHandle); + if (NULL == FileInformation) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"Not enough memory to get the file information!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + return EFI_OUT_OF_RESOURCES; + } + + // + // Update the size of RAM disk according to the file size. + // + Size = FileInformation->FileSize; + } + + if (Size > (UINTN) -1) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"The given RAM disk size is too large!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + return EFI_OUT_OF_RESOURCES; + } + + if (MemoryType == RAM_DISK_BOOT_SERVICE_DATA_MEMORY) { + Status = gBS->AllocatePool ( + EfiBootServicesData, + (UINTN)Size, + (VOID**)&StartingAddr + ); + } else if (MemoryType == RAM_DISK_RESERVED_MEMORY) { + Status = gBS->AllocatePool ( + EfiReservedMemoryType, + (UINTN)Size, + (VOID**)&StartingAddr + ); + } else { + Status = EFI_INVALID_PARAMETER; + } + + if ((StartingAddr == NULL) || EFI_ERROR(Status)) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"Not enough memory to create the RAM disk!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + return EFI_OUT_OF_RESOURCES; + } + + if (FileHandle != NULL) { + // + // Copy the file content to the RAM disk. + // + BufferSize = (UINTN) Size; + FileHandle->Read ( + FileHandle, + &BufferSize, + (VOID *)(UINTN) StartingAddr + ); + if (BufferSize != FileInformation->FileSize) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"File content read error!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + return EFI_DEVICE_ERROR; + } + } + + // + // Register the newly created RAM disk. + // + Status = RamDiskRegister ( + ((UINT64)(UINTN) StartingAddr), + Size, + &gEfiVirtualDiskGuid, + NULL, + &DevicePath + ); + if (EFI_ERROR (Status)) { + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"Fail to register the newly created RAM disk!", + L"Press ENTER to continue ...", + L"", + NULL + ); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + return Status; + } + + // + // If RAM disk is created within HII, memory should be freed when the + // RAM disk is unregisterd. + // + PrivateData = RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks.BackLink); + PrivateData->CreateMethod = RamDiskCreateHii; + + return EFI_SUCCESS; +} + + +/** + This function updates the registered RAM disks list on the main form. + + @param[in, out] ConfigPrivate + Private data for configurating hii data for RAM + disks. + +**/ +VOID +UpdateMainForm ( + IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate + ) +{ + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + LIST_ENTRY *Entry; + UINTN Index; + RAM_DISK_PRIVATE_DATA *PrivateData; + CHAR16 *String; + CHAR16 RamDiskStr[128]; + EFI_STRING_ID StringId; + + // + // Init OpCode Handle + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (EndOpCodeHandle != NULL); + + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = MAIN_LABEL_LIST_START; + + // + // Create Hii Extend Label OpCode as the end opcode + // + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = MAIN_LABEL_LIST_END; + + Index = 0; + BASE_LIST_FOR_EACH (Entry, &RegisteredRamDisks) { + PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry); + PrivateData->CheckBoxId = (EFI_QUESTION_ID) + (MAIN_CHECKBOX_QUESTION_ID_START + Index); + // + // CheckBox is unchecked by default. + // + PrivateData->CheckBoxChecked = FALSE; + String = RamDiskStr; + + UnicodeSPrint ( + String, + sizeof (RamDiskStr), + L" RAM Disk %d: [0x%lx, 0x%lx]\n", + Index, + PrivateData->StartingAddr, + PrivateData->StartingAddr + PrivateData->Size - 1 + ); + + StringId = HiiSetString (ConfigPrivate->HiiHandle, 0, RamDiskStr, NULL); + ASSERT (StringId != 0); + + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, + PrivateData->CheckBoxId, + 0, + 0, + StringId, + STRING_TOKEN (STR_RAM_DISK_LIST_HELP), + EFI_IFR_FLAG_CALLBACK, + 0, + NULL + ); + + Index++; + } + + HiiUpdateForm ( + ConfigPrivate->HiiHandle, + &gRamDiskFormSetGuid, + MAIN_FORM_ID, + StartOpCodeHandle, + EndOpCodeHandle + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); +} + + +/** + This function processes the results of changes in configuration. + + @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param[in] Action Specifies the type of action taken by the browser. + @param[in] QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. + @param[in] Type The type of value for the question. + @param[in] Value A pointer to the data being sent to the original + exporting driver. + @param[out] ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. + +**/ +EFI_STATUS +EFIAPI +RamDiskCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + EFI_STATUS Status; + RAM_DISK_PRIVATE_DATA *PrivateData; + RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate; + EFI_DEVICE_PATH_PROTOCOL *FileDevPath; + EFI_FILE_HANDLE FileHandle; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { + return EFI_INVALID_PARAMETER; + } + + ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This); + + if (Action == EFI_BROWSER_ACTION_RETRIEVE) { + Status = EFI_UNSUPPORTED; + if (QuestionId == CREATE_RAW_SIZE_QUESTION_ID) { + Value->u64 = EFI_PAGE_SIZE; + ConfigPrivate->ConfigStore.Size = EFI_PAGE_SIZE; + Status = EFI_SUCCESS; + } else if (QuestionId == CREATE_RAW_MEMORY_TYPE_QUESTION_ID) { + Value->u8 = RAM_DISK_BOOT_SERVICE_DATA_MEMORY; + ConfigPrivate->ConfigStore.MemType = RAM_DISK_BOOT_SERVICE_DATA_MEMORY; + Status = EFI_SUCCESS; + } + return Status; + } + + if ((Action != EFI_BROWSER_ACTION_CHANGED) && + (Action != EFI_BROWSER_ACTION_CHANGING) && + (Action != EFI_BROWSER_ACTION_FORM_OPEN)) { + return EFI_UNSUPPORTED; + } + + // + // Update the RAM disk list show at the main form first. + // + if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { + Status = EFI_UNSUPPORTED; + if (QuestionId == MAIN_GOTO_FILE_EXPLORER_ID) { + UpdateMainForm (ConfigPrivate); + Status = EFI_SUCCESS; + } + return Status; + } + + Status = EFI_SUCCESS; + + if (Action == EFI_BROWSER_ACTION_CHANGING) { + switch (QuestionId) { + case MAIN_GOTO_FILE_EXPLORER_ID: + Status = ChooseFile (NULL, NULL, NULL, &FileDevPath); + if (EFI_ERROR (Status)) { + break; + } + + if (FileDevPath != NULL) { + // + // Open the file. + // + Status = EfiOpenFileByDevicePath ( + &FileDevPath, + &FileHandle, + EFI_FILE_MODE_READ, + 0 + ); + if (EFI_ERROR (Status)) { + break; + } + + // + // Create from file, RAM disk size is zero. It will be updated + // according to the file size. + // + Status = HiiCreateRamDisk ( + 0, + FileHandle, + ConfigPrivate->ConfigStore.MemType + ); + if (EFI_ERROR (Status)) { + break; + } + + // + // Refresh the registered RAM disks list. + // + UpdateMainForm (ConfigPrivate); + } + break; + + default: + break; + } + } else if (Action == EFI_BROWSER_ACTION_CHANGED) { + switch (QuestionId) { + case MAIN_REMOVE_RD_QUESTION_ID: + // + // Remove the selected RAM disks + // + BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) { + PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry); + if (PrivateData->CheckBoxChecked) { + RamDiskUnregister ( + (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath + ); + } + } + + UpdateMainForm (ConfigPrivate); + + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + break; + + case CREATE_RAW_SIZE_QUESTION_ID: + ConfigPrivate->ConfigStore.Size = Value->u64; + break; + + case CREATE_RAW_MEMORY_TYPE_QUESTION_ID: + ConfigPrivate->ConfigStore.MemType = Value->u8; + break; + + case CREATE_RAW_SUBMIT_QUESTION_ID: + // + // Create raw, FileHandle is NULL. + // + Status = HiiCreateRamDisk ( + ConfigPrivate->ConfigStore.Size, + NULL, + ConfigPrivate->ConfigStore.MemType + ); + if (EFI_ERROR (Status)) { + break; + } + + // + // Refresh the registered RAM disks list. + // + UpdateMainForm (ConfigPrivate); + + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + + case CREATE_RAW_DISCARD_QUESTION_ID: + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + + default: + // + // QuestionIds for checkboxes + // + if ((QuestionId >= MAIN_CHECKBOX_QUESTION_ID_START) && + (QuestionId < CREATE_RAW_RAM_DISK_FORM_ID)) { + BASE_LIST_FOR_EACH (Entry, &RegisteredRamDisks) { + PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry); + if (PrivateData->CheckBoxId == QuestionId) { + PrivateData->CheckBoxChecked = (BOOLEAN) (Value->u8 != 0); + } + } + } + break; + } + } + + return EFI_SUCCESS; +} -- cgit 1.2.3-korg