diff --git a/td-shim/src/bin/td-shim/e820.rs b/td-shim/src/bin/td-shim/e820.rs index 2c1b3792..475faf42 100644 --- a/td-shim/src/bin/td-shim/e820.rs +++ b/td-shim/src/bin/td-shim/e820.rs @@ -3,8 +3,6 @@ // SPDX-License-Identifier: BSD-2-Clause-Patent use core::ptr::slice_from_raw_parts; - -use alloc::vec::Vec; use td_shim::e820::{E820Entry, E820Type}; // Linux BootParam supports 128 e820 entries, so... @@ -12,7 +10,8 @@ const MAX_E820_ENTRY: usize = 128; #[derive(Debug)] pub struct E820Table { - entries: Vec, + entries: [E820Entry; MAX_E820_ENTRY], + num_entries: usize, } #[derive(Debug)] @@ -20,12 +19,14 @@ pub enum E820Error { RangeAlreadyExists, RangeNotExists, TooManyEntries, + InvalidIndex, } impl Default for E820Table { fn default() -> Self { Self { - entries: Vec::new(), + entries: [E820Entry::default(); MAX_E820_ENTRY], + num_entries: 0, } } } @@ -64,8 +65,7 @@ impl E820Table { if self.entries.len() == MAX_E820_ENTRY && !self.able_to_merge(pos, r#type, start, length) { return Err(E820Error::TooManyEntries); } - self.entries - .insert(pos, E820Entry::new(start, length, r#type)); + self.insert_entry(pos, E820Entry::new(start, length, r#type)); self.merge(); Ok(()) } @@ -108,8 +108,7 @@ impl E820Table { } self.entries[idx].size -= length; self.entries[idx].addr = start + length; - self.entries - .insert(idx, E820Entry::new(start, length, r#type)) + self.insert_entry(idx, E820Entry::new(start, length, r#type))?; } else if self.entries[idx].addr + self.entries[idx].size == start + length { // check if the new entry can be merged with the right one if entry_num == MAX_E820_ENTRY @@ -118,20 +117,18 @@ impl E820Table { return Err(E820Error::TooManyEntries); } self.entries[idx].size -= length; - self.entries - .insert(idx + 1, E820Entry::new(start, length, r#type)) + self.insert_entry(idx + 1, E820Entry::new(start, length, r#type))?; } else { self.entries[idx].size = start - self.entries[idx].addr; - self.entries - .insert(idx + 1, E820Entry::new(start, length, r#type)); - self.entries.insert( + self.insert_entry(idx + 1, E820Entry::new(start, length, r#type))?; + self.insert_entry( idx + 2, E820Entry::new( start + length, entry_end - (start + length), self.entries[idx].r#type.into(), ), - ); + )?; } self.merge(); return Ok(()); @@ -169,7 +166,7 @@ impl E820Table { && self.entries[idx].r#type == self.entries[idx + 1].r#type { self.entries[idx].size += self.entries[idx + 1].size; - self.entries.remove(idx + 1); + self.remove_entry(idx + 1); entry_num -= 1; continue; } @@ -177,6 +174,39 @@ impl E820Table { } } + fn insert_entry(&mut self, index: usize, entry: E820Entry) -> Result<(), E820Error> { + if index >= MAX_E820_ENTRY { + return Err(E820Error::InvalidIndex); + } + if self.num_entries >= MAX_E820_ENTRY { + return Err(E820Error::TooManyEntries); + } + + // Move all entries after the index back one position + for idx in (index + 1..self.num_entries + 1).rev() { + self.entries[idx] = self.entries[idx - 1]; + } + + self.entries[index] = entry; + self.num_entries += 1; + Ok(()) + } + + fn remove_entry(&mut self, index: usize) -> Result<(), E820Error> { + if index >= MAX_E820_ENTRY { + return Err(E820Error::InvalidIndex); + } + + // Move all entries after the index forward one position + for idx in index + 1..self.num_entries { + self.entries[idx - 1] = self.entries[idx]; + } + + self.entries[self.num_entries - 1] = E820Entry::default(); + self.num_entries -= 1; + Ok(()) + } + pub fn as_slice(&self) -> &[E820Entry] { &self.entries }