MdeModulePkg: Add RamDiskDxe driver implementation
The RamDiskDxe driver will: 1. Produce the EFI RAM Disk Protocol 2. Install RAM disk device path and block I/O related protocols on the RAM disk device handle. 3. Install RAM disk configuration form to HII database Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Samer El-Haj-Mahmoud <elhaj@hpe.com> Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
258
MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c
Normal file
258
MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskBlockIo.c
Normal file
@ -0,0 +1,258 @@
|
||||
/** @file
|
||||
Produce EFI_BLOCK_IO_PROTOCOL on a RAM disk device.
|
||||
|
||||
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include "RamDiskImpl.h"
|
||||
|
||||
//
|
||||
// The EFI_BLOCK_IO_PROTOCOL instances that is installed onto the handle
|
||||
// for newly registered RAM disks
|
||||
//
|
||||
EFI_BLOCK_IO_PROTOCOL mRamDiskBlockIoTemplate = {
|
||||
EFI_BLOCK_IO_PROTOCOL_REVISION,
|
||||
(EFI_BLOCK_IO_MEDIA *) 0,
|
||||
RamDiskBlkIoReset,
|
||||
RamDiskBlkIoReadBlocks,
|
||||
RamDiskBlkIoWriteBlocks,
|
||||
RamDiskBlkIoFlushBlocks
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
Initialize the BlockIO protocol of a RAM disk device.
|
||||
|
||||
@param[in] PrivateData Points to RAM disk private data.
|
||||
|
||||
**/
|
||||
VOID
|
||||
RamDiskInitBlockIo (
|
||||
IN RAM_DISK_PRIVATE_DATA *PrivateData
|
||||
)
|
||||
{
|
||||
EFI_BLOCK_IO_PROTOCOL *BlockIo;
|
||||
EFI_BLOCK_IO_MEDIA *Media;
|
||||
|
||||
BlockIo = &PrivateData->BlockIo;
|
||||
Media = &PrivateData->Media;
|
||||
|
||||
CopyMem (BlockIo, &mRamDiskBlockIoTemplate, sizeof (EFI_BLOCK_IO_PROTOCOL));
|
||||
|
||||
BlockIo->Media = Media;
|
||||
Media->RemovableMedia = FALSE;
|
||||
Media->MediaPresent = TRUE;
|
||||
Media->LogicalPartition = FALSE;
|
||||
Media->ReadOnly = FALSE;
|
||||
Media->WriteCaching = FALSE;
|
||||
Media->BlockSize = RAM_DISK_BLOCK_SIZE;
|
||||
Media->LastBlock = DivU64x32 (
|
||||
PrivateData->Size + RAM_DISK_BLOCK_SIZE - 1,
|
||||
RAM_DISK_BLOCK_SIZE
|
||||
) - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reset the Block Device.
|
||||
|
||||
@param This Indicates a pointer to the calling context.
|
||||
@param ExtendedVerification Driver may perform diagnostics on reset.
|
||||
|
||||
@retval EFI_SUCCESS The device was reset.
|
||||
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
|
||||
not be reset.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RamDiskBlkIoReset (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN BOOLEAN ExtendedVerification
|
||||
)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Read BufferSize bytes from Lba into Buffer.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
@param[in] MediaId Id of the media, changes every time the media is
|
||||
replaced.
|
||||
@param[in] Lba The starting Logical Block Address to read from.
|
||||
@param[in] BufferSize Size of Buffer, must be a multiple of device block
|
||||
size.
|
||||
@param[out] Buffer A pointer to the destination buffer for the data.
|
||||
The caller is responsible for either having
|
||||
implicit or explicit ownership of the buffer.
|
||||
|
||||
@retval EFI_SUCCESS The data was read correctly from the device.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error while performing
|
||||
the read.
|
||||
@retval EFI_NO_MEDIA There is no media in the device.
|
||||
@retval EFI_MEDIA_CHANGED The MediaId does not matched the current
|
||||
device.
|
||||
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block
|
||||
size of the device.
|
||||
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
|
||||
valid, or the buffer is not on proper alignment.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RamDiskBlkIoReadBlocks (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
{
|
||||
RAM_DISK_PRIVATE_DATA *PrivateData;
|
||||
UINTN NumberOfBlocks;
|
||||
|
||||
if (Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (BufferSize == 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);
|
||||
|
||||
if (MediaId != PrivateData->Media.MediaId) {
|
||||
return EFI_MEDIA_CHANGED;
|
||||
}
|
||||
|
||||
if ((BufferSize % PrivateData->Media.BlockSize) != 0) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (Lba > PrivateData->Media.LastBlock) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
NumberOfBlocks = BufferSize / PrivateData->Media.BlockSize;
|
||||
if ((Lba + NumberOfBlocks - 1) > PrivateData->Media.LastBlock) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
Buffer,
|
||||
(VOID *)(UINTN)(PrivateData->StartingAddr + MultU64x32 (Lba, PrivateData->Media.BlockSize)),
|
||||
BufferSize
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Write BufferSize bytes from Lba into Buffer.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
@param[in] MediaId The media ID that the write request is for.
|
||||
@param[in] Lba The starting logical block address to be written.
|
||||
The caller is responsible for writing to only
|
||||
legitimate locations.
|
||||
@param[in] BufferSize Size of Buffer, must be a multiple of device block
|
||||
size.
|
||||
@param[in] Buffer A pointer to the source buffer for the data.
|
||||
|
||||
@retval EFI_SUCCESS The data was written correctly to the device.
|
||||
@retval EFI_WRITE_PROTECTED The device can not be written to.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error while performing
|
||||
the write.
|
||||
@retval EFI_NO_MEDIA There is no media in the device.
|
||||
@retval EFI_MEDIA_CHNAGED The MediaId does not matched the current
|
||||
device.
|
||||
@retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block
|
||||
size of the device.
|
||||
@retval EFI_INVALID_PARAMETER The write request contains LBAs that are not
|
||||
valid, or the buffer is not on proper alignment.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RamDiskBlkIoWriteBlocks (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This,
|
||||
IN UINT32 MediaId,
|
||||
IN EFI_LBA Lba,
|
||||
IN UINTN BufferSize,
|
||||
IN VOID *Buffer
|
||||
)
|
||||
{
|
||||
RAM_DISK_PRIVATE_DATA *PrivateData;
|
||||
UINTN NumberOfBlocks;
|
||||
|
||||
if (Buffer == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (BufferSize == 0) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
PrivateData = RAM_DISK_PRIVATE_FROM_BLKIO (This);
|
||||
|
||||
if (MediaId != PrivateData->Media.MediaId) {
|
||||
return EFI_MEDIA_CHANGED;
|
||||
}
|
||||
|
||||
if (TRUE == PrivateData->Media.ReadOnly) {
|
||||
return EFI_WRITE_PROTECTED;
|
||||
}
|
||||
|
||||
if ((BufferSize % PrivateData->Media.BlockSize) != 0) {
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (Lba > PrivateData->Media.LastBlock) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
NumberOfBlocks = BufferSize / PrivateData->Media.BlockSize;
|
||||
if ((Lba + NumberOfBlocks - 1) > PrivateData->Media.LastBlock) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
CopyMem (
|
||||
(VOID *)(UINTN)(PrivateData->StartingAddr + MultU64x32 (Lba, PrivateData->Media.BlockSize)),
|
||||
Buffer,
|
||||
BufferSize
|
||||
);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Flush the Block Device.
|
||||
|
||||
@param[in] This Indicates a pointer to the calling context.
|
||||
|
||||
@retval EFI_SUCCESS All outstanding data was written to the device.
|
||||
@retval EFI_DEVICE_ERROR The device reported an error while writting
|
||||
back the data
|
||||
@retval EFI_NO_MEDIA There is no media in the device.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
RamDiskBlkIoFlushBlocks (
|
||||
IN EFI_BLOCK_IO_PROTOCOL *This
|
||||
)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user