acpki: implement input interface
This commit is contained in:
parent
0354699ae3
commit
1eeee43d64
|
@ -11,7 +11,7 @@ pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
|
|||
pub const RTIO_O_STATUS_DESTINATION_UNREACHABLE: i32 = 4;
|
||||
pub const RTIO_I_STATUS_WAIT_EVENT: i32 = 1;
|
||||
pub const RTIO_I_STATUS_OVERFLOW: i32 = 2;
|
||||
pub const RTIO_I_STATUS_WAIT_STATUS: i32 = 4;
|
||||
pub const RTIO_I_STATUS_WAIT_STATUS: i32 = 4; // TODO
|
||||
pub const RTIO_I_STATUS_DESTINATION_UNREACHABLE: i32 = 8;
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -32,7 +32,7 @@ struct Transaction {
|
|||
padding: i64,
|
||||
reply_status: VolatileCell<i32>,
|
||||
reply_data: VolatileCell<i32>,
|
||||
reply_timestamp: VolatileCell<u64>
|
||||
reply_timestamp: VolatileCell<i64>
|
||||
}
|
||||
|
||||
static mut TRANSACTION_BUFFER: Transaction = Transaction {
|
||||
|
@ -69,16 +69,18 @@ pub extern fn get_counter() -> i64 {
|
|||
}
|
||||
}
|
||||
|
||||
static mut NOW: i64 = 0;
|
||||
|
||||
pub extern fn now_mu() -> i64 {
|
||||
unsafe { TRANSACTION_BUFFER.request_timestamp }
|
||||
unsafe { NOW }
|
||||
}
|
||||
|
||||
pub extern fn at_mu(t: i64) {
|
||||
unsafe { TRANSACTION_BUFFER.request_timestamp = t }
|
||||
unsafe { NOW = t }
|
||||
}
|
||||
|
||||
pub extern fn delay_mu(dt: i64) {
|
||||
unsafe { TRANSACTION_BUFFER.request_timestamp += dt }
|
||||
unsafe { NOW += dt }
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
|
@ -107,6 +109,7 @@ pub extern fn output(target: i32, data: i32) {
|
|||
|
||||
TRANSACTION_BUFFER.request_cmd = 0;
|
||||
TRANSACTION_BUFFER.request_target = target;
|
||||
TRANSACTION_BUFFER.request_timestamp = NOW;
|
||||
TRANSACTION_BUFFER.request_data = data as i64;
|
||||
|
||||
asm::dmb();
|
||||
|
@ -133,15 +136,112 @@ pub extern fn output_wide(target: i32, data: CSlice<i32>) {
|
|||
}
|
||||
|
||||
pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
|
||||
unimplemented!();
|
||||
unsafe {
|
||||
// Clear status so we can observe response
|
||||
TRANSACTION_BUFFER.reply_status.set(0);
|
||||
|
||||
TRANSACTION_BUFFER.request_cmd = 1;
|
||||
TRANSACTION_BUFFER.request_timestamp = NOW;
|
||||
TRANSACTION_BUFFER.request_target = channel << 8;
|
||||
|
||||
asm::dmb();
|
||||
asm::sev();
|
||||
|
||||
let mut status;
|
||||
loop {
|
||||
status = TRANSACTION_BUFFER.reply_status.get();
|
||||
if status != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||
artiq_raise!("RTIOOverflow",
|
||||
"RTIO input overflow on channel {0}",
|
||||
channel as i64, 0, 0);
|
||||
}
|
||||
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
||||
return -1
|
||||
}
|
||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||
artiq_raise!("RTIODestinationUnreachable",
|
||||
"RTIO destination unreachable, input, on channel {0}",
|
||||
channel as i64, 0, 0);
|
||||
}
|
||||
|
||||
TRANSACTION_BUFFER.reply_timestamp.get()
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn input_data(channel: i32) -> i32 {
|
||||
unimplemented!();
|
||||
unsafe {
|
||||
TRANSACTION_BUFFER.reply_status.set(0);
|
||||
|
||||
TRANSACTION_BUFFER.request_cmd = 1;
|
||||
TRANSACTION_BUFFER.request_timestamp = -1;
|
||||
TRANSACTION_BUFFER.request_target = channel << 8;
|
||||
|
||||
asm::dmb();
|
||||
asm::sev();
|
||||
|
||||
let mut status;
|
||||
loop {
|
||||
status = TRANSACTION_BUFFER.reply_status.get();
|
||||
if status != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||
artiq_raise!("RTIOOverflow",
|
||||
"RTIO input overflow on channel {0}",
|
||||
channel as i64, 0, 0);
|
||||
}
|
||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||
artiq_raise!("RTIODestinationUnreachable",
|
||||
"RTIO destination unreachable, input, on channel {0}",
|
||||
channel as i64, 0, 0);
|
||||
}
|
||||
|
||||
TRANSACTION_BUFFER.reply_data.get()
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedData {
|
||||
unimplemented!();
|
||||
unsafe {
|
||||
TRANSACTION_BUFFER.reply_status.set(0);
|
||||
|
||||
TRANSACTION_BUFFER.request_cmd = 1;
|
||||
TRANSACTION_BUFFER.request_timestamp = timeout;
|
||||
TRANSACTION_BUFFER.request_target = channel << 8;
|
||||
|
||||
asm::dmb();
|
||||
asm::sev();
|
||||
|
||||
let mut status;
|
||||
loop {
|
||||
status = TRANSACTION_BUFFER.reply_status.get();
|
||||
if status != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||
artiq_raise!("RTIOOverflow",
|
||||
"RTIO input overflow on channel {0}",
|
||||
channel as i64, 0, 0);
|
||||
}
|
||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||
artiq_raise!("RTIODestinationUnreachable",
|
||||
"RTIO destination unreachable, input, on channel {0}",
|
||||
channel as i64, 0, 0);
|
||||
}
|
||||
|
||||
TimestampedData {
|
||||
timestamp: TRANSACTION_BUFFER.reply_timestamp.get(),
|
||||
data: TRANSACTION_BUFFER.reply_data.get(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_log(data: &[i8]) {
|
||||
|
|
Loading…
Reference in New Issue