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 0296fc2c..5caf0f09 100644 --- a/alioth/src/board/board_x86_64/board_x86_64.rs +++ b/alioth/src/board/board_x86_64/board_x86_64.rs @@ -435,6 +435,7 @@ where if self.config.coco.is_none() { let ram = memory.ram_bus(); acpi_table.relocate(EBDA_START + size_of::() as u64); + acpi_table.update_checksums(); ram.write_range( EBDA_START, size_of::() as u64, diff --git a/alioth/src/device/fw_cfg/acpi.rs b/alioth/src/device/fw_cfg/acpi.rs index 84e5f307..61753d44 100644 --- a/alioth/src/device/fw_cfg/acpi.rs +++ b/alioth/src/device/fw_cfg/acpi.rs @@ -87,6 +87,7 @@ fn create_acpi_table_checksum(offset: usize, len: usize) -> AddChecksum { pub fn create_acpi_loader(mut acpi_table: AcpiTable) -> [FwCfgItem; 3] { acpi_table.relocate(0); + acpi_table.clear_checksums(); let mut table_loader_bytes: Vec = Vec::new(); let allocate_rsdp = Allocate { command: COMMAND_ALLOCATE, diff --git a/alioth/src/firmware/acpi/acpi.rs b/alioth/src/firmware/acpi/acpi.rs index 83481385..1d90e0fd 100644 --- a/alioth/src/firmware/acpi/acpi.rs +++ b/alioth/src/firmware/acpi/acpi.rs @@ -210,16 +210,18 @@ impl AcpiTable { let old_addr: u64 = transmute!(self.rsdp.xsdt_physical_address); self.rsdp.xsdt_physical_address = transmute!(table_addr); - let sum = wrapping_sum(&self.rsdp.as_bytes()[0..20]); - self.rsdp.checksum = self.rsdp.checksum.wrapping_sub(sum); - let ext_sum = wrapping_sum(self.rsdp.as_bytes()); - self.rsdp.extended_checksum = self.rsdp.extended_checksum.wrapping_sub(ext_sum); - for pointer in self.table_pointers.iter() { let (old_val, _) = u64::read_from_prefix(&self.tables[*pointer..]).unwrap(); let new_val = old_val.wrapping_sub(old_addr).wrapping_add(table_addr); IntoBytes::write_to_prefix(&new_val, &mut self.tables[*pointer..]).unwrap(); } + } + + pub fn update_checksums(&mut self) { + let sum = wrapping_sum(&self.rsdp.as_bytes()[0..20]); + self.rsdp.checksum = self.rsdp.checksum.wrapping_sub(sum); + let ext_sum = wrapping_sum(self.rsdp.as_bytes()); + self.rsdp.extended_checksum = self.rsdp.extended_checksum.wrapping_sub(ext_sum); for (start, len) in self.table_checksums.iter() { let sum = wrapping_sum(&self.tables[*start..(*start + *len)]); @@ -228,6 +230,15 @@ impl AcpiTable { } } + pub fn clear_checksums(&mut self) { + for (start, _) in self.table_checksums.iter() { + let checksum = &mut self.tables[start + offset_of!(AcpiTableHeader, checksum)]; + *checksum = 0; + } + self.rsdp.checksum = 0; + self.rsdp.extended_checksum = 0; + } + pub fn rsdp(&self) -> &AcpiTableRsdp { &self.rsdp }