Move denali to new thread spawn
This commit is contained in:
parent
c4613cf87f
commit
79e1ea2791
|
@ -1,6 +1,8 @@
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::rc::Rc;
|
use alloc::sync::Arc;
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
|
use mammoth::sync::Mutex;
|
||||||
|
use mammoth::thread;
|
||||||
|
|
||||||
use mammoth::{mem::MemoryRegion, thread::Thread, zion::ZError};
|
use mammoth::{mem::MemoryRegion, thread::Thread, zion::ZError};
|
||||||
|
|
||||||
|
@ -48,8 +50,6 @@ pub struct PciDeviceHeader {
|
||||||
pub struct AhciController {
|
pub struct AhciController {
|
||||||
pci_memory: MemoryRegion,
|
pci_memory: MemoryRegion,
|
||||||
hba_memory: MemoryRegion,
|
hba_memory: MemoryRegion,
|
||||||
irq_port: Option<mammoth::port::PortServer>,
|
|
||||||
irq_thread: Option<Box<Thread>>,
|
|
||||||
ports: [Option<PortController<'static>>; 32],
|
ports: [Option<PortController<'static>>; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,18 +68,12 @@ impl AhciController {
|
||||||
let mut controller = Self {
|
let mut controller = Self {
|
||||||
pci_memory,
|
pci_memory,
|
||||||
hba_memory,
|
hba_memory,
|
||||||
irq_port: None,
|
|
||||||
irq_thread: None,
|
|
||||||
ports: [const { None }; 32],
|
ports: [const { None }; 32],
|
||||||
};
|
};
|
||||||
controller.init();
|
controller.init();
|
||||||
controller
|
controller
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn join(&self) -> Result<(), ZError> {
|
|
||||||
self.irq_thread.as_ref().unwrap().join()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(&mut self) {
|
fn init(&mut self) {
|
||||||
self.ahci_hba().global_host_control.set_hba_reset(true);
|
self.ahci_hba().global_host_control.set_hba_reset(true);
|
||||||
|
|
||||||
|
@ -95,28 +89,11 @@ impl AhciController {
|
||||||
|
|
||||||
mammoth::syscall::thread_sleep(50).unwrap();
|
mammoth::syscall::thread_sleep(50).unwrap();
|
||||||
|
|
||||||
self.register_irq();
|
|
||||||
|
|
||||||
self.init_ports().unwrap();
|
self.init_ports().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_server(&self) -> Result<Box<Thread>, ZError> {
|
fn irq_num(&self) -> u64 {
|
||||||
let thread_entry = |server_ptr: *const c_void| {
|
match self.pci_header().interrupt_pin {
|
||||||
let server = unsafe {
|
|
||||||
(server_ptr as *mut Self)
|
|
||||||
.as_mut()
|
|
||||||
.expect("Failed to convert to server")
|
|
||||||
};
|
|
||||||
server.irq_loop();
|
|
||||||
};
|
|
||||||
Thread::spawn(
|
|
||||||
thread_entry,
|
|
||||||
self as *const Self as *const core::ffi::c_void,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn register_irq(&mut self) {
|
|
||||||
let irq_num = match self.pci_header().interrupt_pin {
|
|
||||||
1 => mammoth::zion::kZIrqPci1,
|
1 => mammoth::zion::kZIrqPci1,
|
||||||
2 => mammoth::zion::kZIrqPci2,
|
2 => mammoth::zion::kZIrqPci2,
|
||||||
3 => mammoth::zion::kZIrqPci3,
|
3 => mammoth::zion::kZIrqPci3,
|
||||||
|
@ -125,29 +102,16 @@ impl AhciController {
|
||||||
"Unrecognized pci interrupt pin {}",
|
"Unrecognized pci interrupt pin {}",
|
||||||
self.pci_header().interrupt_pin
|
self.pci_header().interrupt_pin
|
||||||
),
|
),
|
||||||
};
|
}
|
||||||
self.irq_port = Some(mammoth::port::PortServer::from_cap(
|
|
||||||
mammoth::syscall::register_irq(irq_num).unwrap(),
|
|
||||||
));
|
|
||||||
|
|
||||||
self.irq_thread = Some(self.run_server().unwrap());
|
|
||||||
|
|
||||||
self.ahci_hba()
|
|
||||||
.global_host_control
|
|
||||||
.set_interrupt_enable(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn irq_loop(&mut self) {
|
fn handle_irq(&mut self) {
|
||||||
loop {
|
for i in 0..self.ahci_hba().capabilities.num_ports() {
|
||||||
self.irq_port.as_ref().unwrap().recv_null().unwrap();
|
let int_offset = 1 << i;
|
||||||
|
if (self.ahci_hba().interrupt_status & int_offset) == int_offset {
|
||||||
for i in 0..self.ahci_hba().capabilities.num_ports() {
|
if let Some(port) = &mut self.ports[i as usize] {
|
||||||
let int_offset = 1 << i;
|
port.handle_interrupt();
|
||||||
if (self.ahci_hba().interrupt_status & int_offset) == int_offset {
|
self.ahci_hba().interrupt_status &= !int_offset;
|
||||||
if let Some(port) = &mut self.ports[i as usize] {
|
|
||||||
port.handle_interrupt();
|
|
||||||
self.ahci_hba().interrupt_status &= !int_offset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,6 +178,24 @@ impl AhciController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn_irq_thread(controller: Arc<Mutex<AhciController>>) -> thread::JoinHandle {
|
||||||
|
let irq_thread = move || {
|
||||||
|
let irq_num = controller.lock().irq_num();
|
||||||
|
let irq_port =
|
||||||
|
mammoth::port::PortServer::from_cap(mammoth::syscall::register_irq(irq_num).unwrap());
|
||||||
|
controller
|
||||||
|
.lock()
|
||||||
|
.ahci_hba()
|
||||||
|
.global_host_control
|
||||||
|
.set_interrupt_enable(true);
|
||||||
|
loop {
|
||||||
|
irq_port.recv_null().unwrap();
|
||||||
|
controller.lock().handle_irq();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thread::spawn(irq_thread)
|
||||||
|
}
|
||||||
|
|
||||||
struct Command {
|
struct Command {
|
||||||
command: SataCommand,
|
command: SataCommand,
|
||||||
lba: u64,
|
lba: u64,
|
||||||
|
@ -253,7 +235,7 @@ impl From<&Command> for HostToDeviceRegisterFis {
|
||||||
|
|
||||||
struct PortController<'a> {
|
struct PortController<'a> {
|
||||||
ahci_port_hba: &'a mut AhciPortHba,
|
ahci_port_hba: &'a mut AhciPortHba,
|
||||||
command_slots: [Option<Rc<Command>>; 32],
|
command_slots: [Option<Arc<Command>>; 32],
|
||||||
command_structures: MemoryRegion,
|
command_structures: MemoryRegion,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +298,7 @@ impl<'a> PortController<'a> {
|
||||||
mammoth::debug!("Sector size: {:#0x}", sector_size);
|
mammoth::debug!("Sector size: {:#0x}", sector_size);
|
||||||
mammoth::debug!("LBA Count: {:#0x}", lba_count);
|
mammoth::debug!("LBA Count: {:#0x}", lba_count);
|
||||||
};
|
};
|
||||||
self.issue_command(Rc::from(Command::identify(callback)?))?;
|
self.issue_command(Arc::from(Command::identify(callback)?))?;
|
||||||
} else {
|
} else {
|
||||||
let sig = self.ahci_port_hba.signature;
|
let sig = self.ahci_port_hba.signature;
|
||||||
mammoth::debug!("Skipping non-sata sig: {:#0x}", sig);
|
mammoth::debug!("Skipping non-sata sig: {:#0x}", sig);
|
||||||
|
@ -324,7 +306,7 @@ impl<'a> PortController<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn issue_command(&mut self, command: Rc<Command>) -> Result<(), ZError> {
|
fn issue_command(&mut self, command: Arc<Command>) -> Result<(), ZError> {
|
||||||
let slot = self.select_slot()?;
|
let slot = self.select_slot()?;
|
||||||
self.command_slots[slot] = Some(command.clone());
|
self.command_slots[slot] = Some(command.clone());
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,5 @@ mod controller;
|
||||||
mod hba;
|
mod hba;
|
||||||
mod port;
|
mod port;
|
||||||
|
|
||||||
|
pub use controller::spawn_irq_thread;
|
||||||
pub use controller::AhciController;
|
pub use controller::AhciController;
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use mammoth::{define_entry, zion::z_err_t};
|
use alloc::sync::Arc;
|
||||||
|
use mammoth::{define_entry, sync::Mutex, zion::z_err_t};
|
||||||
|
|
||||||
use denali::ahci::AhciController;
|
use denali::ahci::{spawn_irq_thread, AhciController};
|
||||||
|
|
||||||
define_entry!();
|
define_entry!();
|
||||||
|
|
||||||
|
@ -19,12 +20,13 @@ extern "C" fn main() -> z_err_t {
|
||||||
.get_ahci_info()
|
.get_ahci_info()
|
||||||
.expect("Failed to get ahci info");
|
.expect("Failed to get ahci info");
|
||||||
|
|
||||||
let ahci_controller = AhciController::new(
|
let ahci_controller = Arc::new(Mutex::new(AhciController::new(
|
||||||
mammoth::mem::MemoryRegion::from_cap(mammoth::cap::Capability::take(ahci_info.ahci_region))
|
mammoth::mem::MemoryRegion::from_cap(mammoth::cap::Capability::take(ahci_info.ahci_region))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
)));
|
||||||
|
|
||||||
ahci_controller.join().unwrap();
|
let thread = spawn_irq_thread(ahci_controller.clone());
|
||||||
|
|
||||||
|
thread.join();
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue