diff --git a/artiq/firmware/Cargo.lock b/artiq/firmware/Cargo.lock index b14a8b490..13bcb05ed 100644 --- a/artiq/firmware/Cargo.lock +++ b/artiq/firmware/Cargo.lock @@ -111,7 +111,6 @@ name = "io" version = "0.0.0" dependencies = [ "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "std_artiq 0.0.0", ] [[package]] diff --git a/artiq/firmware/libio/Cargo.toml b/artiq/firmware/libio/Cargo.toml index 4f6ffd678..9729aca32 100644 --- a/artiq/firmware/libio/Cargo.toml +++ b/artiq/firmware/libio/Cargo.toml @@ -9,7 +9,6 @@ path = "lib.rs" [dependencies] byteorder = { version = "1.0", default-features = false, optional = true } -std_artiq = { path = "../libstd_artiq", optional = true } [features] alloc = [] diff --git a/artiq/firmware/libio/lib.rs b/artiq/firmware/libio/lib.rs index 8c0b501af..c536e5383 100644 --- a/artiq/firmware/libio/lib.rs +++ b/artiq/firmware/libio/lib.rs @@ -8,9 +8,6 @@ extern crate alloc; #[cfg(feature = "byteorder")] extern crate byteorder; -#[cfg(feature = "std_artiq")] -extern crate std_artiq; - use core::result; use core::fmt; @@ -67,6 +64,14 @@ pub trait Read { } } +impl<'a, T: Read> Read for &'a mut T { + type ReadError = T::ReadError; + + fn read(&mut self, buf: &mut [u8]) -> result::Result { + T::read(self, buf) + } +} + pub trait Write { type WriteError; type FlushError; @@ -99,7 +104,23 @@ pub trait Write { fn size_hint(&mut self, _min: usize, _max: Option) {} } -#[cfg(not(feature = "std_artiq"))] +impl<'a, T: Write> Write for &'a mut T { + type WriteError = T::WriteError; + type FlushError = T::FlushError; + + fn write(&mut self, buf: &[u8]) -> result::Result { + T::write(self, buf) + } + + fn flush(&mut self) -> result::Result<(), Self::FlushError> { + T::flush(self) + } + + fn size_hint(&mut self, min: usize, max: Option) { + T::size_hint(self, min, max) + } +} + impl<'a> Write for &'a mut [u8] { type WriteError = !; type FlushError = !; @@ -116,6 +137,22 @@ impl<'a> Write for &'a mut [u8] { } } +#[cfg(feature = "alloc")] +impl<'a> Write for alloc::Vec { + type WriteError = !; + type FlushError = !; + + fn write(&mut self, buf: &[u8]) -> result::Result { + self.extend_from_slice(buf); + Ok(buf.len()) + } + + #[inline] + fn flush(&mut self) -> result::Result<(), Self::FlushError> { + Ok(()) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum CursorError { EndOfBuffer @@ -196,7 +233,7 @@ impl Write for Cursor<::alloc::Vec> { #[inline] fn write(&mut self, buf: &[u8]) -> result::Result { - self.inner.extend(buf); + self.inner.extend_from_slice(buf); Ok(buf.len()) } @@ -205,44 +242,3 @@ impl Write for Cursor<::alloc::Vec> { Ok(()) } } - -#[cfg(feature = "std_artiq")] -impl Read for T where T: std_artiq::io::Read + ?Sized { - type ReadError = std_artiq::io::Error; - - fn read(&mut self, buf: &mut [u8]) -> result::Result { - std_artiq::io::Read::read(self, buf) - } -} - -#[cfg(feature = "std_artiq")] -impl Write for T where T: std_artiq::io::Write + ?Sized { - type WriteError = std_artiq::io::Error; - type FlushError = std_artiq::io::Error; - - fn write(&mut self, buf: &[u8]) -> result::Result { - std_artiq::io::Write::write(self, buf) - } - - fn flush(&mut self) -> result::Result<(), Self::WriteError> { - std_artiq::io::Write::flush(self) - } -} - -#[cfg(feature = "std_artiq")] -impl From> for std_artiq::io::Error - where T: Into -{ - fn from(value: Error) -> std_artiq::io::Error { - match value { - Error::UnexpectedEof => - std_artiq::io::Error::new(std_artiq::io::ErrorKind::UnexpectedEof, - "unexpected end of stream"), - Error::Unrecognized => - std_artiq::io::Error::new(std_artiq::io::ErrorKind::InvalidData, - "unrecognized data"), - Error::Other(err) => - err.into() - } - } -} diff --git a/artiq/firmware/libio/proto.rs b/artiq/firmware/libio/proto.rs index bb36ffa40..0722f6926 100644 --- a/artiq/firmware/libio/proto.rs +++ b/artiq/firmware/libio/proto.rs @@ -36,21 +36,6 @@ impl From>> for IoError } } -#[cfg(feature = "alloc")] -#[cfg(feature = "std_artiq")] -impl From> for ::std_artiq::io::Error - where T: Into<::std_artiq::io::Error> -{ - fn from(value: ReadStringError) -> ::std_artiq::io::Error { - match value { - ReadStringError::Utf8Error(_) => - ::std_artiq::io::Error::new(::std_artiq::io::ErrorKind::InvalidData, - "invalid UTF-8"), - ReadStringError::Other(err) => err.into() - } - } -} - pub trait ProtoRead { type ReadError; diff --git a/artiq/firmware/runtime/Cargo.toml b/artiq/firmware/runtime/Cargo.toml index 2057502df..3f05a2cb2 100644 --- a/artiq/firmware/runtime/Cargo.toml +++ b/artiq/firmware/runtime/Cargo.toml @@ -19,7 +19,7 @@ cslice = { version = "0.3" } log = { version = "0.4", default-features = false } managed = { version = "0.6", default-features = false, features = ["alloc", "map"] } unwind_backtrace = { path = "../libunwind_backtrace" } -io = { path = "../libio", features = ["byteorder", "std_artiq"] } +io = { path = "../libio", features = ["byteorder"] } alloc_list = { path = "../liballoc_list" } board_misoc = { path = "../libboard_misoc", features = ["uart_console", "smoltcp"] } std_artiq = { path = "../libstd_artiq", features = ["alloc", "io_error_alloc"] } diff --git a/artiq/firmware/runtime/analyzer.rs b/artiq/firmware/runtime/analyzer.rs index 2ff4d6cd4..8bebf851b 100644 --- a/artiq/firmware/runtime/analyzer.rs +++ b/artiq/firmware/runtime/analyzer.rs @@ -1,4 +1,4 @@ -use std::io::{self, Write}; +use io::{self, Write}; use board_misoc::{csr, cache}; use sched::{Io, TcpListener, TcpStream}; use analyzer_proto::*; @@ -35,7 +35,7 @@ fn disarm() { } } -fn worker(stream: &mut TcpStream) -> io::Result<()> { +fn worker(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> { let data = unsafe { &BUFFER.data[..] }; let overflow_occurred = unsafe { csr::rtio_analyzer::message_encoder_overflow_read() != 0 }; let total_byte_count = unsafe { csr::rtio_analyzer::dma_byte_count_read() }; diff --git a/artiq/firmware/runtime/kern_hwreq.rs b/artiq/firmware/runtime/kern_hwreq.rs index fec653e9c..610e5be96 100644 --- a/artiq/firmware/runtime/kern_hwreq.rs +++ b/artiq/firmware/runtime/kern_hwreq.rs @@ -1,4 +1,4 @@ -use std::io; +use io; use kernel_proto as kern; use sched::Io; use session::{kern_acknowledge, kern_send}; @@ -291,7 +291,7 @@ mod spi { } } -pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result { +pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result { match request { #[cfg(has_rtio_core)] &kern::RtioInitRequest => { diff --git a/artiq/firmware/runtime/mgmt.rs b/artiq/firmware/runtime/mgmt.rs index 2e30c5cfd..d1ae97260 100644 --- a/artiq/firmware/runtime/mgmt.rs +++ b/artiq/firmware/runtime/mgmt.rs @@ -1,27 +1,26 @@ -use std::io::{self, Read, Write}; use log::{self, LevelFilter}; +use io::{self, Read, Write, proto::ProtoWrite}; use board_misoc::boot; -use io::proto::ProtoWrite; use logger_artiq::BufferLogger; use sched::Io; use sched::{TcpListener, TcpStream}; use mgmt_proto::*; use profiler; -fn check_magic(stream: &mut TcpStream) -> io::Result<()> { +fn check_magic(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> { const MAGIC: &'static [u8] = b"ARTIQ management\n"; let mut magic: [u8; 17] = [0; 17]; stream.read_exact(&mut magic)?; if magic != MAGIC { - Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic")) + Err(io::Error::Unrecognized) } else { Ok(()) } } -fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<()> { +fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> { check_magic(stream)?; info!("new connection from {}", stream.remote_endpoint()); @@ -35,7 +34,7 @@ fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<()> { } Request::ClearLog => { - BufferLogger::with(|logger| -> io::Result<()> { + BufferLogger::with(|logger| -> io::Result<(), ::std::io::Error> { let mut buffer = io.until_ok(|| logger.buffer())?; Ok(buffer.clear()) })?; @@ -44,7 +43,7 @@ fn worker(io: &Io, stream: &mut TcpStream) -> io::Result<()> { } Request::PullLog => { - BufferLogger::with(|logger| -> io::Result<()> { + BufferLogger::with(|logger| -> io::Result<(), ::std::io::Error> { loop { // Do this *before* acquiring the buffer, since that sets the log level // to OFF. @@ -166,8 +165,7 @@ pub fn thread(io: Io) { let mut stream = TcpStream::from_handle(&io, stream); match worker(&io, &mut stream) { Ok(()) => (), - Err(ref err) if err.kind() == io::ErrorKind::UnexpectedEof => (), - Err(ref err) if err.kind() == io::ErrorKind::WriteZero => (), + Err(io::Error::UnexpectedEof) => (), Err(err) => error!("aborted: {}", err) } }); diff --git a/artiq/firmware/runtime/moninj.rs b/artiq/firmware/runtime/moninj.rs index ecb862b38..36fae9430 100644 --- a/artiq/firmware/runtime/moninj.rs +++ b/artiq/firmware/runtime/moninj.rs @@ -1,6 +1,6 @@ use alloc::btree_map::BTreeMap; -use std::io::{self, Read}; +use io::{self, Read}; use sched::Io; use sched::{TcpListener, TcpStream}; use board_misoc::{clock, csr}; @@ -9,13 +9,13 @@ use drtioaux; use moninj_proto::*; -fn check_magic(stream: &mut TcpStream) -> io::Result<()> { +fn check_magic(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> { const MAGIC: &'static [u8] = b"ARTIQ moninj\n"; let mut magic: [u8; 13] = [0; 13]; stream.read_exact(&mut magic)?; if magic != MAGIC { - Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic")) + Err(io::Error::Unrecognized) } else { Ok(()) } @@ -159,7 +159,7 @@ fn read_injection_status(channel: u32, probe: u8) -> u8 { 0 } -fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> io::Result<()> { +fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> { let mut watch_list = BTreeMap::new(); let mut next_check = 0; diff --git a/artiq/firmware/runtime/rtio_dma.rs b/artiq/firmware/runtime/rtio_dma.rs index b0f964d86..6c135e72a 100644 --- a/artiq/firmware/runtime/rtio_dma.rs +++ b/artiq/firmware/runtime/rtio_dma.rs @@ -1,7 +1,7 @@ use core::mem; use alloc::{Vec, String, BTreeMap}; -use std::io::Write; +use io::Write; const ALIGNMENT: usize = 64; diff --git a/artiq/firmware/runtime/sched.rs b/artiq/firmware/runtime/sched.rs index e9ca34cc3..d6f2efcb7 100644 --- a/artiq/firmware/runtime/sched.rs +++ b/artiq/firmware/runtime/sched.rs @@ -9,8 +9,9 @@ use fringe::generator::{Generator, Yielder, State as GeneratorState}; use smoltcp::wire::IpEndpoint; use smoltcp::socket::{SocketHandle, SocketRef}; +use io::{Read, Write}; use board_misoc::clock; -use std::io::{Read, Write, Result, Error, ErrorKind}; +use std::io::{Result, Error, ErrorKind}; use urc::Urc; type SocketSet = ::smoltcp::socket::SocketSet<'static, 'static, 'static>; @@ -446,6 +447,8 @@ impl<'a> TcpStream<'a> { } impl<'a> Read for TcpStream<'a> { + type ReadError = Error; + fn read(&mut self, buf: &mut [u8]) -> Result { // Only borrow the underlying socket for the span of the next statement. let result = self.with_lower(|mut s| s.recv_slice(buf)); @@ -470,6 +473,9 @@ impl<'a> Read for TcpStream<'a> { } impl<'a> Write for TcpStream<'a> { + type WriteError = Error; + type FlushError = Error; + fn write(&mut self, buf: &[u8]) -> Result { // Only borrow the underlying socket for the span of the next statement. let result = self.with_lower(|mut s| s.send_slice(buf)); diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index 82cf8c89c..63e397776 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -2,8 +2,8 @@ use core::{mem, str, cell::{Cell, RefCell}, fmt::Write as FmtWrite}; use alloc::{Vec, String}; use byteorder::{ByteOrder, NetworkEndian}; +use io::{self, Read, Write}; use board_misoc::{ident, cache, config}; -use std::io::{self, Read, Write}; use {mailbox, rpc_queue, kernel}; use urc::Urc; use sched::{ThreadHandle, Io}; @@ -23,13 +23,13 @@ macro_rules! unexpected { ($($arg:tt)*) => { { error!($($arg)*); - return Err(io::Error::new(io::ErrorKind::InvalidData, "protocol error")) + return Err(io::Error::Unrecognized) } }; } -fn io_error(msg: &str) -> io::Error { - io::Error::new(io::ErrorKind::Other, msg) +fn io_error(msg: &str) -> io::Error<::std::io::Error> { + io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::Other, msg)) } // Persistent state @@ -102,19 +102,19 @@ impl<'a> Drop for Session<'a> { } } -fn check_magic(stream: &mut TcpStream) -> io::Result<()> { +fn check_magic(stream: &mut TcpStream) -> io::Result<(), ::std::io::Error> { const MAGIC: &'static [u8] = b"ARTIQ coredev\n"; let mut magic: [u8; 14] = [0; 14]; stream.read_exact(&mut magic)?; if magic != MAGIC { - Err(io::Error::new(io::ErrorKind::InvalidData, "unrecognized magic")) + Err(io::Error::Unrecognized) } else { Ok(()) } } -fn host_read(stream: &mut TcpStream) -> io::Result { +fn host_read(stream: &mut TcpStream) -> io::Result { let request = host::Request::read_from(stream)?; match &request { &host::Request::LoadKernel(_) => debug!("comm<-host LoadLibrary(...)"), @@ -123,12 +123,12 @@ fn host_read(stream: &mut TcpStream) -> io::Result { Ok(request) } -fn host_write(stream: &mut Write, reply: host::Reply) -> io::Result<()> { +fn host_write(stream: &mut TcpStream, reply: host::Reply) -> io::Result<(), ::std::io::Error> { debug!("comm->host {:?}", reply); - Ok(reply.write_to(stream)?) + reply.write_to(stream) } -pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<()> { +pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<(), ::std::io::Error> { match request { &kern::LoadRequest(_) => debug!("comm->kern LoadRequest(...)"), &kern::DmaRetrieveReply { trace, duration } => { @@ -141,15 +141,15 @@ pub fn kern_send(io: &Io, request: &kern::Message) -> io::Result<()> { _ => debug!("comm->kern {:?}", request) } unsafe { mailbox::send(request as *const _ as usize) } - io.until(mailbox::acknowledged) + Ok(io.until(mailbox::acknowledged)?) } -fn kern_recv_notrace(io: &Io, f: F) -> io::Result - where F: FnOnce(&kern::Message) -> io::Result { +fn kern_recv_notrace(io: &Io, f: F) -> io::Result + where F: FnOnce(&kern::Message) -> io::Result { io.until(|| mailbox::receive() != 0)?; if !kernel::validate(mailbox::receive()) { let message = format!("invalid kernel CPU pointer 0x{:x}", mailbox::receive()); - return Err(io::Error::new(io::ErrorKind::InvalidData, message)) + return Err(io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::InvalidData, message))) } f(unsafe { &*(mailbox::receive() as *const kern::Message) }) @@ -171,20 +171,20 @@ fn kern_recv_dotrace(reply: &kern::Message) { } #[inline(always)] -fn kern_recv(io: &Io, f: F) -> io::Result - where F: FnOnce(&kern::Message) -> io::Result { +fn kern_recv(io: &Io, f: F) -> io::Result + where F: FnOnce(&kern::Message) -> io::Result { kern_recv_notrace(io, |reply| { kern_recv_dotrace(reply); f(reply) }) } -pub fn kern_acknowledge() -> io::Result<()> { +pub fn kern_acknowledge() -> io::Result<(), ::std::io::Error> { mailbox::acknowledge(); Ok(()) } -unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Result<()> { +unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Result<(), ::std::io::Error> { if session.running() { unexpected!("attempted to load a new kernel while a kernel was running") } @@ -200,8 +200,8 @@ unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Resul } &kern::LoadReply(Err(ref error)) => { kernel::stop(); - Err(io::Error::new(io::ErrorKind::Other, - format!("cannot load kernel: {}", error))) + Err(io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::Other, + format!("cannot load kernel: {}", error)))) } other => unexpected!("unexpected reply from kernel CPU: {:?}", other) @@ -209,7 +209,7 @@ unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Resul }) } -fn kern_run(session: &mut Session) -> io::Result<()> { +fn kern_run(session: &mut Session) -> io::Result<(), ::std::io::Error> { if session.kernel_state != KernelState::Loaded { unexpected!("attempted to run a kernel while not in Loaded state") } @@ -221,7 +221,7 @@ fn kern_run(session: &mut Session) -> io::Result<()> { fn process_host_message(io: &Io, stream: &mut TcpStream, - session: &mut Session) -> io::Result<()> { + session: &mut Session) -> io::Result<(), ::std::io::Error> { match host_read(stream)? { host::Request::SystemInfo => { host_write(stream, host::Reply::SystemInfo { @@ -359,7 +359,7 @@ fn process_host_message(io: &Io, } fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>, - session: &mut Session) -> io::Result { + session: &mut Session) -> io::Result { kern_recv_notrace(io, |request| { match (request, session.kernel_state) { (&kern::LoadReply(_), KernelState::Loaded) | @@ -516,7 +516,7 @@ fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>, } fn process_kern_queued_rpc(stream: &mut TcpStream, - _session: &mut Session) -> io::Result<()> { + _session: &mut Session) -> io::Result<(), ::std::io::Error> { rpc_queue::dequeue(|slice| { debug!("comm<-kern (async RPC)"); let length = NetworkEndian::read_u32(slice) as usize; @@ -529,7 +529,7 @@ fn process_kern_queued_rpc(stream: &mut TcpStream, fn host_kernel_worker(io: &Io, stream: &mut TcpStream, - congress: &mut Congress) -> io::Result<()> { + congress: &mut Congress) -> io::Result<(), ::std::io::Error> { let mut session = Session::new(congress); loop { @@ -568,7 +568,7 @@ fn host_kernel_worker(io: &Io, fn flash_kernel_worker(io: &Io, congress: &mut Congress, - config_key: &str) -> io::Result<()> { + config_key: &str) -> io::Result<(), ::std::io::Error> { let mut session = Session::new(congress); config::read(config_key, |result| { @@ -578,7 +578,8 @@ fn flash_kernel_worker(io: &Io, // so make a copy. kern_load(io, &mut session, Vec::from(kernel).as_ref()) }, - _ => Err(io::Error::new(io::ErrorKind::NotFound, "kernel not found")), + _ => Err(io::Error::Other(::std::io::Error::new(::std::io::ErrorKind::NotFound, + "kernel not found"))), } })?; kern_run(&mut session)?; @@ -639,13 +640,12 @@ pub fn thread(io: Io) { info!("running startup kernel"); match flash_kernel_worker(&io, &mut congress, "startup_kernel") { Ok(()) => info!("startup kernel finished"), + Err(io::Error::Other(ref err)) if err.kind() == ::std::io::ErrorKind::NotFound => { + info!("no startup kernel found") + } Err(err) => { - if err.kind() == io::ErrorKind::NotFound { - info!("no startup kernel found") - } else { - congress.finished_cleanly.set(false); - error!("startup kernel aborted: {}", err); - } + congress.finished_cleanly.set(false); + error!("startup kernel aborted: {}", err); } } }) @@ -674,15 +674,16 @@ pub fn thread(io: Io) { let mut stream = TcpStream::from_handle(&io, stream); match host_kernel_worker(&io, &mut stream, &mut *congress) { Ok(()) => (), + Err(io::Error::UnexpectedEof) => { + info!("connection closed"); + } + Err(io::Error::Other(ref err)) + if err.kind() == ::std::io::ErrorKind::Interrupted => { + info!("kernel interrupted"); + } Err(err) => { - if err.kind() == io::ErrorKind::UnexpectedEof { - info!("connection closed"); - } else if err.kind() == io::ErrorKind::Interrupted { - info!("kernel interrupted"); - } else { - congress.finished_cleanly.set(false); - error!("session aborted: {}", err); - } + congress.finished_cleanly.set(false); + error!("session aborted: {}", err); } } }); @@ -697,15 +698,17 @@ pub fn thread(io: Io) { match flash_kernel_worker(&io, &mut *congress, "idle_kernel") { Ok(()) => info!("idle kernel finished, standing by"), + Err(io::Error::Other(ref err)) + if err.kind() == ::std::io::ErrorKind::Interrupted => { + info!("idle kernel interrupted"); + } + Err(io::Error::Other(ref err)) + if err.kind() == ::std::io::ErrorKind::NotFound => { + info!("no idle kernel found"); + while io.relinquish().is_ok() {} + } Err(err) => { - if err.kind() == io::ErrorKind::Interrupted { - info!("idle kernel interrupted"); - } else if err.kind() == io::ErrorKind::NotFound { - info!("no idle kernel found"); - while io.relinquish().is_ok() {} - } else { - error!("idle kernel aborted: {}", err); - } + error!("idle kernel aborted: {}", err); } } })