Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2ae30b5a955e
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3e829d0d01ea
Choose a head ref
  • 5 commits
  • 14 files changed
  • 1 contributor

Commits on Oct 6, 2016

  1. test: add more RPC tests.

    whitequark committed Oct 6, 2016
    Copy the full SHA
    6b2789e View commit details
  2. Copy the full SHA
    84214ab View commit details
  3. Rust: implement exceptional kernel termination.

    This also adjusts the way backtraces are serialized by kloader.
    whitequark committed Oct 6, 2016
    Copy the full SHA
    226fa72 View commit details
  4. Rust: implement exceptional RPC replies.

    whitequark committed Oct 6, 2016
    Copy the full SHA
    e92f205 View commit details
  5. Rust: unborrow cache after kernel stops.

    whitequark committed Oct 6, 2016
    Copy the full SHA
    3e829d0 View commit details
6 changes: 6 additions & 0 deletions artiq/runtime.rs/src/cache.rs
Original file line number Diff line number Diff line change
@@ -44,4 +44,10 @@ impl Cache {
});
Ok(())
}

pub unsafe fn unborrow(&mut self) {
for (_key, entry) in self.entries.iter_mut() {
entry.borrowed = false;
}
}
}
1 change: 0 additions & 1 deletion artiq/runtime.rs/src/kernel.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ use board::csr;
use mailbox;

const KERNELCPU_EXEC_ADDRESS: usize = 0x42000000;
const KERNELCPU_PAYLOAD_ADDRESS: usize = 0x42020000;
const KERNELCPU_LAST_ADDRESS: usize = (0x4fffffff - 1024*1024);
const KSUPPORT_HEADER_SIZE: usize = 0x80;

15 changes: 3 additions & 12 deletions artiq/runtime.rs/src/kernel_proto.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,6 @@ pub struct Exception<'a> {
pub param: [u64; 3],
}

pub use self::c::BacktraceItem;

#[derive(Debug)]
pub enum Message<'a> {
LoadRequest(&'a [u8]),
@@ -29,7 +27,7 @@ pub enum Message<'a> {
RunFinished,
RunException {
exception: Exception<'a>,
backtrace: &'a [BacktraceItem]
backtrace: &'a [usize]
},

WatchdogSetRequest { ms: u64 },
@@ -112,7 +110,7 @@ impl<'a> Message<'a> {
let msg = c::RpcRecvReply {
ty: c::Type::RpcRecvReply,
alloc_size: alloc_size as _,
exception: exn.map_or(ptr::null(), |exn| &exn as *const _)
exception: exn.as_ref().map_or(ptr::null(), |exn| exn as *const _)
};
f(&msg as *const _ as *const _)
}
@@ -315,7 +313,7 @@ mod c {
pub struct RunException {
pub ty: Type,
pub exception: *const Exception,
pub backtrace: *const BacktraceItem,
pub backtrace: *const usize,
pub backtrace_size: size_t
}

@@ -417,13 +415,6 @@ mod c {
pub param: [u64; 3],
}

#[repr(C)]
#[derive(Debug)]
pub struct BacktraceItem {
pub function: usize,
pub offset: usize
}

pub unsafe fn from_c_str_len<'a>(ptr: *const c_char, len: size_t) -> &'a str {
str::from_utf8_unchecked(slice::from_raw_parts(ptr as *const u8, len))
}
71 changes: 65 additions & 6 deletions artiq/runtime.rs/src/session.rs
Original file line number Diff line number Diff line change
@@ -264,7 +264,36 @@ fn process_host_message(waiter: Waiter,
Ok(())
}

request => unexpected!("unexpected request {:?} from host machine", request)
host::Request::RpcException {
name, message, param, file, line, column, function
} => {
if session.kernel_state != KernelState::RpcWait {
unexpected!("unsolicited RPC reply")
}

try!(kern_recv(waiter, |reply| {
match reply {
kern::RpcRecvRequest { .. } => Ok(()),
other =>
unexpected!("unexpected reply from kernel CPU: {:?}", other)
}
}));
try!(kern_send(waiter, kern::RpcRecvReply {
alloc_size: 0,
exception: Some(kern::Exception {
name: &name,
message: &message,
param: param,
file: &file,
line: line,
column: column,
function: &function
})
}));

session.kernel_state = KernelState::Running;
Ok(())
}
}
}

@@ -350,9 +379,41 @@ fn process_kern_message(waiter: Waiter,
}

