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:
|
def rtio_get_counter() -> TInt64:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
|
def drtio_get_link_status(linkno: TInt32) -> TBool:
|
||||||
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
|
||||||
class Core:
|
class Core:
|
||||||
"""Core device driver.
|
"""Core device driver.
|
||||||
|
@ -155,6 +159,14 @@ class Core:
|
||||||
def get_rtio_counter_mu(self):
|
def get_rtio_counter_mu(self):
|
||||||
return rtio_get_counter()
|
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
|
@kernel
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""Clear RTIO FIFOs, release RTIO PHY reset, and set the time cursor
|
"""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_retrieve = ::dma_retrieve),
|
||||||
api!(dma_playback = ::dma_playback),
|
api!(dma_playback = ::dma_playback),
|
||||||
|
|
||||||
api!(drtio_get_packet_counts = ::rtio::drtio_dbg::get_packet_counts),
|
api!(drtio_get_link_status = ::rtio::drtio::get_link_status),
|
||||||
api!(drtio_get_buffer_space_req_count = ::rtio::drtio_dbg::get_buffer_space_req_count),
|
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_start = ::nrt_bus::i2c::start),
|
||||||
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
api!(i2c_restart = ::nrt_bus::i2c::restart),
|
||||||
|
|
|
@ -210,11 +210,16 @@ mod imp {
|
||||||
|
|
||||||
pub use self::imp::*;
|
pub use self::imp::*;
|
||||||
|
|
||||||
pub mod drtio_dbg {
|
pub mod drtio {
|
||||||
use ::send;
|
use ::send;
|
||||||
use ::recv;
|
use ::recv;
|
||||||
use kernel_proto::*;
|
use kernel_proto::*;
|
||||||
|
|
||||||
|
pub extern fn get_link_status(linkno: i32) -> bool {
|
||||||
|
send(&DrtioLinkStatusRequest { linkno: linkno as u8 });
|
||||||
|
recv!(&DrtioLinkStatusReply { up } => up)
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct PacketCounts(i32, i32);
|
pub struct PacketCounts(i32, i32);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,9 @@ pub enum Message<'a> {
|
||||||
duration: u64
|
duration: u64
|
||||||
},
|
},
|
||||||
|
|
||||||
|
DrtioLinkStatusRequest { linkno: u8 },
|
||||||
|
DrtioLinkStatusReply { up: bool },
|
||||||
|
|
||||||
DrtioPacketCountRequest { linkno: u8 },
|
DrtioPacketCountRequest { linkno: u8 },
|
||||||
DrtioPacketCountReply { tx_cnt: u32, rx_cnt: u32 },
|
DrtioPacketCountReply { tx_cnt: u32, rx_cnt: u32 },
|
||||||
DrtioBufferSpaceReqCountRequest { linkno: u8 },
|
DrtioBufferSpaceReqCountRequest { linkno: u8 },
|
||||||
|
|
|
@ -300,6 +300,11 @@ pub fn process_kern_hwreq(io: &Io, request: &kern::Message) -> io::Result<bool>
|
||||||
kern_acknowledge()
|
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)]
|
#[cfg(has_rtio_core)]
|
||||||
&kern::DrtioPacketCountRequest { linkno } => {
|
&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;
|
let linkno = linkno as usize;
|
||||||
|
/* This function may be called by kernels with arbitrary
|
||||||
|
* linkno values.
|
||||||
|
*/
|
||||||
|
if linkno >= csr::DRTIO.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
(csr::DRTIO[linkno].link_up_read)() == 1
|
(csr::DRTIO[linkno].link_up_read)() == 1
|
||||||
}
|
}
|
||||||
|
@ -195,6 +201,7 @@ mod drtio {
|
||||||
|
|
||||||
pub fn startup(_io: &Io) {}
|
pub fn startup(_io: &Io) {}
|
||||||
pub fn init() {}
|
pub fn init() {}
|
||||||
|
pub fn link_up(_linkno: u8) -> bool { false }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn async_error_thread(io: Io) {
|
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``.
|
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
|
* (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: ::
|
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