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"
|
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"
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue