/** @file | |
Data structures for FAT recovery PEIM | |
Copyright (c) 2006 - 2018, 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. | |
**/ | |
#ifndef _FAT_PEIM_H_ | |
#define _FAT_PEIM_H_ | |
#include <PiPei.h> | |
#include <Guid/RecoveryDevice.h> | |
#include <Ppi/BlockIo.h> | |
#include <Ppi/BlockIo2.h> | |
#include <Ppi/DeviceRecoveryModule.h> | |
#include <Library/DebugLib.h> | |
#include <Library/BaseLib.h> | |
#include <Library/PeimEntryPoint.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/PcdLib.h> | |
#include <Library/PeiServicesTablePointerLib.h> | |
#include <Library/PeiServicesLib.h> | |
#include "FatLiteApi.h" | |
#include "FatLiteFmt.h" | |
// | |
// Definitions | |
// | |
#define PEI_FAT_CACHE_SIZE 4 | |
#define PEI_FAT_MAX_BLOCK_SIZE 8192 | |
#define FAT_MAX_FILE_NAME_LENGTH 128 | |
#define PEI_FAT_MAX_BLOCK_DEVICE 64 | |
#define PEI_FAT_MAX_BLOCK_IO_PPI 32 | |
#define PEI_FAT_MAX_VOLUME 64 | |
#define PEI_FAT_MEMMORY_PAGE_SIZE 0x1000 | |
// | |
// Data Structures | |
// | |
// | |
// The block device | |
// | |
typedef struct { | |
UINT32 BlockSize; | |
UINT64 LastBlock; | |
UINT32 IoAlign; | |
BOOLEAN Logical; | |
BOOLEAN PartitionChecked; | |
// | |
// Following fields only valid for logical device | |
// | |
CHAR8 PartitionFlag[8]; | |
UINT64 StartingPos; | |
UINTN ParentDevNo; | |
// | |
// Following fields only valid for physical device | |
// | |
EFI_PEI_BLOCK_DEVICE_TYPE DevType; | |
UINT8 InterfaceType; | |
// | |
// EFI_PEI_READ_BLOCKS ReadFunc; | |
// | |
EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlockIo; | |
EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2; | |
UINT8 PhysicalDevNo; | |
} PEI_FAT_BLOCK_DEVICE; | |
// | |
// the Volume structure | |
// | |
typedef struct { | |
UINTN BlockDeviceNo; | |
UINTN VolumeNo; | |
UINT64 VolumeSize; | |
UINTN MaxCluster; | |
CHAR16 VolumeLabel[FAT_MAX_FILE_NAME_LENGTH]; | |
PEI_FAT_TYPE FatType; | |
UINT64 FatPos; | |
UINT32 SectorSize; | |
UINT32 ClusterSize; | |
UINT64 FirstClusterPos; | |
UINT64 RootDirPos; | |
UINT32 RootEntries; | |
UINT32 RootDirCluster; | |
} PEI_FAT_VOLUME; | |
// | |
// File instance | |
// | |
typedef struct { | |
PEI_FAT_VOLUME *Volume; | |
CHAR16 FileName[FAT_MAX_FILE_NAME_LENGTH]; | |
BOOLEAN IsFixedRootDir; | |
UINT32 StartingCluster; | |
UINT32 CurrentPos; | |
UINT32 StraightReadAmount; | |
UINT32 CurrentCluster; | |
UINT8 Attributes; | |
UINT32 FileSize; | |
} PEI_FAT_FILE; | |
// | |
// Cache Buffer | |
// | |
typedef struct { | |
BOOLEAN Valid; | |
UINTN BlockDeviceNo; | |
UINT64 Lba; | |
UINT32 Lru; | |
UINT64 Buffer[PEI_FAT_MAX_BLOCK_SIZE / 8]; | |
UINTN Size; | |
} PEI_FAT_CACHE_BUFFER; | |
// | |
// Private Data. | |
// This structure abstracts the whole memory usage in FAT PEIM. | |
// The entry point routine will get a chunk of memory (by whatever | |
// means) whose size is sizeof(PEI_FAT_PRIVATE_DATA), which is clean | |
// in both 32 and 64 bit environment. The boundary of the memory chunk | |
// should be 64bit aligned. | |
// | |
#define PEI_FAT_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('p', 'f', 'a', 't') | |
typedef struct { | |
UINTN Signature; | |
EFI_PEI_DEVICE_RECOVERY_MODULE_PPI DeviceRecoveryPpi; | |
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; | |
EFI_PEI_NOTIFY_DESCRIPTOR NotifyDescriptor[2]; | |
UINT8 UnicodeCaseMap[0x300]; | |
CHAR8 *EngUpperMap; | |
CHAR8 *EngLowerMap; | |
CHAR8 *EngInfoMap; | |
UINT64 BlockData[PEI_FAT_MAX_BLOCK_SIZE / 8]; | |
UINTN BlockDeviceCount; | |
PEI_FAT_BLOCK_DEVICE BlockDevice[PEI_FAT_MAX_BLOCK_DEVICE]; | |
UINTN VolumeCount; | |
PEI_FAT_VOLUME Volume[PEI_FAT_MAX_VOLUME]; | |
PEI_FAT_FILE File; | |
PEI_FAT_CACHE_BUFFER CacheBuffer[PEI_FAT_CACHE_SIZE]; | |
} PEI_FAT_PRIVATE_DATA; | |
#define PEI_FAT_PRIVATE_DATA_FROM_THIS(a) \ | |
CR (a, PEI_FAT_PRIVATE_DATA, DeviceRecoveryPpi, PEI_FAT_PRIVATE_DATA_SIGNATURE) | |
// | |
// Extract INT32 from char array | |
// | |
#define UNPACK_INT32(a) \ | |
(INT32) ((((UINT8 *) a)[0] << 0) | (((UINT8 *) a)[1] << 8) | (((UINT8 *) a)[2] << 16) | (((UINT8 *) a)[3] << 24)) | |
// | |
// Extract UINT32 from char array | |
// | |
#define UNPACK_UINT32(a) \ | |
(UINT32) ((((UINT8 *) a)[0] << 0) | (((UINT8 *) a)[1] << 8) | (((UINT8 *) a)[2] << 16) | (((UINT8 *) a)[3] << 24)) | |
// | |
// API functions | |
// | |
/** | |
Finds the recovery file on a FAT volume. | |
This function finds the the recovery file named FileName on a specified FAT volume and returns | |
its FileHandle pointer. | |
@param PrivateData Global memory map for accessing global | |
variables. | |
@param VolumeIndex The index of the volume. | |
@param FileName The recovery file name to find. | |
@param Handle The output file handle. | |
@retval EFI_DEVICE_ERROR Some error occured when operating the FAT | |
volume. | |
@retval EFI_NOT_FOUND The recovery file was not found. | |
@retval EFI_SUCCESS The recovery file was successfully found on the | |
FAT volume. | |
**/ | |
EFI_STATUS | |
FindRecoveryFile ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN UINTN VolumeIndex, | |
IN CHAR16 *FileName, | |
OUT PEI_FILE_HANDLE *Handle | |
); | |
/** | |
Returns the number of DXE capsules residing on the device. | |
This function, by whatever mechanism, searches for DXE capsules from the associated device and | |
returns the number and maximum size in bytes of the capsules discovered.Entry 1 is assumed to be | |
the highest load priority and entry N is assumed to be the lowest priority. | |
@param PeiServices General-purpose services that are available to | |
every PEIM. | |
@param This Indicates the | |
EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance. | |
@param NumberRecoveryCapsules Pointer to a caller-allocated UINTN.On output, | |
*NumberRecoveryCapsules contains the number of | |
recovery capsule images available for retrieval | |
from this PEIM instance. | |
@retval EFI_SUCCESS The function completed successfully. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetNumberRecoveryCapsules ( | |
IN EFI_PEI_SERVICES **PeiServices, | |
IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This, | |
OUT UINTN *NumberRecoveryCapsules | |
); | |
/** | |
Returns the size and type of the requested recovery capsule. | |
This function returns the size and type of the capsule specified by CapsuleInstance. | |
@param PeiServices General-purpose services that are available to | |
every PEIM. | |
@param This Indicates the | |
EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance. | |
@param CapsuleInstance Specifies for which capsule instance to | |
retrieve the information.T his parameter must | |
be between one and the value returned by | |
GetNumberRecoveryCapsules() in | |
NumberRecoveryCapsules. | |
@param Size A pointer to a caller-allocated UINTN in which | |
the size of the requested recovery module is | |
returned. | |
@param CapsuleType A pointer to a caller-allocated EFI_GUID in | |
which the type of the requested recovery | |
capsule is returned.T he semantic meaning of | |
the value returned is defined by the | |
implementation. | |
@retval EFI_SUCCESS The capsule type and size were retrieved. | |
@retval EFI_INVALID_PARAMETER The input CapsuleInstance does not match any | |
discovered recovery capsule. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetRecoveryCapsuleInfo ( | |
IN EFI_PEI_SERVICES **PeiServices, | |
IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This, | |
IN UINTN CapsuleInstance, | |
OUT UINTN *Size, | |
OUT EFI_GUID *CapsuleType | |
); | |
/** | |
Loads a DXE capsule from some media into memory. | |
This function, by whatever mechanism, retrieves a DXE capsule from some device | |
and loads it into memory. Note that the published interface is device neutral. | |
@param[in] PeiServices General-purpose services that are available | |
to every PEIM | |
@param[in] This Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI | |
instance. | |
@param[in] CapsuleInstance Specifies which capsule instance to retrieve. | |
@param[out] Buffer Specifies a caller-allocated buffer in which | |
the requested recovery capsule will be returned. | |
@retval EFI_SUCCESS The capsule was loaded correctly. | |
@retval EFI_DEVICE_ERROR A device error occurred. | |
@retval EFI_NOT_FOUND A requested recovery DXE capsule cannot be found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
LoadRecoveryCapsule ( | |
IN EFI_PEI_SERVICES **PeiServices, | |
IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This, | |
IN UINTN CapsuleInstance, | |
OUT VOID *Buffer | |
); | |
/** | |
This version is different from the version in Unicode collation | |
protocol in that this version strips off trailing blanks. | |
Converts an 8.3 FAT file name using an OEM character set | |
to a Null-terminated Unicode string. | |
Here does not expand DBCS FAT chars. | |
@param FatSize The size of the string Fat in bytes. | |
@param Fat A pointer to a Null-terminated string that contains | |
an 8.3 file name using an OEM character set. | |
@param Str A pointer to a Null-terminated Unicode string. The | |
string must be allocated in advance to hold FatSize | |
Unicode characters | |
**/ | |
VOID | |
EngFatToStr ( | |
IN UINTN FatSize, | |
IN CHAR8 *Fat, | |
OUT CHAR16 *Str | |
); | |
/** | |
Performs a case-insensitive comparison of two Null-terminated Unicode strings. | |
@param PrivateData Global memory map for accessing global variables | |
@param Str1 First string to perform case insensitive comparison. | |
@param Str2 Second string to perform case insensitive comparison. | |
**/ | |
BOOLEAN | |
EngStriColl ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN CHAR16 *Str1, | |
IN CHAR16 *Str2 | |
); | |
/** | |
Reads a block of data from the block device by calling | |
underlying Block I/O service. | |
@param PrivateData Global memory map for accessing global variables | |
@param BlockDeviceNo The index for the block device number. | |
@param Lba The logic block address to read data from. | |
@param BufferSize The size of data in byte to read. | |
@param Buffer The buffer of the | |
@retval EFI_DEVICE_ERROR The specified block device number exceeds the maximum | |
device number. | |
@retval EFI_DEVICE_ERROR The maximum address has exceeded the maximum address | |
of the block device. | |
**/ | |
EFI_STATUS | |
FatReadBlock ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN UINTN BlockDeviceNo, | |
IN EFI_PEI_LBA Lba, | |
IN UINTN BufferSize, | |
OUT VOID *Buffer | |
); | |
/** | |
Check if there is a valid FAT in the corresponding Block device | |
of the volume and if yes, fill in the relevant fields for the | |
volume structure. Note there should be a valid Block device number | |
already set. | |
@param PrivateData Global memory map for accessing global | |
variables. | |
@param Volume On input, the BlockDeviceNumber field of the | |
Volume should be a valid value. On successful | |
output, all fields except the VolumeNumber | |
field is initialized. | |
@retval EFI_SUCCESS A FAT is found and the volume structure is | |
initialized. | |
@retval EFI_NOT_FOUND There is no FAT on the corresponding device. | |
@retval EFI_DEVICE_ERROR There is something error while accessing device. | |
**/ | |
EFI_STATUS | |
FatGetBpbInfo ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN OUT PEI_FAT_VOLUME *Volume | |
); | |
/** | |
Gets the next cluster in the cluster chain. | |
@param PrivateData Global memory map for accessing global variables | |
@param Volume The volume | |
@param Cluster The cluster | |
@param NextCluster The cluster number of the next cluster | |
@retval EFI_SUCCESS The address is got | |
@retval EFI_INVALID_PARAMETER ClusterNo exceeds the MaxCluster of the volume. | |
@retval EFI_DEVICE_ERROR Read disk error | |
**/ | |
EFI_STATUS | |
FatGetNextCluster ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN PEI_FAT_VOLUME *Volume, | |
IN UINT32 Cluster, | |
OUT UINT32 *NextCluster | |
); | |
/** | |
Disk reading. | |
@param PrivateData the global memory map; | |
@param BlockDeviceNo the block device to read; | |
@param StartingAddress the starting address. | |
@param Size the amount of data to read. | |
@param Buffer the buffer holding the data | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_DEVICE_ERROR Something error. | |
**/ | |
EFI_STATUS | |
FatReadDisk ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN UINTN BlockDeviceNo, | |
IN UINT64 StartingAddress, | |
IN UINTN Size, | |
OUT VOID *Buffer | |
); | |
/** | |
Set a file's CurrentPos and CurrentCluster, then compute StraightReadAmount. | |
@param PrivateData the global memory map | |
@param File the file | |
@param Pos the Position which is offset from the file's | |
CurrentPos | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER Pos is beyond file's size. | |
@retval EFI_DEVICE_ERROR Something error while accessing media. | |
**/ | |
EFI_STATUS | |
FatSetFilePos ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN PEI_FAT_FILE *File, | |
IN UINT32 Pos | |
); | |
/** | |
Reads file data. Updates the file's CurrentPos. | |
@param PrivateData Global memory map for accessing global variables | |
@param File The file. | |
@param Size The amount of data to read. | |
@param Buffer The buffer storing the data. | |
@retval EFI_SUCCESS The data is read. | |
@retval EFI_INVALID_PARAMETER File is invalid. | |
@retval EFI_DEVICE_ERROR Something error while accessing media. | |
**/ | |
EFI_STATUS | |
FatReadFile ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN PEI_FAT_FILE *File, | |
IN UINTN Size, | |
OUT VOID *Buffer | |
); | |
/** | |
This function reads the next item in the parent directory and | |
initializes the output parameter SubFile (CurrentPos is initialized to 0). | |
The function updates the CurrentPos of the parent dir to after the item read. | |
If no more items were found, the function returns EFI_NOT_FOUND. | |
@param PrivateData Global memory map for accessing global variables | |
@param ParentDir The parent directory. | |
@param SubFile The File structure containing the sub file that | |
is caught. | |
@retval EFI_SUCCESS The next sub file is obtained. | |
@retval EFI_INVALID_PARAMETER The ParentDir is not a directory. | |
@retval EFI_NOT_FOUND No more sub file exists. | |
@retval EFI_DEVICE_ERROR Something error while accessing media. | |
**/ | |
EFI_STATUS | |
FatReadNextDirectoryEntry ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData, | |
IN PEI_FAT_FILE *ParentDir, | |
OUT PEI_FAT_FILE *SubFile | |
); | |
/** | |
This function finds partitions (logical devices) in physical block devices. | |
@param PrivateData Global memory map for accessing global variables. | |
**/ | |
VOID | |
FatFindPartitions ( | |
IN PEI_FAT_PRIVATE_DATA *PrivateData | |
); | |
#endif // _FAT_PEIM_H_ |