diff --git a/runtime/src/comms.rs b/runtime/src/comms.rs index 96fddec..7280f0e 100644 --- a/runtime/src/comms.rs +++ b/runtime/src/comms.rs @@ -19,6 +19,7 @@ use libboard_zynq::{ }; use libsupport_zynq::alloc::{vec, vec::Vec}; use libasync::{smoltcp::{Sockets, TcpStream}, task}; +use alloc::sync::Arc; use crate::kernel; @@ -136,7 +137,22 @@ enum Reply { ClockFailure = 15, } -async fn send_header(stream: &TcpStream, reply: Reply) -> Result<()> { +async fn write_i32(stream: &TcpStream, value: i32) -> Result<()> { + stream.send([ + (value >> 24) as u8, + (value >> 16) as u8, + (value >> 8) as u8, + value as u8].iter().copied()).await?; + Ok(()) +} + +async fn write_chunk(stream: &TcpStream, chunk: &[u8]) -> Result<()> { + write_i32(stream, chunk.len() as i32).await?; + stream.send(chunk.iter().copied()).await?; + Ok(()) +} + +async fn write_header(stream: &TcpStream, reply: Reply) -> Result<()> { stream.send([0x5a, 0x5a, 0x5a, 0x5a, reply.to_u8().unwrap()].iter().copied()).await?; Ok(()) } @@ -149,7 +165,7 @@ async fn handle_connection(stream: &TcpStream, control: Rc { - send_header(&stream, Reply::SystemInfo).await?; + write_header(&stream, Reply::SystemInfo).await?; stream.send("ARZQ".bytes()).await?; }, Request::LoadKernel => { @@ -160,14 +176,24 @@ async fn handle_connection(stream: &TcpStream, control: Rc write_header(&stream, Reply::LoadCompleted).await?, + kernel::Message::LoadFailed => { + write_header(&stream, Reply::LoadFailed).await?; + write_chunk(&stream, b"core1 failed to process data").await?; + }, + _ => { + println!("received unexpected message from core1: {:?}", reply); + write_header(&stream, Reply::LoadFailed).await?; + write_chunk(&stream, b"core1 sent unexpected reply").await?; + } + } } else { read_drain(&stream, length).await?; - send_header(&stream, Reply::LoadFailed).await?; + write_header(&stream, Reply::LoadFailed).await?; + write_chunk(&stream, b"kernel is too large").await?; } } _ => return Err(Error::UnrecognizedPacket) diff --git a/runtime/src/kernel.rs b/runtime/src/kernel.rs index 8dccb07..550428f 100644 --- a/runtime/src/kernel.rs +++ b/runtime/src/kernel.rs @@ -1,16 +1,19 @@ -use alloc::{vec, vec::Vec}; +use alloc::{vec, vec::Vec, sync::Arc}; use libcortex_a9::{mutex::Mutex, sync_channel::{self, sync_channel}}; use libboard_zynq::println; use libsupport_zynq::boot::Core1; use dyld; +use crate::pl::csr; +use crate::rtio; #[derive(Debug)] pub enum Message { - LoadRequest, - LoadReply, + LoadRequest(Arc>), + LoadCompleted, + LoadFailed, } static CHANNEL_0TO1: Mutex>> = Mutex::new(None); @@ -54,6 +57,40 @@ impl Control { } } +macro_rules! api { + ($i:ident) => ({ + extern { static $i: u8; } + api!($i = &$i as *const _) + }); + ($i:ident, $d:item) => ({ + $d + api!($i = $i) + }); + ($i:ident = $e:expr) => { + (stringify!($i), $e as *const ()) + } +} + +fn resolve(required: &[u8]) -> Option { + let api = &[ + /* proxified syscalls */ + api!(now = csr::rtio::NOW_HI_ADDR as *const _), + + api!(rtio_init = rtio::init), + api!(rtio_get_destination_status = rtio::get_destination_status), + api!(rtio_get_counter = rtio::get_counter), + api!(rtio_output = rtio::output), + api!(rtio_output_wide = rtio::output_wide), + api!(rtio_input_timestamp = rtio::input_timestamp), + api!(rtio_input_data = rtio::input_data), + api!(rtio_input_timestamped_data = rtio::input_timestamped_data), + ]; + api.iter() + .find(|&&(exported, _)| exported.as_bytes() == required) + .map(|&(_, ptr)| ptr as u32) +} + + #[no_mangle] pub fn main_core1() { println!("Core1 started"); @@ -70,10 +107,20 @@ pub fn main_core1() { } let core1_rx = core1_rx.unwrap(); + let mut image = vec![0; 32768]; for message in core1_rx { - println!("core1 received: {:?}", message); match *message { - Message::LoadRequest => core1_tx.send(Message::LoadReply), + Message::LoadRequest(data) => { + match dyld::Library::load(&data, &mut image, &resolve) { + Ok(library) => { + core1_tx.send(Message::LoadCompleted) + }, + Err(error) => { + println!("failed to load shared library: {}", error); + core1_tx.send(Message::LoadFailed) + } + } + }, _ => println!("Core1 received unexpected message: {:?}", message), } }