firmware: use the cslice crate to get rid of unsafe code in ksupport.

pull/666/head
whitequark 2017-02-02 00:51:58 +00:00
parent 9a9a3aa7de
commit c2cf60e7f6
7 changed files with 50 additions and 42 deletions

View File

@ -29,6 +29,11 @@ name = "byteorder"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cslice"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fringe"
version = "1.1.0"
@ -54,6 +59,7 @@ dependencies = [
"board 0.0.0",
"build_artiq 0.0.0",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"std_artiq 0.0.0",
]
@ -144,6 +150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
"checksum cslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0f8cb7306107e4b10e64994de6d3274bd08996a7c1322a27b86482392f96be0a"
"checksum fringe 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "987689dcfad85eee8d76b477865641ec483e63fb86d52966bfc350c4a647d78a"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"

View File

@ -17,3 +17,4 @@ alloc_none = { path = "../liballoc_none" }
std_artiq = { path = "../libstd_artiq" }
board = { path = "../libboard" }
byteorder = { version = "1.0", default-features = false }
cslice = { version = "0.3" }

View File

@ -7,6 +7,7 @@ extern crate std_artiq as std;
extern crate libc;
extern crate byteorder;
extern crate board;
extern crate cslice;
#[path = "../runtime/mailbox.rs"]
mod mailbox;
@ -50,6 +51,7 @@ macro_rules! artiq_raise {
use core::{mem, ptr, slice, str};
use std::io::Cursor;
use libc::{c_char, size_t};
use cslice::{CSlice, CMutSlice, AsCSlice};
use kernel_proto::*;
use dyld::Library;
@ -99,34 +101,22 @@ pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u3
loop {}
}
#[repr(C)]
pub struct ArtiqList<T> {
ptr: *const T,
len: usize
}
impl<T> ArtiqList<T> {
pub fn from_slice(slice: &'static [T]) -> ArtiqList<T> {
ArtiqList { ptr: slice.as_ptr(), len: slice.len() }
}
pub unsafe fn as_slice(&self) -> &[T] {
slice::from_raw_parts(self.ptr, self.len)
}
}
static mut NOW: u64 = 0;
#[no_mangle]
pub extern fn send_to_core_log(ptr: *const u8, len: usize) {
send(&LogSlice(unsafe {
str::from_utf8_unchecked(slice::from_raw_parts(ptr, len))
}))
pub extern fn send_to_core_log(text: CSlice<u8>) {
match str::from_utf8(text.as_ref()) {
Ok(s) => send(&LogSlice(s)),
Err(e) => {
send(&LogSlice(str::from_utf8(&text.as_ref()[..e.valid_up_to()]).unwrap()));
send(&LogSlice("(invalid utf-8)\n"));
}
}
}
#[no_mangle]
pub extern fn send_to_rtio_log(timestamp: i64, ptr: *const u8, len: usize) {
rtio::log(timestamp, unsafe { slice::from_raw_parts(ptr, len) })
pub extern fn send_to_rtio_log(timestamp: i64, text: CSlice<u8>) {
rtio::log(timestamp, text.as_ref())
}
extern fn abort() -> ! {
@ -185,9 +175,7 @@ extern fn recv_rpc(slot: *mut ()) -> usize {
#[no_mangle]
pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception,
backtrace_data: *mut usize,
backtrace_size: usize) -> ! {
let backtrace = unsafe { slice::from_raw_parts_mut(backtrace_data, backtrace_size) };
mut backtrace: CMutSlice<usize>) -> ! {
let mut cursor = 0;
for index in 0..backtrace.len() {
if backtrace[index] > kernel_proto::KERNELCPU_PAYLOAD_ADDRESS {
@ -195,7 +183,7 @@ pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception,
cursor += 1;
}
}
let backtrace = &mut backtrace[0..cursor];
let backtrace = &mut backtrace.as_mut()[0..cursor];
send(&NowSave(unsafe { NOW }));
send(&RunException {
@ -218,21 +206,21 @@ extern fn watchdog_clear(id: i32) {
send(&WatchdogClear { id: id as usize })
}
extern fn cache_get(key: *const u8) -> ArtiqList<i32> {
extern fn cache_get(key: *const u8) -> CSlice<'static, i32> {
extern { fn strlen(s: *const c_char) -> size_t; }
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
let key = unsafe { str::from_utf8_unchecked(key) };
send(&CacheGetRequest { key: key });
recv!(&CacheGetReply { value } => ArtiqList::from_slice(value))
recv!(&CacheGetReply { value } => value.as_c_slice())
}
extern fn cache_put(key: *const u8, list: ArtiqList<i32>) {
extern fn cache_put(key: *const u8, list: CSlice<i32>) {
extern { fn strlen(s: *const c_char) -> size_t; }
let key = unsafe { slice::from_raw_parts(key, strlen(key as *const c_char)) };
let key = unsafe { str::from_utf8_unchecked(key) };
send(&CachePutRequest { key: key, value: unsafe { list.as_slice() } });
send(&CachePutRequest { key: key, value: list.as_ref() });
recv!(&CachePutReply { succeeded } => {
if !succeeded {
artiq_raise!("CacheError", "cannot put into a busy cache row")

View File

@ -1,9 +1,9 @@
#[path = "../runtime/kernel_proto.rs"]
mod kernel_proto;
use board::csr;
use core::ptr::{read_volatile, write_volatile};
use ::ArtiqList;
use cslice::CSlice;
use board::csr;
use ::send;
use kernel_proto::*;
@ -84,12 +84,11 @@ pub extern fn output(timestamp: i64, channel: i32, addr: i32, data: i32) {
}
}
pub extern fn output_wide(timestamp: i64, channel: i32, addr: i32, list: ArtiqList<i32>) {
pub extern fn output_wide(timestamp: i64, channel: i32, addr: i32, data: CSlice<i32>) {
unsafe {
csr::rtio::chan_sel_write(channel as u32);
csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr as u32);
let data = list.as_slice();
for i in 0..data.len() {
rtio_o_data_write(i, data[i] as u32)
}

View File

@ -308,7 +308,8 @@ static _Unwind_Reason_Code __artiq_uncaught_exception(
if(actions & _UA_END_OF_STACK) {
EH_LOG0("end of stack");
__artiq_terminate(&inflight->artiq, inflight->backtrace, inflight->backtrace_size);
struct slice backtrace = { inflight->backtrace, inflight->backtrace_size };
__artiq_terminate(&inflight->artiq, backtrace);
} else {
EH_LOG0("continue");
return _URC_NO_REASON;

View File

@ -4,6 +4,11 @@
#include <stdint.h>
#include <stddef.h>
struct slice {
void *ptr;
size_t len;
};
struct artiq_exception {
union {
uintptr_t typeinfo;
@ -43,8 +48,7 @@ void __artiq_reraise(void)
/* Called by the runtime */
void __artiq_terminate(struct artiq_exception *artiq_exn,
uintptr_t *backtrace,
size_t backtrace_size)
struct slice backtrace)
__attribute__((noreturn));
#ifdef __cplusplus

View File

@ -6,8 +6,13 @@
#include <link.h>
#include <dlfcn.h>
void send_to_core_log(const char *ptr, size_t length);
void send_to_rtio_log(long long int timestamp, const char *ptr, size_t length);
struct slice {
void *ptr;
size_t len;
};
void send_to_core_log(struct slice str);
void send_to_rtio_log(long long int timestamp, struct slice data);
#define KERNELCPU_EXEC_ADDRESS 0x40800000
#define KERNELCPU_PAYLOAD_ADDRESS 0x40840000
@ -28,7 +33,8 @@ int fprintf(FILE *stream, const char *fmt, ...)
vsnprintf(buf, size + 1, fmt, args);
va_end(args);
send_to_core_log(buf, size);
struct slice str = { buf, size };
send_to_core_log(str);
return 0;
}
@ -113,7 +119,8 @@ int core_log(const char *fmt, ...)
vsnprintf(buf, size + 1, fmt, args);
va_end(args);
send_to_core_log(buf, size);
struct slice str = { buf, size };
send_to_core_log(str);
return 0;
}
@ -132,5 +139,6 @@ void rtio_log(long long int timestamp, const char *fmt, ...)
vsnprintf(buf, size + 1, fmt, args);
va_end(args);
send_to_rtio_log(timestamp, buf, size);
struct slice str = { buf, size };
send_to_rtio_log(timestamp, str);
}