diff --git a/artiq/coredevice/comm_generic.py b/artiq/coredevice/comm_generic.py index 8afa8c096..b44e1fee2 100644 --- a/artiq/coredevice/comm_generic.py +++ b/artiq/coredevice/comm_generic.py @@ -59,6 +59,9 @@ class _D2HMsgType(Enum): class UnsupportedDevice(Exception): pass +class LoadError(Exception): + pass + class RPCReturnValueError(ValueError): pass @@ -265,7 +268,11 @@ class CommGeneric: self._write_header(_H2DMsgType.LOAD_KERNEL) self._write_bytes(kernel_library) - self._read_empty(_D2HMsgType.LOAD_COMPLETED) + self._read_header() + if self._read_type == _D2HMsgType.LOAD_FAILED: + raise LoadError(self._read_string()) + else: + self._read_expect(_D2HMsgType.LOAD_COMPLETED) def run(self): self._write_empty(_H2DMsgType.RUN_KERNEL) diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index ba1c3544c..41c3b837a 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -2,6 +2,7 @@ use std::prelude::v1::*; use std::{mem, str}; use std::cell::RefCell; use std::io::{self, Read, Write}; +use std::error::Error; use std::btree_set::BTreeSet; use {config, rtio_mgt, mailbox, rpc_queue, kernel}; use logger_artiq::BufferLogger; @@ -179,8 +180,10 @@ unsafe fn kern_load(io: &Io, session: &mut Session, library: &[u8]) -> io::Resul session.kernel_state = KernelState::Loaded; Ok(()) } - &kern::LoadReply(Err(error)) => - unexpected!("cannot load kernel: {}", error), + &kern::LoadReply(Err(error)) => { + Err(io::Error::new(io::ErrorKind::Other, + format!("cannot load kernel: {}", error))) + } other => unexpected!("unexpected reply from kernel CPU: {:?}", other) } @@ -259,9 +262,9 @@ fn process_host_message(io: &Io, host::Request::LoadKernel(kernel) => match unsafe { kern_load(io, session, &kernel) } { Ok(()) => host_write(stream, host::Reply::LoadCompleted), - Err(_) => { - try!(kern_acknowledge()); - host_write(stream, host::Reply::LoadFailed) + Err(error) => { + host_write(stream, host::Reply::LoadFailed(error.description())); + kern_acknowledge() } }, diff --git a/artiq/firmware/runtime/session_proto.rs b/artiq/firmware/runtime/session_proto.rs index e83b955f7..3f9df8864 100644 --- a/artiq/firmware/runtime/session_proto.rs +++ b/artiq/firmware/runtime/session_proto.rs @@ -92,7 +92,7 @@ pub enum Reply<'a> { ClockSwitchFailed, LoadCompleted, - LoadFailed, + LoadFailed(&'a str), KernelFinished, KernelStartupFailed, @@ -141,8 +141,9 @@ impl<'a> Reply<'a> { Reply::LoadCompleted => { try!(write_u8(writer, 5)); }, - Reply::LoadFailed => { + Reply::LoadFailed(reason) => { try!(write_u8(writer, 6)); + try!(write_string(writer, reason)); }, Reply::KernelFinished => {