xref: /cloud-hypervisor/arch/src/aarch64/uefi.rs (revision f6cd3bd86ded632da437b6dd6077f4237d2f71fe)
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 use vm_memory::{GuestAddress, GuestMemory};
9 
10 /// Errors thrown while loading UEFI binary
11 #[derive(Debug)]
12 pub enum Error {
13     /// Unable to seek to UEFI image start.
14     SeekUefiStart,
15     /// Unable to seek to UEFI image end.
16     SeekUefiEnd,
17     /// UEFI image too big.
18     UefiTooBig,
19     /// Unable to read UEFI image
20     ReadUefiImage,
21 }
22 type Result<T> = result::Result<T, Error>;
23 
24 pub fn load_uefi<F, M: GuestMemory>(
25     guest_mem: &M,
26     guest_addr: GuestAddress,
27     uefi_image: &mut F,
28 ) -> Result<()>
29 where
30     F: Read + Seek + AsFd,
31 {
32     let uefi_size = uefi_image
33         .seek(SeekFrom::End(0))
34         .map_err(|_| Error::SeekUefiEnd)? as usize;
35 
36     // edk2 image on virtual platform is smaller than 3M
37     if uefi_size > 0x300000 {
38         return Err(Error::UefiTooBig);
39     }
40     uefi_image.rewind().map_err(|_| Error::SeekUefiStart)?;
41     guest_mem
42         .read_exact_volatile_from(guest_addr, &mut uefi_image.as_fd(), uefi_size)
43         .map_err(|_| Error::ReadUefiImage)
44 }
45