diff --git a/alioth/src/board/board_x86_64/board_x86_64.rs b/alioth/src/board/board_x86_64/board_x86_64.rs index 3c9b863a..00f7463f 100644 --- a/alioth/src/board/board_x86_64/board_x86_64.rs +++ b/alioth/src/board/board_x86_64/board_x86_64.rs @@ -454,6 +454,8 @@ where dev.add_acpi(acpi_table).context(error::FwCfg)?; let mem_regions = memory.mem_region_entries(); dev.add_e820(&mem_regions).context(error::FwCfg)?; + dev.add_ram_size(self.config.mem.size); + dev.add_cpu_count(self.config.cpu.count); } Ok(()) } diff --git a/alioth/src/device/fw_cfg/fw_cfg.rs b/alioth/src/device/fw_cfg/fw_cfg.rs index 46cafb90..14ab4543 100644 --- a/alioth/src/device/fw_cfg/fw_cfg.rs +++ b/alioth/src/device/fw_cfg/fw_cfg.rs @@ -51,7 +51,7 @@ use crate::mem::emulated::{Action, Mmio}; use crate::mem::mapped::RamBus; #[cfg(target_arch = "x86_64")] use crate::mem::{MemRegionEntry, MemRegionType}; -use crate::utils::endian::{Bu16, Bu32, Bu64, Lu32}; +use crate::utils::endian::{Bu16, Bu32, Bu64, Lu16, Lu32, Lu64}; #[cfg(target_arch = "x86_64")] use self::acpi::create_acpi_loader; @@ -104,7 +104,9 @@ pub enum FwCfgContent { Bytes(Vec), Slice(&'static [u8]), File(u64, File), + Lu16(Lu16), Lu32(Lu32), + Lu64(Lu64), } struct FwCfgContentAccess<'a> { @@ -127,10 +129,18 @@ impl Read for FwCfgContentAccess<'_> { Some(mut s) => s.read(buf), None => Err(ErrorKind::UnexpectedEof)?, }, + FwCfgContent::Lu16(n) => match n.as_bytes().get(self.offset as usize..) { + Some(mut s) => s.read(buf), + None => Err(ErrorKind::UnexpectedEof)?, + }, FwCfgContent::Lu32(n) => match n.as_bytes().get(self.offset as usize..) { Some(mut s) => s.read(buf), None => Err(ErrorKind::UnexpectedEof)?, }, + FwCfgContent::Lu64(n) => match n.as_bytes().get(self.offset as usize..) { + Some(mut s) => s.read(buf), + None => Err(ErrorKind::UnexpectedEof)?, + }, } } } @@ -147,7 +157,9 @@ impl FwCfgContent { FwCfgContent::Bytes(v) => v.len(), FwCfgContent::File(offset, f) => (f.metadata()?.len() - offset) as usize, FwCfgContent::Slice(s) => s.len(), + FwCfgContent::Lu16(n) => size_of_val(n), FwCfgContent::Lu32(n) => size_of_val(n), + FwCfgContent::Lu64(n) => size_of_val(n), }; u32::try_from(ret).map_err(|_| std::io::ErrorKind::InvalidInput.into()) } @@ -173,7 +185,9 @@ impl FwCfgContent { } } } + FwCfgContent::Lu16(n) => n.as_bytes().get(offset as usize).copied(), FwCfgContent::Lu32(n) => n.as_bytes().get(offset as usize).copied(), + FwCfgContent::Lu64(n) => n.as_bytes().get(offset as usize).copied(), } } } @@ -266,6 +280,14 @@ impl FwCfg { self.get_file_dir_mut()[0..4].copy_from_slice(header.as_bytes()); } + pub fn add_ram_size(&mut self, size: u64) { + self.known_items[FW_CFG_RAM_SIZE as usize] = FwCfgContent::Lu64(size.into()); + } + + pub fn add_cpu_count(&mut self, count: u16) { + self.known_items[FW_CFG_NB_CPUS as usize] = FwCfgContent::Lu16(count.into()); + } + #[cfg(target_arch = "x86_64")] pub(crate) fn add_e820(&mut self, mem_regions: &[(u64, MemRegionEntry)]) -> Result<()> { let mut bytes = vec![]; diff --git a/alioth/src/device/fw_cfg/fw_cfg_test.rs b/alioth/src/device/fw_cfg/fw_cfg_test.rs index 576b385c..abe3858c 100644 --- a/alioth/src/device/fw_cfg/fw_cfg_test.rs +++ b/alioth/src/device/fw_cfg/fw_cfg_test.rs @@ -34,7 +34,9 @@ fn create_file_with_content(content: &str) -> io::Result { #[case(FwCfgContent::Bytes(vec![0x01, 0x02, 0x03]), 3)] #[case(FwCfgContent::default(), 0)] #[case(FwCfgContent::Slice(b"abcd"), 4)] +#[case(FwCfgContent::Lu16(1234.into()), 2)] #[case(FwCfgContent::Lu32(1234.into()), 4)] +#[case(FwCfgContent::Lu64(1234.into()), 8)] fn test_fw_cfg_content_size(#[case] content: FwCfgContent, #[case] size: u32) { assert_matches!(content.size(), Ok(v) if v == size); } @@ -51,7 +53,9 @@ fn test_fw_cfg_content_file_size() { #[case(FwCfgContent::Bytes(vec![0x01, 0x02, 0x03]), 2, Some(0x03))] #[case(FwCfgContent::default(), 1, None)] #[case(FwCfgContent::Slice(b"abcd"), 0, Some(b'a'))] -#[case(FwCfgContent::Lu32(0xab_cd_u32.into()), 0, Some(0xcd))] +#[case(FwCfgContent::Lu16(0x12_u16.into()), 0, Some(0x12))] +#[case(FwCfgContent::Lu32(0xabcd_u32.into()), 1, Some(0xab))] +#[case(FwCfgContent::Lu64(0xef_abcd_u64.into()), 2, Some(0xef))] fn test_fw_cfg_content_read( #[case] content: FwCfgContent, #[case] offset: u32, @@ -75,8 +79,12 @@ fn test_fw_cfg_content_file_read() { #[case(FwCfgContent::Bytes(vec![0x01, 0x02, 0x03]), 4, &[])] #[case(FwCfgContent::default(), 1, &[])] #[case(FwCfgContent::Slice(b"abcd"), 0, &[b'a', b'b', b'c', b'd'])] -#[case(FwCfgContent::Lu32(0xab_cd_u32.into()), 0, &[0xcd, 0xab, 0x00, 0x00])] -#[case(FwCfgContent::Lu32(0xab_cd_u32.into()), 5, &[])] +#[case(FwCfgContent::Lu16(0xabcd_u16.into()), 0, &[0xcd, 0xab])] +#[case(FwCfgContent::Lu16(0xabcd_u16.into()), 2, &[])] +#[case(FwCfgContent::Lu32(0x1234_abcd_u32.into()), 0, &[0xcd, 0xab, 0x34, 0x12])] +#[case(FwCfgContent::Lu32(0x1234_abcd_u32.into()), 5, &[])] +#[case(FwCfgContent::Lu64(0xfcfe_1234_abcd_u64.into()), 0, &[0xcd, 0xab, 0x34, 0x12, 0xfe, 0xfc])] +#[case(FwCfgContent::Lu64(0xfcfe_1234_abcd_u64.into()), 8, &[])] fn test_fw_cfg_content_access( #[case] content: FwCfgContent, #[case] offset: u32,