From ef2bbe5012b778f5e9fe4f56752f79075965c7c8 Mon Sep 17 00:00:00 2001 From: Ruoqing He Date: Mon, 11 Aug 2025 00:01:03 +0000 Subject: [PATCH] arch: riscv: Introduce UEFI module Provide Error definitions and load_uefi to be referenced while loading firmware. Signed-off-by: Ruoqing He --- arch/src/riscv64/mod.rs | 2 ++ arch/src/riscv64/uefi.rs | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 arch/src/riscv64/uefi.rs diff --git a/arch/src/riscv64/mod.rs b/arch/src/riscv64/mod.rs index a04cf9471..128698961 100644 --- a/arch/src/riscv64/mod.rs +++ b/arch/src/riscv64/mod.rs @@ -7,6 +7,8 @@ pub mod fdt; /// Layout for this riscv64 system. pub mod layout; +/// Module for loading UEFI binary. +pub mod uefi; use std::collections::HashMap; use std::fmt::Debug; diff --git a/arch/src/riscv64/uefi.rs b/arch/src/riscv64/uefi.rs new file mode 100644 index 000000000..bd40e36ff --- /dev/null +++ b/arch/src/riscv64/uefi.rs @@ -0,0 +1,50 @@ +// Copyright 2020 Arm Limited (or its affiliates). All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 + +use std::io::{Read, Seek, SeekFrom}; +use std::os::fd::AsFd; +use std::result; + +use thiserror::Error; +use vm_memory::{GuestAddress, GuestMemory}; + +/// Errors thrown while loading UEFI binary +#[derive(Debug, Error)] +pub enum Error { + /// Unable to seek to UEFI image start. + #[error("Unable to seek to UEFI image start")] + SeekUefiStart, + /// Unable to seek to UEFI image end. + #[error("Unable to seek to UEFI image end")] + SeekUefiEnd, + /// UEFI image too big. + #[error("UEFI image too big")] + UefiTooBig, + /// Unable to read UEFI image + #[error("Unable to read UEFI image")] + ReadUefiImage, +} +type Result = result::Result; + +pub fn load_uefi( + guest_mem: &M, + guest_addr: GuestAddress, + uefi_image: &mut F, +) -> Result<()> +where + F: Read + Seek + AsFd, +{ + let uefi_size = uefi_image + .seek(SeekFrom::End(0)) + .map_err(|_| Error::SeekUefiEnd)? as usize; + + // edk2 image on virtual platform is smaller than 3M + if uefi_size > 0x300000 { + return Err(Error::UefiTooBig); + } + uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?; + guest_mem + .read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size) + .map_err(|_| Error::ReadUefiImage) +}