Advance firmware and IOMMU support

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-15 12:57:45 +01:00
parent 01ce7a649b
commit 9dd372ad14
7 changed files with 518 additions and 134 deletions
@@ -143,9 +143,12 @@ pub struct CommandBuffer {
}
impl CommandBuffer {
pub const RESERVED_COMPLETION_INDEX: usize = 0;
pub const FIRST_COMMAND_INDEX: usize = 1;
pub fn new(entry_count: usize) -> Result<Self, &'static str> {
if entry_count == 0 {
return Err("IOMMU command buffer entry count must be non-zero");
if entry_count <= Self::FIRST_COMMAND_INDEX {
return Err("IOMMU command buffer entry count must leave room for command entries");
}
let byte_len = entry_count
@@ -187,6 +190,22 @@ impl CommandBuffer {
self.capacity
}
pub fn completion_store_dma_addr(&self) -> u64 {
self.buffer.physical_address() as u64
}
pub fn clear_completion_store(&mut self) {
self.commands_mut()[0] = CommandEntry::default();
}
pub fn read_completion_store(&self) -> u32 {
unsafe { core::ptr::read_volatile(self.buffer.as_ptr() as *const u32) }
}
pub fn completion_store_cpu_ptr(&self) -> *mut u32 {
self.buffer.as_ptr() as *mut u32
}
fn commands_mut(&mut self) -> &mut [CommandEntry] {
unsafe {
slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as *mut CommandEntry, self.capacity)
@@ -282,6 +301,31 @@ impl EventLog {
self.capacity
}
pub fn completion_store_dma_addr(&self) -> u64 {
let offset = (self.capacity - 1) * EVENT_LOG_ENTRY_SIZE;
(self.buffer.physical_address() + offset) as u64
}
pub fn completion_store_cpu_ptr(&self) -> *mut u32 {
let offset = (self.capacity - 1) * EVENT_LOG_ENTRY_SIZE;
unsafe { self.buffer.as_ptr().add(offset) as *mut u32 }
}
pub fn clear_completion_store(&mut self) {
let offset = (self.capacity - 1) * EVENT_LOG_ENTRY_SIZE;
unsafe {
core::ptr::write_bytes(
self.buffer.as_mut_ptr().add(offset),
0,
EVENT_LOG_ENTRY_SIZE,
)
};
}
pub fn read_completion_store(&self) -> u32 {
unsafe { core::ptr::read_volatile(self.completion_store_cpu_ptr() as *const u32) }
}
fn entries(&self) -> &[EventLogEntry] {
unsafe {
slice::from_raw_parts(self.buffer.as_ptr() as *const EventLogEntry, self.capacity)