diff --git a/src/libio/src/cursor.rs b/src/libio/src/cursor.rs index 85ff478f..095ae1fe 100644 --- a/src/libio/src/cursor.rs +++ b/src/libio/src/cursor.rs @@ -69,7 +69,7 @@ impl<'a> Write for Cursor<&'a mut [u8]> { } #[cfg(feature = "alloc")] -impl Write for Cursor<::alloc::vec::Vec> { +impl Write for Cursor<&mut ::alloc::vec::Vec> { type WriteError = !; type FlushError = !; diff --git a/src/runtime/src/comms.rs b/src/runtime/src/comms.rs index 9fb24968..b4e50909 100644 --- a/src/runtime/src/comms.rs +++ b/src/runtime/src/comms.rs @@ -139,6 +139,21 @@ async fn handle_connection(stream: &TcpStream, control: Rc { let mut control = control.borrow_mut(); control.tx.async_send(kernel::Message::StartRequest).await; + loop { + let reply = control.rx.async_recv().await; + match *reply { + kernel::Message::KernelFinished => { + write_header(&stream, Reply::KernelFinished).await?; + break; + }, + kernel::Message::RpcSend { is_async, data } => { + debug!("RPC: is_async={} data={:?}", is_async, data); + }, + _ => { + error!("received unexpected message from core1 while kernel was running: {:?}", reply); + } + } + } } _ => return Err(Error::UnrecognizedPacket) } diff --git a/src/runtime/src/kernel.rs b/src/runtime/src/kernel.rs index d031ef5b..34cd1eb5 100644 --- a/src/runtime/src/kernel.rs +++ b/src/runtime/src/kernel.rs @@ -1,11 +1,14 @@ use core::{ptr, mem}; use log::{debug, error}; use alloc::{vec::Vec, sync::Arc}; +use cslice::CSlice; use libcortex_a9::{mutex::Mutex, sync_channel::{self, sync_channel}}; use libsupport_zynq::boot::Core1; use dyld; +use io; +use crate::rpc; use crate::rtio; @@ -15,6 +18,8 @@ pub enum Message { LoadCompleted, LoadFailed, StartRequest, + KernelFinished, + RpcSend { is_async: bool, data: Arc> }, } static CHANNEL_0TO1: Mutex>> = Mutex::new(None); @@ -57,6 +62,34 @@ impl Control { } } +static mut KERNEL_CHANNEL_0TO1: *mut () = ptr::null_mut(); +static mut KERNEL_CHANNEL_1TO0: *mut () = ptr::null_mut(); + +extern fn rpc_send(service: u32, tag: &CSlice, data: *const *const ()) { + let core1_rx: &mut sync_channel::Receiver = unsafe { mem::transmute(KERNEL_CHANNEL_0TO1) }; + let core1_tx: &mut sync_channel::Sender = unsafe { mem::transmute(KERNEL_CHANNEL_1TO0) }; + let mut buffer = Arc::new(Vec::::new()); + { + let mut writer = io::Cursor::new(Arc::get_mut(&mut buffer).unwrap()); + rpc::send_args(&mut writer, service, tag.as_ref(), data).expect("RPC encoding failed"); + } + core1_tx.send(Message::RpcSend { is_async: false, data: buffer }) +} + +extern fn rpc_send_async(service: u32, tag: &CSlice, data: *const *const ()) { + let core1_tx: &mut sync_channel::Sender = unsafe { mem::transmute(KERNEL_CHANNEL_1TO0) }; + let mut buffer = Arc::new(Vec::::new()); + { + let mut writer = io::Cursor::new(Arc::get_mut(&mut buffer).unwrap()); + rpc::send_args(&mut writer, service, tag.as_ref(), data).expect("RPC encoding failed"); + } + core1_tx.send(Message::RpcSend { is_async: true, data: buffer }) +} + +extern fn rpc_recv(slot: *mut ()) -> usize { + unimplemented!(); +} + macro_rules! api { ($i:ident) => ({ extern { static $i: u8; } @@ -77,6 +110,10 @@ fn resolve(required: &[u8]) -> Option { api!(at_mu = rtio::at_mu), api!(delay_mu = rtio::delay_mu), + api!(rpc_send = rpc_send), + api!(rpc_send_async = rpc_send_async), + api!(rpc_recv = rpc_recv), + api!(rtio_init = rtio::init), api!(rtio_get_destination_status = rtio::get_destination_status), api!(rtio_get_counter = rtio::get_counter), @@ -108,10 +145,11 @@ pub fn main_core1() { while core1_rx.is_none() { core1_rx = CHANNEL_0TO1.lock().take(); } - let core1_rx = core1_rx.unwrap(); + let mut core1_rx = core1_rx.unwrap(); let mut current_modinit: Option = None; - for message in core1_rx { + loop { + let message = core1_rx.recv(); match *message { Message::LoadRequest(data) => { match dyld::load(&data, &resolve) { @@ -127,11 +165,11 @@ pub fn main_core1() { let __modinit__ = library.lookup(b"__modinit__").unwrap(); current_modinit = Some(__modinit__); debug!("kernel loaded"); - core1_tx.send(Message::LoadCompleted) + core1_tx.send(Message::LoadCompleted); }, Err(error) => { error!("failed to load shared library: {}", error); - core1_tx.send(Message::LoadFailed) + core1_tx.send(Message::LoadFailed); } } }, @@ -139,10 +177,15 @@ pub fn main_core1() { debug!("kernel starting"); if let Some(__modinit__) = current_modinit { unsafe { + KERNEL_CHANNEL_0TO1 = mem::transmute(&mut core1_rx); + KERNEL_CHANNEL_1TO0 = mem::transmute(&mut core1_tx); (mem::transmute::(__modinit__))(); + KERNEL_CHANNEL_0TO1 = ptr::null_mut(); + KERNEL_CHANNEL_1TO0 = ptr::null_mut(); } } - debug!("kernel terminated"); + debug!("kernel finished"); + core1_tx.send(Message::KernelFinished); } _ => error!("Core1 received unexpected message: {:?}", message), }