From 36fbc6973cbde855502b6f07fa80207e2bf0536b Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Thu, 5 May 2016 20:25:43 +0200 Subject: ArmVirtPkg: retire PlatformIntelBdsLib This library instance is no longer referenced. Cc: Ard Biesheuvel Cc: Ruiyu Ni Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek Reviewed-by: Ard Biesheuvel Tested-by: Ard Biesheuvel Reviewed-by: Ruiyu Ni --- .../Library/PlatformIntelBdsLib/IntelBdsPlatform.c | 491 --------- .../Library/PlatformIntelBdsLib/IntelBdsPlatform.h | 56 - .../PlatformIntelBdsLib/PlatformIntelBdsLib.inf | 81 -- .../Library/PlatformIntelBdsLib/QemuKernel.c | 1115 -------------------- 4 files changed, 1743 deletions(-) delete mode 100644 ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c delete mode 100644 ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h delete mode 100644 ArmVirtPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf delete mode 100644 ArmVirtPkg/Library/PlatformIntelBdsLib/QemuKernel.c (limited to 'ArmVirtPkg') diff --git a/ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c b/ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c deleted file mode 100644 index 02d698b455..0000000000 --- a/ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c +++ /dev/null @@ -1,491 +0,0 @@ -/** @file - Implementation for PlatformBdsLib library class interfaces. - - Copyright (C) 2015, Red Hat, Inc. - Copyright (c) 2014, ARM Ltd. All rights reserved.
- Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
- - This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT - WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "IntelBdsPlatform.h" - -#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) } - - -#pragma pack (1) -typedef struct { - VENDOR_DEVICE_PATH SerialDxe; - UART_DEVICE_PATH Uart; - VENDOR_DEFINED_DEVICE_PATH TermType; - EFI_DEVICE_PATH_PROTOCOL End; -} PLATFORM_SERIAL_CONSOLE; -#pragma pack () - -#define SERIAL_DXE_FILE_GUID { \ - 0xD3987D4B, 0x971A, 0x435F, \ - { 0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41 } \ - } - -STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = { - // - // VENDOR_DEVICE_PATH SerialDxe - // - { - { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) }, - SERIAL_DXE_FILE_GUID - }, - - // - // UART_DEVICE_PATH Uart - // - { - { MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) }, - 0, // Reserved - FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate - FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits - FixedPcdGet8 (PcdUartDefaultParity), // Parity - FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits - }, - - // - // VENDOR_DEFINED_DEVICE_PATH TermType - // - { - { - MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, - DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH) - } - // - // Guid to be filled in dynamically - // - }, - - // - // EFI_DEVICE_PATH_PROTOCOL End - // - { - END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, - DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL) - } -}; - - -#pragma pack (1) -typedef struct { - USB_CLASS_DEVICE_PATH Keyboard; - EFI_DEVICE_PATH_PROTOCOL End; -} PLATFORM_USB_KEYBOARD; -#pragma pack () - -STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = { - // - // USB_CLASS_DEVICE_PATH Keyboard - // - { - { - MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, - DP_NODE_LEN (USB_CLASS_DEVICE_PATH) - }, - 0xFFFF, // VendorId: any - 0xFFFF, // ProductId: any - 3, // DeviceClass: HID - 1, // DeviceSubClass: boot - 1 // DeviceProtocol: keyboard - }, - - // - // EFI_DEVICE_PATH_PROTOCOL End - // - { - END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, - DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL) - } -}; - -// -// BDS Platform Functions -// -/** - Platform Bds init. Include the platform firmware vendor, revision - and so crc check. - -**/ -VOID -EFIAPI -PlatformBdsInit ( - VOID - ) -{ - // - // Signal EndOfDxe PI Event - // - EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); -} - - -/** - Check if the handle satisfies a particular condition. - - @param[in] Handle The handle to check. - @param[in] ReportText A caller-allocated string passed in for reporting - purposes. It must never be NULL. - - @retval TRUE The condition is satisfied. - @retval FALSE Otherwise. This includes the case when the condition could not - be fully evaluated due to an error. -**/ -typedef -BOOLEAN -(EFIAPI *FILTER_FUNCTION) ( - IN EFI_HANDLE Handle, - IN CONST CHAR16 *ReportText - ); - - -/** - Process a handle. - - @param[in] Handle The handle to process. - @param[in] ReportText A caller-allocated string passed in for reporting - purposes. It must never be NULL. -**/ -typedef -VOID -(EFIAPI *CALLBACK_FUNCTION) ( - IN EFI_HANDLE Handle, - IN CONST CHAR16 *ReportText - ); - -/** - Locate all handles that carry the specified protocol, filter them with a - callback function, and pass each handle that passes the filter to another - callback. - - @param[in] ProtocolGuid The protocol to look for. - - @param[in] Filter The filter function to pass each handle to. If this - parameter is NULL, then all handles are processed. - - @param[in] Process The callback function to pass each handle to that - clears the filter. -**/ -STATIC -VOID -FilterAndProcess ( - IN EFI_GUID *ProtocolGuid, - IN FILTER_FUNCTION Filter OPTIONAL, - IN CALLBACK_FUNCTION Process - ) -{ - EFI_STATUS Status; - EFI_HANDLE *Handles; - UINTN NoHandles; - UINTN Idx; - - Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid, - NULL /* SearchKey */, &NoHandles, &Handles); - if (EFI_ERROR (Status)) { - // - // This is not an error, just an informative condition. - // - DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid, - Status)); - return; - } - - ASSERT (NoHandles > 0); - for (Idx = 0; Idx < NoHandles; ++Idx) { - CHAR16 *DevicePathText; - STATIC CHAR16 Fallback[] = L""; - - // - // The ConvertDevicePathToText() function handles NULL input transparently. - // - DevicePathText = ConvertDevicePathToText ( - DevicePathFromHandle (Handles[Idx]), - FALSE, // DisplayOnly - FALSE // AllowShortcuts - ); - if (DevicePathText == NULL) { - DevicePathText = Fallback; - } - - if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) { - Process (Handles[Idx], DevicePathText); - } - - if (DevicePathText != Fallback) { - FreePool (DevicePathText); - } - } - gBS->FreePool (Handles); -} - - -/** - This FILTER_FUNCTION checks if a handle corresponds to a PCI display device. -**/ -STATIC -BOOLEAN -EFIAPI -IsPciDisplay ( - IN EFI_HANDLE Handle, - IN CONST CHAR16 *ReportText - ) -{ - EFI_STATUS Status; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 Pci; - - Status = gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid, - (VOID**)&PciIo); - if (EFI_ERROR (Status)) { - // - // This is not an error worth reporting. - // - return FALSE; - } - - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0 /* Offset */, - sizeof Pci / sizeof (UINT32), &Pci); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status)); - return FALSE; - } - - return IS_PCI_DISPLAY (&Pci); -} - - -/** - This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking - the matching driver to produce all first-level child handles. -**/ -STATIC -VOID -EFIAPI -Connect ( - IN EFI_HANDLE Handle, - IN CONST CHAR16 *ReportText - ) -{ - EFI_STATUS Status; - - Status = gBS->ConnectController ( - Handle, // ControllerHandle - NULL, // DriverImageHandle - NULL, // RemainingDevicePath -- produce all children - FALSE // Recursive - ); - DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, "%a: %s: %r\n", - __FUNCTION__, ReportText, Status)); -} - - -/** - This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the - handle, and adds it to ConOut and ErrOut. -**/ -STATIC -VOID -EFIAPI -AddOutput ( - IN EFI_HANDLE Handle, - IN CONST CHAR16 *ReportText - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - DevicePath = DevicePathFromHandle (Handle); - if (DevicePath == NULL) { - DEBUG ((EFI_D_ERROR, "%a: %s: handle %p: device path not found\n", - __FUNCTION__, ReportText, Handle)); - return; - } - - Status = BdsLibUpdateConsoleVariable (L"ConOut", DevicePath, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__, - ReportText, Status)); - return; - } - - Status = BdsLibUpdateConsoleVariable (L"ErrOut", DevicePath, NULL); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__, - ReportText, Status)); - return; - } - - DEBUG ((EFI_D_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__, - ReportText)); -} - - -/** - The function will execute with as the platform policy, current policy - is driven by boot mode. IBV/OEM can customize this code for their specific - policy action. - - @param DriverOptionList The header of the driver option link list - @param BootOptionList The header of the boot option link list - @param ProcessCapsules A pointer to ProcessCapsules() - @param BaseMemoryTest A pointer to BaseMemoryTest() - -**/ -VOID -EFIAPI -PlatformBdsPolicyBehavior ( - IN LIST_ENTRY *DriverOptionList, - IN LIST_ENTRY *BootOptionList, - IN PROCESS_CAPSULES ProcessCapsules, - IN BASEM_MEMORY_TEST BaseMemoryTest - ) -{ - // - // Locate the PCI root bridges and make the PCI bus driver connect each, - // non-recursively. This will produce a number of child handles with PciIo on - // them. - // - FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect); - - // - // Signal the ACPI platform driver that it can download QEMU ACPI tables. - // - EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid); - - // - // Find all display class PCI devices (using the handles from the previous - // step), and connect them non-recursively. This should produce a number of - // child handles with GOPs on them. - // - FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect); - - // - // Now add the device path of all handles with GOP on them to ConOut and - // ErrOut. - // - FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput); - - // - // Add the hardcoded short-form USB keyboard device path to ConIn. - // - BdsLibUpdateConsoleVariable (L"ConIn", - (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL); - - // - // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut. - // - CopyGuid (&mSerialConsole.TermType.Guid, - PcdGetPtr (PcdTerminalTypeGuidBuffer)); - BdsLibUpdateConsoleVariable (L"ConIn", - (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); - BdsLibUpdateConsoleVariable (L"ConOut", - (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); - BdsLibUpdateConsoleVariable (L"ErrOut", - (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); - - // - // Connect the consoles based on the above variables. - // - BdsLibConnectAllDefaultConsoles (); - - // - // Show the splash screen. - // - EnableQuietBoot (PcdGetPtr (PcdLogoFile)); - - // - // Connect the rest of the devices. - // - BdsLibConnectAll (); - - // - // Process QEMU's -kernel command line option. Note that the kernel booted - // this way should receive ACPI tables, which is why we connect all devices - // first (see above) -- PCI enumeration blocks ACPI table installation, if - // there is a PCI host. - // - TryRunningQemuKernel (); - - BdsLibEnumerateAllBootOption (BootOptionList); - SetBootOrderFromQemu (BootOptionList); - // - // The BootOrder variable may have changed, reload the in-memory list with - // it. - // - BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); - - PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE); -} - -/** - Hook point after a boot attempt succeeds. We don't expect a boot option to - return, so the UEFI 2.0 specification defines that you will default to an - interactive mode and stop processing the BootOrder list in this case. This - is also a platform implementation and can be customized by IBV/OEM. - - @param Option Pointer to Boot Option that succeeded to boot. - -**/ -VOID -EFIAPI -PlatformBdsBootSuccess ( - IN BDS_COMMON_OPTION *Option - ) -{ -} - -/** - Hook point after a boot attempt fails. - - @param Option Pointer to Boot Option that failed to boot. - @param Status Status returned from failed boot. - @param ExitData Exit data returned from failed boot. - @param ExitDataSize Exit data size returned from failed boot. - -**/ -VOID -EFIAPI -PlatformBdsBootFail ( - IN BDS_COMMON_OPTION *Option, - IN EFI_STATUS Status, - IN CHAR16 *ExitData, - IN UINTN ExitDataSize - ) -{ -} - -/** - This function locks platform flash that is not allowed to be updated during normal boot path. - The flash layout is platform specific. -**/ -VOID -EFIAPI -PlatformBdsLockNonUpdatableFlash ( - VOID - ) -{ - return; -} diff --git a/ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h b/ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h deleted file mode 100644 index 190ce9b294..0000000000 --- a/ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h +++ /dev/null @@ -1,56 +0,0 @@ -/** @file - Head file for BDS Platform specific code - - Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
- - This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT - WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _INTEL_BDS_PLATFORM_H_ -#define _INTEL_BDS_PLATFORM_H_ - -#include -#include -#include -#include -#include -#include -#include -#include - -VOID -PlatformBdsEnterFrontPage ( - IN UINT16 TimeoutDefault, - IN BOOLEAN ConnectAllHappened - ); - -/** - Download the kernel, the initial ramdisk, and the kernel command line from - QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two - image files, and load and start the kernel from it. - - The kernel will be instructed via its command line to load the initrd from - the same Simple FileSystem. - - @retval EFI_NOT_FOUND Kernel image was not found. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. - @retval EFI_PROTOCOL_ERROR Unterminated kernel command line. - - @return Error codes from any of the underlying - functions. On success, the function doesn't - return. -**/ -EFI_STATUS -EFIAPI -TryRunningQemuKernel ( - VOID - ); - -#endif // _INTEL_BDS_PLATFORM_H diff --git a/ArmVirtPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf b/ArmVirtPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf deleted file mode 100644 index f104accc03..0000000000 --- a/ArmVirtPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf +++ /dev/null @@ -1,81 +0,0 @@ -## @file -# Implementation for PlatformBdsLib library class interfaces. -# -# Copyright (C) 2015, Red Hat, Inc. -# Copyright (c) 2014, ARM Ltd. All rights reserved.
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials are licensed and made available -# under the terms and conditions of the BSD License which accompanies this -# distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR -# IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = PlatformIntelBdsLib - FILE_GUID = 46DF84EB-F603-4D39-99D8-E1E86B50BCC2 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = ARM AARCH64 -# - -[Sources] - IntelBdsPlatform.c - QemuKernel.c - -[Packages] - IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - OvmfPkg/OvmfPkg.dec - ArmVirtPkg/ArmVirtPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DebugLib - DevicePathLib - GenericBdsLib - MemoryAllocationLib - PcdLib - PrintLib - QemuBootOrderLib - QemuFwCfgLib - UefiBootServicesTableLib - UefiLib - UefiRuntimeServicesTableLib - -[FixedPcd] - gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity - gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits - -[Pcd] - gArmVirtTokenSpaceGuid.PcdTerminalTypeGuidBuffer - -[Guids] - gEfiFileInfoGuid - gEfiFileSystemInfoGuid - gEfiFileSystemVolumeLabelInfoIdGuid - gEfiEndOfDxeEventGroupGuid - gRootBridgesConnectedEventGroupGuid - -[Protocols] - gEfiDevicePathProtocolGuid - gEfiGraphicsOutputProtocolGuid - gEfiLoadedImageProtocolGuid - gEfiPciRootBridgeIoProtocolGuid - gEfiSimpleFileSystemProtocolGuid diff --git a/ArmVirtPkg/Library/PlatformIntelBdsLib/QemuKernel.c b/ArmVirtPkg/Library/PlatformIntelBdsLib/QemuKernel.c deleted file mode 100644 index 402db97a80..0000000000 --- a/ArmVirtPkg/Library/PlatformIntelBdsLib/QemuKernel.c +++ /dev/null @@ -1,1115 +0,0 @@ -/** @file - Try to load an EFI-stubbed ARM Linux kernel from QEMU's fw_cfg. - - This implementation differs from OvmfPkg/Library/LoadLinuxLib. An EFI - stub in the subject kernel is a hard requirement here. - - Copyright (C) 2014, Red Hat, Inc. - - This program and the accompanying materials are licensed and made available - under the terms and conditions of the BSD License which accompanies this - distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT - WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "IntelBdsPlatform.h" - -// -// Static data that hosts the fw_cfg blobs and serves file requests. -// -typedef enum { - KernelBlobTypeKernel, - KernelBlobTypeInitrd, - KernelBlobTypeCommandLine, - KernelBlobTypeMax -} KERNEL_BLOB_TYPE; - -typedef struct { - FIRMWARE_CONFIG_ITEM CONST SizeKey; - FIRMWARE_CONFIG_ITEM CONST DataKey; - CONST CHAR16 * CONST Name; - UINT32 Size; - UINT8 *Data; -} KERNEL_BLOB; - -STATIC KERNEL_BLOB mKernelBlob[KernelBlobTypeMax] = { - { QemuFwCfgItemKernelSize, QemuFwCfgItemKernelData, L"kernel" }, - { QemuFwCfgItemInitrdSize, QemuFwCfgItemInitrdData, L"initrd" }, - { QemuFwCfgItemCommandLineSize, QemuFwCfgItemCommandLineData, L"cmdline" } -}; - -STATIC UINT64 mTotalBlobBytes; - -// -// Device path for the handle that incorporates our "EFI stub filesystem". The -// GUID is arbitrary and need not be standardized or advertized. -// -#pragma pack(1) -typedef struct { - VENDOR_DEVICE_PATH VenHwNode; - EFI_DEVICE_PATH_PROTOCOL EndNode; -} SINGLE_VENHW_NODE_DEVPATH; -#pragma pack() - -STATIC CONST SINGLE_VENHW_NODE_DEVPATH mFileSystemDevicePath = { - { - { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH) } }, - { - 0xb0fae7e7, 0x6b07, 0x49d0, - { 0x9e, 0x5b, 0x3b, 0xde, 0xc8, 0x3b, 0x03, 0x9d } - } - }, - - { - END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, - { sizeof (EFI_DEVICE_PATH_PROTOCOL) } - } -}; - -// -// The "file in the EFI stub filesystem" abstraction. -// -STATIC EFI_TIME mInitTime; - -#define STUB_FILE_SIG SIGNATURE_64 ('S', 'T', 'U', 'B', 'F', 'I', 'L', 'E') - -typedef struct { - UINT64 Signature; // Carries STUB_FILE_SIG. - - KERNEL_BLOB_TYPE BlobType; // Index into mKernelBlob. KernelBlobTypeMax - // denotes the root directory of the filesystem. - - UINT64 Position; // Byte position for regular files; - // next directory entry to return for the root - // directory. - - EFI_FILE_PROTOCOL File; // Standard protocol interface. -} STUB_FILE; - -#define STUB_FILE_FROM_FILE(FilePointer) \ - CR (FilePointer, STUB_FILE, File, STUB_FILE_SIG) - -// -// Tentative definition of the file protocol template. The initializer -// (external definition) will be provided later. -// -STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate; - - -// -// Protocol member functions for File. -// - -/** - Opens a new file relative to the source file's location. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is - the file handle to the source location. This would - typically be an open handle to a directory. - - @param[out] NewHandle A pointer to the location to return the opened handle - for the new file. - - @param[in] FileName The Null-terminated string of the name of the file to - be opened. The file name may contain the following - path modifiers: "\", ".", and "..". - - @param[in] OpenMode The mode to open the file. The only valid - combinations that the file may be opened with are: - Read, Read/Write, or Create/Read/Write. - - @param[in] Attributes Only valid for EFI_FILE_MODE_CREATE, in which case - these are the attribute bits for the newly created - file. - - @retval EFI_SUCCESS The file was opened. - @retval EFI_NOT_FOUND The specified file could not be found on the - device. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_MEDIA_CHANGED The device has a different medium in it or the - medium is no longer supported. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a - file for write when the media is - write-protected. - @retval EFI_ACCESS_DENIED The service denied access to the file. - @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the - file. - @retval EFI_VOLUME_FULL The volume is full. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileOpen ( - IN EFI_FILE_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **NewHandle, - IN CHAR16 *FileName, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - CONST STUB_FILE *StubFile; - UINTN BlobType; - STUB_FILE *NewStubFile; - - // - // We're read-only. - // - switch (OpenMode) { - case EFI_FILE_MODE_READ: - break; - - case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE: - case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE: - return EFI_WRITE_PROTECTED; - - default: - return EFI_INVALID_PARAMETER; - } - - // - // Only the root directory supports opening files in it. - // - StubFile = STUB_FILE_FROM_FILE (This); - if (StubFile->BlobType != KernelBlobTypeMax) { - return EFI_UNSUPPORTED; - } - - // - // Locate the file. - // - for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) { - if (StrCmp (FileName, mKernelBlob[BlobType].Name) == 0) { - break; - } - } - if (BlobType == KernelBlobTypeMax) { - return EFI_NOT_FOUND; - } - - // - // Found it. - // - NewStubFile = AllocatePool (sizeof *NewStubFile); - if (NewStubFile == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - NewStubFile->Signature = STUB_FILE_SIG; - NewStubFile->BlobType = (KERNEL_BLOB_TYPE)BlobType; - NewStubFile->Position = 0; - CopyMem (&NewStubFile->File, &mEfiFileProtocolTemplate, - sizeof mEfiFileProtocolTemplate); - *NewHandle = &NewStubFile->File; - - return EFI_SUCCESS; -} - - -/** - Closes a specified file handle. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file - handle to close. - - @retval EFI_SUCCESS The file was closed. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileClose ( - IN EFI_FILE_PROTOCOL *This - ) -{ - FreePool (STUB_FILE_FROM_FILE (This)); - return EFI_SUCCESS; -} - - -/** - Close and delete the file handle. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the - handle to the file to delete. - - @retval EFI_SUCCESS The file was closed and deleted, and the - handle was closed. - @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not - deleted. - -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileDelete ( - IN EFI_FILE_PROTOCOL *This - ) -{ - FreePool (STUB_FILE_FROM_FILE (This)); - return EFI_WARN_DELETE_FAILURE; -} - - -/** - Helper function that formats an EFI_FILE_INFO structure into the - user-allocated buffer, for any valid KERNEL_BLOB_TYPE value (including - KernelBlobTypeMax, which stands for the root directory). - - The interface follows the EFI_FILE_GET_INFO -- and for directories, the - EFI_FILE_READ -- interfaces. - - @param[in] BlobType The KERNEL_BLOB_TYPE value identifying the fw_cfg - blob backing the STUB_FILE that information is - being requested about. If BlobType equals - KernelBlobTypeMax, then information will be - provided about the root directory of the - filesystem. - - @param[in,out] BufferSize On input, the size of Buffer. On output, the - amount of data returned in Buffer. In both cases, - the size is measured in bytes. - - @param[out] Buffer A pointer to the data buffer to return. The - buffer's type is EFI_FILE_INFO. - - @retval EFI_SUCCESS The information was returned. - @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to store the - EFI_FILE_INFO structure. BufferSize has been - updated with the size needed to complete the - request. -**/ -STATIC -EFI_STATUS -ConvertKernelBlobTypeToFileInfo ( - IN KERNEL_BLOB_TYPE BlobType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - CONST CHAR16 *Name; - UINT64 FileSize; - UINT64 Attribute; - - UINTN NameSize; - UINTN FileInfoSize; - EFI_FILE_INFO *FileInfo; - UINTN OriginalBufferSize; - - if (BlobType == KernelBlobTypeMax) { - // - // getting file info about the root directory - // - Name = L"\\"; - FileSize = KernelBlobTypeMax; - Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY; - } else { - CONST KERNEL_BLOB *Blob; - - Blob = &mKernelBlob[BlobType]; - Name = Blob->Name; - FileSize = Blob->Size; - Attribute = EFI_FILE_READ_ONLY; - } - - NameSize = (StrLen(Name) + 1) * 2; - FileInfoSize = OFFSET_OF (EFI_FILE_INFO, FileName) + NameSize; - ASSERT (FileInfoSize >= sizeof *FileInfo); - - OriginalBufferSize = *BufferSize; - *BufferSize = FileInfoSize; - if (OriginalBufferSize < *BufferSize) { - return EFI_BUFFER_TOO_SMALL; - } - - FileInfo = (EFI_FILE_INFO *)Buffer; - FileInfo->Size = FileInfoSize; - FileInfo->FileSize = FileSize; - FileInfo->PhysicalSize = FileSize; - FileInfo->Attribute = Attribute; - - CopyMem (&FileInfo->CreateTime, &mInitTime, sizeof mInitTime); - CopyMem (&FileInfo->LastAccessTime, &mInitTime, sizeof mInitTime); - CopyMem (&FileInfo->ModificationTime, &mInitTime, sizeof mInitTime); - CopyMem (FileInfo->FileName, Name, NameSize); - - return EFI_SUCCESS; -} - - -/** - Reads data from a file, or continues scanning a directory. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that - is the file handle to read data from. - - @param[in,out] BufferSize On input, the size of the Buffer. On output, the - amount of data returned in Buffer. In both cases, - the size is measured in bytes. If the read goes - beyond the end of the file, the read length is - truncated to the end of the file. - - If This is a directory, the function reads the - directory entry at the current position and - returns the entry (as EFI_FILE_INFO) in Buffer. If - there are no more directory entries, the - BufferSize is set to zero on output. - - @param[out] Buffer The buffer into which the data is read. - - @retval EFI_SUCCESS Data was read. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted - file. - @retval EFI_DEVICE_ERROR On entry, the current file position is beyond - the end of the file. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to store the - current directory entry as a EFI_FILE_INFO - structure. BufferSize has been updated with the - size needed to complete the request, and the - directory position has not been advanced. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileRead ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - STUB_FILE *StubFile; - CONST KERNEL_BLOB *Blob; - UINT64 Left; - - StubFile = STUB_FILE_FROM_FILE (This); - - // - // Scanning the root directory? - // - if (StubFile->BlobType == KernelBlobTypeMax) { - EFI_STATUS Status; - - if (StubFile->Position == KernelBlobTypeMax) { - // - // Scanning complete. - // - *BufferSize = 0; - return EFI_SUCCESS; - } - - Status = ConvertKernelBlobTypeToFileInfo ( - (KERNEL_BLOB_TYPE)StubFile->Position, - BufferSize, - Buffer); - if (EFI_ERROR (Status)) { - return Status; - } - - ++StubFile->Position; - return EFI_SUCCESS; - } - - // - // Reading a file. - // - Blob = &mKernelBlob[StubFile->BlobType]; - if (StubFile->Position > Blob->Size) { - return EFI_DEVICE_ERROR; - } - - Left = Blob->Size - StubFile->Position; - if (*BufferSize > Left) { - *BufferSize = (UINTN)Left; - } - if (Blob->Data != NULL) { - CopyMem (Buffer, Blob->Data + StubFile->Position, *BufferSize); - } - StubFile->Position += *BufferSize; - return EFI_SUCCESS; -} - - -/** - Writes data to a file. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that - is the file handle to write data to. - - @param[in,out] BufferSize On input, the size of the Buffer. On output, the - amount of data actually written. In both cases, - the size is measured in bytes. - - @param[in] Buffer The buffer of data to write. - - @retval EFI_SUCCESS Data was written. - @retval EFI_UNSUPPORTED Writes to open directory files are not - supported. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_WRITE_PROTECTED The file or medium is write-protected. - @retval EFI_ACCESS_DENIED The file was opened read only. - @retval EFI_VOLUME_FULL The volume is full. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileWrite ( - IN EFI_FILE_PROTOCOL *This, - IN OUT UINTN *BufferSize, - IN VOID *Buffer - ) -{ - STUB_FILE *StubFile; - - StubFile = STUB_FILE_FROM_FILE (This); - return (StubFile->BlobType == KernelBlobTypeMax) ? - EFI_UNSUPPORTED : - EFI_WRITE_PROTECTED; -} - - -/** - Returns a file's current position. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the - file handle to get the current position on. - - @param[out] Position The address to return the file's current position - value. - - @retval EFI_SUCCESS The position was returned. - @retval EFI_UNSUPPORTED The request is not valid on open directories. - @retval EFI_DEVICE_ERROR An attempt was made to get the position from a - deleted file. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileGetPosition ( - IN EFI_FILE_PROTOCOL *This, - OUT UINT64 *Position - ) -{ - STUB_FILE *StubFile; - - StubFile = STUB_FILE_FROM_FILE (This); - if (StubFile->BlobType == KernelBlobTypeMax) { - return EFI_UNSUPPORTED; - } - - *Position = StubFile->Position; - return EFI_SUCCESS; -} - - -/** - Sets a file's current position. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the - file handle to set the requested position on. - - @param[in] Position The byte position from the start of the file to set. For - regular files, MAX_UINT64 means "seek to end". For - directories, zero means "rewind directory scan". - - @retval EFI_SUCCESS The position was set. - @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open - directories. - @retval EFI_DEVICE_ERROR An attempt was made to set the position of a - deleted file. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileSetPosition ( - IN EFI_FILE_PROTOCOL *This, - IN UINT64 Position - ) -{ - STUB_FILE *StubFile; - KERNEL_BLOB *Blob; - - StubFile = STUB_FILE_FROM_FILE (This); - - if (StubFile->BlobType == KernelBlobTypeMax) { - if (Position == 0) { - // - // rewinding a directory scan is allowed - // - StubFile->Position = 0; - return EFI_SUCCESS; - } - return EFI_UNSUPPORTED; - } - - // - // regular file seek - // - Blob = &mKernelBlob[StubFile->BlobType]; - if (Position == MAX_UINT64) { - // - // seek to end - // - StubFile->Position = Blob->Size; - } else { - // - // absolute seek from beginning -- seeking past the end is allowed - // - StubFile->Position = Position; - } - return EFI_SUCCESS; -} - - -/** - Returns information about a file. - - @param[in] This A pointer to the EFI_FILE_PROTOCOL instance - that is the file handle the requested - information is for. - - @param[in] InformationType The type identifier GUID for the information - being requested. The following information - types are supported, storing the - corresponding structures in Buffer: - - - gEfiFileInfoGuid: EFI_FILE_INFO - - - gEfiFileSystemInfoGuid: - EFI_FILE_SYSTEM_INFO - - - gEfiFileSystemVolumeLabelInfoIdGuid: - EFI_FILE_SYSTEM_VOLUME_LABEL - - @param[in,out] BufferSize On input, the size of Buffer. On output, the - amount of data returned in Buffer. In both - cases, the size is measured in bytes. - - @param[out] Buffer A pointer to the data buffer to return. The - buffer's type is indicated by - InformationType. - - @retval EFI_SUCCESS The information was returned. - @retval EFI_UNSUPPORTED The InformationType is not known. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to store the - information structure requested by - InformationType. BufferSize has been updated - with the size needed to complete the request. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileGetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN OUT UINTN *BufferSize, - OUT VOID *Buffer - ) -{ - CONST STUB_FILE *StubFile; - UINTN OriginalBufferSize; - - StubFile = STUB_FILE_FROM_FILE (This); - - if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { - return ConvertKernelBlobTypeToFileInfo (StubFile->BlobType, BufferSize, - Buffer); - } - - OriginalBufferSize = *BufferSize; - - if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { - EFI_FILE_SYSTEM_INFO *FileSystemInfo; - - *BufferSize = sizeof *FileSystemInfo; - if (OriginalBufferSize < *BufferSize) { - return EFI_BUFFER_TOO_SMALL; - } - - FileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer; - FileSystemInfo->Size = sizeof *FileSystemInfo; - FileSystemInfo->ReadOnly = TRUE; - FileSystemInfo->VolumeSize = mTotalBlobBytes; - FileSystemInfo->FreeSpace = 0; - FileSystemInfo->BlockSize = 1; - FileSystemInfo->VolumeLabel[0] = L'\0'; - - return EFI_SUCCESS; - } - - if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { - EFI_FILE_SYSTEM_VOLUME_LABEL *FileSystemVolumeLabel; - - *BufferSize = sizeof *FileSystemVolumeLabel; - if (OriginalBufferSize < *BufferSize) { - return EFI_BUFFER_TOO_SMALL; - } - - FileSystemVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer; - FileSystemVolumeLabel->VolumeLabel[0] = L'\0'; - - return EFI_SUCCESS; - } - - return EFI_UNSUPPORTED; -} - - -/** - Sets information about a file. - - @param[in] File A pointer to the EFI_FILE_PROTOCOL instance that - is the file handle the information is for. - - @param[in] InformationType The type identifier for the information being - set. - - @param[in] BufferSize The size, in bytes, of Buffer. - - @param[in] Buffer A pointer to the data buffer to write. The - buffer's type is indicated by InformationType. - - @retval EFI_SUCCESS The information was set. - @retval EFI_UNSUPPORTED The InformationType is not known. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the - media is read-only. - @retval EFI_WRITE_PROTECTED InformationType is - EFI_FILE_PROTOCOL_SYSTEM_INFO_ID and the media - is read only. - @retval EFI_WRITE_PROTECTED InformationType is - EFI_FILE_SYSTEM_VOLUME_LABEL_ID and the media - is read-only. - @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file - to a file that is already present. - @retval EFI_ACCESS_DENIED An attempt is being made to change the - EFI_FILE_DIRECTORY Attribute. - @retval EFI_ACCESS_DENIED An attempt is being made to change the size of - a directory. - @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the - file was opened read-only and an attempt is - being made to modify a field other than - Attribute. - @retval EFI_VOLUME_FULL The volume is full. - @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type - indicated by InformationType. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileSetInfo ( - IN EFI_FILE_PROTOCOL *This, - IN EFI_GUID *InformationType, - IN UINTN BufferSize, - IN VOID *Buffer - ) -{ - return EFI_WRITE_PROTECTED; -} - - -/** - Flushes all modified data associated with a file to a device. - - @param [in] This A pointer to the EFI_FILE_PROTOCOL instance that is the - file handle to flush. - - @retval EFI_SUCCESS The data was flushed. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_WRITE_PROTECTED The file or medium is write-protected. - @retval EFI_ACCESS_DENIED The file was opened read-only. - @retval EFI_VOLUME_FULL The volume is full. -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileFlush ( - IN EFI_FILE_PROTOCOL *This - ) -{ - return EFI_WRITE_PROTECTED; -} - -// -// External definition of the file protocol template. -// -STATIC CONST EFI_FILE_PROTOCOL mEfiFileProtocolTemplate = { - EFI_FILE_PROTOCOL_REVISION, // revision 1 - StubFileOpen, - StubFileClose, - StubFileDelete, - StubFileRead, - StubFileWrite, - StubFileGetPosition, - StubFileSetPosition, - StubFileGetInfo, - StubFileSetInfo, - StubFileFlush, - NULL, // OpenEx, revision 2 - NULL, // ReadEx, revision 2 - NULL, // WriteEx, revision 2 - NULL // FlushEx, revision 2 -}; - - -// -// Protocol member functions for SimpleFileSystem. -// - -/** - Open the root directory on a volume. - - @param[in] This A pointer to the volume to open the root directory on. - - @param[out] Root A pointer to the location to return the opened file handle - for the root directory in. - - @retval EFI_SUCCESS The device was opened. - @retval EFI_UNSUPPORTED This volume does not support the requested file - system type. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_ACCESS_DENIED The service denied access to the file. - @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of - resources. - @retval EFI_MEDIA_CHANGED The device has a different medium in it or the - medium is no longer supported. Any existing - file handles for this volume are no longer - valid. To access the files on the new medium, - the volume must be reopened with OpenVolume(). -**/ -STATIC -EFI_STATUS -EFIAPI -StubFileSystemOpenVolume ( - IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, - OUT EFI_FILE_PROTOCOL **Root - ) -{ - STUB_FILE *StubFile; - - StubFile = AllocatePool (sizeof *StubFile); - if (StubFile == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - StubFile->Signature = STUB_FILE_SIG; - StubFile->BlobType = KernelBlobTypeMax; - StubFile->Position = 0; - CopyMem (&StubFile->File, &mEfiFileProtocolTemplate, - sizeof mEfiFileProtocolTemplate); - *Root = &StubFile->File; - - return EFI_SUCCESS; -} - -STATIC CONST EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mFileSystem = { - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, - StubFileSystemOpenVolume -}; - - -// -// Utility functions. -// - -/** - Populate a blob in mKernelBlob. - - param[in,out] Blob Pointer to the KERNEL_BLOB element in mKernelBlob that is - to be filled from fw_cfg. - - @retval EFI_SUCCESS Blob has been populated. If fw_cfg reported a - size of zero for the blob, then Blob->Data has - been left unchanged. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for Blob->Data. -**/ -STATIC -EFI_STATUS -FetchBlob ( - IN OUT KERNEL_BLOB *Blob - ) -{ - UINT32 Left; - - // - // Read blob size. - // - QemuFwCfgSelectItem (Blob->SizeKey); - Blob->Size = QemuFwCfgRead32 (); - if (Blob->Size == 0) { - return EFI_SUCCESS; - } - - // - // Read blob. - // - Blob->Data = AllocatePool (Blob->Size); - if (Blob->Data == NULL) { - DEBUG ((EFI_D_ERROR, "%a: failed to allocate %Ld bytes for \"%s\"\n", - __FUNCTION__, (INT64)Blob->Size, Blob->Name)); - return EFI_OUT_OF_RESOURCES; - } - - DEBUG ((EFI_D_INFO, "%a: loading %Ld bytes for \"%s\"\n", __FUNCTION__, - (INT64)Blob->Size, Blob->Name)); - QemuFwCfgSelectItem (Blob->DataKey); - - Left = Blob->Size; - do { - UINT32 Chunk; - - Chunk = (Left < SIZE_1MB) ? Left : SIZE_1MB; - QemuFwCfgReadBytes (Chunk, Blob->Data + (Blob->Size - Left)); - Left -= Chunk; - DEBUG ((EFI_D_VERBOSE, "%a: %Ld bytes remaining for \"%s\"\n", - __FUNCTION__, (INT64)Left, Blob->Name)); - } while (Left > 0); - return EFI_SUCCESS; -} - - -// -// The entry point of the feature. -// - -/** - Download the kernel, the initial ramdisk, and the kernel command line from - QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the two - image files, and load and start the kernel from it. - - The kernel will be instructed via its command line to load the initrd from - the same Simple FileSystem. - - @retval EFI_NOT_FOUND Kernel image was not found. - @retval EFI_OUT_OF_RESOURCES Memory allocation failed. - @retval EFI_PROTOCOL_ERROR Unterminated kernel command line. - - @return Error codes from any of the underlying - functions. On success, the function doesn't - return. -**/ -EFI_STATUS -EFIAPI -TryRunningQemuKernel ( - VOID - ) -{ - UINTN BlobType; - KERNEL_BLOB *CurrentBlob; - KERNEL_BLOB *KernelBlob, *InitrdBlob, *CommandLineBlob; - EFI_STATUS Status; - EFI_HANDLE FileSystemHandle; - EFI_DEVICE_PATH_PROTOCOL *KernelDevicePath; - EFI_HANDLE KernelImageHandle; - EFI_LOADED_IMAGE_PROTOCOL *KernelLoadedImage; - - Status = gRT->GetTime (&mInitTime, NULL /* Capabilities */); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: GetTime(): %r\n", __FUNCTION__, Status)); - return Status; - } - - // - // Fetch all blobs. - // - for (BlobType = 0; BlobType < KernelBlobTypeMax; ++BlobType) { - CurrentBlob = &mKernelBlob[BlobType]; - Status = FetchBlob (CurrentBlob); - if (EFI_ERROR (Status)) { - goto FreeBlobs; - } - mTotalBlobBytes += CurrentBlob->Size; - } - KernelBlob = &mKernelBlob[KernelBlobTypeKernel]; - InitrdBlob = &mKernelBlob[KernelBlobTypeInitrd]; - CommandLineBlob = &mKernelBlob[KernelBlobTypeCommandLine]; - - if (KernelBlob->Data == NULL) { - Status = EFI_NOT_FOUND; - goto FreeBlobs; - } - - // - // Create a new handle with a single VenHw() node device path protocol on it, - // plus a custom SimpleFileSystem protocol on it. - // - FileSystemHandle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces (&FileSystemHandle, - &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath, - &gEfiSimpleFileSystemProtocolGuid, &mFileSystem, - NULL); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: InstallMultipleProtocolInterfaces(): %r\n", - __FUNCTION__, Status)); - goto FreeBlobs; - } - - // - // Create a device path for the kernel image to be loaded from that will call - // back into our file system. - // - KernelDevicePath = FileDevicePath (FileSystemHandle, KernelBlob->Name); - if (KernelDevicePath == NULL) { - DEBUG ((EFI_D_ERROR, "%a: failed to allocate kernel device path\n", - __FUNCTION__)); - Status = EFI_OUT_OF_RESOURCES; - goto UninstallProtocols; - } - - // - // Load the image. This should call back into our file system. - // - Status = gBS->LoadImage ( - FALSE, // BootPolicy: exact match required - gImageHandle, // ParentImageHandle - KernelDevicePath, - NULL, // SourceBuffer - 0, // SourceSize - &KernelImageHandle - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: LoadImage(): %r\n", __FUNCTION__, Status)); - goto FreeKernelDevicePath; - } - - // - // Construct the kernel command line. - // - Status = gBS->OpenProtocol ( - KernelImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **)&KernelLoadedImage, - gImageHandle, // AgentHandle - NULL, // ControllerHandle - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - ASSERT_EFI_ERROR (Status); - - if (CommandLineBlob->Data == NULL) { - KernelLoadedImage->LoadOptionsSize = 0; - } else { - // - // Verify NUL-termination of the command line. - // - if (CommandLineBlob->Data[CommandLineBlob->Size - 1] != '\0') { - DEBUG ((EFI_D_ERROR, "%a: kernel command line is not NUL-terminated\n", - __FUNCTION__)); - Status = EFI_PROTOCOL_ERROR; - goto UnloadKernelImage; - } - - // - // Drop the terminating NUL, convert to UTF-16. - // - KernelLoadedImage->LoadOptionsSize = (CommandLineBlob->Size - 1) * 2; - } - - if (InitrdBlob->Data != NULL) { - // - // Append ' initrd=' in UTF-16. - // - KernelLoadedImage->LoadOptionsSize += - (8 + StrLen(InitrdBlob->Name)) * 2; - } - - if (KernelLoadedImage->LoadOptionsSize == 0) { - KernelLoadedImage->LoadOptions = NULL; - } else { - // - // NUL-terminate in UTF-16. - // - KernelLoadedImage->LoadOptionsSize += 2; - - KernelLoadedImage->LoadOptions = AllocatePool ( - KernelLoadedImage->LoadOptionsSize); - if (KernelLoadedImage->LoadOptions == NULL) { - KernelLoadedImage->LoadOptionsSize = 0; - Status = EFI_OUT_OF_RESOURCES; - goto UnloadKernelImage; - } - - UnicodeSPrintAsciiFormat ( - KernelLoadedImage->LoadOptions, - KernelLoadedImage->LoadOptionsSize, - "%a%a%s", - (CommandLineBlob->Data == NULL) ? "" : (CHAR8 *)CommandLineBlob->Data, - (InitrdBlob->Data == NULL) ? "" : " initrd=", - (InitrdBlob->Data == NULL) ? L"" : InitrdBlob->Name - ); - DEBUG ((EFI_D_INFO, "%a: command line: \"%s\"\n", __FUNCTION__, - (CHAR16 *)KernelLoadedImage->LoadOptions)); - } - - // - // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event. - // - EfiSignalEventReadyToBoot(); - - // - // Start the image. - // - Status = gBS->StartImage ( - KernelImageHandle, - NULL, // ExitDataSize - NULL // ExitData - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "%a: StartImage(): %r\n", __FUNCTION__, Status)); - } - - if (KernelLoadedImage->LoadOptions != NULL) { - FreePool (KernelLoadedImage->LoadOptions); - } - KernelLoadedImage->LoadOptionsSize = 0; - -UnloadKernelImage: - gBS->UnloadImage (KernelImageHandle); - -FreeKernelDevicePath: - FreePool (KernelDevicePath); - -UninstallProtocols: - gBS->UninstallMultipleProtocolInterfaces (FileSystemHandle, - &gEfiSimpleFileSystemProtocolGuid, &mFileSystem, - &gEfiDevicePathProtocolGuid, &mFileSystemDevicePath, - NULL); - -FreeBlobs: - while (BlobType > 0) { - CurrentBlob = &mKernelBlob[--BlobType]; - if (CurrentBlob->Data != NULL) { - FreePool (CurrentBlob->Data); - CurrentBlob->Size = 0; - CurrentBlob->Data = NULL; - } - } - - return Status; -} -- cgit v1.2.3