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