From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by mx.groups.io with SMTP id smtpd.web10.57130.1675699298372861309 for ; Mon, 06 Feb 2023 08:01:38 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=Tor3vRVH; spf=pass (domain: intel.com, ip: 134.134.136.31, mailfrom: andrei.warkentin@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1675699298; x=1707235298; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=5SJT5hZMoz7uWoHSid2gkJdT+USJ76O1thKAmHeQ9+w=; b=Tor3vRVHnIOz/qVeWA99cmtqvMhFMfjJemFJd/Oogncwk1PRGPlBfVVx elTbEvHcSLEUW1z3Royo7dPlxcRl5rHs+xQIw31PQ+8PFCqAw8+W5oYyL qK3BesPSAz+17l2UAJae6TWMhvxWT2UncL+J6QN11nbmaO1WlrupLRm4m TSq5X8NAlYIc+7PXs7CzvW2BJ2/mVakNxcGypAkPYpGahMukouD9cqMI7 Wh/Rb46QeZ7VVowYFZrIZGDtMKmVVlePOGr5Iw0saylYyOsV+1UxcMzCM cMVTIifEYe8/E+tWqxl90NDX7FOxCIWttwfN6UW+bdiMQnCaAPgX5o+A9 A==; X-IronPort-AV: E=McAfee;i="6500,9779,10613"; a="391631662" X-IronPort-AV: E=Sophos;i="5.97,276,1669104000"; d="scan'208";a="391631662" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Feb 2023 08:01:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10613"; a="775203700" X-IronPort-AV: E=Sophos;i="5.97,276,1669104000"; d="scan'208";a="775203700" Received: from orsmsx601.amr.corp.intel.com ([10.22.229.14]) by fmsmga002.fm.intel.com with ESMTP; 06 Feb 2023 08:01:28 -0800 Received: from orsmsx612.amr.corp.intel.com (10.22.229.25) by ORSMSX601.amr.corp.intel.com (10.22.229.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Mon, 6 Feb 2023 08:01:28 -0800 Received: from orsmsx611.amr.corp.intel.com (10.22.229.24) by ORSMSX612.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16; Mon, 6 Feb 2023 08:01:27 -0800 Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx611.amr.corp.intel.com (10.22.229.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.16 via Frontend Transport; Mon, 6 Feb 2023 08:01:27 -0800 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (104.47.58.104) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.16; Mon, 6 Feb 2023 08:01:27 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OCvVL20i9+Q9xjcxDruCJUz3ehq4LfnQIzSiUM7/mJVTupOjoqoCnlCRt134JIvYmMqUwDwq0OUWv4Zui0qs8X8SK9d6XGxIeP+I6qPQcDlNrSNagGA+Fqn6Ntev663wt5WbSQzEm78SC1/Ii3/sPHnVDGPsLAonYEiEu3E1QXORDOZFqXCXblK8NeT1WkgmKh3KbQom7T7306zio6y4eJppAFNbPvx4mfwBDiwGiBovRZBDgMEBkwRgMjSP4DFQjP7a2VZMJm4D8cuk3LT1cULN8DXpIc0UfDpj27FLQo14NUCWE9BbpEwI1eVcMPWyiZvA6vn8FW5QUNwvLKSUSg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=/yHFMa0uqdf7TurVmmK+3dwUFqhSuZ5Aerr4+yvty74=; b=h8LrK7RirC6ySxFnd68kG1tqc4npwYYzyhaVCE9YxMDXZ59mWBYvlyCUcH6p7pE3est471V0yTYj59YbAiKt0fKQiq/OENAap4Ty3p7PJkbacTheMHN7Y4hs4kNcVfFRWj3P5xdWzGVCQb/h+JDQXRTOngtjPwpO93kmXO48Na5GtlQwIGyKriCwlD+N8LMpC5ulphSiwRZyIX0zdyPIARWezdMsZqSsk4egDyWgyN8km/R9bpUD1Ot+ZCvnshz7ELc/J08PD8CtbiLU2WTOn47OlcT7vYfdFTumoibEupRaYYNEGJuUWJ9ikRtpZISqNlFGrQh4HZ5t0pPhJ94VeQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from PH8PR11MB6856.namprd11.prod.outlook.com (2603:10b6:510:22b::7) by CH3PR11MB7938.namprd11.prod.outlook.com (2603:10b6:610:12f::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6064.34; Mon, 6 Feb 2023 16:01:25 +0000 Received: from PH8PR11MB6856.namprd11.prod.outlook.com ([fe80::9dba:633a:320c:87b]) by PH8PR11MB6856.namprd11.prod.outlook.com ([fe80::9dba:633a:320c:87b%5]) with mapi id 15.20.6064.032; Mon, 6 Feb 2023 16:01:25 +0000 From: "Andrei Warkentin" To: "devel@edk2.groups.io" , "sunilvl@ventanamicro.com" CC: Ard Biesheuvel , "Yao, Jiewen" , "Justen, Jordan L" , "Gerd Hoffmann" , Abner Chang Subject: Re: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library Thread-Topic: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg/RiscVVirt: Add PlatformBootManagerLib library Thread-Index: AQHZM01yW/NfIb+bEUmyGBaU4yR99a7CIeYQ Date: Mon, 6 Feb 2023 16:01:24 +0000 Message-ID: References: <20230128191807.2080547-1-sunilvl@ventanamicro.com> <20230128191807.2080547-14-sunilvl@ventanamicro.com> In-Reply-To: <20230128191807.2080547-14-sunilvl@ventanamicro.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: PH8PR11MB6856:EE_|CH3PR11MB7938:EE_ x-ms-office365-filtering-correlation-id: bea65906-4801-4586-03e4-08db085b6602 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: gs3I54tyzL4wpfmJHwC6QqSKcQqD0IaUl4PF6R4jmjNIyquJ4CR/gSUtzTE61mbg/WFPqMnbzBFHimpvmJgqrphZ/zR5DOPCcsb4Xr37jxOrmceII9o2mxSjQs+1QE7qYhywagcw2HvBg40/SPK+DEe3+1u2J/0QRcuB8rauhJ2m1vzGiZo1jFPNXeuPXdvBDMOMf09xj+KPDlfb2A1e1mqBO3UoIm3wrCdHUU8134OdqTlL2lD2vPytRxtes3AA/vsbkmcBv1bneQlr3s41oPMt2CQGp9zgOKa0O/b19gJrJvQJa8ZNUSbt/DJmS7PBPlc1vJQBoCkAnAGjYX4wC5RKXYbwtIpxVUPrZFQLfZMaj8OCLRmaV+0n7/AvlXLmqnwEyieo4QBeNoqQUcBrVTCp28OtcwaNi2rwrmZY5SxUlWR1XLVc4kfOAyRLYDmVkDMf4aealjKtF59Yi50HzY8VTMaqYdcRPEh2dGIcmVpBWqwp/UquLBQ/g9/zH+VLLKdw/4W8XXRDD5Q1mgrOqGNGtj06HpzDtfVWqqT5zzDvTAAdag3CEBhaBlNos6IHv2ynwv0PJHrLasu0uImI9tQ6D647HknpeP52V0V2dxJy7pSEGiHoO63lrt068MCndkNcirunatF9qAUeLiX85AYZfe6bjFXqgHOcF+wD/g5d4KoHeW/ZmV413iDLSw9C0Pqn0H7/Y86BsvlWZ2oFsYr9LCam8sFHYKxtKEFpjg2N8Ik4JtcPo97cpNAko0ISQJh5ZEcqGOjoGcwVzLfvrA== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH8PR11MB6856.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(366004)(346002)(136003)(39860400002)(396003)(376002)(451199018)(66899018)(478600001)(52536014)(30864003)(33656002)(86362001)(8936002)(41300700001)(66556008)(66446008)(64756008)(76116006)(66476007)(8676002)(66946007)(5660300002)(4326008)(2906002)(82960400001)(38100700002)(38070700005)(122000001)(316002)(19627235002)(7696005)(71200400001)(966005)(53546011)(54906003)(55016003)(110136005)(6506007)(186003)(9686003)(26005)(83380400001)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?kYj93Jyzz0GDPdyapHLeE48n4DLWbxpXROi4Z4lT0cngPyFKWeA5Q9VIyrtM?= =?us-ascii?Q?pNcBNYtnhbNQikExn6NOz87+wkESNWTDHZgGY3muBXgJE1TSenZ2pCNqOMOZ?= =?us-ascii?Q?slD7aoJdbyRGs1ielJF+jbp8koPaiBdSDPirYyv803K176kaNWIGkYrADlgc?= =?us-ascii?Q?tXUb5SOKEE5sA0ryjBcetyU66uEgbjxYXH+s+1huc7YWmdyU5Sk/n24ukhtS?= =?us-ascii?Q?Y/E2YLi+4hNAQ/0nKvHnAEmlU4R6EnaxFoo4LYpSBdP3Ep2O+xTv4o6V9Udm?= =?us-ascii?Q?u3T6azUd/d0P8ZVEhjCSF3YacoAKRzTJ5++luyIgGtwXOK8tkxOVWgWWomod?= =?us-ascii?Q?Nih5637kM4kiYNQ5Yi8b4XwR96L6Z9Ah0glEo9KGCDG0/9SrnEtd9EDXPnWm?= =?us-ascii?Q?K3EOXNw5XJ/0eWrHsEOx24MkhKmy/szKYoTFSY28ksCNgCN8jjdKDRofFcKy?= =?us-ascii?Q?+tiza1HJKL4iH8dfx9vH0tsEwbTbuXfSHebeDPHmzZBU43kEhN3d51Dwp+Mo?= =?us-ascii?Q?6GAdptgbifZiTCn8j4hLM7d7ZK11fWGCiYeRbpr9o3SnZmx1k5PDgVYR4Td+?= =?us-ascii?Q?QguIbPNMlIkl1XgWTP/N86X3aYg8nYR9Rytdq4xqznqGiW4kBSWgCnGrGyeB?= =?us-ascii?Q?l23vM+1DaJBcm82VFAhCbY1guOpfNzuI3/C+FhuNHDtlN82bIIdvfxrEVM87?= =?us-ascii?Q?hp3uiTfWR1F91bVHpweueoRh2Dezf/EQSJi1Mc3Nz8YgTzU3h9CEFIOTr/UO?= =?us-ascii?Q?xyY87YJHMEmFXnXpanmlqNnSvagx6qom47H1hBqgYchv9lLL+twiPPyNUOeW?= =?us-ascii?Q?shQgExkfLTkpCJwZIPRCteBwfQqu5Tp7Rwbw8rwZetyP4Xw8K8bCOdtkHQjk?= =?us-ascii?Q?s3PE/g+VedX7XvCu6r6fIbbFh/YbicqEpKkOli7NUovub3OmzrTwz0AhpslI?= =?us-ascii?Q?rx5EqxKmBWafV83xH1PwYPVJNj0oOvuvP+W9Jrf/poe/dsahTqSYqzVaNn3w?= =?us-ascii?Q?njNrgvJbIIWO+YJrn2UmorQbJBTjtrMRSRPbblLpySsfdiKJVzR9LDbPiXix?= =?us-ascii?Q?jRhWCJs+NeOZXAGdBt0j3L161CsPqM3YqKTgDscEn2pVdFQeFbx4/2qbLeAw?= =?us-ascii?Q?9wDQBdC5fBLZ/r6ao3KwBrEy2p1OfrPiuPNS0ual4bwXILxfRHAL3W0pcWnK?= =?us-ascii?Q?QT8ahawrpUrOH+LvmZw2eiA84L8roDH/yS+b7/Tn/xJi5BJuu0IMeLd0Eqtz?= =?us-ascii?Q?JZuaMN1nsJrHey2vrTGfplppRNRGS/qAyS4QehGDUfcs5gEVgIpvLRmjOprC?= =?us-ascii?Q?uS1FLvZgiyVmNuJh9rLG5cg6E7k7ih75lNqdyHYulH4l/ZEdEfU2w+Q3S8Ay?= =?us-ascii?Q?zKtXIyFhdFmWeWVw6iEDk7fVSGQZdjb7Jhbfx5vC8K++43ox4kpz3WKrH7Yq?= =?us-ascii?Q?cSNoPMNTZp9MtBdyMxp++PpEPMuX1U9RIk8X/EuQUwbsSTXxxHdDiEEct7v1?= =?us-ascii?Q?tRkzeos36UKTlaKrgFjxf8A28eeEPrlWzcnzm52T5jKeJjRmJViQfeckGXGs?= =?us-ascii?Q?L5z+xZFjPCZUcNM5te0DOmRA6gUaHWGPsC2DZ6WggnwXbnggmKeQWaaNqTcf?= =?us-ascii?Q?cA=3D=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: PH8PR11MB6856.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: bea65906-4801-4586-03e4-08db085b6602 X-MS-Exchange-CrossTenant-originalarrivaltime: 06 Feb 2023 16:01:24.9355 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: wfTGOf/4jHcBRJ0/Gs2BLY7AoQFfjFpqg7riUtX1j1qGjfQ1nfRvBIlfJqAJEYlsyzo9XJ3aEHuTGeipLYkMfFakRmjfHs1DkxLbMZkmWrI= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR11MB7938 Return-Path: andrei.warkentin@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Andrei Warkentin -----Original Message----- From: devel@edk2.groups.io On Behalf Of Sunil V L Sent: Saturday, January 28, 2023 1:18 PM To: devel@edk2.groups.io Cc: Ard Biesheuvel ; Yao, Jiewen ; Justen, Jordan L ; Gerd Hoffmann ; Abner Chang Subject: [edk2-devel] [edk2-staging/RiscV64QemuVirt PATCH V7 13/20] OvmfPkg= /RiscVVirt: Add PlatformBootManagerLib library RISC-V Qemu Virt platfform needs the PlatformBootManagerLib similar to the = one in ArmVirtPlatform. Add the library in OvmfPkg/RiscVVirt leveraging the= one from Arm. Cc: Ard Biesheuvel Cc: Jiewen Yao Cc: Jordan Justen Cc: Gerd Hoffmann Signed-off-by: Sunil V L Acked-by: Abner Chang --- OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManagerLib.in= f | 75 ++ OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h = | 45 + OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c = | 1078 ++++++++++++++++++++ OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c = | 77 ++ 4 files changed, 1275 insertions(+) diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootM= anagerLib.inf b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBo= otManagerLib.inf new file mode 100644 index 000000000000..9d66c8110c53 --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBootManag +++ erLib.inf @@ -0,0 +1,75 @@ +## @file +# Implementation for PlatformBootManagerLib library class interfaces for = RISC-V. +# +# Copyright (c) 2022, Ventana Micro Systems Inc. All rights=20 +reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # ## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D DxeRiscV64PlatformBootManagerLib + FILE_GUID =3D 4FC87DC9-2666-49BB-9023-B5FAA1E9E732 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D PlatformBootManagerLib|DXE_DRIVER + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D RISCV64 +# + +[Sources] + PlatformBm.c + PlatformBm.h + QemuKernel.c + +[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 + QemuBootOrderLib + QemuLoadImageLib + ReportStatusCodeLib + TpmPlatformHierarchyLib + 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] + gEfiFirmwareVolume2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiPciRootBridgeIoProtocolGuid + gVirtioDeviceProtocolGuid diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h = b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h new file mode 100644 index 000000000000..70c52d9832ca --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.h @@ -0,0 +1,45 @@ +/** @file + Head file for BDS Platform specific code + + Copyright (C) 2015-2016, Red Hat, Inc. + Copyright (c) 2004 - 2008, Intel Corporation. All rights=20 + reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PLATFORM_BM_H_ +#define _PLATFORM_BM_H_ + +#include +#include +#include +#include +#include #include=20 + +#include +#include + +/** + Download the kernel, the initial ramdisk, and the kernel command line=20 +from + QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the=20 +two + image files, and load and start the kernel from it. + + The kernel will be instructed via its command line to load the initrd=20 + 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/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c = b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c new file mode 100644 index 000000000000..2559889638ad --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/PlatformBm.c @@ -0,0 +1,1078 @@ +/** @file + Implementation for PlatformBootManagerLib library class interfaces. + + Copyright (C) 2015-2016, Red Hat, Inc. + Copyright (c) 2014, ARM Ltd. All rights reserved.
Copyright (c)=20 + 2004 - 2018, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include #include=20 + #include #include=20 + #include #include=20 + #include=20 + +#include #include=20 + #include #include=20 + #include #include=20 + #include #include=20 + #include #include=20 + #include=20 + +#include +#include + +#include "PlatformBm.h" + +#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof=20 +(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 =3D { + // + // 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 =3D { + // + // 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 coul= d 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=20 +with a + callback function, and pass each handle that passes the filter to=20 +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 process= ed. + + @param[in] Process The callback function to pass each handle to th= at + 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 =3D 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", + __FUNCTION__, + ProtocolGuid, + Status + )); + return; + } + + ASSERT (NoHandles > 0); + for (Idx =3D 0; Idx < NoHandles; ++Idx) { + CHAR16 *DevicePathText; + STATIC CHAR16 Fallback[] =3D L""; + + // + // The ConvertDevicePathToText() function handles NULL input transpare= ntly. + // + DevicePathText =3D ConvertDevicePathToText ( + DevicePathFromHandle (Handles[Idx]), + FALSE, // DisplayOnly + FALSE // AllowShortcuts + ); + if (DevicePathText =3D=3D NULL) { + DevicePathText =3D Fallback; + } + + if ((Filter =3D=3D NULL) || Filter (Handles[Idx], DevicePathText)) { + Process (Handles[Idx], DevicePathText); + } + + if (DevicePathText !=3D Fallback) { + FreePool (DevicePathText); + } + } + + gBS->FreePool (Handles); +} + +/** + This FILTER_FUNCTION checks if a handle corresponds to a PCI display dev= ice. +**/ +STATIC +BOOLEAN +EFIAPI +IsPciDisplay ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + Status =3D gBS->HandleProtocol ( + Handle, + &gEfiPciIoProtocolGuid, + (VOID **)&PciIo + ); + if (EFI_ERROR (Status)) { + // + // This is not an error worth reporting. + // + return FALSE; + } + + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0 /* Offset */, + sizeof Pci / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status)= ); + return FALSE; + } + + return IS_PCI_DISPLAY (&Pci); +} + +/** + This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG=20 +device at + the VIRTIO_DEVICE_PROTOCOL level. +**/ +STATIC +BOOLEAN +EFIAPI +IsVirtioRng ( + IN EFI_HANDLE Handle, + IN CONST CHAR16 *ReportText + ) +{ + EFI_STATUS Status; + VIRTIO_DEVICE_PROTOCOL *VirtIo; + + Status =3D gBS->HandleProtocol ( + Handle, + &gVirtioDeviceProtocolGuid, + (VOID **)&VirtIo + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return (BOOLEAN)(VirtIo->SubSystemDeviceId =3D=3D + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE); } + +/** + This FILTER_FUNCTION checks if a handle corresponds to a Virtio RNG=20 +device at + the EFI_PCI_IO_PROTOCOL level. +**/ +STATIC +BOOLEAN +EFIAPI +IsVirtioPciRng ( + 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 =3D gBS->HandleProtocol ( + Handle, + &gEfiPciIoProtocolGuid, + (VOID **)&PciIo + ); + if (EFI_ERROR (Status)) { + return FALSE; + } + + // + // Read and check VendorId. + // + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint16, + PCI_VENDOR_ID_OFFSET, + 1, + &VendorId + ); + if (EFI_ERROR (Status)) { + goto PciError; + } + + if (VendorId !=3D VIRTIO_VENDOR_ID) { + return FALSE; + } + + // + // Read DeviceId and RevisionId. + // + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint16, + PCI_DEVICE_ID_OFFSET, + 1, + &DeviceId + ); + if (EFI_ERROR (Status)) { + goto PciError; + } + + Status =3D 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 =20 + // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can =20 + // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and =20 + // SubsystemId will only play a sanity-check role. Otherwise, DeviceId=20 + can // only be sanity-checked, and SubsystemId will decide. + // + if ((DeviceId =3D=3D 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) && + (RevisionId >=3D 0x01)) + { + Virtio10 =3D TRUE; + } else if ((DeviceId >=3D 0x1000) && (DeviceId <=3D 0x103F) && (Revision= Id =3D=3D 0x00)) { + Virtio10 =3D FALSE; + } else { + return FALSE; + } + + // + // Read and check SubsystemId as dictated by Virtio10. + // + Status =3D PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint16, + PCI_SUBSYSTEM_ID_OFFSET, + 1, + &SubsystemId + ); + if (EFI_ERROR (Status)) { + goto PciError; + } + + if (Virtio10 && (SubsystemId >=3D 0x40)) { + return TRUE; + } + + if (!Virtio10 && (SubsystemId =3D=3D VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) { + return TRUE; + } + + return FALSE; + +PciError: + DEBUG ((DEBUG_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText,=20 +Status)); + return FALSE; +} + +/** + This CALLBACK_FUNCTION attempts to connect a handle non-recursively,=20 +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 =3D 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", + __FUNCTION__, + ReportText, + Status + )); +} + +/** + This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from=20 +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 =3D DevicePathFromHandle (Handle); if (DevicePath =3D=3D NUL= L)=20 + { + DEBUG (( + DEBUG_ERROR, + "%a: %s: handle %p: device path not found\n", + __FUNCTION__, + ReportText, + Handle + )); + return; + } + + Status =3D EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath,=20 + NULL); if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: %s: adding to ConOut: %r\n", + __FUNCTION__, + ReportText, + Status + )); + return; + } + + Status =3D EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath,=20 + NULL); if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: %s: adding to ErrOut: %r\n", + __FUNCTION__, + ReportText, + Status + )); + return; + } + + DEBUG (( + DEBUG_VERBOSE, + "%a: %s: added to ConOut and ErrOut\n", + __FUNCTION__, + 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 =3D gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); DevicePath =3D= =20 + DevicePathFromHandle (LoadedImage->DeviceHandle); ASSERT (DevicePath=20 + !=3D NULL); DevicePath =3D AppendDevicePathNode ( + DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&FileNode + ); + ASSERT (DevicePath !=3D NULL); + + Status =3D EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + BootOptions =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, + LoadOptionTypeBoot + ); + + OptionIndex =3D EfiBootManagerFindLoadOption ( + &NewOption, + BootOptions, + BootOptionCount + ); + + if (OptionIndex =3D=3D -1) { + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN)= ; + ASSERT_EFI_ERROR (Status); + } + + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); } + +/** + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot=20 +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=20 + 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()=20 +only + avoids exact duplicates. +**/ +STATIC +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions =3D EfiBootManagerGetLoadOptions ( + &BootOptionCount, + LoadOptionTypeBoot + ); + + for (Index =3D 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 =3D BootOptions[Index].FilePath; + if (!((DevicePathType (Node1) =3D=3D HARDWARE_DEVICE_PATH) && + (DevicePathSubType (Node1) =3D=3D HW_MEMMAP_DP)) && + !((DevicePathType (Node1) =3D=3D MEDIA_DEVICE_PATH) && + (DevicePathSubType (Node1) =3D=3D MEDIA_PIWG_FW_VOL_DP))) + { + continue; + } + + // + // If the second device path node is not FvFile(...), then keep the bo= ot + // option. + // + Node2 =3D NextDevicePathNode (Node1); + if ((DevicePathType (Node2) !=3D MEDIA_DEVICE_PATH) || + (DevicePathSubType (Node2) !=3D MEDIA_PIWG_FW_FILE_DP)) + { + continue; + } + + // + // Locate the Firmware Volume2 protocol instance that is denoted by th= e + // 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 t= he + // boot option. + // + SearchNode =3D Node1; + Status =3D gBS->LocateDevicePath ( + &gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, + &FvHandle + ); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the F= vFile + // 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 =3D gBS->HandleProtocol ( + FvHandle, + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&FvProtocol + ); + ASSERT_EFI_ERROR (Status); + + FvFileNode =3D (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer=3D=3DNULL means we request metadata only: BufferSize, Foun= dType, + // FileAttributes. + // + Status =3D 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 =3D EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, + LoadOptionTypeBoot + ); + DEBUG_CODE_BEGIN (); + CHAR16 *DevicePathString; + + DevicePathString =3D ConvertDevicePathToText ( + BootOptions[Index].FilePath, + FALSE, + FALSE + ); + DEBUG (( + EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE, + "%a: removing stale Boot#%04x %s: %r\n", + __FUNCTION__, + (UINT32)BootOptions[Index].OptionNumber, + DevicePathString =3D=3D NULL ? L"" : DevicePathString, + Status + )); + if (DevicePathString !=3D 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 =3D SCAN_NULL; + Enter.UnicodeChar =3D CHAR_CARRIAGE_RETURN; + Status =3D EfiBootManagerRegisterContinueKeyOption (0, &Enter= , NULL); + ASSERT_EFI_ERROR (Status); + + // + // Map F2 and ESC to Boot Manager Menu + // + F2.ScanCode =3D SCAN_F2; + F2.UnicodeChar =3D CHAR_NULL; + Esc.ScanCode =3D SCAN_ESC; + Esc.UnicodeChar =3D CHAR_NULL; + Status =3D EfiBootManagerGetBootManagerMenu (&BootOption); + ASSERT_EFI_ERROR (Status); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, + (UINT16)BootOption.OptionNumber, + 0, + &F2, + NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_STARTED); + Status =3D EfiBootManagerAddKeyOptionVariable ( + NULL, + (UINT16)BootOption.OptionNumber, + 0, + &Esc, + NULL + ); + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D 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; + RETURN_STATUS PcdStatus; + EFI_STATUS Status; + + // + // Signal EndOfDxe PI Event + // + EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); + + // + // Disable the TPM 2 platform hierarchy // =20 + ConfigureTpmPlatformHierarchy (); + + // + // Dispatch deferred images after EndOfDxe event. + // + EfiBootManagerDispatchDeferredImages (); + + // + // Locate the PCI root bridges and make the PCI bus driver connect=20 + each, // non-recursively. This will produce a number of child handles=20 + 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=20 + previous // step), and connect them non-recursively. This should=20 + 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=20 + 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 + ); + + // + // Set the front page timeout from the QEMU configuration. + // + FrontPageTimeout =3D GetFrontPageTimeoutFromQemu (); + PcdStatus =3D PcdSet16S (PcdPlatformBootTimeOut, FrontPageTimeout= ); + ASSERT_RETURN_ERROR (PcdStatus); + // + // Reflect the PCD in the standard Timeout variable. + // + Status =3D 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", + __FUNCTION__, + EFI_TIME_OUT_VARIABLE_NAME, + FrontPageTimeout, + Status + )); + + // + // Register platform-specific boot options and keyboard shortcuts. + // + PlatformRegisterOptionsAndKeys (); + + // + // At this point, VIRTIO_DEVICE_PROTOCOL instances exist only for=20 + Virtio MMIO // transports. Install EFI_RNG_PROTOCOL instances on Virtio = MMIO RNG devices. + // + FilterAndProcess (&gVirtioDeviceProtocolGuid, IsVirtioRng, Connect); + + // + // Install both VIRTIO_DEVICE_PROTOCOL and (dependent)=20 +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 scen= ario + > 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=20 +PlatformBootManagerAfterConsole ( + VOID + ) +{ + RETURN_STATUS Status; + UINTN FirmwareVerLength; + + FirmwareVerLength =3D StrLen (PcdGetPtr (PcdFirmwareVersionString)); =20 + // // 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 "); // //=20 + Process QEMU's -kernel command line option. The kernel booted this way = =20 + // will receive ACPI tables: in PlatformBootManagerBeforeConsole(), we = =20 + // connected any and all PCI root bridges, and then signaled the ACPI =20 + // platform driver. + // + TryRunningQemuKernel (); + + // + // Connect the purported boot devices. + // + Status =3D ConnectDevicesFromQemu (); + if (RETURN_ERROR (Status)) { + // + // Connect the rest of the devices. + // + EfiBootManagerConnectAll (); + } + + // + // Enumerate all possible boot options, then filter and reorder them=20 + based on // the QEMU configuration. + // + EfiBootManagerRefreshAllBootOption (); + + // + // Register UEFI Shell + // + PlatformRegisterFvBootOption ( + &gUefiShellFileGuid, + L"EFI Internal Shell", + LOAD_OPTION_ACTIVE + ); + + RemoveStaleFvFileOptions (); + SetBootOrderFromQemu (); + + 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 =3D PcdGet16 (PcdPlatformBootTimeOut); + + // + // If PcdPlatformBootTimeOut is set to zero, then we consider //=20 + that no progress update should be enacted. + // + if (TimeoutInitial =3D=3D 0) { + return; + } + + Black.Raw =3D 0x00000000; + White.Raw =3D 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=20 +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=20 + return status // is EFI_NOT_FOUND. + // + Status =3D EfiBootManagerGetBootManagerMenu (&BootManagerMenu); if=20 + (EFI_ERROR (Status)) { + return; + } + + // + // Normally BdsDxe does not print anything to the system console, but=20 + this is // a last resort -- the end-user will likely not see any=20 + DEBUG messages // logged in this situation. + // + // AsciiPrint() will NULL-check gST->ConOut internally. We check=20 + gST->ConIn // here to see if it makes sense to request and wait for a ke= ypress. + // + if (gST->ConIn !=3D 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 =3D gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index); + ASSERT_EFI_ERROR (Status); + ASSERT (Index =3D=3D 0); + + // + // Drain any queued keys. + // + while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) { + // + // just throw away Key + // + } + } + + for ( ; ;) { + EfiBootManagerBoot (&BootManagerMenu); + } +} diff --git a/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c = b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c new file mode 100644 index 000000000000..736628174f4e --- /dev/null +++ b/OvmfPkg/RiscVVirt/Library/PlatformBootManagerLib/QemuKernel.c @@ -0,0 +1,77 @@ +/** @file + Try to load an EFI-stubbed RISC-V Linux kernel from QEMU's fw_cfg. + + This implementation differs from OvmfPkg/Library/LoadLinuxLib. An EFI = =20 + stub in the subject kernel is a hard requirement here. + + Copyright (C) 2014-2016, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent **/ + +#include +#include + +#include "PlatformBm.h" + +// +// The entry point of the feature. +// + +/** + Download the kernel, the initial ramdisk, and the kernel command line=20 +from + QEMU's fw_cfg. Construct a minimal SimpleFileSystem that contains the=20 +two + image files, and load and start the kernel from it. + + The kernel will be instructed via its command line to load the initrd=20 + 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 + ) +{ + EFI_STATUS Status; + EFI_HANDLE KernelImageHandle; + + Status =3D QemuLoadKernelImage (&KernelImageHandle); if (EFI_ERROR=20 + (Status)) { + return Status; + } + + // + // Signal the EFI_EVENT_GROUP_READY_TO_BOOT event. + // + EfiSignalEventReadyToBoot (); + + REPORT_STATUS_CODE ( + EFI_PROGRESS_CODE, + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT) + ); + + // + // Start the image. + // + Status =3D QemuStartKernelImage (&KernelImageHandle); if (EFI_ERROR=20 + (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: QemuStartKernelImage(): %r\n", + __FUNCTION__, + Status + )); + } + + QemuUnloadKernelImage (KernelImageHandle); + + return Status; +} -- 2.38.0