kern::RunFinished => {
try!(kern_acknowledge());
kernel::stop();
session.kernel_state = KernelState::Absent;
unsafe { session.congress.cache.unborrow() }

match stream {
None => return Ok(true),
Some(ref mut stream) =>
host_write(stream, host::Reply::KernelFinished)
}
}

kern::RunException { exception: ref exn, backtrace } => {
kernel::stop();
session.kernel_state = KernelState::Absent;
return Ok(true)
unsafe { session.congress.cache.unborrow() }

match stream {
None => {
error!("exception in flash kernel");
error!("{}: {} {:?}", exn.name, exn.message, exn.param);
error!("at {}:{}:{} in {}", exn.file, exn.line, exn.column, exn.function);
return Ok(true)
},
Some(ref mut stream) =>
host_write(stream, host::Reply::KernelException {
name: exn.name,
message: exn.message,
param: exn.param,
file: exn.file,
line: exn.line,
column: exn.column,
function: exn.function,
backtrace: backtrace
})
}
}

request => unexpected!("unexpected request {:?} from kernel CPU", request)
@@ -371,9 +432,7 @@ fn host_kernel_worker(waiter: Waiter,
}

if mailbox::receive() != 0 {
if try!(process_kern_message(waiter, Some(stream), &mut session)) {
try!(host_write(stream, host::Reply::KernelFinished))
}
try!(process_kern_message(waiter, Some(stream), &mut session));
}

