]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
SecurityPkg: Make time based AuthVariable update atomic
[mirror_edk2.git] / OvmfPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
index b94dc67392882464d91fc479fcfab0bd8501dc25..24424f83a986ab39f4596b7f771b8b6f562337b9 100644 (file)
@@ -1,6 +1,7 @@
 /** @file\r
 \r
-  Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (C) 2013, Red Hat, Inc.\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -21,8 +22,6 @@
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 \r
-STATIC BOOLEAN mQemuFwCfgSupported = FALSE;\r
-\r
 \r
 /**\r
   Reads an 8-bit I/O port fifo into a block of memory.\r
@@ -50,23 +49,31 @@ IoReadFifo8 (
   OUT     VOID                      *Buffer\r
   );\r
 \r
-\r
 /**\r
-  Returns a boolean indicating if the firmware configuration interface\r
-  is available or not.\r
+  Writes an 8-bit I/O port fifo from a block of memory.\r
+\r
+  Writes the 8-bit I/O fifo port specified by Port.\r
+\r
+  The port is written Count times, and the data are obtained\r
+  from the provided Buffer.\r
 \r
-  @retval    TRUE   The interface is available\r
-  @retval    FALSE  The interface is not available\r
+  This function must guarantee that all I/O read and write operations are\r
+  serialized.\r
+\r
+  If 8-bit I/O port operations are not supported, then ASSERT().\r
+\r
+  @param  Port    The I/O port to read.\r
+  @param  Count   The number of times to read I/O port.\r
+  @param  Buffer  The buffer to store the read data into.\r
 \r
 **/\r
-BOOLEAN\r
+VOID\r
 EFIAPI\r
-QemuFwCfgIsAvailable (\r
-  VOID\r
-  )\r
-{\r
-  return mQemuFwCfgSupported;\r
-}\r
+IoWriteFifo8 (\r
+  IN      UINTN                     Port,\r
+  IN      UINTN                     Count,\r
+  OUT     VOID                      *Buffer\r
+  );\r
 \r
 \r
 /**\r
@@ -125,13 +132,36 @@ QemuFwCfgReadBytes (
   IN VOID                   *Buffer\r
   )\r
 {\r
-  if (mQemuFwCfgSupported) {\r
+  if (InternalQemuFwCfgIsAvailable ()) {\r
     InternalQemuFwCfgReadBytes (Size, Buffer);\r
   } else {\r
     ZeroMem (Buffer, Size);\r
   }\r
 }\r
 \r
+/**\r
+  Write firmware configuration bytes from a buffer\r
+\r
+  If called multiple times, then the data written will\r
+  continue at the offset of the firmware configuration\r
+  item where the previous write ended.\r
+\r
+  @param[in] Size - Size in bytes to write\r
+  @param[in] Buffer - Buffer to read data from\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QemuFwCfgWriteBytes (\r
+  IN UINTN                  Size,\r
+  IN VOID                   *Buffer\r
+  )\r
+{\r
+  if (InternalQemuFwCfgIsAvailable ()) {\r
+    IoWriteFifo8 (0x511, Size, Buffer);\r
+  }\r
+}\r
+\r
 \r
 /**\r
   Reads a UINT8 firmware configuration value\r
@@ -213,34 +243,82 @@ QemuFwCfgRead64 (
 }\r
 \r
 \r
+/**\r
+  Find the configuration item corresponding to the firmware configuration file.\r
+\r
+  @param[in]  Name - Name of file to look up.\r
+  @param[out] Item - Configuration item corresponding to the file, to be passed\r
+                     to QemuFwCfgSelectItem ().\r
+  @param[out] Size - Number of bytes in the file.\r
+\r
+  @return    RETURN_SUCCESS       If file is found.\r
+             RETURN_NOT_FOUND     If file is not found.\r
+             RETURN_UNSUPPORTED   If firmware configuration is unavailable.\r
+\r
+**/\r
 RETURN_STATUS\r
 EFIAPI\r
-QemuFwCfgInitialize (\r
-  VOID\r
+QemuFwCfgFindFile (\r
+  IN   CONST CHAR8           *Name,\r
+  OUT  FIRMWARE_CONFIG_ITEM  *Item,\r
+  OUT  UINTN                 *Size\r
   )\r
 {\r
-  UINT32 Signature;\r
-  UINT32 Revision;\r
-\r
-  //\r
-  // Enable the access routines while probing to see if it is supported.\r
-  //\r
-  mQemuFwCfgSupported = TRUE;\r
-\r
-  QemuFwCfgSelectItem (QemuFwCfgItemSignature);\r
-  Signature = QemuFwCfgRead32 ();\r
-  DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));\r
-  QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);\r
-  Revision = QemuFwCfgRead32 ();\r
-  DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));\r
-  if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||\r
-      (Revision < 1)\r
-     ) {\r
-    DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));\r
-    mQemuFwCfgSupported = FALSE;\r
-    return RETURN_SUCCESS;\r
+  UINT32 Count;\r
+  UINT32 Idx;\r
+\r
+  if (!InternalQemuFwCfgIsAvailable ()) {\r
+    return RETURN_UNSUPPORTED;\r
   }\r
 \r
-  DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n"));\r
-  return RETURN_SUCCESS;\r
+  QemuFwCfgSelectItem (QemuFwCfgItemFileDir);\r
+  Count = SwapBytes32 (QemuFwCfgRead32 ());\r
+\r
+  for (Idx = 0; Idx < Count; ++Idx) {\r
+    UINT32 FileSize;\r
+    UINT16 FileSelect;\r
+    UINT16 FileReserved;\r
+    CHAR8  FName[QEMU_FW_CFG_FNAME_SIZE];\r
+\r
+    FileSize     = QemuFwCfgRead32 ();\r
+    FileSelect   = QemuFwCfgRead16 ();\r
+    FileReserved = QemuFwCfgRead16 ();\r
+    InternalQemuFwCfgReadBytes (sizeof (FName), FName);\r
+\r
+    if (AsciiStrCmp (Name, FName) == 0) {\r
+      *Item = SwapBytes16 (FileSelect);\r
+      *Size = SwapBytes32 (FileSize);\r
+      return RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return RETURN_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+  Determine if S3 support is explicitly enabled.\r
+\r
+  @retval  TRUE   if S3 support is explicitly enabled.\r
+           FALSE  otherwise. This includes unavailability of the firmware\r
+                  configuration interface.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QemuFwCfgS3Enabled (\r
+  VOID\r
+  )\r
+{\r
+  RETURN_STATUS        Status;\r
+  FIRMWARE_CONFIG_ITEM FwCfgItem;\r
+  UINTN                FwCfgSize;\r
+  UINT8                SystemStates[6];\r
+\r
+  Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);\r
+  if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {\r
+    return FALSE;\r
+  }\r
+  QemuFwCfgSelectItem (FwCfgItem);\r
+  QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);\r
+  return (BOOLEAN) (SystemStates[3] & BIT7);\r
 }\r