From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id E8422AC10F5 for ; Thu, 19 Oct 2023 12:12:41 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=QJD2XRhB9KRKhld05HaNUTuOEfqsD8cdOG1Cgv55Rok=; c=relaxed/simple; d=groups.io; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version:In-Reply-To:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type:Content-Disposition; s=20140610; t=1697717560; v=1; b=rKmb7mBL/dlg7SY4Kd0Gt3kvavVibGkzymz+uF/Jb5b/HxugXkHqIrFARU4EcdczPtnItfol LcrNREnKxVSYZYjBux/Yefpdmy77uhHa0k3FJBHE3RHe/KfYK9ph8kUj36ZftTd2EzoTkyax8Wx OkaFhtPEM0EOb2uqeBmxNjZY= X-Received: by 127.0.0.2 with SMTP id QrrXYY7687511x1atQ0VpqD9; Thu, 19 Oct 2023 05:12:40 -0700 X-Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) by mx.groups.io with SMTP id smtpd.web11.25737.1697717560058520980 for ; Thu, 19 Oct 2023 05:12:40 -0700 X-Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1c5c91bec75so55740605ad.3 for ; Thu, 19 Oct 2023 05:12:40 -0700 (PDT) X-Gm-Message-State: EbTyebGU52izTyNbx0sWaRscx7686176AA= X-Google-Smtp-Source: AGHT+IFF5hUvQNk95OjqVDUkGAjtrkvRxbvCWOJLVmCBodYXU7qUuxrvu8bmBZRdL04NDI0bX8wHrQ== X-Received: by 2002:a17:902:fa45:b0:1ca:3c63:d5cc with SMTP id lb5-20020a170902fa4500b001ca3c63d5ccmr1869860plb.49.1697717559217; Thu, 19 Oct 2023 05:12:39 -0700 (PDT) X-Received: from sunil-laptop ([2409:4071:6e8b:3a98:dd76:4e82:7da6:44ab]) by smtp.gmail.com with ESMTPSA id w14-20020a170902e88e00b001c726147a46sm1789627plg.234.2023.10.19.05.12.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Oct 2023 05:12:38 -0700 (PDT) Date: Thu, 19 Oct 2023 17:42:32 +0530 From: "Sunil V L" To: John Chew Cc: devel@edk2.groups.io, Yong Li Subject: Re: [edk2-devel] [PATCH v1 4/6] StarFive/JH7110Pkg: Add PlatformBootManagerLib library Message-ID: References: <20231019025921.1593-1-yuinyee.chew@starfivetech.com> <20231019025921.1593-4-yuinyee.chew@starfivetech.com> MIME-Version: 1.0 In-Reply-To: <20231019025921.1593-4-yuinyee.chew@starfivetech.com> Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,sunilvl@ventanamicro.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=rKmb7mBL; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Hi John, On Thu, Oct 19, 2023 at 10:59:19AM +0800, John Chew wrote: > From: JohnChew > > For JH7110 with graphic console > This commit message needs to be improved. From the code, I can't find why this library needs to be copied for your platform. Why not migrate and use the library in ArmPkg to MdePkg? > Cc: Sunil V L > Co-authored-by: Yong Li > Signed-off-by: John Chew > --- > Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.c | 1014 ++++++++++++++++++++ > Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.h | 46 + > Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf | 71 ++ > 3 files changed, 1131 insertions(+) > > diff --git a/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.c b/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.c > new file mode 100755 > index 000000000000..b58d2c7cbcd5 > --- /dev/null > +++ b/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.c > @@ -0,0 +1,1014 @@ > +/** @file > +* Implementation for PlatformBootManagerLib library class interfaces. > +* > +* Copyright (C) 2015-2016, Red Hat, Inc. > +* Copyright (c) 2014, ARM Ltd. All rights reserved.
> +* Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
> +* Copyright (c) 2023, StarFive Technology Co., Ltd. All rights reserved.
> +* > +* SPDX-License-Identifier: BSD-2-Clause-Patent > +* > +**/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "PlatformBm.h" > + > +#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) } > + > +#define VERSION_STRING_PREFIX L"RISC-V EDK2 firmware version " > + > +#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 () > + > +STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = { > + // > + // VENDOR_DEVICE_PATH SerialDxe > + // > + { > + { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) }, > + EDKII_SERIAL_PORT_LIB_VENDOR_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) > + } > +}; > + > +/** > + 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 (( > + DEBUG_VERBOSE, > + "%a: %g: %r\n", > + __func__, > + 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 ((DEBUG_ERROR, "%a: %s: %r\n", __func__, ReportText, Status)); > + return FALSE; > + } > + > + return IS_PCI_DISPLAY (&Pci); > +} > + > + > +/** > + This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG device at > + the EFI_PCI_IO_PROTOCOL level. > +**/ > +STATIC > +BOOLEAN > +EFIAPI > +IsVirtioPciRng ( Is this required? Thanks, Sunil > + IN EFI_HANDLE Handle, > + IN CONST CHAR16 *ReportText > + ) > +{ > + EFI_STATUS Status; > + EFI_PCI_IO_PROTOCOL *PciIo; > + UINT16 VendorId; > + UINT16 DeviceId; > + UINT8 RevisionId; > + BOOLEAN Virtio10; > + UINT16 SubsystemId; > + > + Status = gBS->HandleProtocol ( > + Handle, > + &gEfiPciIoProtocolGuid, > + (VOID **)&PciIo > + ); > + if (EFI_ERROR (Status)) { > + return FALSE; > + } > + > + // > + // Read and check VendorId. > + // > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + PCI_VENDOR_ID_OFFSET, > + 1, > + &VendorId > + ); > + if (EFI_ERROR (Status)) { > + goto PciError; > + } > + > + if (VendorId != VIRTIO_VENDOR_ID) { > + return FALSE; > + } > + > + // > + // Read DeviceId and RevisionId. > + // > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + PCI_DEVICE_ID_OFFSET, > + 1, > + &DeviceId > + ); > + if (EFI_ERROR (Status)) { > + goto PciError; > + } > + > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint8, > + PCI_REVISION_ID_OFFSET, > + 1, > + &RevisionId > + ); > + if (EFI_ERROR (Status)) { > + goto PciError; > + } > + > + // > + // From DeviceId and RevisionId, determine whether the device is a > + // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can > + // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and > + // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can > + // only be sanity-checked, and SubsystemId will decide. > + // > + if ((DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) && > + (RevisionId >= 0x01)) > + { > + Virtio10 = TRUE; > + } else if ((DeviceId >= 0x1000) && (DeviceId <= 0x103F) && (RevisionId == 0x00)) { > + Virtio10 = FALSE; > + } else { > + return FALSE; > + } > + > + // > + // Read and check SubsystemId as dictated by Virtio10. > + // > + Status = PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint16, > + PCI_SUBSYSTEM_ID_OFFSET, > + 1, > + &SubsystemId > + ); > + if (EFI_ERROR (Status)) { > + goto PciError; > + } > + > + if (Virtio10 && (SubsystemId >= 0x40)) { > + return TRUE; > + } > + > + if (!Virtio10 && (SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) { > + return TRUE; > + } > + > + return FALSE; > + > +PciError: > + DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __func__, ReportText, Status)); > + return FALSE; > +} > + > +/** > + 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) ? DEBUG_ERROR : DEBUG_VERBOSE, > + "%a: %s: %r\n", > + __func__, > + 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 (( > + DEBUG_ERROR, > + "%a: %s: handle %p: device path not found\n", > + __func__, > + ReportText, > + Handle > + )); > + return; > + } > + > + Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: %s: adding to ConOut: %r\n", > + __func__, > + ReportText, > + Status > + )); > + return; > + } > + > + Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); > + if (EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_ERROR, > + "%a: %s: adding to ErrOut: %r\n", > + __func__, > + ReportText, > + Status > + )); > + return; > + } > + > + DEBUG (( > + DEBUG_VERBOSE, > + "%a: %s: added to ConOut and ErrOut\n", > + __func__, > + ReportText > + )); > +} > + > +STATIC > +VOID > +PlatformRegisterFvBootOption ( > + EFI_GUID *FileGuid, > + CHAR16 *Description, > + UINT32 Attributes > + ) > +{ > + EFI_STATUS Status; > + INTN OptionIndex; > + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; > + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; > + UINTN BootOptionCount; > + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; > + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + > + Status = gBS->HandleProtocol ( > + gImageHandle, > + &gEfiLoadedImageProtocolGuid, > + (VOID **)&LoadedImage > + ); > + ASSERT_EFI_ERROR (Status); > + > + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); > + DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle); > + ASSERT (DevicePath != NULL); > + DevicePath = AppendDevicePathNode ( > + DevicePath, > + (EFI_DEVICE_PATH_PROTOCOL *)&FileNode > + ); > + ASSERT (DevicePath != NULL); > + > + Status = EfiBootManagerInitializeLoadOption ( > + &NewOption, > + LoadOptionNumberUnassigned, > + LoadOptionTypeBoot, > + Attributes, > + Description, > + DevicePath, > + NULL, > + 0 > + ); > + ASSERT_EFI_ERROR (Status); > + FreePool (DevicePath); > + > + BootOptions = EfiBootManagerGetLoadOptions ( > + &BootOptionCount, > + LoadOptionTypeBoot > + ); > + > + OptionIndex = EfiBootManagerFindLoadOption ( > + &NewOption, > + BootOptions, > + BootOptionCount > + ); > + > + if (OptionIndex == -1) { > + Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); > + ASSERT_EFI_ERROR (Status); > + } > + > + EfiBootManagerFreeLoadOption (&NewOption); > + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); > +} > + > +/** > + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options > + whose device paths do not resolve exactly to an FvFile in the system. > + > + This removes any boot options that point to binaries built into the firmware > + and have become stale due to any of the following: > + - FvMain's base address or size changed (historical), > + - FvMain's FvNameGuid changed, > + - the FILE_GUID of the pointed-to binary changed, > + - the referenced binary is no longer built into the firmware. > + > + EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only > + avoids exact duplicates. > +**/ > +STATIC > +VOID > +RemoveStaleFvFileOptions ( > + VOID > + ) > +{ > + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; > + UINTN BootOptionCount; > + UINTN Index; > + > + BootOptions = EfiBootManagerGetLoadOptions ( > + &BootOptionCount, > + LoadOptionTypeBoot > + ); > + > + for (Index = 0; Index < BootOptionCount; ++Index) { > + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode; > + EFI_STATUS Status; > + EFI_HANDLE FvHandle; > + > + // > + // If the device path starts with neither MemoryMapped(...) nor Fv(...), > + // then keep the boot option. > + // > + Node1 = BootOptions[Index].FilePath; > + if (!((DevicePathType (Node1) == HARDWARE_DEVICE_PATH) && > + (DevicePathSubType (Node1) == HW_MEMMAP_DP)) && > + !((DevicePathType (Node1) == MEDIA_DEVICE_PATH) && > + (DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP))) > + { > + continue; > + } > + > + // > + // If the second device path node is not FvFile(...), then keep the boot > + // option. > + // > + Node2 = NextDevicePathNode (Node1); > + if ((DevicePathType (Node2) != MEDIA_DEVICE_PATH) || > + (DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP)) > + { > + continue; > + } > + > + // > + // Locate the Firmware Volume2 protocol instance that is denoted by the > + // boot option. If this lookup fails (i.e., the boot option references a > + // firmware volume that doesn't exist), then we'll proceed to delete the > + // boot option. > + // > + SearchNode = Node1; > + Status = gBS->LocateDevicePath ( > + &gEfiFirmwareVolume2ProtocolGuid, > + &SearchNode, > + &FvHandle > + ); > + > + if (!EFI_ERROR (Status)) { > + // > + // The firmware volume was found; now let's see if it contains the FvFile > + // identified by GUID. > + // > + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; > + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode; > + UINTN BufferSize; > + EFI_FV_FILETYPE FoundType; > + EFI_FV_FILE_ATTRIBUTES FileAttributes; > + UINT32 AuthenticationStatus; > + > + Status = gBS->HandleProtocol ( > + FvHandle, > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID **)&FvProtocol > + ); > + ASSERT_EFI_ERROR (Status); > + > + FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; > + // > + // Buffer==NULL means we request metadata only: BufferSize, FoundType, > + // FileAttributes. > + // > + Status = FvProtocol->ReadFile ( > + FvProtocol, > + &FvFileNode->FvFileName, // NameGuid > + NULL, // Buffer > + &BufferSize, > + &FoundType, > + &FileAttributes, > + &AuthenticationStatus > + ); > + if (!EFI_ERROR (Status)) { > + // > + // The FvFile was found. Keep the boot option. > + // > + continue; > + } > + } > + > + // > + // Delete the boot option. > + // > + Status = EfiBootManagerDeleteLoadOptionVariable ( > + BootOptions[Index].OptionNumber, > + LoadOptionTypeBoot > + ); > + DEBUG_CODE_BEGIN (); > + CHAR16 *DevicePathString; > + > + DevicePathString = ConvertDevicePathToText ( > + BootOptions[Index].FilePath, > + FALSE, > + FALSE > + ); > + DEBUG (( > + EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE, > + "%a: removing stale Boot#%04x %s: %r\n", > + __func__, > + (UINT32)BootOptions[Index].OptionNumber, > + DevicePathString == NULL ? L"" : DevicePathString, > + Status > + )); > + if (DevicePathString != NULL) { > + FreePool (DevicePathString); > + } > + > + DEBUG_CODE_END (); > + } > + > + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); > +} > + > +STATIC > +VOID > +PlatformRegisterOptionsAndKeys ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + EFI_INPUT_KEY Enter; > + EFI_INPUT_KEY F2; > + EFI_INPUT_KEY Esc; > + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; > + > + // > + // Register ENTER as CONTINUE key > + // > + Enter.ScanCode = SCAN_NULL; > + Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; > + Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); > + ASSERT_EFI_ERROR (Status); > + > + // > + // Map F2 and ESC to Boot Manager Menu > + // > + F2.ScanCode = SCAN_F2; > + F2.UnicodeChar = CHAR_NULL; > + Esc.ScanCode = SCAN_ESC; > + Esc.UnicodeChar = CHAR_NULL; > + Status = EfiBootManagerGetBootManagerMenu (&BootOption); > + ASSERT_EFI_ERROR (Status); > + Status = EfiBootManagerAddKeyOptionVariable ( > + NULL, > + (UINT16)BootOption.OptionNumber, > + 0, > + &F2, > + NULL > + ); > + ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); > + Status = EfiBootManagerAddKeyOptionVariable ( > + NULL, > + (UINT16)BootOption.OptionNumber, > + 0, > + &Esc, > + NULL > + ); > + ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); > +} > + > +// > +// BDS Platform Functions > +// > + > +/** > + Do the platform init, can be customized by OEM/IBV > + Possible things that can be done in PlatformBootManagerBeforeConsole: > + > Update console variable: 1. include hot-plug devices; > + > 2. Clear ConIn and add SOL for AMT > + > Register new Driver#### or Boot#### > + > Register new Key####: e.g.: F12 > + > Signal ReadyToLock event > + > Authentication action: 1. connect Auth devices; > + > 2. Identify auto logon user. > +**/ > +VOID > +EFIAPI > +PlatformBootManagerBeforeConsole ( > + VOID > + ) > +{ > + UINT16 FrontPageTimeout; > + EFI_STATUS Status; > + > + // > + // Signal EndOfDxe PI Event > + // > + EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); > + > + // > + // Dispatch deferred images after EndOfDxe event. > + // > + EfiBootManagerDispatchDeferredImages (); > + > + // > + // 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. > + // > + EfiBootManagerUpdateConsoleVariable ( > + ConIn, > + (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, > + NULL > + ); > + > + // > + // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut. > + // > + CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid); > + > + EfiBootManagerUpdateConsoleVariable ( > + ConIn, > + (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, > + NULL > + ); > + EfiBootManagerUpdateConsoleVariable ( > + ConOut, > + (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, > + NULL > + ); > + EfiBootManagerUpdateConsoleVariable ( > + ErrOut, > + (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, > + NULL > + ); > + > + // > + // Reflect the PCD in the standard Timeout variable. > + // > + Status = gRT->SetVariable ( > + EFI_TIME_OUT_VARIABLE_NAME, > + &gEfiGlobalVariableGuid, > + (EFI_VARIABLE_NON_VOLATILE | > + EFI_VARIABLE_BOOTSERVICE_ACCESS | > + EFI_VARIABLE_RUNTIME_ACCESS), > + sizeof FrontPageTimeout, > + &FrontPageTimeout > + ); > + DEBUG (( > + EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE, > + "%a: SetVariable(%s, %u): %r\n", > + __func__, > + EFI_TIME_OUT_VARIABLE_NAME, > + FrontPageTimeout, > + Status > + )); > + > + // > + // Register platform-specific boot options and keyboard shortcuts. > + // > + PlatformRegisterOptionsAndKeys (); > + > + // > + // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL > + // instances on Virtio PCI RNG devices. > + // > + FilterAndProcess (&gEfiPciIoProtocolGuid, IsVirtioPciRng, Connect); > +} > + > +/** > + Do the platform specific action after the console is ready > + Possible things that can be done in PlatformBootManagerAfterConsole: > + > Console post action: > + > Dynamically switch output mode from 100x31 to 80x25 for certain scenario > + > Signal console ready platform customized event > + > Run diagnostics like memory testing > + > Connect certain devices > + > Dispatch additional option roms > + > Special boot: e.g.: USB boot, enter UI > +**/ > +VOID > +EFIAPI > +PlatformBootManagerAfterConsole ( > + VOID > + ) > +{ > + UINTN FirmwareVerLength; > + > + FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString)); > + // > + // Show the splash screen. > + // > + BootLogoEnableLogo (); > + > + if (FirmwareVerLength > 0) { > + Print ( > + VERSION_STRING_PREFIX L"%s\n", > + PcdGetPtr (PcdFirmwareVersionString) > + ); > + } > + > + Print (L"Press ESCAPE within 10 seconds for boot options "); > + > + // > + // Enumerate all possible boot options, then filter and reorder them based on > + // the QEMU configuration. > + // > + EfiBootManagerRefreshAllBootOption (); > + > + // > + // Register UEFI Shell > + // > + PlatformRegisterFvBootOption ( > + &gUefiShellFileGuid, > + L"EFI Internal Shell", > + LOAD_OPTION_ACTIVE > + ); > + > + RemoveStaleFvFileOptions (); > + > + PlatformBmPrintScRegisterHandler (); > +} > + > +/** > + This function is called each second during the boot manager waits the > + timeout. > + > + @param TimeoutRemain The remaining timeout. > +**/ > +VOID > +EFIAPI > +PlatformBootManagerWaitCallback ( > + UINT16 TimeoutRemain > + ) > +{ > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black; > + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White; > + UINT16 TimeoutInitial; > + > + TimeoutInitial = PcdGet16 (PcdPlatformBootTimeOut); > + > + // > + // If PcdPlatformBootTimeOut is set to zero, then we consider > + // that no progress update should be enacted. > + // > + if (TimeoutInitial == 0) { > + return; > + } > + > + Black.Raw = 0x00000000; > + White.Raw = 0x00FFFFFF; > + > + BootLogoUpdateProgress ( > + White.Pixel, > + Black.Pixel, > + L"Start boot option", > + White.Pixel, > + (TimeoutInitial - TimeoutRemain) * 100 / TimeoutInitial, > + 0 > + ); > +} > + > +/** > + The function is called when no boot option could be launched, > + including platform recovery options and options pointing to applications > + built into firmware volumes. > + > + If this function returns, BDS attempts to enter an infinite loop. > +**/ > +VOID > +EFIAPI > +PlatformBootManagerUnableToBoot ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + EFI_INPUT_KEY Key; > + EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu; > + UINTN Index; > + > + // > + // BootManagerMenu doesn't contain the correct information when return status > + // is EFI_NOT_FOUND. > + // > + Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu); > + if (EFI_ERROR (Status)) { > + return; > + } > + > + // > + // Normally BdsDxe does not print anything to the system console, but this is > + // a last resort -- the end-user will likely not see any DEBUG messages > + // logged in this situation. > + // > + // AsciiPrint() will NULL-check gST->ConOut internally. We check gST->ConIn > + // here to see if it makes sense to request and wait for a keypress. > + // > + if (gST->ConIn != NULL) { > + AsciiPrint ( > + "%a: No bootable option or device was found.\n" > + "%a: Press any key to enter the Boot Manager Menu.\n", > + gEfiCallerBaseName, > + gEfiCallerBaseName > + ); > + Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index); > + ASSERT_EFI_ERROR (Status); > + ASSERT (Index == 0); > + > + // > + // Drain any queued keys. > + // > + while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) { > + // > + // just throw away Key > + // > + } > + } > + > + for ( ; ;) { > + EfiBootManagerBoot (&BootManagerMenu); > + } > +} > diff --git a/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.h b/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.h > new file mode 100755 > index 000000000000..067af555ad31 > --- /dev/null > +++ b/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBm.h > @@ -0,0 +1,46 @@ > +/** @file > +* Head file for BDS Platform specific code > +* > +* Copyright (C) 2015-2016, Red Hat, Inc. > +* Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
> +* Copyright (c) 2023, StarFive Technology Co., Ltd. All rights reserved.
> +* > +* SPDX-License-Identifier: BSD-2-Clause-Patent > +* > +**/ > + > +#ifndef _PLATFORM_BM_H_ > +#define _PLATFORM_BM_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** > + 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 // _PLATFORM_BM_H_ > diff --git a/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf > new file mode 100755 > index 000000000000..d967f808cf7f > --- /dev/null > +++ b/Silicon/StarFive/JH7110Pkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf > @@ -0,0 +1,71 @@ > +## @file > +# Implementation for PlatformBootManagerLib library class interfaces for RISC-V. > +# > +# Copyright (c) 2022, Ventana Micro Systems Inc. All rights reserved.
> +# Copyright (c) 2023, StarFive Technology Co., Ltd. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = DxeRiscV64PlatformBootManagerLib > + FILE_GUID = 900C3D64-E5EA-0F56-1F51-64D593F374D2 > + MODULE_TYPE = DXE_DRIVER > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER > + > +# > +# The following information is for reference only and not required by the build tools. > +# > +# VALID_ARCHITECTURES = RISCV64 > +# > + > +[Sources] > + PlatformBm.c > + PlatformBm.h > + > +[Packages] > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + OvmfPkg/OvmfPkg.dec > + SecurityPkg/SecurityPkg.dec > + ShellPkg/ShellPkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + BootLogoLib > + DebugLib > + DevicePathLib > + MemoryAllocationLib > + PcdLib > + PlatformBmPrintScLib > + ReportStatusCodeLib > + UefiBootManagerLib > + UefiBootServicesTableLib > + UefiLib > + UefiRuntimeServicesTableLib > + > +[FixedPcd] > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity > + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits > + > +[Pcd] > + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut > + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString > + > +[Guids] > + gEfiEndOfDxeEventGroupGuid > + gEfiGlobalVariableGuid > + gRootBridgesConnectedEventGroupGuid > + gUefiShellFileGuid > + gEfiTtyTermGuid > + > +[Protocols] > + gEfiGenericMemTestProtocolGuid ## CONSUMES > + gEfiGraphicsOutputProtocolGuid ## CONSUMES > + gEfiPciRootBridgeIoProtocolGuid > -- > 2.34.1 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#109800): https://edk2.groups.io/g/devel/message/109800 Mute This Topic: https://groups.io/mt/102053683/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-