hvlite_core/worker/
rom.rs1use guestmem::MapRom;
11use guestmem::MappableGuestMemory;
12use guestmem::MemoryMapper;
13use guestmem::UnmapRom;
14use hvlite_pcat_locator::RomFileLocation;
15use std::io::Read;
16use std::io::Seek;
17use std::io::SeekFrom;
18
19pub struct Rom {
20 mapper: Box<dyn MemoryMapper>,
21 name: String,
22 len: u64,
23 backing: sparse_mmap::Mappable,
24}
25
26pub struct RomBuilder {
27 name: String,
28 mapper: Box<dyn MemoryMapper>,
29}
30
31impl RomBuilder {
32 pub fn new(name: String, mapper: Box<dyn MemoryMapper>) -> Self {
33 Self { name, mapper }
34 }
35
36 pub fn build_from_file_location(self, details: &RomFileLocation) -> std::io::Result<Rom> {
38 let mut file = &details.file;
39 file.seek(SeekFrom::Start(details.start))?;
40 let mut buf = vec![0; details.len];
41 file.read_exact(&mut buf)?;
42 self.build_from_slice(&buf)
43 }
44
45 fn build_from_slice(self, data: &[u8]) -> std::io::Result<Rom> {
47 let backing = sparse_mmap::alloc_shared_memory(data.len())?;
48 let mapping = sparse_mmap::SparseMapping::new(data.len())?;
49 mapping.map_file(0, data.len(), &backing, 0, true)?;
50 mapping.write_at(0, data).unwrap();
51 Ok(Rom {
52 name: self.name,
53 mapper: self.mapper,
54 len: data.len() as u64,
55 backing,
56 })
57 }
58}
59
60impl MapRom for Rom {
61 fn map_rom(&self, gpa: u64, offset: u64, len: u64) -> std::io::Result<Box<dyn UnmapRom>> {
62 assert!(offset + len <= self.len);
63 let (mut memory, region) = self.mapper.new_region(len as usize, self.name.clone())?;
64 region.map(0, &self.backing, offset, len as usize, false)?;
65 memory.map_to_guest(gpa, false)?;
66 Ok(Box::new(MappedRom(memory)))
67 }
68
69 fn len(&self) -> u64 {
70 self.len
71 }
72}
73
74struct MappedRom(Box<dyn MappableGuestMemory>);
75
76impl UnmapRom for MappedRom {
77 fn unmap_rom(mut self) {
78 self.0.unmap_from_guest();
79 }
80}