summaryrefslogtreecommitdiff
path: root/ArmVirtPkg
diff options
context:
space:
mode:
Diffstat (limited to 'ArmVirtPkg')
-rw-r--r--ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.c491
-rw-r--r--ArmVirtPkg/Library/PlatformIntelBdsLib/IntelBdsPlatform.h56
-rw-r--r--ArmVirtPkg/Library/PlatformIntelBdsLib/PlatformIntelBdsLib.inf81
-rw-r--r--ArmVirtPkg/Library/PlatformIntelBdsLib/QemuKernel.c1115
4 files changed, 0 insertions, 1743 deletions
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.<BR>
- Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
-
- 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 <IndustryStandard/Pci22.h>
-#include <Library/DevicePathLib.h>
-#include <Library/PcdLib.h>
-#include <Library/PlatformBdsLib.h>
-#include <Library/QemuBootOrderLib.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/GraphicsOutput.h>
-#include <Protocol/PciIo.h>
-#include <Protocol/PciRootBridgeIo.h>
-#include <Guid/EventGroup.h>
-#include <Guid/RootBridgesConnectedEventGroup.h>
-
-#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"<device path unavailable>";
-
- //
- // 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.<BR>
-
- 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 <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-
-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.<BR>
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
-#
-# 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 <Guid/FileInfo.h>
-#include <Guid/FileSystemInfo.h>
-#include <Guid/FileSystemVolumeLabelInfo.h>
-#include <Library/PrintLib.h>
-#include <Library/QemuFwCfgLib.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/LoadedImage.h>
-#include <Protocol/SimpleFileSystem.h>
-
-#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=<name>' 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;
-}