Run denali server thread.

This commit is contained in:
Drew Galbraith 2025-02-01 12:11:59 -08:00
parent 10e536acab
commit a5cdd23f0b
7 changed files with 104 additions and 19 deletions

View File

@ -28,11 +28,11 @@ pub struct Task {
id: TaskId,
// FIXME: This only needs to be sync because of the CURRENT_EXECUTOR
// needing to be shared between threads.
future: Pin<Box<dyn Future<Output = ()> + Sync>>,
future: Pin<Box<dyn Future<Output = ()> + Sync + Send>>,
}
impl Task {
pub fn new(future: impl Future<Output = ()> + Sync + 'static) -> Task {
pub fn new(future: impl Future<Output = ()> + Sync + Send + 'static) -> Task {
Task {
id: TaskId::new(),
future: Box::pin(future),

View File

@ -99,7 +99,7 @@ where
mut byte_buffer: ByteBuffer<1024>,
mut cap_buffer: Vec<u64>,
reply_port_cap: Capability,
) -> impl Future<Output = ()> + Sync {
) -> impl Future<Output = ()> + Sync + Send {
async move {
let resp = self
.handle_request(method, &mut byte_buffer, &mut cap_buffer)
@ -134,12 +134,14 @@ where
method_number: u64,
byte_buffer: &mut ByteBuffer<1024>,
cap_buffer: &mut Vec<z_cap_t>,
) -> impl Future<Output = Result<usize, ZError>> + Sync;
) -> impl Future<Output = Result<usize, ZError>> + Sync + Send;
}
pub fn spawn_async_server_thread<T>(server: Arc<T>, executor: Arc<Mutex<Executor>>)
pub fn spawn_async_server_thread<T>(server: Arc<T>, executor: Arc<Mutex<Executor>>) -> JoinHandle
where
T: AsyncYunqServer + Send + Sync + 'static,
{
server.server_loop(executor);
thread::spawn(move || {
server.server_loop(executor);
})
}

View File

@ -9,6 +9,7 @@ use alloc::boxed::Box;
use alloc::sync::Arc;
use mammoth::cap::Capability;
use mammoth::sync::Mutex;
use mammoth::syscall;
use mammoth::{mem, thread};
use mammoth::{mem::MemoryRegion, zion::ZError};
@ -141,10 +142,12 @@ impl AhciController {
for port in self.ports.iter().flatten() {
let sig = port.get_signature();
if sig == 0x101 {
let command = Command::identify()?;
let mut command = Command::identify()?;
mammoth::debug!("IDENT!");
port.issue_command(&command)?.await;
let ident = command.memory_region.slice::<u16>();
let memory_region =
MemoryRegion::from_cap(Capability::take(command.release_mem_cap()))?;
let ident = memory_region.slice::<u16>();
let new_sector_size = if ident[106] & (1 << 12) != 0 {
ident[117] as u32 | ((ident[118] as u32) << 16)
} else {
@ -170,6 +173,18 @@ impl AhciController {
}
Ok(())
}
pub async fn issue_command(&self, port_num: usize, command: &Command) -> Result<(), ZError> {
assert!(port_num < 32);
self.ports[port_num]
.as_ref()
.ok_or(ZError::INVALID_ARGUMENT)?
.issue_command(command)?
.await;
Ok(())
}
}
pub fn spawn_irq_thread(controller: Arc<AhciController>) -> thread::JoinHandle {
@ -202,11 +217,11 @@ enum CommandStatus {
struct CommandFuture {
status: Arc<Mutex<CommandStatus>>,
trigger: Box<dyn Fn() + Sync>,
trigger: Box<dyn Fn() + Sync + Send>,
}
impl CommandFuture {
fn new(status: Arc<Mutex<CommandStatus>>, trigger: Box<dyn Fn() + Sync>) -> Self {
fn new(status: Arc<Mutex<CommandStatus>>, trigger: Box<dyn Fn() + Sync + Send>) -> Self {
Self { status, trigger }
}
}
@ -236,28 +251,44 @@ impl Future for CommandFuture {
}
}
struct Command {
pub struct Command {
command: SataCommand,
lba: u64,
sector_cnt: u16,
paddr: u64,
#[allow(dead_code)] // We need to own this even if we never access it.
memory_region: MemoryRegion,
memory_region: Option<Capability>,
}
impl Command {
pub fn identify() -> Result<Self, ZError> {
let (memory_region, paddr) = MemoryRegion::contiguous_physical(512)?;
let (memory_region, paddr) = syscall::memory_object_contiguous_physical(512)?;
Ok(Self {
command: SataCommand::IdentifyDevice,
lba: 0,
sector_cnt: 1,
paddr,
memory_region,
memory_region: Some(memory_region),
})
}
pub fn read(lba: u64, lba_count: u16) -> Result<Self, ZError> {
let (memory_region, paddr) =
syscall::memory_object_contiguous_physical(512 * (lba_count as u64))?;
Ok(Self {
command: SataCommand::DmaReadExt,
lba,
sector_cnt: lba_count,
paddr,
memory_region: Some(memory_region),
})
}
pub fn release_mem_cap(&mut self) -> u64 {
self.memory_region.take().unwrap().release()
}
}
impl From<&Command> for HostToDeviceRegisterFis {

View File

@ -6,3 +6,4 @@ mod port;
pub use controller::identify_ports;
pub use controller::spawn_irq_thread;
pub use controller::AhciController;
pub use controller::Command;

View File

@ -11,7 +11,8 @@ use mammoth::{
zion::z_err_t,
};
use denali::ahci::{identify_ports, spawn_irq_thread, AhciController};
use denali::ahci::{self, identify_ports, spawn_irq_thread, AhciController};
use denali::{denali_server::DenaliServerImpl, AsyncDenaliServer};
define_entry!();
@ -29,14 +30,25 @@ extern "C" fn main() -> z_err_t {
ahci_info.ahci_region,
)));
let mut executor = Executor::new();
let executor = Arc::new(Mutex::new(Executor::new()));
executor.spawn(Task::new(identify_ports(ahci_controller.clone())));
executor
.clone()
.lock()
.spawn(Task::new(identify_ports(ahci_controller.clone())));
let thread = spawn_irq_thread(ahci_controller.clone());
executor.run();
let denali_server =
Arc::new(AsyncDenaliServer::new(DenaliServerImpl::new(ahci_controller.clone())).unwrap());
let server_thread = yunq::server::spawn_async_server_thread(denali_server, executor.clone());
executor.clone().lock().run();
thread.join().expect("Failed to wait on irq thread.");
server_thread
.join()
.expect("Failed to wait on server thread.");
0
}

View File

@ -0,0 +1,38 @@
use alloc::sync::Arc;
use mammoth::zion::ZError;
use crate::{
ahci::{AhciController, Command},
AsyncDenaliServerHandler, ReadManyRequest, ReadRequest, ReadResponse,
};
pub struct DenaliServerImpl {
ahci_controller: Arc<AhciController>,
}
impl DenaliServerImpl {
pub fn new(controller: Arc<AhciController>) -> Self {
DenaliServerImpl {
ahci_controller: controller,
}
}
}
impl AsyncDenaliServerHandler for DenaliServerImpl {
async fn read(&self, req: ReadRequest) -> Result<ReadResponse, ZError> {
let mut command = Command::read(req.block.lba, req.block.size as u16)?;
self.ahci_controller
.issue_command(req.device_id as usize, &command)
.await?;
Ok(ReadResponse {
device_id: req.device_id,
size: req.block.size,
memory: command.release_mem_cap(),
})
}
async fn read_many(&self, req: ReadManyRequest) -> Result<ReadResponse, ZError> {
Err(ZError::UNIMPLEMENTED)
}
}

View File

@ -5,3 +5,4 @@ use core::include;
include!(concat!(env!("OUT_DIR"), "/yunq.rs"));
pub mod ahci;
pub mod denali_server;