if session.kernel_state == KernelState::Running {
91 changes: 46 additions & 45 deletions artiq/runtime.rs/src/session_proto.rs
Original file line number Diff line number Diff line change
@@ -15,46 +15,6 @@ fn write_sync(writer: &mut Write) -> io::Result<()> {
writer.write_all(&[0x5a; 4])
}

#[derive(Debug)]
pub struct Exception {
name: String,
message: String,
param: [u64; 3],
file: String,
line: u32,
column: u32,
function: String,
}

impl Exception {
pub fn read_from(reader: &mut Read) -> io::Result<Exception> {
Ok(Exception {
name: try!(read_string(reader)),
message: try!(read_string(reader)),
param: [try!(read_u64(reader)),
try!(read_u64(reader)),
try!(read_u64(reader))],
file: try!(read_string(reader)),
line: try!(read_u32(reader)),
column: try!(read_u32(reader)),
function: try!(read_string(reader))
})
}

pub fn write_to(&self, writer: &mut Write) -> io::Result<()> {
try!(write_string(writer, &self.name));
try!(write_string(writer, &self.message));
try!(write_u64(writer, self.param[0]));
try!(write_u64(writer, self.param[1]));
try!(write_u64(writer, self.param[2]));
try!(write_string(writer, &self.file));
try!(write_u32(writer, self.line));
try!(write_u32(writer, self.column));
try!(write_string(writer, &self.function));
Ok(())
}
}

#[derive(Debug)]
pub enum Request {
Log,
@@ -67,7 +27,15 @@ pub enum Request {
RunKernel,

RpcReply { tag: Vec<u8>, data: Vec<u8> },
RpcException(Exception),
RpcException {
name: String,
message: String,
param: [u64; 3],
file: String,
line: u32,
column: u32,
function: String,
},

FlashRead { key: String },
FlashWrite { key: String, value: Vec<u8> },
@@ -100,7 +68,17 @@ impl Request {
try!(reader.read_exact(&mut data));
Request::RpcReply { tag: tag, data: data }
}
8 => Request::RpcException(try!(Exception::read_from(reader))),
8 => Request::RpcException {
name: try!(read_string(reader)),
message: try!(read_string(reader)),
param: [try!(read_u64(reader)),
try!(read_u64(reader)),
try!(read_u64(reader))],
file: try!(read_string(reader)),
line: try!(read_u32(reader)),
column: try!(read_u32(reader)),
function: try!(read_string(reader))
},
9 => Request::FlashRead {
key: try!(read_string(reader))
},
@@ -130,7 +108,16 @@ pub enum Reply<'a> {

KernelFinished,
KernelStartupFailed,
KernelException(Exception),
KernelException {
name: &'a str,
message: &'a str,
param: [u64; 3],
file: &'a str,
line: u32,
column: u32,
function: &'a str,
backtrace: &'a [usize]
},

RpcRequest { service: u32, data: &'a [u8] },

@@ -179,9 +166,23 @@ impl<'a> Reply<'a> {
Reply::KernelStartupFailed => {
try!(write_u8(&mut buf, 8));
},
Reply::KernelException(ref exception) => {
Reply::KernelException {
name, message, param, file, line, column, function, backtrace
} => {
try!(write_u8(&mut buf, 9));
try!(exception.write_to(writer));
try!(write_string(&mut buf, name));
try!(write_string(&mut buf, message));
try!(write_u64(&mut buf, param[0]));
try!(write_u64(&mut buf, param[1]));
try!(write_u64(&mut buf, param[2]));
try!(write_string(&mut buf, file));
try!(write_u32(&mut buf, line));
try!(write_u32(&mut buf, column));
try!(write_string(&mut buf, function));
try!(write_u32(&mut buf, backtrace.len() as u32));
for &addr in backtrace {
try!(write_u32(&mut buf, addr as u32))
}
},

Reply::RpcRequest { service, data } => {
4 changes: 2 additions & 2 deletions artiq/runtime/Makefile
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@ CFLAGS += -I$(LIBALLOC_DIRECTORY) \
-I$(LIBUNWIND_DIRECTORY) \
-I$(LIBUNWIND_DIRECTORY)/../unwinder/include \
-I$(LIBLWIP_DIRECTORY)/../lwip/src/include \
-I$(LIBLWIP_DIRECTORY) \
-DNDEBUG
-I$(LIBLWIP_DIRECTORY)
CFLAGS += -DNDEBUG

all: runtime.bin runtime.fbi

5 changes: 2 additions & 3 deletions artiq/runtime/artiq_personality.c
Original file line number Diff line number Diff line change
@@ -233,7 +233,7 @@ struct artiq_raised_exception {
struct _Unwind_Exception unwind;
struct artiq_exception artiq;
int handled;
struct artiq_backtrace_item backtrace[1024];
uintptr_t backtrace[1024];
size_t backtrace_size;
};

@@ -303,8 +303,7 @@ static _Unwind_Reason_Code __artiq_uncaught_exception(
uintptr_t pcOffset = pc - funcStart;
EH_LOG("===> uncaught (pc=%p+%p)", (void*)funcStart, (void*)pcOffset);

inflight->backtrace[inflight->backtrace_size].function = funcStart;
inflight->backtrace[inflight->backtrace_size].offset = pcOffset;
inflight->backtrace[inflight->backtrace_size] = funcStart + pcOffset;
++inflight->backtrace_size;

if(actions & _UA_END_OF_STACK) {
7 changes: 1 addition & 6 deletions artiq/runtime/artiq_personality.h
Original file line number Diff line number Diff line change
@@ -17,11 +17,6 @@ struct artiq_exception {
int64_t param[3];
};

struct artiq_backtrace_item {
intptr_t function;
intptr_t offset;
};

#ifdef __cplusplus
extern "C" {
#endif
@@ -48,7 +43,7 @@ void __artiq_reraise(void)

/* Called by the runtime */
void __artiq_terminate(struct artiq_exception *artiq_exn,
struct artiq_backtrace_item *backtrace,
uintptr_t *backtrace,
size_t backtrace_size)
__attribute__((noreturn));

16 changes: 0 additions & 16 deletions artiq/runtime/kloader.c
Original file line number Diff line number Diff line change
@@ -58,22 +58,6 @@ void kloader_start_kernel()
mailbox_acknowledge();
}

void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace,
size_t *backtrace_size) {
struct artiq_backtrace_item *cursor = backtrace;

// Remove all backtrace items belonging to ksupport and subtract
// shared object base from the addresses.
for(int i = 0; i < *backtrace_size; i++) {
if(backtrace[i].function > KERNELCPU_PAYLOAD_ADDRESS) {
backtrace[i].function -= KERNELCPU_PAYLOAD_ADDRESS;
*cursor++ = backtrace[i];
}
}

*backtrace_size = cursor - backtrace;
}

static int kloader_start_flash_kernel(char *key)
{
#if (defined CSR_SPIFLASH_BASE && defined CONFIG_SPIFLASH_PAGE_SIZE)
4 changes: 0 additions & 4 deletions artiq/runtime/kloader.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
#ifndef __KLOADER_H
#define __KLOADER_H

#include "artiq_personality.h"

#define KERNELCPU_EXEC_ADDRESS 0x42000000
#define KERNELCPU_PAYLOAD_ADDRESS 0x42020000
#define KERNELCPU_LAST_ADDRESS (0x4fffffff - 1024*1024)
#define KSUPPORT_HEADER_SIZE 0x80

int kloader_load_library(const void *code);
void kloader_filter_backtrace(struct artiq_backtrace_item *backtrace,
size_t *backtrace_size);

int kloader_start_startup_kernel(void);
int kloader_start_idle_kernel(void);
Loading