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

This commit is contained in:
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" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" 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]] [[package]]
name = "fringe" name = "fringe"
version = "1.1.0" version = "1.1.0"
@ -54,6 +59,7 @@ dependencies = [
"board 0.0.0", "board 0.0.0",
"build_artiq 0.0.0", "build_artiq 0.0.0",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "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", "std_artiq 0.0.0",
] ]
@ -144,6 +150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata] [metadata]
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8" "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 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 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" "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" } std_artiq = { path = "../libstd_artiq" }
board = { path = "../libboard" } board = { path = "../libboard" }
byteorder = { version = "1.0", default-features = false } 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 libc;
extern crate byteorder; extern crate byteorder;
extern crate board; extern crate board;
extern crate cslice;
#[path = "../runtime/mailbox.rs"] #[path = "../runtime/mailbox.rs"]
mod mailbox; mod mailbox;
@ -50,6 +51,7 @@ macro_rules! artiq_raise {
use core::{mem, ptr, slice, str}; use core::{mem, ptr, slice, str};
use std::io::Cursor; use std::io::Cursor;
use libc::{c_char, size_t}; use libc::{c_char, size_t};
use cslice::{CSlice, CMutSlice, AsCSlice};
use kernel_proto::*; use kernel_proto::*;
use dyld::Library; use dyld::Library;
@ -99,34 +101,22 @@ pub extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u3
loop {} 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; static mut NOW: u64 = 0;
#[no_mangle] #[no_mangle]
pub extern fn send_to_core_log(ptr: *const u8, len: usize) { pub extern fn send_to_core_log(text: CSlice<u8>) {
send(&LogSlice(unsafe { match str::from_utf8(text.as_ref()) {
str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) 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] #[no_mangle]
pub extern fn send_to_rtio_log(timestamp: i64, ptr: *const u8, len: usize) { pub extern fn send_to_rtio_log(timestamp: i64, text: CSlice<u8>) {
rtio::log(timestamp, unsafe { slice::from_raw_parts(ptr, len) }) rtio::log(timestamp, text.as_ref())
} }
extern fn abort() -> ! { extern fn abort() -> ! {
@ -185,9 +175,7 @@ extern fn recv_rpc(slot: *mut ()) -> usize {
#[no_mangle] #[no_mangle]
pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception, pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception,
backtrace_data: *mut usize, mut backtrace: CMutSlice<usize>) -> ! {
backtrace_size: usize) -> ! {
let backtrace = unsafe { slice::from_raw_parts_mut(backtrace_data, backtrace_size) };
let mut cursor = 0; let mut cursor = 0;
for index in 0..backtrace.len() { for index in 0..backtrace.len() {
if backtrace[index] > kernel_proto::KERNELCPU_PAYLOAD_ADDRESS { if backtrace[index] > kernel_proto::KERNELCPU_PAYLOAD_ADDRESS {
@ -195,7 +183,7 @@ pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception,
cursor += 1; cursor += 1;
} }
} }
let backtrace = &mut backtrace[0..cursor]; let backtrace = &mut backtrace.as_mut()[0..cursor];
send(&NowSave(unsafe { NOW })); send(&NowSave(unsafe { NOW }));
send(&RunException { send(&RunException {
@ -218,21 +206,21 @@ extern fn watchdog_clear(id: i32) {
send(&WatchdogClear { id: id as usize }) 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; } 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 { slice::from_raw_parts(key, strlen(key as *const c_char)) };
let key = unsafe { str::from_utf8_unchecked(key) }; let key = unsafe { str::from_utf8_unchecked(key) };
send(&CacheGetRequest { key: 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; } 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 { slice::from_raw_parts(key, strlen(key as *const c_char)) };
let key = unsafe { str::from_utf8_unchecked(key) }; 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 } => { recv!(&CachePutReply { succeeded } => {
if !succeeded { if !succeeded {
artiq_raise!("CacheError", "cannot put into a busy cache row") artiq_raise!("CacheError", "cannot put into a busy cache row")

View File

@ -1,9 +1,9 @@
#[path = "../runtime/kernel_proto.rs"] #[path = "../runtime/kernel_proto.rs"]
mod kernel_proto; mod kernel_proto;
use board::csr;
use core::ptr::{read_volatile, write_volatile}; use core::ptr::{read_volatile, write_volatile};
use ::ArtiqList; use cslice::CSlice;
use board::csr;
use ::send; use ::send;
use kernel_proto::*; 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 { unsafe {
csr::rtio::chan_sel_write(channel as u32); csr::rtio::chan_sel_write(channel as u32);
csr::rtio::o_timestamp_write(timestamp as u64); csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr as u32); csr::rtio::o_address_write(addr as u32);
let data = list.as_slice();
for i in 0..data.len() { for i in 0..data.len() {
rtio_o_data_write(i, data[i] as u32) 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) { if(actions & _UA_END_OF_STACK) {
EH_LOG0("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 { } else {
EH_LOG0("continue"); EH_LOG0("continue");
return _URC_NO_REASON; return _URC_NO_REASON;

View File

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

View File

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