--- /dev/null
+/** @file\r
+ GUIDs used as HII FormSet and HII Package list GUID in RamDiskDxe driver.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __RAM_DISK_HII_GUID_H__\r
+#define __RAM_DISK_HII_GUID_H__\r
+\r
+#define RAM_DISK_FORM_SET_GUID \\r
+ { \\r
+ 0x2a46715f, 0x3581, 0x4a55, {0x8e, 0x73, 0x2b, 0x76, 0x9a, 0xaa, 0x30, 0xc5} \\r
+ }\r
+\r
+extern EFI_GUID gRamDiskFormSetGuid;\r
+\r
+#endif\r
\r
gEfiIfrFrontPageGuid = { 0xe58809f8, 0xfbc1, 0x48e2, { 0x88, 0x3a, 0xa3, 0x0f, 0xdc, 0x4b, 0x44, 0x1e } }\r
\r
+ ## Include/Guid/RamDiskHii.h\r
+ gRamDiskFormSetGuid = { 0x2a46715f, 0x3581, 0x4a55, { 0x8e, 0x73, 0x2b, 0x76, 0x9a, 0xaa, 0x30, 0xc5 }}\r
+\r
\r
[Ppis]\r
## Include/Ppi/AtaController.h\r
MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf\r
MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf\r
MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf\r
+ MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf\r
MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf\r
MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
MdeModulePkg/Universal/MemoryTest/GenericMemoryTestDxe/GenericMemoryTestDxe.inf\r
--- /dev/null
+/** @file\r
+ Produce EFI_BLOCK_IO_PROTOCOL on a RAM disk device.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "RamDiskImpl.h"\r
+\r
+//\r
+// The EFI_BLOCK_IO_PROTOCOL instances that is installed onto the handle\r
+// for newly registered RAM disks\r
+//\r
+EFI_BLOCK_IO_PROTOCOL mRamDiskBlockIoTemplate = {\r
+ EFI_BLOCK_IO_PROTOCOL_REVISION,\r
+ (EFI_BLOCK_IO_MEDIA *) 0,\r
+ RamDiskBlkIoReset,\r
+ RamDiskBlkIoReadBlocks,\r
+ RamDiskBlkIoWriteBlocks,\r
+ RamDiskBlkIoFlushBlocks\r
+};\r
+\r
+\r
+/**\r
+ Initialize the BlockIO protocol of a RAM disk device.\r
+\r
+ @param[in] PrivateData Points to RAM disk private data.\r
+\r
+**/\r
+VOID\r
+RamDiskInitBlockIo (\r
+ IN RAM_DISK_PRIVATE_DATA *PrivateData\r
+ )\r
+{\r
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;\r
+ EFI_BLOCK_IO_MEDIA *Media;\r
+\r
+ BlockIo = &PrivateData->BlockIo;\r
+ Media = &PrivateData->Media;\r
+\r
+ CopyMem (BlockIo, &mRamDiskBlockIoTemplate, sizeof (EFI_BLOCK_IO_PROTOCOL));\r
+\r
+ BlockIo->Media = Media;\r
+ Media->RemovableMedia = FALSE;\r
+ Media->MediaPresent = TRUE;\r
+ Media->LogicalPartition = FALSE;\r
+ Media->ReadOnly = FALSE;\r
+ Media->WriteCaching = FALSE;\r
+ Media->BlockSize = RAM_DISK_BLOCK_SIZE;\r
+ Media->LastBlock = DivU64x32 (\r
+ PrivateData->Size + RAM_DISK_BLOCK_SIZE - 1,\r
+ RAM_DISK_BLOCK_SIZE\r
+ ) - 1;\r
+}\r
+\r
+\r
+/**\r
+ Reset the Block Device.\r
+\r
+ @param This Indicates a pointer to the calling context.\r
+ @param ExtendedVerification Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
+ not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoReset (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Read BufferSize bytes from Lba into Buffer.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] MediaId Id of the media, changes every time the media is\r
+ replaced.\r
+ @param[in] Lba The starting Logical Block Address to read from.\r
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block\r
+ size.\r
+ @param[out] Buffer A pointer to the destination buffer for the data.\r
+ The caller is responsible for either having\r
+ implicit or explicit ownership of the buffer.\r
+\r
+ @retval EFI_SUCCESS The data was read correctly from the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing\r
+ the read.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGED The MediaId does not matched the current\r
+ device.\r
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block\r
+ size of the device.\r
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not\r
+ valid, or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoReadBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ )\r
+{\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ UINTN NumberOfBlocks;\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BufferSize == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);\r
+\r
+ if (MediaId != PrivateData->Media.MediaId) {\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if ((BufferSize % PrivateData->Media.BlockSize) != 0) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ if (Lba > PrivateData->Media.LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ NumberOfBlocks = BufferSize / PrivateData->Media.BlockSize;\r
+ if ((Lba + NumberOfBlocks - 1) > PrivateData->Media.LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ CopyMem (\r
+ Buffer,\r
+ (VOID *)(UINTN)(PrivateData->StartingAddr + MultU64x32 (Lba, PrivateData->Media.BlockSize)),\r
+ BufferSize\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Write BufferSize bytes from Lba into Buffer.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] MediaId The media ID that the write request is for.\r
+ @param[in] Lba The starting logical block address to be written.\r
+ The caller is responsible for writing to only\r
+ legitimate locations.\r
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block\r
+ size.\r
+ @param[in] Buffer A pointer to the source buffer for the data.\r
+\r
+ @retval EFI_SUCCESS The data was written correctly to the device.\r
+ @retval EFI_WRITE_PROTECTED The device can not be written to.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing\r
+ the write.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current\r
+ device.\r
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block\r
+ size of the device.\r
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not\r
+ valid, or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoWriteBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ UINTN NumberOfBlocks;\r
+\r
+ if (Buffer == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (BufferSize == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);\r
+\r
+ if (MediaId != PrivateData->Media.MediaId) {\r
+ return EFI_MEDIA_CHANGED;\r
+ }\r
+\r
+ if (TRUE == PrivateData->Media.ReadOnly) {\r
+ return EFI_WRITE_PROTECTED;\r
+ }\r
+\r
+ if ((BufferSize % PrivateData->Media.BlockSize) != 0) {\r
+ return EFI_BAD_BUFFER_SIZE;\r
+ }\r
+\r
+ if (Lba > PrivateData->Media.LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ NumberOfBlocks = BufferSize / PrivateData->Media.BlockSize;\r
+ if ((Lba + NumberOfBlocks - 1) > PrivateData->Media.LastBlock) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ CopyMem (\r
+ (VOID *)(UINTN)(PrivateData->StartingAddr + MultU64x32 (Lba, PrivateData->Media.BlockSize)),\r
+ Buffer,\r
+ BufferSize\r
+ );\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Flush the Block Device.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+\r
+ @retval EFI_SUCCESS All outstanding data was written to the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while writting\r
+ back the data\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoFlushBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This\r
+ )\r
+{\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ The driver entry point for RamDiskDxe driver.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "RamDiskImpl.h"\r
+\r
+//\r
+// Handle for the EFI_RAM_DISK_PROTOCOL instance\r
+//\r
+EFI_HANDLE mRamDiskHandle = NULL;\r
+\r
+//\r
+// The EFI_RAM_DISK_PROTOCOL instances that is installed onto the driver\r
+// handle\r
+//\r
+EFI_RAM_DISK_PROTOCOL mRamDiskProtocol = {\r
+ RamDiskRegister,\r
+ RamDiskUnregister\r
+};\r
+\r
+//\r
+// RamDiskDxe driver maintains a list of registered RAM disks.\r
+//\r
+LIST_ENTRY RegisteredRamDisks;\r
+UINTN ListEntryNum;\r
+\r
+\r
+/**\r
+ The entry point for RamDiskDxe driver.\r
+\r
+ @param[in] ImageHandle The image handle of the driver.\r
+ @param[in] SystemTable The system table.\r
+\r
+ @retval EFI_ALREADY_STARTED The driver already exists in system.\r
+ @retval EFI_OUT_OF_RESOURCES Fail to execute entry point due to lack of\r
+ resources.\r
+ @retval EFI_SUCCES All the related protocols are installed on\r
+ the driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskDxeEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;\r
+ VOID *DummyInterface;\r
+\r
+ //\r
+ // If already started, return.\r
+ //\r
+ Status = gBS->LocateProtocol (\r
+ &gEfiRamDiskProtocolGuid,\r
+ NULL,\r
+ &DummyInterface\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_INFO, "Driver already started!\n"));\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+\r
+ //\r
+ // Create a private data structure.\r
+ //\r
+ ConfigPrivate = AllocateCopyPool (sizeof (RAM_DISK_CONFIG_PRIVATE_DATA), &mRamDiskConfigPrivateDataTemplate);\r
+ if (ConfigPrivate == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Install RAM disk configuration form\r
+ //\r
+ Status = InstallRamDiskConfigForm (ConfigPrivate);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Install the EFI_RAM_DISK_PROTOCOL and RAM disk private data onto a\r
+ // new handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &mRamDiskHandle,\r
+ &gEfiRamDiskProtocolGuid,\r
+ &mRamDiskProtocol,\r
+ &gEfiCallerIdGuid,\r
+ ConfigPrivate,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Initialize the list of registered RAM disks maintained by the driver\r
+ //\r
+ InitializeListHead (&RegisteredRamDisks);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+ if (ConfigPrivate != NULL) {\r
+ UninstallRamDiskConfigForm (ConfigPrivate);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Unload the RamDiskDxe driver and its configuration form.\r
+\r
+ @param[in] ImageHandle The driver's image handle.\r
+\r
+ @retval EFI_SUCCESS The RamDiskDxe driver and its configuration\r
+ form is unloaded.\r
+ @retval Others Failed to unload the form.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskDxeUnload (\r
+ IN EFI_HANDLE ImageHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;\r
+\r
+ Status = gBS->HandleProtocol (\r
+ mRamDiskHandle,\r
+ &gEfiCallerIdGuid,\r
+ (VOID **) &ConfigPrivate\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ASSERT (ConfigPrivate->Signature == RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE);\r
+\r
+ //\r
+ // Unregister all registered RAM disks\r
+ //\r
+ UnregisterAllRamDisks ();\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ mRamDiskHandle,\r
+ &gEfiRamDiskProtocolGuid,\r
+ &mRamDiskProtocol,\r
+ &gEfiCallerIdGuid,\r
+ ConfigPrivate,\r
+ NULL\r
+ );\r
+\r
+ UninstallRamDiskConfigForm (ConfigPrivate);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+## @file\r
+# Produces EFI_RAM_DISK_PROTOCOL and provides the capability to\r
+# create/remove RAM disks in a setup browser.\r
+#\r
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = RamDiskDxe\r
+ MODULE_UNI_FILE = RamDiskDxe.uni\r
+ FILE_GUID = 28A03FF4-12B3-4305-A417-BB1A4F94081E\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ ENTRY_POINT = RamDiskDxeEntryPoint\r
+ UNLOAD_IMAGE = RamDiskDxeUnload\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+ RamDiskDriver.c\r
+ RamDiskImpl.c\r
+ RamDiskBlockIo.c\r
+ RamDiskProtocol.c\r
+ RamDiskFileExplorer.c\r
+ RamDiskImpl.h\r
+ RamDiskHii.vfr\r
+ RamDiskHiiStrings.uni\r
+ RamDiskNVData.h\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ BaseMemoryLib\r
+ DebugLib\r
+ UefiLib\r
+ UefiDriverEntryPoint\r
+ UefiBootServicesTableLib\r
+ UefiHiiServicesLib\r
+ MemoryAllocationLib\r
+ HiiLib\r
+ FileExplorerLib\r
+ DevicePathLib\r
+ PrintLib\r
+\r
+[Guids]\r
+ gEfiIfrTianoGuid ## PRODUCES ## GUID # HII opcode\r
+ ## PRODUCES ## HII\r
+ ## CONSUMES ## HII\r
+ gRamDiskFormSetGuid\r
+ gEfiVirtualDiskGuid ## SOMETIMES_CONSUMES ## GUID\r
+ gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the information type\r
+\r
+[Protocols]\r
+ gEfiRamDiskProtocolGuid ## PRODUCES\r
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES\r
+ gEfiDevicePathProtocolGuid ## PRODUCES\r
+ gEfiBlockIoProtocolGuid ## PRODUCES\r
+ gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES\r
+\r
+[Depex]\r
+ gEfiHiiConfigRoutingProtocolGuid AND\r
+ gEfiHiiDatabaseProtocolGuid\r
--- /dev/null
+// /** @file\r
+// Produces EFI_RAM_DISK_PROTOCOL and provides the capability to\r
+// create/remove RAM disks in a setup browser.\r
+//\r
+// Copyright (c) 2016, Intel Corporation. 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
+// which accompanies this distribution. The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+// **/\r
+\r
+#string STR_MODULE_ABSTRACT #language en-US "Produces EFI_RAM_DISK_PROTOCOL and provides the capability to create/remove RAM disks in a setup browser."\r
+\r
+#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI_RAM_DISK_PROTOCOL and provides the capability to create/remove RAM disks in a setup browser."\r
+\r
--- /dev/null
+/** @file\r
+ Internal file explorer helper functions for RamDiskDxe driver.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "RamDiskImpl.h"\r
+\r
+\r
+/**\r
+ Helper function called as part of the code needed to allocate the proper\r
+ sized buffer for various EFI interfaces.\r
+\r
+ @param[in, out] Status Current status.\r
+ @param[in, out] Buffer Current allocated buffer, or NULL.\r
+ @param[in] BufferSize Current buffer size needed.\r
+\r
+ @retval TRUE If the buffer was reallocated and the caller should\r
+ try the API again.\r
+ @retval FALSE The caller should not call this function again.\r
+\r
+**/\r
+BOOLEAN\r
+GrowBuffer (\r
+ IN OUT EFI_STATUS *Status,\r
+ IN OUT VOID **Buffer,\r
+ IN UINTN BufferSize\r
+ )\r
+{\r
+ BOOLEAN TryAgain;\r
+\r
+ //\r
+ // If this is an initial request, buffer will be null with a new buffer size\r
+ //\r
+ if ((*Buffer == NULL) && (BufferSize != 0)) {\r
+ *Status = EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ //\r
+ // If the status code is "buffer too small", resize the buffer\r
+ //\r
+ TryAgain = FALSE;\r
+ if (*Status == EFI_BUFFER_TOO_SMALL) {\r
+\r
+ if (*Buffer != NULL) {\r
+ FreePool (*Buffer);\r
+ }\r
+\r
+ *Buffer = AllocateZeroPool (BufferSize);\r
+\r
+ if (*Buffer != NULL) {\r
+ TryAgain = TRUE;\r
+ } else {\r
+ *Status = EFI_OUT_OF_RESOURCES;\r
+ }\r
+ }\r
+ //\r
+ // If there's an error, free the buffer\r
+ //\r
+ if (!TryAgain && EFI_ERROR (*Status) && (*Buffer != NULL)) {\r
+ FreePool (*Buffer);\r
+ *Buffer = NULL;\r
+ }\r
+\r
+ return TryAgain;\r
+}\r
+\r
+\r
+/**\r
+ This function gets the file information from an open file descriptor,\r
+ and stores it in a buffer allocated from pool.\r
+\r
+ @param[in] FHand File Handle.\r
+\r
+ @return A pointer to a buffer with file information or NULL is returned.\r
+\r
+**/\r
+EFI_FILE_INFO *\r
+FileInfo (\r
+ IN EFI_FILE_HANDLE FHand\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_FILE_INFO *Buffer;\r
+ UINTN BufferSize;\r
+\r
+ //\r
+ // Initialize for GrowBuffer loop\r
+ //\r
+ Buffer = NULL;\r
+ BufferSize = SIZE_OF_EFI_FILE_INFO + 200;\r
+\r
+ //\r
+ // Call the real function\r
+ //\r
+ while (GrowBuffer (&Status, (VOID **) &Buffer, BufferSize)) {\r
+ Status = FHand->GetInfo (\r
+ FHand,\r
+ &gEfiFileInfoGuid,\r
+ &BufferSize,\r
+ Buffer\r
+ );\r
+ }\r
+\r
+ return Buffer;\r
+}\r
+\r
+\r
+/**\r
+ This function will open a file or directory referenced by DevicePath.\r
+\r
+ This function opens a file with the open mode according to the file path. The\r
+ Attributes is valid only for EFI_FILE_MODE_CREATE.\r
+\r
+ @param[in, out] FilePath On input, the device path to the file.\r
+ On output, the remaining device path.\r
+ @param[out] FileHandle Pointer to the file handle.\r
+ @param[in] OpenMode The mode to open the file with.\r
+ @param[in] Attributes The file's file attributes.\r
+\r
+ @retval EFI_SUCCESS The information was set.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_UNSUPPORTED Could not open the file path.\r
+ @retval EFI_NOT_FOUND The specified file could not be found on the\r
+ device or the file system could not be found\r
+ on the device.\r
+ @retval EFI_NO_MEDIA The device has no medium.\r
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or\r
+ the medium is no longer supported.\r
+ @retval EFI_DEVICE_ERROR The device reported an error.\r
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.\r
+ @retval EFI_ACCESS_DENIED The file was opened read only.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open\r
+ the file.\r
+ @retval EFI_VOLUME_FULL The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpenFileByDevicePath(\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,\r
+ OUT EFI_FILE_HANDLE *FileHandle,\r
+ IN UINT64 OpenMode,\r
+ IN UINT64 Attributes\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;\r
+ EFI_FILE_PROTOCOL *Handle1;\r
+ EFI_FILE_PROTOCOL *Handle2;\r
+ EFI_HANDLE DeviceHandle;\r
+\r
+ if ((FilePath == NULL || FileHandle == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiSimpleFileSystemProtocolGuid,\r
+ FilePath,\r
+ &DeviceHandle\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->OpenProtocol(\r
+ DeviceHandle,\r
+ &gEfiSimpleFileSystemProtocolGuid,\r
+ (VOID**)&EfiSimpleFileSystemProtocol,\r
+ gImageHandle,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);\r
+ if (EFI_ERROR (Status)) {\r
+ FileHandle = NULL;\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // go down directories one node at a time.\r
+ //\r
+ while (!IsDevicePathEnd (*FilePath)) {\r
+ //\r
+ // For file system access each node should be a file path component\r
+ //\r
+ if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||\r
+ DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP\r
+ ) {\r
+ FileHandle = NULL;\r
+ return (EFI_INVALID_PARAMETER);\r
+ }\r
+ //\r
+ // Open this file path node\r
+ //\r
+ Handle2 = Handle1;\r
+ Handle1 = NULL;\r
+\r
+ //\r
+ // Try to test opening an existing file\r
+ //\r
+ Status = Handle2->Open (\r
+ Handle2,\r
+ &Handle1,\r
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
+ OpenMode &~EFI_FILE_MODE_CREATE,\r
+ 0\r
+ );\r
+\r
+ //\r
+ // see if the error was that it needs to be created\r
+ //\r
+ if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {\r
+ Status = Handle2->Open (\r
+ Handle2,\r
+ &Handle1,\r
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,\r
+ OpenMode,\r
+ Attributes\r
+ );\r
+ }\r
+ //\r
+ // Close the last node\r
+ //\r
+ Handle2->Close (Handle2);\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ return (Status);\r
+ }\r
+\r
+ //\r
+ // Get the next node\r
+ //\r
+ *FilePath = NextDevicePathNode (*FilePath);\r
+ }\r
+\r
+ //\r
+ // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!\r
+ //\r
+ *FileHandle = (VOID*)Handle1;\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+///** @file\r
+// VFR file used by the RamDiskDxe driver.\r
+//\r
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+// This program and the accompanying materials\r
+// are licensed and made available under the terms and conditions of the BSD License\r
+// which accompanies this distribution. The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+//**/\r
+\r
+#include "RamDiskNVData.h"\r
+\r
+formset\r
+ guid = RAM_DISK_FORM_SET_GUID,\r
+ title = STRING_TOKEN(STR_FORM_SET_TITLE),\r
+ help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP),\r
+ classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
+\r
+ varstore RAM_DISK_CONFIGURATION,\r
+ varid = RAM_DISK_CONFIGURATION_VARSTORE_ID,\r
+ name = RAM_DISK_CONFIGURATION,\r
+ guid = RAM_DISK_FORM_SET_GUID;\r
+\r
+ //\r
+ // Form #1 "Main Form - Add/Remove/Show RAM Disks"\r
+ //\r
+ form formid = MAIN_FORM_ID,\r
+ title = STRING_TOKEN(STR_MAIN_FORM_TITLE);\r
+\r
+ goto CREATE_RAW_RAM_DISK_FORM_ID,\r
+ prompt = STRING_TOKEN(STR_GOTO_ADD_RAW_FORM),\r
+ help = STRING_TOKEN(STR_GOTO_ADD_RAW_FORM_HELP);\r
+\r
+ goto MAIN_FORM_ID,\r
+ prompt = STRING_TOKEN(STR_GOTO_ADD_FROM_FILE_FORM),\r
+ help = STRING_TOKEN(STR_GOTO_ADD_FROM_FILE_FORM_HELP),\r
+ flags = INTERACTIVE,\r
+ key = MAIN_GOTO_FILE_EXPLORER_ID;\r
+\r
+ subtitle text = STRING_TOKEN(STR_RAM_DISK_NULL_STRING);\r
+ subtitle text = STRING_TOKEN(STR_RAM_DISK_LIST_TEXT);\r
+\r
+ label MAIN_LABEL_LIST_START;\r
+ label MAIN_LABEL_LIST_END;\r
+\r
+ subtitle text = STRING_TOKEN(STR_RAM_DISK_NULL_STRING);\r
+\r
+ text\r
+ help = STRING_TOKEN(STR_REMOVE_SEL_HELP),\r
+ text = STRING_TOKEN(STR_REMOVE_SEL_TEXT),\r
+ flags = INTERACTIVE,\r
+ key = MAIN_REMOVE_RD_QUESTION_ID;\r
+\r
+ endform;\r
+\r
+ //\r
+ // Form #2 "Add New Raw RAM Disk"\r
+ //\r
+ form formid = CREATE_RAW_RAM_DISK_FORM_ID,\r
+ title = STRING_TOKEN(STR_ADD_RAW_FORM_TITLE);\r
+\r
+ subtitle text = STRING_TOKEN(STR_RAM_DISK_NULL_STRING);\r
+\r
+ numeric varid = RAM_DISK_CONFIGURATION.Size,\r
+ questionid = CREATE_RAW_SIZE_QUESTION_ID,\r
+ prompt = STRING_TOKEN(STR_SIZE_PROMPT),\r
+ help = STRING_TOKEN(STR_SIZE_HELP),\r
+ flags = DISPLAY_UINT_HEX | INTERACTIVE,\r
+ minimum = 1,\r
+ maximum = 0xFFFFFFFFFFFFFFFF,\r
+ endnumeric;\r
+\r
+ subtitle text = STRING_TOKEN(STR_RAM_DISK_NULL_STRING);\r
+\r
+ text\r
+ help = STRING_TOKEN(STR_CREATE_AND_EXIT_HELP),\r
+ text = STRING_TOKEN(STR_CREATE_AND_EXIT_PROMPT),\r
+ flags = INTERACTIVE,\r
+ key = CREATE_RAW_SUBMIT_QUESTION_ID;\r
+\r
+ text\r
+ help = STRING_TOKEN(STR_DISCARD_AND_EXIT_HELP),\r
+ text = STRING_TOKEN(STR_DISCARD_AND_EXIT_PROMPT),\r
+ flags = INTERACTIVE,\r
+ key = CREATE_RAW_DISCARD_QUESTION_ID;\r
+\r
+ endform;\r
+\r
+endformset;\r
--- /dev/null
+// /** @file\r
+// String definitions for RamDiskDxe driver form.\r
+//\r
+// Copyright (c) 2016, Intel Corporation. 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
+// which accompanies this distribution. The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+// **/\r
+\r
+#langdef en-US "English"\r
+\r
+#string STR_FORM_SET_TITLE #language en-US "RAM Disk Configutation"\r
+#string STR_FORM_SET_TITLE_HELP #language en-US "Press <Enter> to add/remove RAM disks."\r
+\r
+#string STR_MAIN_FORM_TITLE #language en-US "RAM Disk HII Main Screen"\r
+#string STR_RAM_DISK_NULL_STRING #language en-US ""\r
+\r
+#string STR_RAM_DISK_LIST_TEXT #language en-US "Created RAM disk list:"\r
+#string STR_RAM_DISK_LIST_HELP #language en-US "Select for remove"\r
+#string STR_GOTO_ADD_RAW_FORM #language en-US "Create raw"\r
+#string STR_GOTO_ADD_RAW_FORM_HELP #language en-US "Create a raw RAM disk."\r
+#string STR_GOTO_ADD_FROM_FILE_FORM #language en-US "Create from file"\r
+#string STR_GOTO_ADD_FROM_FILE_FORM_HELP #language en-US "Create a RAM disk from a given file."\r
+#string STR_REMOVE_SEL_HELP #language en-US "Remove selected RAM disk(s)"\r
+#string STR_REMOVE_SEL_TEXT #language en-US "Remove selected RAM disk(s)."\r
+\r
+#string STR_ADD_RAW_FORM_TITLE #language en-US "Add A Raw RAM Disk"\r
+#string STR_ADD_RAW_FORM_SUBTITLE_TEXT #language en-US " "\r
+\r
+#string STR_SIZE_PROMPT #language en-US "Size (Hex):"\r
+#string STR_SIZE_HELP #language en-US "The valid RAM disk size should be multiples of the RAM disk block size."\r
+\r
+#string STR_CREATE_AND_EXIT_HELP #language en-US "Create a new RAM disk with the given starting and ending address."\r
+#string STR_CREATE_AND_EXIT_PROMPT #language en-US "Create & Exit"\r
+#string STR_DISCARD_AND_EXIT_HELP #language en-US "Discard and exit."\r
+#string STR_DISCARD_AND_EXIT_PROMPT #language en-US "Discard & Exit"\r
--- /dev/null
+/** @file\r
+ HII Config Access protocol implementation of RamDiskDxe driver.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "RamDiskImpl.h"\r
+\r
+CHAR16 mRamDiskStorageName[] = L"RAM_DISK_CONFIGURATION";\r
+\r
+RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate = {\r
+ RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE,\r
+ {\r
+ RamDiskExtractConfig,\r
+ RamDiskRouteConfig,\r
+ RamDiskCallback\r
+ }\r
+};\r
+\r
+HII_VENDOR_DEVICE_PATH mRamDiskHiiVendorDevicePath = {\r
+ {\r
+ {\r
+ HARDWARE_DEVICE_PATH,\r
+ HW_VENDOR_DP,\r
+ {\r
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+ }\r
+ },\r
+ RAM_DISK_FORM_SET_GUID\r
+ },\r
+ {\r
+ END_DEVICE_PATH_TYPE,\r
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+ {\r
+ (UINT8) (END_DEVICE_PATH_LENGTH),\r
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+ }\r
+ }\r
+};\r
+\r
+\r
+/**\r
+ This function publish the RAM disk configuration Form.\r
+\r
+ @param[in, out] ConfigPrivateData\r
+ Points to RAM disk configuration private data.\r
+\r
+ @retval EFI_SUCCESS HII Form is installed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
+ @retval Others Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallRamDiskConfigForm (\r
+ IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_HANDLE HiiHandle;\r
+ EFI_HANDLE DriverHandle;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+\r
+ DriverHandle = NULL;\r
+ ConfigAccess = &ConfigPrivateData->ConfigAccess;\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mRamDiskHiiVendorDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ ConfigAccess,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ ConfigPrivateData->DriverHandle = DriverHandle;\r
+\r
+ //\r
+ // Publish the HII package list\r
+ //\r
+ HiiHandle = HiiAddPackages (\r
+ &gRamDiskFormSetGuid,\r
+ DriverHandle,\r
+ RamDiskDxeStrings,\r
+ RamDiskHiiBin,\r
+ NULL\r
+ );\r
+ if (HiiHandle == NULL) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mRamDiskHiiVendorDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ ConfigAccess,\r
+ NULL\r
+ );\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ConfigPrivateData->HiiHandle = HiiHandle;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ This function removes RAM disk configuration Form.\r
+\r
+ @param[in, out] ConfigPrivateData\r
+ Points to RAM disk configuration private data.\r
+\r
+**/\r
+VOID\r
+UninstallRamDiskConfigForm (\r
+ IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData\r
+ )\r
+{\r
+ //\r
+ // Uninstall HII package list\r
+ //\r
+ if (ConfigPrivateData->HiiHandle != NULL) {\r
+ HiiRemovePackages (ConfigPrivateData->HiiHandle);\r
+ ConfigPrivateData->HiiHandle = NULL;\r
+ }\r
+\r
+ //\r
+ // Uninstall HII Config Access Protocol\r
+ //\r
+ if (ConfigPrivateData->DriverHandle != NULL) {\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ ConfigPrivateData->DriverHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ &mRamDiskHiiVendorDevicePath,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ &ConfigPrivateData->ConfigAccess,\r
+ NULL\r
+ );\r
+ ConfigPrivateData->DriverHandle = NULL;\r
+ }\r
+\r
+ FreePool (ConfigPrivateData);\r
+}\r
+\r
+\r
+/**\r
+ Unregister all registered RAM disks.\r
+\r
+**/\r
+VOID\r
+UnregisterAllRamDisks (\r
+ VOID\r
+ )\r
+{\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *NextEntry;\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+\r
+ if (!IsListEmpty(&RegisteredRamDisks)) {\r
+ EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
+\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ PrivateData->Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &PrivateData->BlockIo,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath,\r
+ NULL\r
+ );\r
+\r
+ RemoveEntryList (&PrivateData->ThisInstance);\r
+\r
+ if (RamDiskCreateHii == PrivateData->CreateMethod) {\r
+ //\r
+ // If a RAM disk is created within HII, then the RamDiskDxe driver\r
+ // driver is responsible for freeing the allocated memory for the\r
+ // RAM disk.\r
+ //\r
+ FreePool ((VOID *)(UINTN) PrivateData->StartingAddr);\r
+ }\r
+\r
+\r
+ gBS->DisconnectController (PrivateData->Handle, NULL, NULL);\r
+\r
+ FreePool (PrivateData->DevicePath);\r
+ FreePool (PrivateData);\r
+ ListEntryNum--;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+/**\r
+ This function allows a caller to extract the current configuration for one\r
+ or more named elements from the target driver.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Request A null-terminated Unicode string in\r
+ <ConfigRequest> format.\r
+ @param[out] Progress On return, points to a character in the Request\r
+ string. Points to the string's null terminator if\r
+ request was successful. Points to the most recent\r
+ '&' before the first failing name/value pair (or\r
+ the beginning of the string if the failure is in\r
+ the first name/value pair) if the request was not\r
+ successful.\r
+ @param[out] Results A null-terminated Unicode string in\r
+ <ConfigAltResp> format which has all values filled\r
+ in for the names in the Request string. String to\r
+ be allocated by the called function.\r
+\r
+ @retval EFI_SUCCESS The Results is filled with the requested\r
+ values.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in\r
+ this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskExtractConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Request,\r
+ OUT EFI_STRING *Progress,\r
+ OUT EFI_STRING *Results\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+ RAM_DISK_CONFIGURATION *Configuration;\r
+ EFI_STRING ConfigRequest;\r
+ EFI_STRING ConfigRequestHdr;\r
+ RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;\r
+ UINTN Size;\r
+ BOOLEAN AllocatedRequest;\r
+\r
+ if (Progress == NULL || Results == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Progress = Request;\r
+ if ((Request != NULL) &&\r
+ !HiiIsConfigHdrMatch (Request, &gRamDiskFormSetGuid, mRamDiskStorageName)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ ConfigRequestHdr = NULL;\r
+ ConfigRequest = NULL;\r
+ AllocatedRequest = FALSE;\r
+ Size = 0;\r
+\r
+ //\r
+ // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
+ //\r
+ ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);\r
+ BufferSize = sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum;\r
+ Configuration = AllocateZeroPool (BufferSize);\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ConfigRequest = Request;\r
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
+ //\r
+ // Request has no request element, construct full request string.\r
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
+ //\r
+ ConfigRequestHdr = HiiConstructConfigHdr (\r
+ &gRamDiskFormSetGuid,\r
+ mRamDiskStorageName,\r
+ ConfigPrivate->DriverHandle\r
+ );\r
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
+ ConfigRequest = AllocateZeroPool (Size);\r
+ ASSERT (ConfigRequest != NULL);\r
+ AllocatedRequest = TRUE;\r
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
+ FreePool (ConfigRequestHdr);\r
+ }\r
+\r
+ Status = gHiiConfigRouting->BlockToConfig (\r
+ gHiiConfigRouting,\r
+ ConfigRequest,\r
+ (UINT8 *) &Configuration,\r
+ BufferSize,\r
+ Results,\r
+ Progress\r
+ );\r
+ //\r
+ // Free the allocated config request string and RAM disk configuration data.\r
+ //\r
+ if (AllocatedRequest) {\r
+ FreePool (ConfigRequest);\r
+ ConfigRequest = NULL;\r
+ }\r
+ FreePool (Configuration);\r
+\r
+ //\r
+ // Set Progress string to the original request string.\r
+ //\r
+ if (Request == NULL) {\r
+ *Progress = NULL;\r
+ } else if (StrStr (Request, L"OFFSET") == NULL) {\r
+ *Progress = Request + StrLen (Request);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ This function processes the results of changes in configuration.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
+ format.\r
+ @param[out] Progress A pointer to a string filled in with the offset of\r
+ the most recent '&' before the first failing\r
+ name/value pair (or the beginning of the string if\r
+ the failure is in the first name/value pair) or\r
+ the terminating NULL if all was successful.\r
+\r
+ @retval EFI_SUCCESS The Results is processed successfully.\r
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in\r
+ this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskRouteConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Configuration,\r
+ OUT EFI_STRING *Progress\r
+ )\r
+{\r
+ if (Configuration == NULL || Progress == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *Progress = Configuration;\r
+ if (!HiiIsConfigHdrMatch (Configuration, &gRamDiskFormSetGuid, mRamDiskStorageName)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *Progress = Configuration + StrLen (Configuration);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Allocate memory and register the RAM disk created within RamDiskDxe\r
+ driver HII.\r
+\r
+ @param[in] Size If creating raw, size of the RAM disk to create.\r
+ If creating from file, zero.\r
+ @param[in] FileHandle If creating raw, NULL. If creating from file, the\r
+ file handle.\r
+\r
+ @retval EFI_SUCCESS RAM disk is created and registered.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to match the\r
+ size required.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiCreateRamDisk (\r
+ IN UINT64 Size,\r
+ IN EFI_FILE_HANDLE FileHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN BufferSize;\r
+ UINT64 StartingAddr;\r
+ EFI_INPUT_KEY Key;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ EFI_FILE_INFO *FileInformation;\r
+\r
+ FileInformation = NULL;\r
+\r
+ if (FileHandle != NULL) {\r
+ //\r
+ // Create from file.\r
+ //\r
+ FileInformation = FileInfo (FileHandle);\r
+ if (NULL == FileInformation) {\r
+ do {\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"",\r
+ L"Not enough memory to get the file information!",\r
+ L"Press ENTER to continue ...",\r
+ L"",\r
+ NULL\r
+ );\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ //\r
+ // Update the size of RAM disk according to the file size.\r
+ //\r
+ Size = FileInformation->FileSize;\r
+ }\r
+\r
+ StartingAddr = (UINTN) AllocatePool ((UINTN) Size);\r
+ if (0 == StartingAddr) {\r
+ do {\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"",\r
+ L"Not enough memory to create the RAM disk!",\r
+ L"Press ENTER to continue ...",\r
+ L"",\r
+ NULL\r
+ );\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ if (FileHandle != NULL) {\r
+ //\r
+ // Copy the file content to the RAM disk.\r
+ //\r
+ BufferSize = (UINTN) Size;\r
+ FileHandle->Read (\r
+ FileHandle,\r
+ &BufferSize,\r
+ (VOID *)(UINTN) StartingAddr\r
+ );\r
+ if (BufferSize != FileInformation->FileSize) {\r
+ do {\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"",\r
+ L"File content read error!",\r
+ L"Press ENTER to continue ...",\r
+ L"",\r
+ NULL\r
+ );\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Register the newly created RAM disk.\r
+ //\r
+ Status = RamDiskRegister (\r
+ StartingAddr,\r
+ Size,\r
+ &gEfiVirtualDiskGuid,\r
+ NULL,\r
+ &DevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ do {\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"",\r
+ L"Fail to register the newly created RAM disk!",\r
+ L"Press ENTER to continue ...",\r
+ L"",\r
+ NULL\r
+ );\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // If RAM disk is created within HII, memory should be freed when the\r
+ // RAM disk is unregisterd.\r
+ //\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks.BackLink);\r
+ PrivateData->CreateMethod = RamDiskCreateHii;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ This function updates the registered RAM disks list on the main form.\r
+\r
+ @param[in, out] ConfigPrivate\r
+ Private data for configurating hii data for RAM\r
+ disks.\r
+\r
+**/\r
+VOID\r
+UpdateMainForm (\r
+ IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate\r
+ )\r
+{\r
+ VOID *StartOpCodeHandle;\r
+ VOID *EndOpCodeHandle;\r
+ EFI_IFR_GUID_LABEL *StartLabel;\r
+ EFI_IFR_GUID_LABEL *EndLabel;\r
+ LIST_ENTRY *Entry;\r
+ UINTN Index;\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ CHAR16 *String;\r
+ CHAR16 RamDiskStr[128];\r
+ EFI_STRING_ID StringId;\r
+ EFI_TPL OldTpl;\r
+\r
+ //\r
+ // Init OpCode Handle\r
+ //\r
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (StartOpCodeHandle != NULL);\r
+\r
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (EndOpCodeHandle != NULL);\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the start opcode\r
+ //\r
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+ StartOpCodeHandle,\r
+ &gEfiIfrTianoGuid,\r
+ NULL,\r
+ sizeof (EFI_IFR_GUID_LABEL)\r
+ );\r
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ StartLabel->Number = MAIN_LABEL_LIST_START;\r
+\r
+ //\r
+ // Create Hii Extend Label OpCode as the end opcode\r
+ //\r
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+ EndOpCodeHandle,\r
+ &gEfiIfrTianoGuid,\r
+ NULL,\r
+ sizeof (EFI_IFR_GUID_LABEL)\r
+ );\r
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ EndLabel->Number = MAIN_LABEL_LIST_END;\r
+\r
+ Index = 0;\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
+ String = RamDiskStr;\r
+\r
+ UnicodeSPrint (\r
+ String,\r
+ sizeof (RamDiskStr),\r
+ L" RAM Disk %d: [0x%lx, 0x%lx]\n",\r
+ Index,\r
+ PrivateData->StartingAddr,\r
+ PrivateData->StartingAddr + PrivateData->Size\r
+ );\r
+\r
+ StringId = HiiSetString (ConfigPrivate->HiiHandle, 0, RamDiskStr, NULL);\r
+ ASSERT (StringId != 0);\r
+\r
+ HiiCreateCheckBoxOpCode (\r
+ StartOpCodeHandle,\r
+ (EFI_QUESTION_ID) (MAIN_CHECKBOX_QUESTION_ID_START + Index),\r
+ RAM_DISK_CONFIGURATION_VARSTORE_ID,\r
+ (UINT16) (RAM_DISK_LIST_VAR_OFFSET + Index),\r
+ StringId,\r
+ STRING_TOKEN (STR_RAM_DISK_LIST_HELP),\r
+ 0,\r
+ 0,\r
+ NULL\r
+ );\r
+\r
+ Index++;\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ HiiUpdateForm (\r
+ ConfigPrivate->HiiHandle,\r
+ &gRamDiskFormSetGuid,\r
+ MAIN_FORM_ID,\r
+ StartOpCodeHandle,\r
+ EndOpCodeHandle\r
+ );\r
+\r
+ HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+ HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+}\r
+\r
+\r
+/**\r
+ This function processes the results of changes in configuration.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Action Specifies the type of action taken by the browser.\r
+ @param[in] QuestionId A unique value which is sent to the original\r
+ exporting driver so that it can identify the type\r
+ of data to expect.\r
+ @param[in] Type The type of value for the question.\r
+ @param[in] Value A pointer to the data being sent to the original\r
+ exporting driver.\r
+ @param[out] ActionRequest On return, points to the action requested by the\r
+ callback function.\r
+\r
+ @retval EFI_SUCCESS The callback successfully handled the action.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
+ variable and its data.\r
+ @retval EFI_DEVICE_ERROR The variable could not be saved.\r
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
+ callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskCallback (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT8 Type,\r
+ IN EFI_IFR_TYPE_VALUE *Value,\r
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivate;\r
+ RAM_DISK_CONFIGURATION *Configuration;\r
+ EFI_DEVICE_PATH_PROTOCOL *FileDevPath;\r
+ EFI_FILE_HANDLE FileHandle;\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *NextEntry;\r
+ EFI_TPL OldTpl;\r
+\r
+ if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+ Status = EFI_UNSUPPORTED;\r
+ if (QuestionId == CREATE_RAW_SIZE_QUESTION_ID) {\r
+ Value->u64 = EFI_PAGE_SIZE;\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ return Status;\r
+ }\r
+\r
+ if ((Action != EFI_BROWSER_ACTION_CHANGED) &&\r
+ (Action != EFI_BROWSER_ACTION_CHANGING) &&\r
+ (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);\r
+\r
+ //\r
+ // Update the RAM disk list show at the main form first.\r
+ //\r
+ if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
+ Status = EFI_UNSUPPORTED;\r
+ if (QuestionId == MAIN_GOTO_FILE_EXPLORER_ID) {\r
+ UpdateMainForm (ConfigPrivate);\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Get Browser data\r
+ //\r
+ Configuration = AllocateZeroPool (sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum);\r
+ if (Configuration == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ HiiGetBrowserData (\r
+ &gRamDiskFormSetGuid,\r
+ mRamDiskStorageName,\r
+ sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum,\r
+ (UINT8 *) Configuration\r
+ );\r
+\r
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+ switch (QuestionId) {\r
+ case MAIN_GOTO_FILE_EXPLORER_ID:\r
+ Status = ChooseFile (NULL, NULL, NULL, &FileDevPath);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ if (FileDevPath != NULL) {\r
+ //\r
+ // Open the file.\r
+ //\r
+ Status = OpenFileByDevicePath (\r
+ &FileDevPath,\r
+ &FileHandle,\r
+ EFI_FILE_MODE_READ,\r
+ 0\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Create from file, RAM disk size is zero. It will be updated\r
+ // according to the file size.\r
+ //\r
+ Status = HiiCreateRamDisk (0, FileHandle);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Refresh the registered RAM disks list.\r
+ //\r
+ UpdateMainForm (ConfigPrivate);\r
+ }\r
+\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+ switch (QuestionId) {\r
+ case MAIN_REMOVE_RD_QUESTION_ID:\r
+ //\r
+ // Remove the selected RAM disks\r
+ //\r
+ Index = 0;\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {\r
+ if (Configuration->RamDiskList[Index++] != 0) {\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
+\r
+ RamDiskUnregister (\r
+ (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath\r
+ );\r
+ }\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ UpdateMainForm (ConfigPrivate);\r
+\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+ ZeroMem (Configuration->RamDiskList, ListEntryNum);\r
+ break;\r
+\r
+ case CREATE_RAW_SUBMIT_QUESTION_ID:\r
+ //\r
+ // Create raw, FileHandle is NULL.\r
+ //\r
+ Status = HiiCreateRamDisk (Configuration->Size, NULL);\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Refresh the registered RAM disks list.\r
+ //\r
+ UpdateMainForm (ConfigPrivate);\r
+\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+ break;\r
+\r
+ case CREATE_RAW_DISCARD_QUESTION_ID:\r
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ HiiSetBrowserData (\r
+ &gRamDiskFormSetGuid,\r
+ mRamDiskStorageName,\r
+ sizeof (RAM_DISK_CONFIGURATION) + ListEntryNum,\r
+ (UINT8 *) Configuration,\r
+ NULL\r
+ );\r
+ }\r
+ FreePool (Configuration);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
--- /dev/null
+/** @file\r
+ The header file of RamDiskDxe driver.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _RAM_DISK_IMPL_H_\r
+#define _RAM_DISK_IMPL_H_\r
+\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiHiiServicesLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/FileExplorerLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Protocol/RamDisk.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Guid/MdeModuleHii.h>\r
+#include <Guid/RamDiskHii.h>\r
+#include <Guid/FileInfo.h>\r
+\r
+#include "RamDiskNVData.h"\r
+\r
+///\r
+/// RAM disk general definitions and declarations\r
+///\r
+\r
+//\r
+// Block size for RAM disk\r
+//\r
+#define RAM_DISK_BLOCK_SIZE 512\r
+\r
+//\r
+// Iterate through the doule linked list. NOT delete safe\r
+//\r
+#define EFI_LIST_FOR_EACH(Entry, ListHead) \\r
+ for(Entry = (ListHead)->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink)\r
+\r
+//\r
+// Iterate through the doule linked list. This is delete-safe.\r
+// Do not touch NextEntry\r
+//\r
+#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \\r
+ for(Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\\r
+ Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink)\r
+\r
+//\r
+// RamDiskDxe driver maintains a list of registered RAM disks.\r
+//\r
+extern LIST_ENTRY RegisteredRamDisks;\r
+extern UINTN ListEntryNum;\r
+\r
+//\r
+// RAM Disk create method.\r
+//\r
+typedef enum _RAM_DISK_CREATE_METHOD {\r
+ RamDiskCreateOthers = 0,\r
+ RamDiskCreateHii\r
+} RAM_DISK_CREATE_METHOD;\r
+\r
+//\r
+// RamDiskDxe driver maintains a list of registered RAM disks.\r
+// The struct contains the list entry and the information of each RAM\r
+// disk\r
+//\r
+typedef struct {\r
+ UINTN Signature;\r
+\r
+ EFI_HANDLE Handle;\r
+\r
+ EFI_BLOCK_IO_PROTOCOL BlockIo;\r
+ EFI_BLOCK_IO_MEDIA Media;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+\r
+ UINT64 StartingAddr;\r
+ UINT64 Size;\r
+ EFI_GUID TypeGuid;\r
+ UINT16 InstanceNumber;\r
+ RAM_DISK_CREATE_METHOD CreateMethod;\r
+\r
+ LIST_ENTRY ThisInstance;\r
+} RAM_DISK_PRIVATE_DATA;\r
+\r
+#define RAM_DISK_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('R', 'D', 'S', 'K')\r
+#define RAM_DISK_PRIVATE_FROM_BLKIO(a) CR (a, RAM_DISK_PRIVATE_DATA, BlockIo, RAM_DISK_PRIVATE_DATA_SIGNATURE)\r
+#define RAM_DISK_PRIVATE_FROM_THIS(a) CR (a, RAM_DISK_PRIVATE_DATA, ThisInstance, RAM_DISK_PRIVATE_DATA_SIGNATURE)\r
+\r
+///\r
+/// RAM disk HII-related definitions and declarations\r
+///\r
+\r
+//\r
+// Tool generated IFR binary data and String package data\r
+//\r
+extern UINT8 RamDiskHiiBin[];\r
+extern UINT8 RamDiskDxeStrings[];\r
+\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH VendorDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+typedef struct {\r
+ UINTN Signature;\r
+\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;\r
+ EFI_HANDLE DriverHandle;\r
+ EFI_HII_HANDLE HiiHandle;\r
+} RAM_DISK_CONFIG_PRIVATE_DATA;\r
+\r
+extern RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate;\r
+\r
+#define RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('R', 'C', 'F', 'G')\r
+#define RAM_DISK_CONFIG_PRIVATE_FROM_THIS(a) CR (a, RAM_DISK_CONFIG_PRIVATE_DATA, ConfigAccess, RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE)\r
+\r
+#define RAM_DISK_LIST_VAR_OFFSET ((UINT16) OFFSET_OF (RAM_DISK_CONFIGURATION, RamDiskList))\r
+\r
+/**\r
+ Register a RAM disk with specified address, size and type.\r
+\r
+ @param[in] RamDiskBase The base address of registered RAM disk.\r
+ @param[in] RamDiskSize The size of registered RAM disk.\r
+ @param[in] RamDiskType The type of registered RAM disk. The GUID can be\r
+ any of the values defined in section 9.3.6.9, or a\r
+ vendor defined GUID.\r
+ @param[in] ParentDevicePath\r
+ Pointer to the parent device path. If there is no\r
+ parent device path then ParentDevicePath is NULL.\r
+ @param[out] DevicePath On return, points to a pointer to the device path\r
+ of the RAM disk device.\r
+ If ParentDevicePath is not NULL, the returned\r
+ DevicePath is created by appending a RAM disk node\r
+ to the parent device path. If ParentDevicePath is\r
+ NULL, the returned DevicePath is a RAM disk device\r
+ path without appending. This function is\r
+ responsible for allocating the buffer DevicePath\r
+ with the boot service AllocatePool().\r
+\r
+ @retval EFI_SUCCESS The RAM disk is registered successfully.\r
+ @retval EFI_INVALID_PARAMETER DevicePath or RamDiskType is NULL.\r
+ RamDiskSize is 0.\r
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance to be created\r
+ is already present in the handle database.\r
+ @retval EFI_OUT_OF_RESOURCES The RAM disk register operation fails due to\r
+ resource limitation.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskRegister (\r
+ IN UINT64 RamDiskBase,\r
+ IN UINT64 RamDiskSize,\r
+ IN EFI_GUID *RamDiskType,\r
+ IN EFI_DEVICE_PATH *ParentDevicePath OPTIONAL,\r
+ OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ );\r
+\r
+/**\r
+ Unregister a RAM disk specified by DevicePath.\r
+\r
+ @param[in] DevicePath A pointer to the device path that describes a RAM\r
+ Disk device.\r
+\r
+ @retval EFI_SUCCESS The RAM disk is unregistered successfully.\r
+ @retval EFI_INVALID_PARAMETER DevicePath is NULL.\r
+ @retval EFI_UNSUPPORTED The device specified by DevicePath is not a\r
+ valid ramdisk device path and not supported\r
+ by the driver.\r
+ @retval EFI_NOT_FOUND The RAM disk pointed by DevicePath doesn't\r
+ exist.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskUnregister (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ );\r
+\r
+/**\r
+ Initialize the BlockIO protocol of a RAM disk device.\r
+\r
+ @param[in] PrivateData Points to RAM disk private data.\r
+\r
+**/\r
+VOID\r
+RamDiskInitBlockIo (\r
+ IN RAM_DISK_PRIVATE_DATA *PrivateData\r
+ );\r
+\r
+/**\r
+ Reset the Block Device.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] ExtendedVerification\r
+ Driver may perform diagnostics on reset.\r
+\r
+ @retval EFI_SUCCESS The device was reset.\r
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and\r
+ could not be reset.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoReset (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN BOOLEAN ExtendedVerification\r
+ );\r
+\r
+/**\r
+ Read BufferSize bytes from Lba into Buffer.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] MediaId Id of the media, changes every time the media is\r
+ replaced.\r
+ @param[in] Lba The starting Logical Block Address to read from.\r
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block\r
+ size.\r
+ @param[out] Buffer A pointer to the destination buffer for the data.\r
+ The caller is responsible for either having\r
+ implicit or explicit ownership of the buffer.\r
+\r
+ @retval EFI_SUCCESS The data was read correctly from the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing\r
+ the read.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHANGED The MediaId does not matched the current\r
+ device.\r
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block\r
+ size of the device.\r
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not\r
+ valid, or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoReadBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BufferSize,\r
+ OUT VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Write BufferSize bytes from Lba into Buffer.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+ @param[in] MediaId The media ID that the write request is for.\r
+ @param[in] Lba The starting logical block address to be written.\r
+ The caller is responsible for writing to only\r
+ legitimate locations.\r
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block\r
+ size.\r
+ @param[in] Buffer A pointer to the source buffer for the data.\r
+\r
+ @retval EFI_SUCCESS The data was written correctly to the device.\r
+ @retval EFI_WRITE_PROTECTED The device can not be written to.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while performing\r
+ the write.\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current\r
+ device.\r
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block\r
+ size of the device.\r
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not\r
+ valid, or the buffer is not on proper alignment.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoWriteBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This,\r
+ IN UINT32 MediaId,\r
+ IN EFI_LBA Lba,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer\r
+ );\r
+\r
+/**\r
+ Flush the Block Device.\r
+\r
+ @param[in] This Indicates a pointer to the calling context.\r
+\r
+ @retval EFI_SUCCESS All outstanding data was written to the device.\r
+ @retval EFI_DEVICE_ERROR The device reported an error while writting\r
+ back the data\r
+ @retval EFI_NO_MEDIA There is no media in the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskBlkIoFlushBlocks (\r
+ IN EFI_BLOCK_IO_PROTOCOL *This\r
+ );\r
+\r
+/**\r
+ This function publish the RAM disk configuration Form.\r
+\r
+ @param[in, out] ConfigPrivateData\r
+ Points to RAM disk configuration private data.\r
+\r
+ @retval EFI_SUCCESS HII Form is installed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.\r
+ @retval Others Other errors as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallRamDiskConfigForm (\r
+ IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData\r
+ );\r
+\r
+/**\r
+ This function removes RAM disk configuration Form.\r
+\r
+ @param[in, out] ConfigPrivateData\r
+ Points to RAM disk configuration private data.\r
+\r
+**/\r
+VOID\r
+UninstallRamDiskConfigForm (\r
+ IN OUT RAM_DISK_CONFIG_PRIVATE_DATA *ConfigPrivateData\r
+ );\r
+\r
+/**\r
+ Unregister all registered RAM disks.\r
+\r
+**/\r
+VOID\r
+UnregisterAllRamDisks (\r
+ VOID\r
+ );\r
+\r
+/**\r
+ This function allows a caller to extract the current configuration for one\r
+ or more named elements from the target driver.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Request A null-terminated Unicode string in\r
+ <ConfigRequest> format.\r
+ @param[out] Progress On return, points to a character in the Request\r
+ string. Points to the string's null terminator if\r
+ request was successful. Points to the most recent\r
+ '&' before the first failing name/value pair (or\r
+ the beginning of the string if the failure is in\r
+ the first name/value pair) if the request was not\r
+ successful.\r
+ @param[out] Results A null-terminated Unicode string in\r
+ <ConfigAltResp> format which has all values filled\r
+ in for the names in the Request string. String to\r
+ be allocated by the called function.\r
+\r
+ @retval EFI_SUCCESS The Results is filled with the requested\r
+ values.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
+ @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in\r
+ this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskExtractConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Request,\r
+ OUT EFI_STRING *Progress,\r
+ OUT EFI_STRING *Results\r
+ );\r
+\r
+/**\r
+ This function processes the results of changes in configuration.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Configuration A null-terminated Unicode string in <ConfigResp>\r
+ format.\r
+ @param[out] Progress A pointer to a string filled in with the offset of\r
+ the most recent '&' before the first failing\r
+ name/value pair (or the beginning of the string if\r
+ the failure is in the first name/value pair) or\r
+ the terminating NULL if all was successful.\r
+\r
+ @retval EFI_SUCCESS The Results is processed successfully.\r
+ @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
+ @retval EFI_NOT_FOUND Routing data doesn't match any storage in\r
+ this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskRouteConfig (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN CONST EFI_STRING Configuration,\r
+ OUT EFI_STRING *Progress\r
+ );\r
+\r
+/**\r
+ This function processes the results of changes in configuration.\r
+\r
+ @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+ @param[in] Action Specifies the type of action taken by the browser.\r
+ @param[in] QuestionId A unique value which is sent to the original\r
+ exporting driver so that it can identify the type\r
+ of data to expect.\r
+ @param[in] Type The type of value for the question.\r
+ @param[in] Value A pointer to the data being sent to the original\r
+ exporting driver.\r
+ @param[out] ActionRequest On return, points to the action requested by the\r
+ callback function.\r
+\r
+ @retval EFI_SUCCESS The callback successfully handled the action.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
+ variable and its data.\r
+ @retval EFI_DEVICE_ERROR The variable could not be saved.\r
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
+ callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskCallback (\r
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN EFI_QUESTION_ID QuestionId,\r
+ IN UINT8 Type,\r
+ IN EFI_IFR_TYPE_VALUE *Value,\r
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
+ );\r
+\r
+\r
+/**\r
+ This function gets the file information from an open file descriptor,\r
+ and stores it in a buffer allocated from pool.\r
+\r
+ @param[in] FHand File Handle.\r
+\r
+ @return A pointer to a buffer with file information or NULL is returned.\r
+\r
+**/\r
+EFI_FILE_INFO *\r
+FileInfo (\r
+ IN EFI_FILE_HANDLE FHand\r
+ );\r
+\r
+\r
+/**\r
+ This function will open a file or directory referenced by DevicePath.\r
+\r
+ This function opens a file with the open mode according to the file path. The\r
+ Attributes is valid only for EFI_FILE_MODE_CREATE.\r
+\r
+ @param[in, out] FilePath On input, the device path to the file.\r
+ On output, the remaining device path.\r
+ @param[out] FileHandle Pointer to the file handle.\r
+ @param[in] OpenMode The mode to open the file with.\r
+ @param[in] Attributes The file's file attributes.\r
+\r
+ @retval EFI_SUCCESS The information was set.\r
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
+ @retval EFI_UNSUPPORTED Could not open the file path.\r
+ @retval EFI_NOT_FOUND The specified file could not be found on the\r
+ device or the file system could not be found\r
+ on the device.\r
+ @retval EFI_NO_MEDIA The device has no medium.\r
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or\r
+ the medium is no longer supported.\r
+ @retval EFI_DEVICE_ERROR The device reported an error.\r
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.\r
+ @retval EFI_ACCESS_DENIED The file was opened read only.\r
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open\r
+ the file.\r
+ @retval EFI_VOLUME_FULL The volume is full.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpenFileByDevicePath(\r
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,\r
+ OUT EFI_FILE_HANDLE *FileHandle,\r
+ IN UINT64 OpenMode,\r
+ IN UINT64 Attributes\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Header file for NV data structure definition.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _RAM_DISK_NVDATA_H_\r
+#define _RAM_DISK_NVDATA_H_\r
+\r
+#include <Guid/HiiPlatformSetupFormset.h>\r
+#include <Guid/RamDiskHii.h>\r
+\r
+#define RAM_DISK_CONFIGURATION_VARSTORE_ID 0x0001\r
+\r
+#define MAIN_FORM_ID 0x1000\r
+#define MAIN_GOTO_FILE_EXPLORER_ID 0x1001\r
+#define MAIN_REMOVE_RD_QUESTION_ID 0x1002\r
+#define MAIN_CHECKBOX_QUESTION_ID_START 0x1003\r
+#define MAIN_LABEL_LIST_START 0x1004\r
+#define MAIN_LABEL_LIST_END 0x1005\r
+\r
+#define CREATE_RAW_RAM_DISK_FORM_ID 0x2000\r
+#define CREATE_RAW_SIZE_QUESTION_ID 0x2001\r
+#define CREATE_RAW_SUBMIT_QUESTION_ID 0x2002\r
+#define CREATE_RAW_DISCARD_QUESTION_ID 0x2003\r
+\r
+typedef struct {\r
+ UINT64 Size;\r
+ //\r
+ // CheckBox status for created RAM disks\r
+ //\r
+ UINT8 RamDiskList[0];\r
+} RAM_DISK_CONFIGURATION;\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ The realization of EFI_RAM_DISK_PROTOCOL.\r
+\r
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "RamDiskImpl.h"\r
+\r
+RAM_DISK_PRIVATE_DATA mRamDiskPrivateDataTemplate = {\r
+ RAM_DISK_PRIVATE_DATA_SIGNATURE,\r
+ NULL\r
+};\r
+\r
+MEDIA_RAM_DISK_DEVICE_PATH mRamDiskDeviceNodeTemplate = {\r
+ {\r
+ MEDIA_DEVICE_PATH,\r
+ MEDIA_RAM_DISK_DP,\r
+ {\r
+ (UINT8) (sizeof (MEDIA_RAM_DISK_DEVICE_PATH)),\r
+ (UINT8) ((sizeof (MEDIA_RAM_DISK_DEVICE_PATH)) >> 8)\r
+ }\r
+ }\r
+};\r
+\r
+\r
+/**\r
+ Initialize the RAM disk device node.\r
+\r
+ @param[in] PrivateData Points to RAM disk private data.\r
+ @param[in, out] RamDiskDevNode Points to the RAM disk device node.\r
+\r
+**/\r
+VOID\r
+RamDiskInitDeviceNode (\r
+ IN RAM_DISK_PRIVATE_DATA *PrivateData,\r
+ IN OUT MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode\r
+ )\r
+{\r
+ WriteUnaligned64 (\r
+ (UINT64 *) &(RamDiskDevNode->StartingAddr[0]),\r
+ (UINT64) PrivateData->StartingAddr\r
+ );\r
+ WriteUnaligned64 (\r
+ (UINT64 *) &(RamDiskDevNode->EndingAddr[0]),\r
+ (UINT64) PrivateData->StartingAddr + PrivateData->Size\r
+ );\r
+ CopyGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid);\r
+ RamDiskDevNode->Instance = PrivateData->InstanceNumber;\r
+}\r
+\r
+\r
+/**\r
+ Register a RAM disk with specified address, size and type.\r
+\r
+ @param[in] RamDiskBase The base address of registered RAM disk.\r
+ @param[in] RamDiskSize The size of registered RAM disk.\r
+ @param[in] RamDiskType The type of registered RAM disk. The GUID can be\r
+ any of the values defined in section 9.3.6.9, or a\r
+ vendor defined GUID.\r
+ @param[in] ParentDevicePath\r
+ Pointer to the parent device path. If there is no\r
+ parent device path then ParentDevicePath is NULL.\r
+ @param[out] DevicePath On return, points to a pointer to the device path\r
+ of the RAM disk device.\r
+ If ParentDevicePath is not NULL, the returned\r
+ DevicePath is created by appending a RAM disk node\r
+ to the parent device path. If ParentDevicePath is\r
+ NULL, the returned DevicePath is a RAM disk device\r
+ path without appending. This function is\r
+ responsible for allocating the buffer DevicePath\r
+ with the boot service AllocatePool().\r
+\r
+ @retval EFI_SUCCESS The RAM disk is registered successfully.\r
+ @retval EFI_INVALID_PARAMETER DevicePath or RamDiskType is NULL.\r
+ RamDiskSize is 0.\r
+ @retval EFI_ALREADY_STARTED A Device Path Protocol instance to be created\r
+ is already present in the handle database.\r
+ @retval EFI_OUT_OF_RESOURCES The RAM disk register operation fails due to\r
+ resource limitation.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskRegister (\r
+ IN UINT64 RamDiskBase,\r
+ IN UINT64 RamDiskSize,\r
+ IN EFI_GUID *RamDiskType,\r
+ IN EFI_DEVICE_PATH *ParentDevicePath OPTIONAL,\r
+ OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ RAM_DISK_PRIVATE_DATA *RegisteredPrivateData;\r
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode;\r
+ UINTN DevicePathSize;\r
+ LIST_ENTRY *Entry;\r
+ EFI_TPL OldTpl;\r
+\r
+ if ((0 == RamDiskSize) || (NULL == RamDiskType) || (NULL == DevicePath)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Add check to prevent data read across the memory boundary\r
+ //\r
+ if (RamDiskBase + RamDiskSize > ((UINTN) -1) - RAM_DISK_BLOCK_SIZE + 1) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ RamDiskDevNode = NULL;\r
+\r
+ //\r
+ // Create a new RAM disk instance and initialize its private data\r
+ //\r
+ PrivateData = AllocateCopyPool (\r
+ sizeof (RAM_DISK_PRIVATE_DATA),\r
+ &mRamDiskPrivateDataTemplate\r
+ );\r
+ if (NULL == PrivateData) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ PrivateData->StartingAddr = RamDiskBase;\r
+ PrivateData->Size = RamDiskSize;\r
+ CopyGuid (&PrivateData->TypeGuid, RamDiskType);\r
+ InitializeListHead (&PrivateData->ThisInstance);\r
+\r
+ //\r
+ // Generate device path information for the registered RAM disk\r
+ //\r
+ RamDiskDevNode = AllocateCopyPool (\r
+ sizeof (MEDIA_RAM_DISK_DEVICE_PATH),\r
+ &mRamDiskDeviceNodeTemplate\r
+ );\r
+ if (NULL == RamDiskDevNode) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ RamDiskInitDeviceNode (PrivateData, RamDiskDevNode);\r
+\r
+ *DevicePath = AppendDevicePathNode (\r
+ ParentDevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *) RamDiskDevNode\r
+ );\r
+ if (NULL == *DevicePath) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ PrivateData->DevicePath = *DevicePath;\r
+\r
+ //\r
+ // Check whether the created device path is already present in the handle\r
+ // database\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ if (!IsListEmpty(&RegisteredRamDisks)) {\r
+ DevicePathSize = GetDevicePathSize (PrivateData->DevicePath);\r
+\r
+ EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {\r
+ RegisteredPrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
+ if (DevicePathSize == GetDevicePathSize (RegisteredPrivateData->DevicePath)) {\r
+ //\r
+ // Compare device path\r
+ //\r
+ if ((CompareMem (\r
+ PrivateData->DevicePath,\r
+ RegisteredPrivateData->DevicePath,\r
+ DevicePathSize)) == 0) {\r
+ *DevicePath = NULL;\r
+ Status = EFI_ALREADY_STARTED;\r
+ goto ErrorExit;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ //\r
+ // Fill Block IO protocol informations for the RAM disk\r
+ //\r
+ RamDiskInitBlockIo (PrivateData);\r
+\r
+ //\r
+ // Install EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO_PROTOCOL on a new\r
+ // handle\r
+ //\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &PrivateData->Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &PrivateData->BlockIo,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PrivateData->DevicePath,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Insert the newly created one to the registered RAM disk list\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ InsertTailList (&RegisteredRamDisks, &PrivateData->ThisInstance);\r
+ ListEntryNum++;\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ gBS->ConnectController (PrivateData->Handle, NULL, NULL, TRUE);\r
+\r
+ FreePool (RamDiskDevNode);\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+ if (RamDiskDevNode != NULL) {\r
+ FreePool (RamDiskDevNode);\r
+ }\r
+\r
+ if (PrivateData != NULL) {\r
+ if (PrivateData->DevicePath) {\r
+ FreePool (PrivateData->DevicePath);\r
+ }\r
+\r
+ FreePool (PrivateData);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Unregister a RAM disk specified by DevicePath.\r
+\r
+ @param[in] DevicePath A pointer to the device path that describes a RAM\r
+ Disk device.\r
+\r
+ @retval EFI_SUCCESS The RAM disk is unregistered successfully.\r
+ @retval EFI_INVALID_PARAMETER DevicePath is NULL.\r
+ @retval EFI_UNSUPPORTED The device specified by DevicePath is not a\r
+ valid ramdisk device path and not supported\r
+ by the driver.\r
+ @retval EFI_NOT_FOUND The RAM disk pointed by DevicePath doesn't\r
+ exist.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RamDiskUnregister (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+ )\r
+{\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *NextEntry;\r
+ BOOLEAN Found;\r
+ UINT64 StartingAddr;\r
+ UINT64 EndingAddr;\r
+ EFI_DEVICE_PATH_PROTOCOL *Header;\r
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDiskDevNode;\r
+ RAM_DISK_PRIVATE_DATA *PrivateData;\r
+ EFI_TPL OldTpl;\r
+\r
+ if (NULL == DevicePath) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Locate the RAM disk device node.\r
+ //\r
+ RamDiskDevNode = NULL;\r
+ Header = DevicePath;\r
+ do {\r
+ //\r
+ // Test if the current device node is a RAM disk.\r
+ //\r
+ if ((MEDIA_DEVICE_PATH == Header->Type) &&\r
+ (MEDIA_RAM_DISK_DP == Header->SubType)) {\r
+ RamDiskDevNode = (MEDIA_RAM_DISK_DEVICE_PATH *) Header;\r
+\r
+ break;\r
+ }\r
+\r
+ Header = NextDevicePathNode (Header);\r
+ } while ((Header->Type != END_DEVICE_PATH_TYPE));\r
+\r
+ if (NULL == RamDiskDevNode) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ Found = FALSE;\r
+ StartingAddr = ReadUnaligned64 ((UINT64 *) &(RamDiskDevNode->StartingAddr[0]));\r
+ EndingAddr = ReadUnaligned64 ((UINT64 *) &(RamDiskDevNode->EndingAddr[0]));\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ if (!IsListEmpty(&RegisteredRamDisks)) {\r
+ EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {\r
+ PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);\r
+\r
+ //\r
+ // Unregister the RAM disk given by its starting address, ending address\r
+ // and type guid.\r
+ //\r
+ if ((StartingAddr == PrivateData->StartingAddr) &&\r
+ (EndingAddr == PrivateData->StartingAddr + PrivateData->Size) &&\r
+ (CompareGuid (&RamDiskDevNode->TypeGuid, &PrivateData->TypeGuid))) {\r
+ //\r
+ // Uninstall the EFI_DEVICE_PATH_PROTOCOL & EFI_BLOCK_IO_PROTOCOL\r
+ //\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ PrivateData->Handle,\r
+ &gEfiBlockIoProtocolGuid,\r
+ &PrivateData->BlockIo,\r
+ &gEfiDevicePathProtocolGuid,\r
+ DevicePath,\r
+ NULL\r
+ );\r
+\r
+ RemoveEntryList (&PrivateData->ThisInstance);\r
+\r
+ if (RamDiskCreateHii == PrivateData->CreateMethod) {\r
+ //\r
+ // If a RAM disk is created within HII, then the RamDiskDxe driver\r
+ // driver is responsible for freeing the allocated memory for the\r
+ // RAM disk.\r
+ //\r
+ FreePool ((VOID *)(UINTN) PrivateData->StartingAddr);\r
+ }\r
+\r
+ gBS->DisconnectController (PrivateData->Handle, NULL, NULL);\r
+\r
+ FreePool (PrivateData->DevicePath);\r
+ FreePool (PrivateData);\r
+ ListEntryNum--;\r
+ Found = TRUE;\r
+\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ if (TRUE == Found) {\r
+ return EFI_SUCCESS;\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+}\r