]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/FwVol/Ffs.c
Check in DxeCore for Nt32 platform. Currently, it does not follow PI/UEFI2.1.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVol / Ffs.c
diff --git a/MdeModulePkg/Core/Dxe/FwVol/Ffs.c b/MdeModulePkg/Core/Dxe/FwVol/Ffs.c
new file mode 100644 (file)
index 0000000..23c84b3
--- /dev/null
@@ -0,0 +1,266 @@
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation                                                         \r
+All rights reserved. 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
+Module Name:\r
+\r
+  Ffs.c\r
+\r
+Abstract:\r
+\r
+  FFS file access utilities.\r
+\r
+--*/\r
+\r
+\r
+#include <DxeMain.h>\r
+\r
+#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *)((UINTN)(Address)))\r
+\r
+\r
+EFI_FFS_FILE_STATE\r
+GetFileState (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Get the FFS file state by checking the highest bit set in the header's state field\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  FfsHeader     -  Points to the FFS file header\r
+    \r
+Returns:\r
+  FFS File state \r
+    \r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE      FileState;\r
+  UINT8                   HighestBit;\r
+\r
+  FileState = FfsHeader->State;\r
+\r
+  if (ErasePolarity != 0) {\r
+    FileState = (EFI_FFS_FILE_STATE)~FileState;\r
+  }\r
+\r
+  HighestBit = 0x80;\r
+  while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {\r
+    HighestBit >>= 1;\r
+  }\r
+\r
+  return (EFI_FFS_FILE_STATE)HighestBit;\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsBufferErased (\r
+  IN UINT8    ErasePolarity,\r
+  IN VOID     *InBuffer,\r
+  IN UINTN    BufferSize\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if a block of buffer is erased\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  InBuffer      -  The buffer to be checked\r
+  BufferSize    -  Size of the buffer in bytes\r
+    \r
+Returns:\r
+  TRUE  -  The block of buffer is erased\r
+  FALSE -  The block of buffer is not erased\r
+    \r
+--*/\r
+{\r
+  UINTN   Count;\r
+  UINT8   EraseByte;\r
+  UINT8   *Buffer;\r
+\r
+  if(ErasePolarity == 1) {\r
+    EraseByte = 0xFF;\r
+  } else {\r
+    EraseByte = 0;\r
+  }\r
+\r
+  Buffer = InBuffer;\r
+  for (Count = 0; Count < BufferSize; Count++) {\r
+    if (Buffer[Count] != EraseByte) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+\r
+BOOLEAN\r
+VerifyFvHeaderChecksum (\r
+  IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Verify checksum of the firmware volume header \r
+\r
+Arguments:\r
+  FvHeader  -  Points to the firmware volume header to be checked\r
+    \r
+Returns:\r
+  TRUE  -  Checksum verification passed\r
+  FALSE -  Checksum verification failed\r
+    \r
+--*/\r
+{\r
+  UINT32  Index;\r
+  UINT32  HeaderLength;\r
+  UINT16  Checksum;\r
+  UINT16  *ptr;\r
+\r
+  HeaderLength = FvHeader->HeaderLength;\r
+  ptr = (UINT16 *)FvHeader;\r
+  Checksum = 0;\r
+\r
+  for (Index = 0; Index < HeaderLength / sizeof (UINT16); Index++) {\r
+    Checksum = (UINT16)(Checksum + ptr[Index]);\r
+  }\r
+\r
+  if (Checksum == 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+STATIC\r
+BOOLEAN\r
+VerifyHeaderChecksum (\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Verify checksum of the FFS file header \r
+\r
+Arguments:\r
+  FfsHeader  -  Points to the FFS file header to be checked\r
+    \r
+Returns:\r
+  TRUE  -  Checksum verification passed\r
+  FALSE -  Checksum verification failed\r
+    \r
+--*/\r
+{\r
+  UINT32            Index;\r
+  UINT8             *ptr;\r
+  UINT8             HeaderChecksum;\r
+\r
+  ptr = (UINT8 *)FfsHeader;\r
+  HeaderChecksum = 0;\r
+  for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {\r
+    HeaderChecksum = (UINT8)(HeaderChecksum + ptr[Index]);\r
+  }\r
+\r
+  HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);\r
+\r
+  if (HeaderChecksum == 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsValidFfsHeader (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader,\r
+  OUT EFI_FFS_FILE_STATE  *FileState\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if it's a valid FFS file header\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  FfsHeader     -  Points to the FFS file header to be checked\r
+  FileState     -  FFS file state to be returned\r
+    \r
+Returns:\r
+  TRUE  -  Valid FFS file header\r
+  FALSE -  Invalid FFS file header\r
+    \r
+--*/\r
+{\r
+  *FileState = GetFileState (ErasePolarity, FfsHeader);\r
+\r
+  switch (*FileState) {\r
+    case EFI_FILE_HEADER_VALID:\r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+    case EFI_FILE_DELETED:\r
+      //\r
+      // Here we need to verify header checksum\r
+      //\r
+      return VerifyHeaderChecksum (FfsHeader);\r
+    \r
+    case EFI_FILE_HEADER_CONSTRUCTION:\r
+    case EFI_FILE_HEADER_INVALID:\r
+    default:\r
+      return FALSE;\r
+  }\r
+}\r
+\r
+\r
+BOOLEAN\r
+IsValidFfsFile (\r
+  IN UINT8                ErasePolarity,\r
+  IN EFI_FFS_FILE_HEADER  *FfsHeader\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+  Check if it's a valid FFS file. \r
+  Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.\r
+\r
+Arguments:\r
+  ErasePolarity -  Erase polarity attribute of the firmware volume\r
+  FfsHeader     -  Points to the FFS file to be checked\r
+    \r
+Returns:\r
+  TRUE  -  Valid FFS file\r
+  FALSE -  Invalid FFS file\r
+    \r
+--*/\r
+{\r
+  EFI_FFS_FILE_STATE  FileState;\r
+\r
+  FileState = GetFileState (ErasePolarity, FfsHeader);\r
+  switch (FileState) {\r
+\r
+    case EFI_FILE_DELETED:\r
+    case EFI_FILE_DATA_VALID:\r
+    case EFI_FILE_MARKED_FOR_UPDATE:\r
+      //\r
+      // Some other vliadation like file content checksum might be done here.\r
+      // For performance issue, Tiano only do FileState check.\r
+      //\r
+      return TRUE;\r
+\r
+    default:\r
+      return FALSE;\r
+  }\r
+}\r
+\r