forked from M-Labs/artiq
Rust: implement all messages used in the kernel interface.
This commit is contained in:
parent
ab3bd67412
commit
5701b2095b
|
@ -1,3 +1,5 @@
|
|||
use core::{ptr, mem, slice};
|
||||
use std::string::String;
|
||||
use std::io;
|
||||
use mailbox;
|
||||
use kernel;
|
||||
|
@ -76,6 +78,60 @@ impl<'a> Message<'a> {
|
|||
f(&msg as *const _ as *const _)
|
||||
}
|
||||
|
||||
Message::WatchdogSetReply { id } => {
|
||||
let msg = c::WatchdogSetReply {
|
||||
ty: c::Type::WatchdogSetReply,
|
||||
id: id as _
|
||||
};
|
||||
f(&msg as *const _ as *const _)
|
||||
}
|
||||
|
||||
Message::RpcRecvReply { alloc_size, exception } => {
|
||||
let exn = exception.map(|exception| {
|
||||
// FIXME: disgusting
|
||||
let name = String::from(exception.name) + "\0";
|
||||
let file = String::from(exception.file) + "\0";
|
||||
let function = String::from(exception.function) + "\0";
|
||||
let message = String::from(exception.message) + "\0";
|
||||
let exn = c::Exception {
|
||||
name: name.as_ptr() as *const _,
|
||||
file: file.as_ptr() as *const _,
|
||||
line: exception.line,
|
||||
column: exception.column,
|
||||
function: function.as_ptr() as *const _,
|
||||
message: message.as_ptr() as *const _,
|
||||
param: exception.param,
|
||||
};
|
||||
mem::forget(name);
|
||||
mem::forget(file);
|
||||
mem::forget(function);
|
||||
mem::forget(message);
|
||||
exn
|
||||
});
|
||||
let msg = c::RpcRecvReply {
|
||||
ty: c::Type::RpcRecvReply,
|
||||
alloc_size: alloc_size as _,
|
||||
exception: exn.map_or(ptr::null(), |exn| &exn as *const _)
|
||||
};
|
||||
f(&msg as *const _ as *const _)
|
||||
}
|
||||
|
||||
Message::CacheGetReply { value } => {
|
||||
let msg = c::CacheGetReply {
|
||||
ty: c::Type::CacheGetReply,
|
||||
length: value.len(),
|
||||
elements: value.as_ptr()
|
||||
};
|
||||
f(&msg as *const _ as *const _)
|
||||
}
|
||||
Message::CachePutReply { succeeded } => {
|
||||
let msg = c::CachePutReply {
|
||||
ty: c::Type::CachePutReply,
|
||||
succeeded: succeeded as _
|
||||
};
|
||||
f(&msg as *const _ as *const _)
|
||||
}
|
||||
|
||||
other => panic!("Message::into_lower: {:?} unimplemented", other)
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +156,57 @@ impl<'a> Message<'a> {
|
|||
}
|
||||
|
||||
c::Type::RunFinished => Message::RunFinished,
|
||||
c::Type::RunException => {
|
||||
let msg = ptr as *const c::RunException;
|
||||
let exc = (*msg).exception;
|
||||
Message::RunException {
|
||||
exception: Exception {
|
||||
name: c::from_c_str((*exc).name),
|
||||
file: c::from_c_str((*exc).file),
|
||||
line: (*exc).line,
|
||||
column: (*exc).column,
|
||||
function: c::from_c_str((*exc).function),
|
||||
message: c::from_c_str((*exc).message),
|
||||
param: (*exc).param,
|
||||
},
|
||||
backtrace: slice::from_raw_parts((*msg).backtrace, (*msg).backtrace_size)
|
||||
}
|
||||
}
|
||||
|
||||
c::Type::WatchdogSetRequest => {
|
||||
let msg = ptr as *const c::WatchdogSetRequest;
|
||||
Message::WatchdogSetRequest { ms: (*msg).ms as u64 }
|
||||
},
|
||||
c::Type::WatchdogClear => {
|
||||
let msg = ptr as *const c::WatchdogClear;
|
||||
Message::WatchdogClear { id: (*msg).id as usize }
|
||||
}
|
||||
|
||||
c::Type::RpcSend => {
|
||||
let msg = ptr as *const c::RpcSend;
|
||||
Message::RpcSend {
|
||||
service: (*msg).service as _,
|
||||
tag: slice::from_raw_parts((*msg).tag as *const _,
|
||||
c::strlen((*msg).tag) as usize),
|
||||
data: (*msg).data as *const _
|
||||
}
|
||||
}
|
||||
c::Type::RpcRecvRequest => {
|
||||
let msg = ptr as *const c::RpcRecvRequest;
|
||||
Message::RpcRecvRequest { slot: (*msg).slot as *mut _ }
|
||||
}
|
||||
|
||||
c::Type::CacheGetRequest => {
|
||||
let msg = ptr as *const c::CacheGetRequest;
|
||||
let key = c::from_c_str((*msg).key);
|
||||
Message::CacheGetRequest { key: key }
|
||||
}
|
||||
c::Type::CachePutRequest => {
|
||||
let msg = ptr as *const c::CachePutRequest;
|
||||
let key = c::from_c_str((*msg).key);
|
||||
let value = slice::from_raw_parts((*msg).elements, (*msg).length);
|
||||
Message::CachePutRequest { key: key, value: value }
|
||||
}
|
||||
|
||||
c::Type::Log => {
|
||||
let msg = ptr as *const c::Log;
|
||||
|
@ -129,13 +236,16 @@ impl<'a> Message<'a> {
|
|||
}
|
||||
|
||||
pub fn acknowledge() {
|
||||
unsafe { mailbox::acknowledge() }
|
||||
mailbox::acknowledge()
|
||||
}
|
||||
}
|
||||
|
||||
// Low-level representation, compatible with the C code in ksupport
|
||||
mod c {
|
||||
use libc::{c_void, c_int, c_char, size_t};
|
||||
use core::{str, slice};
|
||||
|
||||
extern { pub fn strlen(ptr: *const c_char) -> size_t; }
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug)]
|
||||
|
@ -312,12 +422,10 @@ mod c {
|
|||
}
|
||||
|
||||
pub unsafe fn from_c_str_len<'a>(ptr: *const c_char, len: size_t) -> &'a str {
|
||||
use core::{str, slice};
|
||||
str::from_utf8_unchecked(slice::from_raw_parts(ptr as *const u8, len))
|
||||
}
|
||||
|
||||
pub unsafe fn from_c_str<'a>(ptr: *const c_char) -> &'a str {
|
||||
extern { fn strlen(cs: *const c_char) -> size_t; }
|
||||
from_c_str_len(ptr, strlen(ptr))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -186,10 +186,11 @@ fn comm_handle(waiter: Waiter,
|
|||
}
|
||||
|
||||
session.kernel_state = KernelState::Running;
|
||||
// TODO: make this a separate request
|
||||
kern_acknowledge()
|
||||
}
|
||||
|
||||
request => unexpected!("unexpected {:?}", request)
|
||||
request => unexpected!("unexpected request {:?} from host machine", request)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,7 +226,7 @@ fn kern_handle(waiter: Waiter,
|
|||
kern_acknowledge()
|
||||
}
|
||||
|
||||
request => unexpected!("unexpected {:?}", request)
|
||||
request => unexpected!("unexpected request {:?} from kernel CPU", request)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue