xref: /cloud-hypervisor/arch/src/aarch64/uefi.rs (revision 88a9f799449c04180c6b9a21d3b9c0c4b57e2bd6)
1 // Copyright 2020 Arm Limited (or its affiliates). All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 
5 use std::io::{Read, Seek, SeekFrom};
6 use std::os::fd::AsFd;
7 use std::result;
8 
9 use thiserror::Error;
10 use vm_memory::{GuestAddress, GuestMemory};
11 
12 /// Errors thrown while loading UEFI binary
13 #[derive(Debug, Error)]
14 pub enum Error {
15     /// Unable to seek to UEFI image start.
16     #[error("Unable to seek to UEFI image start")]
17     SeekUefiStart,
18     /// Unable to seek to UEFI image end.
19     #[error("Unable to seek to UEFI image end")]
20     SeekUefiEnd,
21     /// UEFI image too big.
22     #[error("UEFI image too big")]
23     UefiTooBig,
24     /// Unable to read UEFI image
25     #[error("Unable to read UEFI image")]
26     ReadUefiImage,
27 }
28 type Result<T> = result::Result<T, Error>;
29 
load_uefi<F, M: GuestMemory>( guest_mem: &M, guest_addr: GuestAddress, uefi_image: &mut F, ) -> Result<()> where F: Read + Seek + AsFd,30 pub fn load_uefi<F, M: GuestMemory>(
31     guest_mem: &M,
32     guest_addr: GuestAddress,
33     uefi_image: &mut F,
34 ) -> Result<()>
35 where
36     F: Read + Seek + AsFd,
37 {
38     let uefi_size = uefi_image
39         .seek(SeekFrom::End(0))
40         .map_err(|_| Error::SeekUefiEnd)? as usize;
41 
42     // edk2 image on virtual platform is smaller than 3M
43     if uefi_size > 0x300000 {
44         return Err(Error::UefiTooBig);
45     }
46     uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
47     guest_mem
48         .read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size)
49         .map_err(|_| Error::ReadUefiImage)
50 }
51