]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
index 804d5b0e42be372c284836584e5b243a8c184678..8e8f54ba3facfe558520b9835603337269e0a6fd 100644 (file)
@@ -2,14 +2,9 @@
 \r
   Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
   Copyright (C) 2013, Red Hat, Inc.\r
 \r
   Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
   Copyright (C) 2013, Red Hat, Inc.\r
+  Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
 \r
 \r
-  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
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
 **/\r
 \r
 \r
 #include "QemuFwCfgLibInternal.h"\r
 \r
 \r
 #include "QemuFwCfgLibInternal.h"\r
 \r
-\r
-/**\r
-  Reads an 8-bit I/O port fifo into a block of memory.\r
-\r
-  Reads the 8-bit I/O fifo port specified by Port.\r
-\r
-  The port is read Count times, and the read data is\r
-  stored in the provided Buffer.\r
-\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
-VOID\r
-EFIAPI\r
-IoReadFifo8 (\r
-  IN      UINTN                     Port,\r
-  IN      UINTN                     Count,\r
-  OUT     VOID                      *Buffer\r
-  );\r
-\r
-/**\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
-  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
-VOID\r
-EFIAPI\r
-IoWriteFifo8 (\r
-  IN      UINTN                     Port,\r
-  IN      UINTN                     Count,\r
-  OUT     VOID                      *Buffer\r
-  );\r
-\r
-\r
 /**\r
   Selects a firmware configuration item for reading.\r
 /**\r
   Selects a firmware configuration item for reading.\r
-  \r
+\r
   Following this call, any data read from this item will start from\r
   the beginning of the configuration item's data.\r
 \r
   Following this call, any data read from this item will start from\r
   the beginning of the configuration item's data.\r
 \r
@@ -90,14 +31,13 @@ IoWriteFifo8 (
 VOID\r
 EFIAPI\r
 QemuFwCfgSelectItem (\r
 VOID\r
 EFIAPI\r
 QemuFwCfgSelectItem (\r
-  IN FIRMWARE_CONFIG_ITEM   QemuFwCfgItem\r
+  IN FIRMWARE_CONFIG_ITEM  QemuFwCfgItem\r
   )\r
 {\r
   )\r
 {\r
-  DEBUG ((EFI_D_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));\r
-  IoWrite16 (0x510, (UINT16)(UINTN) QemuFwCfgItem);\r
+  DEBUG ((DEBUG_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN)QemuFwCfgItem));\r
+  IoWrite16 (FW_CFG_IO_SELECTOR, (UINT16)(UINTN)QemuFwCfgItem);\r
 }\r
 \r
 }\r
 \r
-\r
 /**\r
   Reads firmware configuration bytes into a buffer\r
 \r
 /**\r
   Reads firmware configuration bytes into a buffer\r
 \r
@@ -108,13 +48,17 @@ QemuFwCfgSelectItem (
 VOID\r
 EFIAPI\r
 InternalQemuFwCfgReadBytes (\r
 VOID\r
 EFIAPI\r
 InternalQemuFwCfgReadBytes (\r
-  IN UINTN                  Size,\r
-  IN VOID                   *Buffer  OPTIONAL\r
+  IN UINTN  Size,\r
+  IN VOID   *Buffer  OPTIONAL\r
   )\r
 {\r
   )\r
 {\r
-  IoReadFifo8 (0x511, Size, Buffer);\r
-}\r
+  if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) {\r
+    InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_READ);\r
+    return;\r
+  }\r
 \r
 \r
+  IoReadFifo8 (FW_CFG_IO_DATA, Size, Buffer);\r
+}\r
 \r
 /**\r
   Reads firmware configuration bytes into a buffer\r
 \r
 /**\r
   Reads firmware configuration bytes into a buffer\r
@@ -130,8 +74,8 @@ InternalQemuFwCfgReadBytes (
 VOID\r
 EFIAPI\r
 QemuFwCfgReadBytes (\r
 VOID\r
 EFIAPI\r
 QemuFwCfgReadBytes (\r
-  IN UINTN                  Size,\r
-  IN VOID                   *Buffer\r
+  IN UINTN  Size,\r
+  IN VOID   *Buffer\r
   )\r
 {\r
   if (InternalQemuFwCfgIsAvailable ()) {\r
   )\r
 {\r
   if (InternalQemuFwCfgIsAvailable ()) {\r
@@ -155,15 +99,62 @@ QemuFwCfgReadBytes (
 VOID\r
 EFIAPI\r
 QemuFwCfgWriteBytes (\r
 VOID\r
 EFIAPI\r
 QemuFwCfgWriteBytes (\r
-  IN UINTN                  Size,\r
-  IN VOID                   *Buffer\r
+  IN UINTN  Size,\r
+  IN VOID   *Buffer\r
   )\r
 {\r
   if (InternalQemuFwCfgIsAvailable ()) {\r
   )\r
 {\r
   if (InternalQemuFwCfgIsAvailable ()) {\r
-    IoWriteFifo8 (0x511, Size, Buffer);\r
+    if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) {\r
+      InternalQemuFwCfgDmaBytes ((UINT32)Size, Buffer, FW_CFG_DMA_CTL_WRITE);\r
+      return;\r
+    }\r
+\r
+    IoWriteFifo8 (FW_CFG_IO_DATA, Size, Buffer);\r
   }\r
 }\r
 \r
   }\r
 }\r
 \r
+/**\r
+  Skip bytes in the firmware configuration item.\r
+\r
+  Increase the offset of the firmware configuration item without transferring\r
+  bytes between the item and a caller-provided buffer. Subsequent read, write\r
+  or skip operations will commence at the increased offset.\r
+\r
+  @param[in] Size  Number of bytes to skip.\r
+**/\r
+VOID\r
+EFIAPI\r
+QemuFwCfgSkipBytes (\r
+  IN UINTN  Size\r
+  )\r
+{\r
+  UINTN  ChunkSize;\r
+  UINT8  SkipBuffer[256];\r
+\r
+  if (!InternalQemuFwCfgIsAvailable ()) {\r
+    return;\r
+  }\r
+\r
+  if (InternalQemuFwCfgDmaIsAvailable () && (Size <= MAX_UINT32)) {\r
+    InternalQemuFwCfgDmaBytes ((UINT32)Size, NULL, FW_CFG_DMA_CTL_SKIP);\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Emulate the skip by reading data in chunks, and throwing it away. The\r
+  // implementation below is suitable even for phases where RAM or dynamic\r
+  // allocation is not available or appropriate. It also doesn't affect the\r
+  // static data footprint for client modules. Large skips are not expected,\r
+  // therefore this fallback is not performance critical. The size of\r
+  // SkipBuffer is thought not to exert a large pressure on the stack in any\r
+  // phase.\r
+  //\r
+  while (Size > 0) {\r
+    ChunkSize = MIN (Size, sizeof SkipBuffer);\r
+    IoReadFifo8 (FW_CFG_IO_DATA, ChunkSize, SkipBuffer);\r
+    Size -= ChunkSize;\r
+  }\r
+}\r
 \r
 /**\r
   Reads a UINT8 firmware configuration value\r
 \r
 /**\r
   Reads a UINT8 firmware configuration value\r
@@ -177,14 +168,13 @@ QemuFwCfgRead8 (
   VOID\r
   )\r
 {\r
   VOID\r
   )\r
 {\r
-  UINT8 Result;\r
+  UINT8  Result;\r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
-\r
 /**\r
   Reads a UINT16 firmware configuration value\r
 \r
 /**\r
   Reads a UINT16 firmware configuration value\r
 \r
@@ -197,14 +187,13 @@ QemuFwCfgRead16 (
   VOID\r
   )\r
 {\r
   VOID\r
   )\r
 {\r
-  UINT16 Result;\r
+  UINT16  Result;\r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
-\r
 /**\r
   Reads a UINT32 firmware configuration value\r
 \r
 /**\r
   Reads a UINT32 firmware configuration value\r
 \r
@@ -217,14 +206,13 @@ QemuFwCfgRead32 (
   VOID\r
   )\r
 {\r
   VOID\r
   )\r
 {\r
-  UINT32 Result;\r
+  UINT32  Result;\r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
-\r
 /**\r
   Reads a UINT64 firmware configuration value\r
 \r
 /**\r
   Reads a UINT64 firmware configuration value\r
 \r
@@ -237,14 +225,13 @@ QemuFwCfgRead64 (
   VOID\r
   )\r
 {\r
   VOID\r
   )\r
 {\r
-  UINT64 Result;\r
+  UINT64  Result;\r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
 \r
   QemuFwCfgReadBytes (sizeof (Result), &Result);\r
 \r
   return Result;\r
 }\r
 \r
-\r
 /**\r
   Find the configuration item corresponding to the firmware configuration file.\r
 \r
 /**\r
   Find the configuration item corresponding to the firmware configuration file.\r
 \r
@@ -266,8 +253,8 @@ QemuFwCfgFindFile (
   OUT  UINTN                 *Size\r
   )\r
 {\r
   OUT  UINTN                 *Size\r
   )\r
 {\r
-  UINT32 Count;\r
-  UINT32 Idx;\r
+  UINT32  Count;\r
+  UINT32  Idx;\r
 \r
   if (!InternalQemuFwCfgIsAvailable ()) {\r
     return RETURN_UNSUPPORTED;\r
 \r
   if (!InternalQemuFwCfgIsAvailable ()) {\r
     return RETURN_UNSUPPORTED;\r
@@ -277,15 +264,15 @@ QemuFwCfgFindFile (
   Count = SwapBytes32 (QemuFwCfgRead32 ());\r
 \r
   for (Idx = 0; Idx < Count; ++Idx) {\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
+    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
 \r
     FileSize     = QemuFwCfgRead32 ();\r
     FileSelect   = QemuFwCfgRead16 ();\r
     FileReserved = QemuFwCfgRead16 ();\r
-    (VOID) FileReserved; /* Force a do-nothing reference. */\r
+    (VOID)FileReserved;  /* Force a do-nothing reference. */\r
     InternalQemuFwCfgReadBytes (sizeof (FName), FName);\r
 \r
     if (AsciiStrCmp (Name, FName) == 0) {\r
     InternalQemuFwCfgReadBytes (sizeof (FName), FName);\r
 \r
     if (AsciiStrCmp (Name, FName) == 0) {\r
@@ -297,31 +284,3 @@ QemuFwCfgFindFile (
 \r
   return RETURN_NOT_FOUND;\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