Home | History | Annotate | Download | only in FatPei
      1 /** @file
      2   Data structures for FAT recovery PEIM
      3 
      4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
      5 
      6 This program and the accompanying materials are licensed and made available
      7 under the terms and conditions of the BSD License which accompanies this
      8 distribution. The full text of the license may be found at
      9 http://opensource.org/licenses/bsd-license.php
     10 
     11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #ifndef _FAT_PEIM_H_
     17 #define _FAT_PEIM_H_
     18 
     19 #include <PiPei.h>
     20 
     21 #include <Guid/RecoveryDevice.h>
     22 #include <Ppi/BlockIo.h>
     23 #include <Ppi/BlockIo2.h>
     24 #include <Ppi/DeviceRecoveryModule.h>
     25 
     26 #include <Library/DebugLib.h>
     27 #include <Library/BaseLib.h>
     28 #include <Library/PeimEntryPoint.h>
     29 #include <Library/BaseMemoryLib.h>
     30 #include <Library/PcdLib.h>
     31 #include <Library/PeiServicesTablePointerLib.h>
     32 #include <Library/PeiServicesLib.h>
     33 
     34 #include "FatLiteApi.h"
     35 #include "FatLiteFmt.h"
     36 
     37 //
     38 // Definitions
     39 //
     40 
     41 #define PEI_FAT_CACHE_SIZE                            4
     42 #define PEI_FAT_MAX_BLOCK_SIZE                        8192
     43 #define FAT_MAX_FILE_NAME_LENGTH                      128
     44 #define PEI_FAT_MAX_BLOCK_DEVICE                      64
     45 #define PEI_FAT_MAX_BLOCK_IO_PPI                      32
     46 #define PEI_FAT_MAX_VOLUME                            64
     47 
     48 #define PEI_FAT_MEMMORY_PAGE_SIZE                     0x1000
     49 
     50 //
     51 // Data Structures
     52 //
     53 //
     54 // The block device
     55 //
     56 typedef struct {
     57 
     58   UINT32                        BlockSize;
     59   UINT64                        LastBlock;
     60   UINT32                        IoAlign;
     61   BOOLEAN                       Logical;
     62   BOOLEAN                       PartitionChecked;
     63 
     64   //
     65   // Following fields only valid for logical device
     66   //
     67   CHAR8                         PartitionFlag[8];
     68   UINT64                        StartingPos;
     69   UINTN                         ParentDevNo;
     70 
     71   //
     72   // Following fields only valid for physical device
     73   //
     74   EFI_PEI_BLOCK_DEVICE_TYPE     DevType;
     75   UINT8                         InterfaceType;
     76   //
     77   // EFI_PEI_READ_BLOCKS         ReadFunc;
     78   //
     79   EFI_PEI_RECOVERY_BLOCK_IO_PPI  *BlockIo;
     80   EFI_PEI_RECOVERY_BLOCK_IO2_PPI *BlockIo2;
     81   UINT8                          PhysicalDevNo;
     82 } PEI_FAT_BLOCK_DEVICE;
     83 
     84 //
     85 // the Volume structure
     86 //
     87 typedef struct {
     88 
     89   UINTN         BlockDeviceNo;
     90   UINTN         VolumeNo;
     91   UINT64        VolumeSize;
     92   UINTN         MaxCluster;
     93   CHAR16        VolumeLabel[FAT_MAX_FILE_NAME_LENGTH];
     94   PEI_FAT_TYPE  FatType;
     95   UINT64        FatPos;
     96   UINT32        SectorSize;
     97   UINT32        ClusterSize;
     98   UINT64        FirstClusterPos;
     99   UINT64        RootDirPos;
    100   UINT32        RootEntries;
    101   UINT32        RootDirCluster;
    102 
    103 } PEI_FAT_VOLUME;
    104 
    105 //
    106 // File instance
    107 //
    108 typedef struct {
    109 
    110   PEI_FAT_VOLUME  *Volume;
    111   CHAR16          FileName[FAT_MAX_FILE_NAME_LENGTH];
    112 
    113   BOOLEAN         IsFixedRootDir;
    114 
    115   UINT32          StartingCluster;
    116   UINT32          CurrentPos;
    117   UINT32          StraightReadAmount;
    118   UINT32          CurrentCluster;
    119 
    120   UINT8           Attributes;
    121   UINT32          FileSize;
    122 
    123 } PEI_FAT_FILE;
    124 
    125 //
    126 // Cache Buffer
    127 //
    128 typedef struct {
    129 
    130   BOOLEAN Valid;
    131   UINTN   BlockDeviceNo;
    132   UINT64  Lba;
    133   UINT32  Lru;
    134   UINT64  Buffer[PEI_FAT_MAX_BLOCK_SIZE / 8];
    135   UINTN   Size;
    136 
    137 } PEI_FAT_CACHE_BUFFER;
    138 
    139 //
    140 // Private Data.
    141 // This structure abstracts the whole memory usage in FAT PEIM.
    142 // The entry point routine will get a chunk of memory (by whatever
    143 // means) whose size is sizeof(PEI_FAT_PRIVATE_DATA), which is clean
    144 // in both 32 and 64 bit environment. The boundary of the memory chunk
    145 // should be 64bit aligned.
    146 //
    147 #define PEI_FAT_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('p', 'f', 'a', 't')
    148 
    149 typedef struct {
    150 
    151   UINTN                               Signature;
    152   EFI_PEI_DEVICE_RECOVERY_MODULE_PPI  DeviceRecoveryPpi;
    153   EFI_PEI_PPI_DESCRIPTOR              PpiDescriptor;
    154   EFI_PEI_NOTIFY_DESCRIPTOR           NotifyDescriptor[2];
    155 
    156   UINT8                               UnicodeCaseMap[0x300];
    157   CHAR8                               *EngUpperMap;
    158   CHAR8                               *EngLowerMap;
    159   CHAR8                               *EngInfoMap;
    160 
    161   UINT64                              BlockData[PEI_FAT_MAX_BLOCK_SIZE / 8];
    162   UINTN                               BlockDeviceCount;
    163   PEI_FAT_BLOCK_DEVICE                BlockDevice[PEI_FAT_MAX_BLOCK_DEVICE];
    164   UINTN                               VolumeCount;
    165   PEI_FAT_VOLUME                      Volume[PEI_FAT_MAX_VOLUME];
    166   PEI_FAT_FILE                        File;
    167   PEI_FAT_CACHE_BUFFER                CacheBuffer[PEI_FAT_CACHE_SIZE];
    168 
    169 } PEI_FAT_PRIVATE_DATA;
    170 
    171 #define PEI_FAT_PRIVATE_DATA_FROM_THIS(a) \
    172   CR (a,  PEI_FAT_PRIVATE_DATA, DeviceRecoveryPpi, PEI_FAT_PRIVATE_DATA_SIGNATURE)
    173 
    174 //
    175 // Extract INT32 from char array
    176 //
    177 #define UNPACK_INT32(a) \
    178   (INT32) ((((UINT8 *) a)[0] << 0) | (((UINT8 *) a)[1] << 8) | (((UINT8 *) a)[2] << 16) | (((UINT8 *) a)[3] << 24))
    179 
    180 //
    181 // Extract UINT32 from char array
    182 //
    183 #define UNPACK_UINT32(a) \
    184   (UINT32) ((((UINT8 *) a)[0] << 0) | (((UINT8 *) a)[1] << 8) | (((UINT8 *) a)[2] << 16) | (((UINT8 *) a)[3] << 24))
    185 
    186 
    187 //
    188 // API functions
    189 //
    190 
    191 /**
    192   Finds the recovery file on a FAT volume.
    193   This function finds the the recovery file named FileName on a specified FAT volume and returns
    194   its FileHandle pointer.
    195 
    196   @param  PrivateData             Global memory map for accessing global
    197                                   variables.
    198   @param  VolumeIndex             The index of the volume.
    199   @param  FileName                The recovery file name to find.
    200   @param  Handle                  The output file handle.
    201 
    202   @retval EFI_DEVICE_ERROR        Some error occured when operating the FAT
    203                                   volume.
    204   @retval EFI_NOT_FOUND           The recovery file was not found.
    205   @retval EFI_SUCCESS             The recovery file was successfully found on the
    206                                   FAT volume.
    207 
    208 **/
    209 EFI_STATUS
    210 FindRecoveryFile (
    211   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    212   IN  UINTN                 VolumeIndex,
    213   IN  CHAR16                *FileName,
    214   OUT PEI_FILE_HANDLE       *Handle
    215   );
    216 
    217 
    218 /**
    219   Returns the number of DXE capsules residing on the device.
    220   This function, by whatever mechanism, searches for DXE capsules from the associated device and
    221   returns the number and maximum size in bytes of the capsules discovered.Entry 1 is assumed to be
    222   the highest load priority and entry N is assumed to be the lowest priority.
    223 
    224   @param  PeiServices             General-purpose services that are available to
    225                                   every PEIM.
    226   @param  This                    Indicates the
    227                                   EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance.
    228   @param  NumberRecoveryCapsules  Pointer to a caller-allocated UINTN.On output,
    229                                   *NumberRecoveryCapsules contains the number of
    230                                   recovery capsule images available for retrieval
    231                                   from this PEIM instance.
    232 
    233   @retval EFI_SUCCESS             The function completed successfully.
    234 
    235 **/
    236 EFI_STATUS
    237 EFIAPI
    238 GetNumberRecoveryCapsules (
    239   IN EFI_PEI_SERVICES                               **PeiServices,
    240   IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI             *This,
    241   OUT UINTN                                         *NumberRecoveryCapsules
    242   );
    243 
    244 
    245 /**
    246   Returns the size and type of the requested recovery capsule.
    247   This function returns the size and type of the capsule specified by CapsuleInstance.
    248 
    249   @param  PeiServices             General-purpose services that are available to
    250                                   every PEIM.
    251   @param  This                    Indicates the
    252                                   EFI_PEI_DEVICE_RECOVERY_MODULE_PPI instance.
    253   @param  CapsuleInstance         Specifies for which capsule instance to
    254                                   retrieve the information.T his parameter must
    255                                   be between one and the value returned by
    256                                   GetNumberRecoveryCapsules() in
    257                                   NumberRecoveryCapsules.
    258   @param  Size                    A pointer to a caller-allocated UINTN in which
    259                                   the size of the requested recovery module is
    260                                   returned.
    261   @param  CapsuleType             A pointer to a caller-allocated EFI_GUID in
    262                                   which the type of the requested recovery
    263                                   capsule is returned.T he semantic meaning of
    264                                   the value returned is defined by the
    265                                   implementation.
    266 
    267   @retval EFI_SUCCESS             The capsule type and size were retrieved.
    268   @retval EFI_INVALID_PARAMETER   The input CapsuleInstance does not match any
    269                                   discovered recovery capsule.
    270 
    271 **/
    272 EFI_STATUS
    273 EFIAPI
    274 GetRecoveryCapsuleInfo (
    275   IN  EFI_PEI_SERVICES                              **PeiServices,
    276   IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI            *This,
    277   IN  UINTN                                         CapsuleInstance,
    278   OUT UINTN                                         *Size,
    279   OUT EFI_GUID                                      *CapsuleType
    280   );
    281 
    282 
    283 /**
    284   Loads a DXE capsule from some media into memory.
    285 
    286   This function, by whatever mechanism, retrieves a DXE capsule from some device
    287   and loads it into memory. Note that the published interface is device neutral.
    288 
    289   @param[in]     PeiServices       General-purpose services that are available
    290                                    to every PEIM
    291   @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
    292                                    instance.
    293   @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.
    294   @param[out]    Buffer            Specifies a caller-allocated buffer in which
    295                                    the requested recovery capsule will be returned.
    296 
    297   @retval EFI_SUCCESS        The capsule was loaded correctly.
    298   @retval EFI_DEVICE_ERROR   A device error occurred.
    299   @retval EFI_NOT_FOUND      A requested recovery DXE capsule cannot be found.
    300 
    301 **/
    302 EFI_STATUS
    303 EFIAPI
    304 LoadRecoveryCapsule (
    305   IN EFI_PEI_SERVICES                             **PeiServices,
    306   IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI           *This,
    307   IN UINTN                                        CapsuleInstance,
    308   OUT VOID                                        *Buffer
    309   );
    310 
    311 
    312 /**
    313   This version is different from the version in Unicode collation
    314   protocol in that this version strips off trailing blanks.
    315   Converts an 8.3 FAT file name using an OEM character set
    316   to a Null-terminated Unicode string.
    317   Here does not expand DBCS FAT chars.
    318 
    319   @param  FatSize           The size of the string Fat in bytes.
    320   @param  Fat               A pointer to a Null-terminated string that contains
    321                             an 8.3 file name using an OEM character set.
    322   @param  Str               A pointer to a Null-terminated Unicode string. The
    323                             string must be allocated in advance to hold FatSize
    324                             Unicode characters
    325 
    326 **/
    327 VOID
    328 EngFatToStr (
    329   IN UINTN                            FatSize,
    330   IN CHAR8                            *Fat,
    331   OUT CHAR16                          *Str
    332   );
    333 
    334 
    335 /**
    336   Performs a case-insensitive comparison of two Null-terminated Unicode strings.
    337 
    338   @param  PrivateData       Global memory map for accessing global variables
    339   @param  Str1              First string to perform case insensitive comparison.
    340   @param  Str2              Second string to perform case insensitive comparison.
    341 
    342 **/
    343 BOOLEAN
    344 EngStriColl (
    345   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    346   IN CHAR16                 *Str1,
    347   IN CHAR16                 *Str2
    348   );
    349 
    350 
    351 /**
    352   Reads a block of data from the block device by calling
    353   underlying Block I/O service.
    354 
    355   @param  PrivateData       Global memory map for accessing global variables
    356   @param  BlockDeviceNo     The index for the block device number.
    357   @param  Lba               The logic block address to read data from.
    358   @param  BufferSize        The size of data in byte to read.
    359   @param  Buffer            The buffer of the
    360 
    361   @retval EFI_DEVICE_ERROR  The specified block device number exceeds the maximum
    362                             device number.
    363   @retval EFI_DEVICE_ERROR  The maximum address has exceeded the maximum address
    364                             of the block device.
    365 
    366 **/
    367 EFI_STATUS
    368 FatReadBlock (
    369   IN  PEI_FAT_PRIVATE_DATA   *PrivateData,
    370   IN  UINTN                  BlockDeviceNo,
    371   IN  EFI_PEI_LBA            Lba,
    372   IN  UINTN                  BufferSize,
    373   OUT VOID                   *Buffer
    374   );
    375 
    376 
    377 /**
    378   Check if there is a valid FAT in the corresponding Block device
    379   of the volume and if yes, fill in the relevant fields for the
    380   volume structure. Note there should be a valid Block device number
    381   already set.
    382 
    383   @param  PrivateData            Global memory map for accessing global
    384                                  variables.
    385   @param  Volume                 On input, the BlockDeviceNumber field of the
    386                                  Volume  should be a valid value. On successful
    387                                  output, all  fields except the VolumeNumber
    388                                  field is initialized.
    389 
    390   @retval EFI_SUCCESS            A FAT is found and the volume structure is
    391                                  initialized.
    392   @retval EFI_NOT_FOUND          There is no FAT on the corresponding device.
    393   @retval EFI_DEVICE_ERROR       There is something error while accessing device.
    394 
    395 **/
    396 EFI_STATUS
    397 FatGetBpbInfo (
    398   IN      PEI_FAT_PRIVATE_DATA  *PrivateData,
    399   IN OUT  PEI_FAT_VOLUME        *Volume
    400   );
    401 
    402 
    403 /**
    404   Gets the next cluster in the cluster chain.
    405 
    406   @param  PrivateData            Global memory map for accessing global variables
    407   @param  Volume                 The volume
    408   @param  Cluster                The cluster
    409   @param  NextCluster            The cluster number of the next cluster
    410 
    411   @retval EFI_SUCCESS            The address is got
    412   @retval EFI_INVALID_PARAMETER  ClusterNo exceeds the MaxCluster of the volume.
    413   @retval EFI_DEVICE_ERROR       Read disk error
    414 
    415 **/
    416 EFI_STATUS
    417 FatGetNextCluster (
    418   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    419   IN  PEI_FAT_VOLUME        *Volume,
    420   IN  UINT32                Cluster,
    421   OUT UINT32                *NextCluster
    422   );
    423 
    424 
    425 /**
    426   Disk reading.
    427 
    428   @param  PrivateData       the global memory map;
    429   @param  BlockDeviceNo     the block device to read;
    430   @param  StartingAddress   the starting address.
    431   @param  Size              the amount of data to read.
    432   @param  Buffer            the buffer holding the data
    433 
    434   @retval EFI_SUCCESS       The function completed successfully.
    435   @retval EFI_DEVICE_ERROR  Something error.
    436 
    437 **/
    438 EFI_STATUS
    439 FatReadDisk (
    440   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    441   IN  UINTN                 BlockDeviceNo,
    442   IN  UINT64                StartingAddress,
    443   IN  UINTN                 Size,
    444   OUT VOID                  *Buffer
    445   );
    446 
    447 
    448 /**
    449   Set a file's CurrentPos and CurrentCluster, then compute StraightReadAmount.
    450 
    451   @param  PrivateData            the global memory map
    452   @param  File                   the file
    453   @param  Pos                    the Position which is offset from the file's
    454                                  CurrentPos
    455 
    456   @retval EFI_SUCCESS            Success.
    457   @retval EFI_INVALID_PARAMETER  Pos is beyond file's size.
    458   @retval EFI_DEVICE_ERROR       Something error while accessing media.
    459 
    460 **/
    461 EFI_STATUS
    462 FatSetFilePos (
    463   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    464   IN  PEI_FAT_FILE          *File,
    465   IN  UINT32                Pos
    466   );
    467 
    468 
    469 /**
    470   Reads file data. Updates the file's CurrentPos.
    471 
    472   @param  PrivateData            Global memory map for accessing global variables
    473   @param  File                   The file.
    474   @param  Size                   The amount of data to read.
    475   @param  Buffer                 The buffer storing the data.
    476 
    477   @retval EFI_SUCCESS            The data is read.
    478   @retval EFI_INVALID_PARAMETER  File is invalid.
    479   @retval EFI_DEVICE_ERROR       Something error while accessing media.
    480 
    481 **/
    482 EFI_STATUS
    483 FatReadFile (
    484   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    485   IN  PEI_FAT_FILE          *File,
    486   IN  UINTN                 Size,
    487   OUT VOID                  *Buffer
    488   );
    489 
    490 
    491 /**
    492   This function reads the next item in the parent directory and
    493   initializes the output parameter SubFile (CurrentPos is initialized to 0).
    494   The function updates the CurrentPos of the parent dir to after the item read.
    495   If no more items were found, the function returns EFI_NOT_FOUND.
    496 
    497   @param  PrivateData            Global memory map for accessing global variables
    498   @param  ParentDir              The parent directory.
    499   @param  SubFile                The File structure containing the sub file that
    500                                  is caught.
    501 
    502   @retval EFI_SUCCESS            The next sub file is obtained.
    503   @retval EFI_INVALID_PARAMETER  The ParentDir is not a directory.
    504   @retval EFI_NOT_FOUND          No more sub file exists.
    505   @retval EFI_DEVICE_ERROR       Something error while accessing media.
    506 
    507 **/
    508 EFI_STATUS
    509 FatReadNextDirectoryEntry (
    510   IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
    511   IN  PEI_FAT_FILE          *ParentDir,
    512   OUT PEI_FAT_FILE          *SubFile
    513   );
    514 
    515 
    516 /**
    517   This function finds partitions (logical devices) in physical block devices.
    518 
    519   @param  PrivateData       Global memory map for accessing global variables.
    520 
    521 **/
    522 VOID
    523 FatFindPartitions (
    524   IN  PEI_FAT_PRIVATE_DATA  *PrivateData
    525   );
    526 
    527 #endif // _FAT_PEIM_H_
    528