Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 95c885b580a8
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2ec6d434419a
Choose a head ref
  • 4 commits
  • 8 files changed
  • 1 contributor

Commits on Nov 26, 2016

  1. runtime: use correct ABI when accepting ARTIQ lists.

    whitequark committed Nov 26, 2016
    Copy the full SHA
    79e70fa View commit details
  2. runtime: refactor rtio_output_list.

    whitequark committed Nov 26, 2016
    Copy the full SHA
    cf12a88 View commit details
  3. runtime: match argument signedness between ARTIQ Python and ksupport.

    This is only required when reading the ABI very strictly, but better
    be conservative here than spend time debugging silly stuff.
    whitequark committed Nov 26, 2016
    Copy the full SHA
    ea25856 View commit details
  4. doc: update LLVM configure command (fixes #628).

    whitequark committed Nov 26, 2016
    Copy the full SHA
    2ec6d43 View commit details
2 changes: 1 addition & 1 deletion artiq/runtime.rs/libksupport/api.rs
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
api!(rtio_get_counter = ::rtio::get_counter),
api!(rtio_log),
api!(rtio_output = ::rtio::output),
api!(rtio_output_list = ::rtio::output_list),
api!(rtio_output_wide = ::rtio::output_wide),
api!(rtio_input_timestamp = ::rtio::input_timestamp),
api!(rtio_input_data = ::rtio::input_data),

22 changes: 16 additions & 6 deletions artiq/runtime.rs/libksupport/i2c.rs
Original file line number Diff line number Diff line change
@@ -75,7 +75,9 @@ mod imp {

use self::imp::*;

pub extern fn init(busno: u32) {
pub extern fn init(busno: i32) {
let busno = busno as u32;

// Set SCL as output, and high level
scl_o(busno, true);
scl_oe(busno, true);
@@ -92,15 +94,19 @@ pub extern fn init(busno: u32) {
}
}

pub extern fn start(busno: u32) {
pub extern fn start(busno: i32) {
let busno = busno as u32;

// Set SCL high then SDA low
scl_o(busno, true);
half_period();
sda_oe(busno, true);
half_period();
}

pub extern fn stop(busno: u32) {
pub extern fn stop(busno: i32) {
let busno = busno as u32;

// First, make sure SCL is low, so that the target releases the SDA line
scl_o(busno, false);
half_period();
@@ -112,7 +118,9 @@ pub extern fn stop(busno: u32) {
half_period();
}

pub extern fn write(busno: u32, data: u8) -> bool {
pub extern fn write(busno: i32, data: i8) -> bool {
let (busno, data) = (busno as u32, data as u8);

// MSB first
for bit in (0..8).rev() {
// Set SCL low and set our bit on SDA
@@ -135,7 +143,9 @@ pub extern fn write(busno: u32, data: u8) -> bool {
!sda_i(busno)
}

pub extern fn read(busno: u32, ack: bool) -> u8 {
pub extern fn read(busno: i32, ack: bool) -> i8 {
let busno = busno as u32;

// Set SCL low first, otherwise setting SDA as input may cause a transition
// on SDA with SCL high which will be interpreted as START/STOP condition.
scl_o(busno, false);
@@ -162,5 +172,5 @@ pub extern fn read(busno: u32, ack: bool) -> u8 {
scl_o(busno, true);
half_period();

data
data as i8
}
33 changes: 24 additions & 9 deletions artiq/runtime.rs/libksupport/lib.rs
Original file line number Diff line number Diff line change
@@ -118,6 +118,22 @@ extern fn panic_fmt(args: core::fmt::Arguments, file: &'static str, line: u32) -
loop {}
}

#[repr(C)]
pub struct ArtiqList<T> {
len: usize,
ptr: *const T
}

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]
@@ -208,35 +224,34 @@ pub extern fn __artiq_terminate(exception: *const kernel_proto::Exception,
loop {}
}

extern fn watchdog_set(ms: i64) -> usize {
extern fn watchdog_set(ms: i64) -> i32 {
if ms < 0 {
artiq_raise!("ValueError", "cannot set a watchdog with a negative timeout")
}

send(&WatchdogSetRequest { ms: ms as u64 });
recv!(&WatchdogSetReply { id } => id)
recv!(&WatchdogSetReply { id } => id) as i32
}

extern fn watchdog_clear(id: usize) {
send(&WatchdogClear { id: id })
extern fn watchdog_clear(id: i32) {
send(&WatchdogClear { id: id as usize })
}

extern fn cache_get(key: *const u8) -> (usize, *const u32) {
extern fn cache_get(key: *const u8) -> ArtiqList<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 } => (value.len(), value.as_ptr()))
recv!(&CacheGetReply { value } => ArtiqList::from_slice(value))
}

extern fn cache_put(key: *const u8, &(len, ptr): &(usize, *const u32)) {
extern fn cache_put(key: *const u8, list: ArtiqList<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) };

let value = unsafe { slice::from_raw_parts(ptr, len) };
send(&CachePutRequest { key: key, value: value });
send(&CachePutRequest { key: key, value: unsafe { list.as_slice() } });
recv!(&CachePutReply { succeeded } => {
if !succeeded {
artiq_raise!("CacheError", "cannot put into a busy cache row")
51 changes: 24 additions & 27 deletions artiq/runtime.rs/libksupport/rtio.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use board::csr;
use core::ptr::{read_volatile, write_volatile};
use core::slice;
use ::ArtiqList;

const RTIO_O_STATUS_FULL: u32 = 1;
const RTIO_O_STATUS_UNDERFLOW: u32 = 2;
@@ -26,20 +26,20 @@ pub extern fn get_counter() -> i64 {
}

#[inline(always)]
pub unsafe fn rtio_o_data_write(w: u32) {
pub unsafe fn rtio_o_data_write(offset: usize, data: u32) {
write_volatile(
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1) as isize),
w);
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - offset) as isize),
data);
}

#[inline(always)]
pub unsafe fn rtio_i_data_read() -> u32 {
pub unsafe fn rtio_i_data_read(offset: usize) -> u32 {
read_volatile(
csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize))
csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1 - offset) as isize))
}

#[inline(never)]
unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) {
unsafe fn process_exceptional_status(timestamp: i64, channel: i32, status: u32) {
if status & RTIO_O_STATUS_FULL != 0 {
while csr::rtio::o_status_read() & RTIO_O_STATUS_FULL != 0 {}
}
@@ -69,12 +69,12 @@ unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32)
}
}

pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) {
pub extern fn output(timestamp: i64, channel: i32, addr: i32, data: i32) {
unsafe {
csr::rtio::chan_sel_write(channel);
csr::rtio::chan_sel_write(channel as u32);
csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr);
rtio_o_data_write(data);
csr::rtio::o_address_write(addr as u32);
rtio_o_data_write(0, data as u32);
csr::rtio::o_we_write(1);
let status = csr::rtio::o_status_read();
if status != 0 {
@@ -83,17 +83,14 @@ pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) {
}
}

pub extern fn output_list(timestamp: i64, channel: u32, addr: u32,
&(len, ptr): &(usize, *const u32)) {
pub extern fn output_wide(timestamp: i64, channel: i32, addr: i32, list: ArtiqList<i32>) {
unsafe {
csr::rtio::chan_sel_write(channel);
csr::rtio::chan_sel_write(channel as u32);
csr::rtio::o_timestamp_write(timestamp as u64);
csr::rtio::o_address_write(addr);
let data = slice::from_raw_parts(ptr, len);
csr::rtio::o_address_write(addr as u32);
let data = list.as_slice();
for i in 0..data.len() {
write_volatile(
csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize),
data[i]);
rtio_o_data_write(i, data[i] as u32)
}
csr::rtio::o_we_write(1);
let status = csr::rtio::o_status_read();
@@ -103,9 +100,9 @@ pub extern fn output_list(timestamp: i64, channel: u32, addr: u32,
}
}

pub extern fn input_timestamp(timeout: i64, channel: u32) -> u64 {
pub extern fn input_timestamp(timeout: i64, channel: i32) -> u64 {
unsafe {
csr::rtio::chan_sel_write(channel);
csr::rtio::chan_sel_write(channel as u32);
let mut status;
loop {
status = csr::rtio::i_status_read();
@@ -139,9 +136,9 @@ pub extern fn input_timestamp(timeout: i64, channel: u32) -> u64 {
}
}

pub extern fn input_data(channel: u32) -> u32 {
pub extern fn input_data(channel: i32) -> i32 {
unsafe {
csr::rtio::chan_sel_write(channel);
csr::rtio::chan_sel_write(channel as u32);
loop {
let status = csr::rtio::i_status_read();
if status == 0 { break }
@@ -154,9 +151,9 @@ pub extern fn input_data(channel: u32) -> u32 {
}
}

let data = rtio_i_data_read();
let data = rtio_i_data_read(0);
csr::rtio::i_re_write(1);
data
data as i32
}
}

@@ -171,14 +168,14 @@ pub fn log(timestamp: i64, data: &[u8]) {
word <<= 8;
word |= data[i] as u32;
if i % 4 == 0 {
rtio_o_data_write(word);
rtio_o_data_write(0, word);
csr::rtio::o_we_write(1);
word = 0;
}
}

word <<= 8;
rtio_o_data_write(word);
rtio_o_data_write(0, word);
csr::rtio::o_we_write(1);
}
}
6 changes: 3 additions & 3 deletions artiq/runtime.rs/src/cache.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ use std::btree_map::BTreeMap;

#[derive(Debug)]
struct Entry {
data: Vec<u32>,
data: Vec<i32>,
borrowed: bool
}

@@ -18,7 +18,7 @@ impl Cache {
Cache { entries: BTreeMap::new() }
}

pub fn get(&mut self, key: &str) -> *const [u32] {
pub fn get(&mut self, key: &str) -> *const [i32] {
match self.entries.get_mut(key) {
None => &[],
Some(ref mut entry) => {
@@ -28,7 +28,7 @@ impl Cache {
}
}

pub fn put(&mut self, key: &str, data: &[u32]) -> Result<(), ()> {
pub fn put(&mut self, key: &str, data: &[i32]) -> Result<(), ()> {
match self.entries.get_mut(key) {
None => (),
Some(ref mut entry) => {
4 changes: 2 additions & 2 deletions artiq/runtime.rs/src/kernel_proto.rs
Original file line number Diff line number Diff line change
@@ -51,8 +51,8 @@ pub enum Message<'a> {
RpcRecvReply(Result<usize, Exception<'a>>),

CacheGetRequest { key: &'a str },
CacheGetReply { value: &'static [u32] },
CachePutRequest { key: &'a str, value: &'static [u32] },
CacheGetReply { value: &'static [i32] },
CachePutRequest { key: &'a str, value: &'a [i32] },
CachePutReply { succeeded: bool },

Log(fmt::Arguments<'a>),
4 changes: 2 additions & 2 deletions artiq/runtime.rs/src/session.rs
Original file line number Diff line number Diff line change
@@ -406,7 +406,7 @@ fn process_kern_message(waiter: Waiter,
&kern::CacheGetRequest { key } => {
let value = session.congress.cache.get(key);
kern_send(waiter, &kern::CacheGetReply {
value: unsafe { mem::transmute::<*const [u32], &'static [u32]>(value) }
value: unsafe { mem::transmute::<*const [i32], &'static [i32]>(value) }
})
}

@@ -470,7 +470,7 @@ fn process_kern_message(waiter: Waiter,
}

fn process_kern_queued_rpc(stream: &mut TcpStream,
session: &mut Session) -> io::Result<()> {
_session: &mut Session) -> io::Result<()> {
rpc_queue::dequeue(|slice| {
trace!("comm<-kern (async RPC)");
let length = NetworkEndian::read_u32(slice) as usize;
2 changes: 1 addition & 1 deletion doc/manual/installing_from_source.rst
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ and the ARTIQ kernels.

$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-or1k -DLLVM_TARGETS_TO_BUILD="OR1K;X86" -DLLVM_ENABLE_ASSERTIONS=ON
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/llvm-or1k -DLLVM_TARGETS_TO_BUILD="OR1K;X86" -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INSTALL_UTILS=ON
$ make -j4
$ sudo make install