forked from M-Labs/artiq
drtio: add kernel API to check for link status. Closes #941
This commit is contained in:
parent
6aaa8bf9d9
commit
432e61bbb4
|
@ -47,6 +47,10 @@ def rtio_init() -> TNone:
|
|||
def rtio_get_counter() -> TInt64:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def drtio_get_link_status(linkno: TInt32) -> TBool:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
class Core:
|
||||
"""Core device driver.
|
||||
|
@ -155,6 +159,14 @@ class Core:
|
|||
def get_rtio_counter_mu(self):
|
||||
return rtio_get_counter()
|
||||
|
||||
@kernel
|
||||
def get_drtio_link_status(self, linkno):
|
||||
"""Returns whether the specified DRTIO link is up.
|
||||
|
||||
This is particularly useful in startup kernels to delay
|
||||
startup until certain DRTIO links are up."""
|
||||
return drtio_get_link_status(linkno)
|
||||
|
||||
@kernel
|
||||
def reset(self):
|
||||
"""Clear RTIO FIFOs, release RTIO PHY reset, and set the time cursor
|
||||
|
|
|
@ -108,8 +108,9 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
|||
api!(dma_retrieve = ::dma_retrieve),
|
||||
api!(dma_playback = ::dma_playback),
|
||||
|
||||
api!(drtio_get_packet_counts = ::rtio::drtio_dbg::get_packet_counts),
|
||||
api!(drtio_get_buffer_space_req_count = ::rtio::drtio_dbg::get_buffer_space_req_count),
|
||||
api!(drtio_get_link_status = ::rtio::drtio::get_link_status),
|
||||
api!(drtio_get_packet_counts = ::rtio::drtio::get_packet_counts),
|
||||
api!(drtio_get_buffer_space_req_count = ::rtio::drtio::get_buffer_space_req_count),
|
||||
|
||||
api!(i2c_start = ::nrt_bus::i2c::start),
|
||||
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
||||
|
|
|
@ -210,11 +210,16 @@ mod imp {
|
|||
|
||||
pub use self::imp::*;
|
||||
|
||||
pub mod drtio_dbg {
|
||||
pub mod drtio {
|
||||
use ::send;
|
||||
use ::recv;
|
||||
use kernel_proto::*;
|
||||
|
||||
pub extern fn get_link_status(linkno: i32) -> bool {
|
||||
send(&DrtioLinkStatusRequest { linkno: linkno as u8 });
|
||||
recv!(&DrtioLinkStatusReply { up } => up)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PacketCounts(i32, i32);
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ pub enum Message<'a> {
|
|||
duration: u64
|
||||
},
|
||||
|
||||
DrtioLinkStatusRequest { linkno: u8 },
|
||||
DrtioLinkStatusReply { up: bool },
|
||||
|
||||
DrtioPacketCountRequest { linkno: u8 },
|
||||
DrtioPacketCountReply { tx_cnt: u32, rx_cnt: u32 },
|
||||
DrtioBufferSpaceReqCountRequest { linkno: u8 },
|
||||
|
|
|
@ -300,6 +300,11 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool>
|
|||
kern_acknowledge()
|
||||
}
|
||||
|
||||
#[cfg(has_rtio_core)]
|
||||
&kern::DrtioLinkStatusRequest { linkno } => {
|
||||
let up = rtio_mgt::drtio::link_up(linkno);
|
||||
kern_send(io, &kern::DrtioLinkStatusReply { up: up })
|
||||
}
|
||||
|
||||
#[cfg(has_rtio_core)]
|
||||
&kern::DrtioPacketCountRequest { linkno } => {
|
||||
|
|
|
@ -54,8 +54,14 @@ pub mod drtio {
|
|||
}
|
||||
}
|
||||
|
||||
fn link_up(linkno: u8) -> bool {
|
||||
pub fn link_up(linkno: u8) -> bool {
|
||||
let linkno = linkno as usize;
|
||||
/* This function may be called by kernels with arbitrary
|
||||
* linkno values.
|
||||
*/
|
||||
if linkno >= csr::DRTIO.len() {
|
||||
return false;
|
||||
}
|
||||
unsafe {
|
||||
(csr::DRTIO[linkno].link_up_read)() == 1
|
||||
}
|
||||
|
@ -195,6 +201,7 @@ mod drtio {
|
|||
|
||||
pub fn startup(_io: &Io) {}
|
||||
pub fn init() {}
|
||||
pub fn link_up(_linkno: u8) -> bool { false }
|
||||
}
|
||||
|
||||
fn async_error_thread(io: Io) {
|
||||
|
|
|
@ -187,6 +187,8 @@ To flash the idle kernel:
|
|||
|
||||
The startup kernel is executed once when the core device powers up. It should initialize DDSes, set up TTL directions, etc. Proceed as with the idle kernel, but using the ``startup_kernel`` key in ``artiq_coreconfig``.
|
||||
|
||||
For DRTIO systems, the startup kernel should wait until the desired links are up, using :method:`artiq.coredevice.Core.get_drtio_link_status`.
|
||||
|
||||
* (optional) Select the startup clock
|
||||
|
||||
The core device may use either an external clock signal or its internal clock. This clock can be switched dynamically after the PC is connected using the ``external_clock`` parameter of the core device driver; however, one may want to select the clock at power-up so that it is used for the startup and idle kernels. Use one of these commands: ::
|
||||
|
|
Loading…
Reference in New Issue