forked from M-Labs/artiq
firmware: use the cslice crate to get rid of unsafe code in ksupport.
This commit is contained in:
parent
9a9a3aa7de
commit
c2cf60e7f6
|
@ -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"
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue