Home | History | Annotate | Download | only in QemuFwCfgLib
      1 /** @file
      2 
      3   Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
      4   Copyright (C) 2013, Red Hat, Inc.
      5 
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this 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 #include "Uefi.h"
     17 #include <Library/BaseLib.h>
     18 #include <Library/BaseMemoryLib.h>
     19 #include <Library/DebugLib.h>
     20 #include <Library/IoLib.h>
     21 #include <Library/QemuFwCfgLib.h>
     22 #include <Library/MemoryAllocationLib.h>
     23 #include <Library/UefiBootServicesTableLib.h>
     24 
     25 
     26 /**
     27   Reads an 8-bit I/O port fifo into a block of memory.
     28 
     29   Reads the 8-bit I/O fifo port specified by Port.
     30 
     31   The port is read Count times, and the read data is
     32   stored in the provided Buffer.
     33 
     34   This function must guarantee that all I/O read and write operations are
     35   serialized.
     36 
     37   If 8-bit I/O port operations are not supported, then ASSERT().
     38 
     39   @param  Port    The I/O port to read.
     40   @param  Count   The number of times to read I/O port.
     41   @param  Buffer  The buffer to store the read data into.
     42 
     43 **/
     44 VOID
     45 EFIAPI
     46 IoReadFifo8 (
     47   IN      UINTN                     Port,
     48   IN      UINTN                     Count,
     49   OUT     VOID                      *Buffer
     50   );
     51 
     52 /**
     53   Writes an 8-bit I/O port fifo from a block of memory.
     54 
     55   Writes the 8-bit I/O fifo port specified by Port.
     56 
     57   The port is written Count times, and the data are obtained
     58   from the provided Buffer.
     59 
     60   This function must guarantee that all I/O read and write operations are
     61   serialized.
     62 
     63   If 8-bit I/O port operations are not supported, then ASSERT().
     64 
     65   @param  Port    The I/O port to read.
     66   @param  Count   The number of times to read I/O port.
     67   @param  Buffer  The buffer to store the read data into.
     68 
     69 **/
     70 VOID
     71 EFIAPI
     72 IoWriteFifo8 (
     73   IN      UINTN                     Port,
     74   IN      UINTN                     Count,
     75   OUT     VOID                      *Buffer
     76   );
     77 
     78 
     79 /**
     80   Selects a firmware configuration item for reading.
     81 
     82   Following this call, any data read from this item will start from
     83   the beginning of the configuration item's data.
     84 
     85   @param[in] QemuFwCfgItem - Firmware Configuration item to read
     86 
     87 **/
     88 VOID
     89 EFIAPI
     90 QemuFwCfgSelectItem (
     91   IN FIRMWARE_CONFIG_ITEM   QemuFwCfgItem
     92   )
     93 {
     94   DEBUG ((EFI_D_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem));
     95   IoWrite16 (0x510, (UINT16)(UINTN) QemuFwCfgItem);
     96 }
     97 
     98 
     99 /**
    100   Reads firmware configuration bytes into a buffer
    101 
    102   @param[in] Size - Size in bytes to read
    103   @param[in] Buffer - Buffer to store data into  (OPTIONAL if Size is 0)
    104 
    105 **/
    106 VOID
    107 EFIAPI
    108 InternalQemuFwCfgReadBytes (
    109   IN UINTN                  Size,
    110   IN VOID                   *Buffer  OPTIONAL
    111   )
    112 {
    113   IoReadFifo8 (0x511, Size, Buffer);
    114 }
    115 
    116 
    117 /**
    118   Reads firmware configuration bytes into a buffer
    119 
    120   If called multiple times, then the data read will
    121   continue at the offset of the firmware configuration
    122   item where the previous read ended.
    123 
    124   @param[in] Size - Size in bytes to read
    125   @param[in] Buffer - Buffer to store data into
    126 
    127 **/
    128 VOID
    129 EFIAPI
    130 QemuFwCfgReadBytes (
    131   IN UINTN                  Size,
    132   IN VOID                   *Buffer
    133   )
    134 {
    135   if (InternalQemuFwCfgIsAvailable ()) {
    136     InternalQemuFwCfgReadBytes (Size, Buffer);
    137   } else {
    138     ZeroMem (Buffer, Size);
    139   }
    140 }
    141 
    142 /**
    143   Write firmware configuration bytes from a buffer
    144 
    145   If called multiple times, then the data written will
    146   continue at the offset of the firmware configuration
    147   item where the previous write ended.
    148 
    149   @param[in] Size - Size in bytes to write
    150   @param[in] Buffer - Buffer to read data from
    151 
    152 **/
    153 VOID
    154 EFIAPI
    155 QemuFwCfgWriteBytes (
    156   IN UINTN                  Size,
    157   IN VOID                   *Buffer
    158   )
    159 {
    160   if (InternalQemuFwCfgIsAvailable ()) {
    161     IoWriteFifo8 (0x511, Size, Buffer);
    162   }
    163 }
    164 
    165 
    166 /**
    167   Reads a UINT8 firmware configuration value
    168 
    169   @return    Value of Firmware Configuration item read
    170 
    171 **/
    172 UINT8
    173 EFIAPI
    174 QemuFwCfgRead8 (
    175   VOID
    176   )
    177 {
    178   UINT8 Result;
    179 
    180   QemuFwCfgReadBytes (sizeof (Result), &Result);
    181 
    182   return Result;
    183 }
    184 
    185 
    186 /**
    187   Reads a UINT16 firmware configuration value
    188 
    189   @return    Value of Firmware Configuration item read
    190 
    191 **/
    192 UINT16
    193 EFIAPI
    194 QemuFwCfgRead16 (
    195   VOID
    196   )
    197 {
    198   UINT16 Result;
    199 
    200   QemuFwCfgReadBytes (sizeof (Result), &Result);
    201 
    202   return Result;
    203 }
    204 
    205 
    206 /**
    207   Reads a UINT32 firmware configuration value
    208 
    209   @return    Value of Firmware Configuration item read
    210 
    211 **/
    212 UINT32
    213 EFIAPI
    214 QemuFwCfgRead32 (
    215   VOID
    216   )
    217 {
    218   UINT32 Result;
    219 
    220   QemuFwCfgReadBytes (sizeof (Result), &Result);
    221 
    222   return Result;
    223 }
    224 
    225 
    226 /**
    227   Reads a UINT64 firmware configuration value
    228 
    229   @return    Value of Firmware Configuration item read
    230 
    231 **/
    232 UINT64
    233 EFIAPI
    234 QemuFwCfgRead64 (
    235   VOID
    236   )
    237 {
    238   UINT64 Result;
    239 
    240   QemuFwCfgReadBytes (sizeof (Result), &Result);
    241 
    242   return Result;
    243 }
    244 
    245 
    246 /**
    247   Find the configuration item corresponding to the firmware configuration file.
    248 
    249   @param[in]  Name - Name of file to look up.
    250   @param[out] Item - Configuration item corresponding to the file, to be passed
    251                      to QemuFwCfgSelectItem ().
    252   @param[out] Size - Number of bytes in the file.
    253 
    254   @return    RETURN_SUCCESS       If file is found.
    255              RETURN_NOT_FOUND     If file is not found.
    256              RETURN_UNSUPPORTED   If firmware configuration is unavailable.
    257 
    258 **/
    259 RETURN_STATUS
    260 EFIAPI
    261 QemuFwCfgFindFile (
    262   IN   CONST CHAR8           *Name,
    263   OUT  FIRMWARE_CONFIG_ITEM  *Item,
    264   OUT  UINTN                 *Size
    265   )
    266 {
    267   UINT32 Count;
    268   UINT32 Idx;
    269 
    270   if (!InternalQemuFwCfgIsAvailable ()) {
    271     return RETURN_UNSUPPORTED;
    272   }
    273 
    274   QemuFwCfgSelectItem (QemuFwCfgItemFileDir);
    275   Count = SwapBytes32 (QemuFwCfgRead32 ());
    276 
    277   for (Idx = 0; Idx < Count; ++Idx) {
    278     UINT32 FileSize;
    279     UINT16 FileSelect;
    280     UINT16 FileReserved;
    281     CHAR8  FName[QEMU_FW_CFG_FNAME_SIZE];
    282 
    283     FileSize     = QemuFwCfgRead32 ();
    284     FileSelect   = QemuFwCfgRead16 ();
    285     FileReserved = QemuFwCfgRead16 ();
    286     (VOID) FileReserved; /* Force a do-nothing reference. */
    287     InternalQemuFwCfgReadBytes (sizeof (FName), FName);
    288 
    289     if (AsciiStrCmp (Name, FName) == 0) {
    290       *Item = SwapBytes16 (FileSelect);
    291       *Size = SwapBytes32 (FileSize);
    292       return RETURN_SUCCESS;
    293     }
    294   }
    295 
    296   return RETURN_NOT_FOUND;
    297 }
    298 
    299 
    300 /**
    301   Determine if S3 support is explicitly enabled.
    302 
    303   @retval  TRUE   if S3 support is explicitly enabled.
    304            FALSE  otherwise. This includes unavailability of the firmware
    305                   configuration interface.
    306 **/
    307 BOOLEAN
    308 EFIAPI
    309 QemuFwCfgS3Enabled (
    310   VOID
    311   )
    312 {
    313   RETURN_STATUS        Status;
    314   FIRMWARE_CONFIG_ITEM FwCfgItem;
    315   UINTN                FwCfgSize;
    316   UINT8                SystemStates[6];
    317 
    318   Status = QemuFwCfgFindFile ("etc/system-states", &FwCfgItem, &FwCfgSize);
    319   if (Status != RETURN_SUCCESS || FwCfgSize != sizeof SystemStates) {
    320     return FALSE;
    321   }
    322   QemuFwCfgSelectItem (FwCfgItem);
    323   QemuFwCfgReadBytes (sizeof SystemStates, SystemStates);
    324   return (BOOLEAN) (SystemStates[3] & BIT7);
    325 }
    326