forked from M-Labs/artiq
drtio: implement get_rtio_destination_status for kernels
This commit is contained in:
parent
f7ad7a99e3
commit
c8cd830118
|
@ -44,11 +44,11 @@ def rtio_init() -> TNone:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
@syscall(flags={"nounwind", "nowrite"})
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
def rtio_get_counter() -> TInt64:
|
def rtio_get_destination_status(linkno: TInt32) -> TBool:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
@syscall(flags={"nounwind", "nowrite"})
|
@syscall(flags={"nounwind", "nowrite"})
|
||||||
def drtio_get_link_status(linkno: TInt32) -> TBool:
|
def rtio_get_counter() -> TInt64:
|
||||||
raise NotImplementedError("syscall not simulated")
|
raise NotImplementedError("syscall not simulated")
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,12 +154,12 @@ class Core:
|
||||||
return rtio_get_counter()
|
return rtio_get_counter()
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def get_drtio_link_status(self, linkno):
|
def get_rtio_destination_status(self, destination):
|
||||||
"""Returns whether the specified DRTIO link is up.
|
"""Returns whether the specified RTIO destination is up.
|
||||||
|
|
||||||
This is particularly useful in startup kernels to delay
|
This is particularly useful in startup kernels to delay
|
||||||
startup until certain DRTIO links are up."""
|
startup until certain DRTIO destinations are up."""
|
||||||
return drtio_get_link_status(linkno)
|
return rtio_get_destination_status(destination)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def reset(self):
|
def reset(self):
|
||||||
|
|
|
@ -10,8 +10,8 @@ class Sines2Sayma(EnvExperiment):
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
print("waiting for DRTIO ready...")
|
print("waiting for DRTIO ready...")
|
||||||
while not (self.core.get_drtio_link_status(0) and
|
while not (self.core.get_rtio_destination_status(0) and
|
||||||
self.core.get_drtio_link_status(1)):
|
self.core.get_rtio_destination_status(1)):
|
||||||
pass
|
pass
|
||||||
print("OK")
|
print("OK")
|
||||||
|
|
||||||
|
@ -27,5 +27,5 @@ class Sines2Sayma(EnvExperiment):
|
||||||
# Do not use a sub-multiple of oscilloscope sample rates.
|
# Do not use a sub-multiple of oscilloscope sample rates.
|
||||||
sawg.frequency0.set(9*MHz)
|
sawg.frequency0.set(9*MHz)
|
||||||
|
|
||||||
while self.core.get_drtio_link_status(0) and self.core.get_drtio_link_status(1):
|
while self.core.get_rtio_destination_status(0) and self.core.get_rtio_destination_status(1):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -23,7 +23,7 @@ class SinesUrukulSayma(EnvExperiment):
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
print("waiting for DRTIO ready...")
|
print("waiting for DRTIO ready...")
|
||||||
while not self.core.get_drtio_link_status(0):
|
while not self.core.get_rtio_destination_status(0):
|
||||||
pass
|
pass
|
||||||
print("OK")
|
print("OK")
|
||||||
|
|
||||||
|
@ -38,5 +38,5 @@ class SinesUrukulSayma(EnvExperiment):
|
||||||
sawg.amplitude1.set(.4)
|
sawg.amplitude1.set(.4)
|
||||||
sawg.frequency0.set(9*MHz)
|
sawg.frequency0.set(9*MHz)
|
||||||
|
|
||||||
while self.core.get_drtio_link_status(0):
|
while self.core.get_rtio_destination_status(0):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -10,7 +10,7 @@ class SAWGTestDRTIO(EnvExperiment):
|
||||||
@kernel
|
@kernel
|
||||||
def run(self):
|
def run(self):
|
||||||
core_log("waiting for DRTIO ready...")
|
core_log("waiting for DRTIO ready...")
|
||||||
while not self.core.get_drtio_link_status(0):
|
while not self.core.get_rtio_destination_status(0):
|
||||||
pass
|
pass
|
||||||
core_log("OK")
|
core_log("OK")
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
||||||
|
|
||||||
/* direct syscalls */
|
/* direct syscalls */
|
||||||
api!(rtio_init = ::rtio::init),
|
api!(rtio_init = ::rtio::init),
|
||||||
|
api!(rtio_get_destination_status = ::rtio::get_destination_status),
|
||||||
api!(rtio_get_counter = ::rtio::get_counter),
|
api!(rtio_get_counter = ::rtio::get_counter),
|
||||||
api!(rtio_log),
|
api!(rtio_log),
|
||||||
api!(rtio_output = ::rtio::output),
|
api!(rtio_output = ::rtio::output),
|
||||||
|
@ -108,8 +109,6 @@ 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_link_status = ::rtio::drtio::get_link_status),
|
|
||||||
|
|
||||||
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),
|
||||||
api!(i2c_stop = ::nrt_bus::i2c::stop),
|
api!(i2c_stop = ::nrt_bus::i2c::stop),
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod imp {
|
||||||
|
|
||||||
use board_misoc::csr;
|
use board_misoc::csr;
|
||||||
use ::send;
|
use ::send;
|
||||||
|
use ::recv;
|
||||||
use kernel_proto::*;
|
use kernel_proto::*;
|
||||||
|
|
||||||
pub const RTIO_O_STATUS_WAIT: u8 = 1;
|
pub const RTIO_O_STATUS_WAIT: u8 = 1;
|
||||||
|
@ -19,6 +20,15 @@ mod imp {
|
||||||
send(&RtioInitRequest);
|
send(&RtioInitRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub extern fn get_destination_status(destination: i32) -> bool {
|
||||||
|
if 0 <= destination && destination <= 255 {
|
||||||
|
send(&RtioDestinationStatusRequest { destination: destination as u8 });
|
||||||
|
recv!(&RtioDestinationStatusReply { up } => up)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub extern fn get_counter() -> i64 {
|
pub extern fn get_counter() -> i64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio::counter_update_write(1);
|
csr::rtio::counter_update_write(1);
|
||||||
|
@ -209,14 +219,3 @@ mod imp {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use self::imp::*;
|
pub use self::imp::*;
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,6 +28,9 @@ pub enum Message<'a> {
|
||||||
|
|
||||||
RtioInitRequest,
|
RtioInitRequest,
|
||||||
|
|
||||||
|
RtioDestinationStatusRequest { destination: u8 },
|
||||||
|
RtioDestinationStatusReply { up: bool },
|
||||||
|
|
||||||
DmaRecordStart(&'a str),
|
DmaRecordStart(&'a str),
|
||||||
DmaRecordAppend(&'a [u8]),
|
DmaRecordAppend(&'a [u8]),
|
||||||
DmaRecordStop {
|
DmaRecordStop {
|
||||||
|
@ -46,9 +49,6 @@ pub enum Message<'a> {
|
||||||
duration: u64
|
duration: u64
|
||||||
},
|
},
|
||||||
|
|
||||||
DrtioLinkStatusRequest { linkno: u8 },
|
|
||||||
DrtioLinkStatusReply { up: bool },
|
|
||||||
|
|
||||||
RunFinished,
|
RunFinished,
|
||||||
RunException {
|
RunException {
|
||||||
exception: Exception<'a>,
|
exception: Exception<'a>,
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
use core::cell::RefCell;
|
||||||
use kernel_proto as kern;
|
use kernel_proto as kern;
|
||||||
use sched::{Io, Error as SchedError};
|
use sched::{Io, Error as SchedError};
|
||||||
use session::{kern_acknowledge, kern_send, Error};
|
use session::{kern_acknowledge, kern_send, Error};
|
||||||
use rtio_mgt;
|
use rtio_mgt;
|
||||||
|
use urc::Urc;
|
||||||
use board_artiq::drtio_routing;
|
use board_artiq::drtio_routing;
|
||||||
use board_artiq::i2c as local_i2c;
|
use board_artiq::i2c as local_i2c;
|
||||||
use board_artiq::spi as local_spi;
|
use board_artiq::spi as local_spi;
|
||||||
|
@ -203,7 +205,9 @@ macro_rules! dispatch {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_kern_hwreq(io: &Io, _routing_table: &drtio_routing::RoutingTable,
|
pub fn process_kern_hwreq(io: &Io,
|
||||||
|
_routing_table: &drtio_routing::RoutingTable,
|
||||||
|
_up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
request: &kern::Message) -> Result<bool, Error<SchedError>> {
|
request: &kern::Message) -> Result<bool, Error<SchedError>> {
|
||||||
match request {
|
match request {
|
||||||
&kern::RtioInitRequest => {
|
&kern::RtioInitRequest => {
|
||||||
|
@ -212,9 +216,15 @@ pub fn process_kern_hwreq(io: &Io, _routing_table: &drtio_routing::RoutingTable,
|
||||||
kern_acknowledge()
|
kern_acknowledge()
|
||||||
}
|
}
|
||||||
|
|
||||||
&kern::DrtioLinkStatusRequest { linkno } => {
|
&kern::RtioDestinationStatusRequest { destination: _destination } => {
|
||||||
let up = rtio_mgt::drtio::link_up(linkno);
|
#[cfg(has_drtio)]
|
||||||
kern_send(io, &kern::DrtioLinkStatusReply { up: up })
|
let up = {
|
||||||
|
let up_destinations = _up_destinations.borrow();
|
||||||
|
up_destinations[_destination as usize]
|
||||||
|
};
|
||||||
|
#[cfg(not(has_drtio))]
|
||||||
|
let up = true;
|
||||||
|
kern_send(io, &kern::RtioDestinationStatusReply { up: up })
|
||||||
}
|
}
|
||||||
|
|
||||||
&kern::I2cStartRequest { busno } => {
|
&kern::I2cStartRequest { busno } => {
|
||||||
|
|
|
@ -287,16 +287,19 @@ fn startup_ethernet() {
|
||||||
#[cfg(not(has_drtio))]
|
#[cfg(not(has_drtio))]
|
||||||
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
||||||
drtio_routing::RoutingTable::default_empty()));
|
drtio_routing::RoutingTable::default_empty()));
|
||||||
|
let up_destinations = urc::Urc::new(RefCell::new(
|
||||||
|
[false; drtio_routing::DEST_COUNT]));
|
||||||
|
|
||||||
let mut scheduler = sched::Scheduler::new();
|
let mut scheduler = sched::Scheduler::new();
|
||||||
let io = scheduler.io();
|
let io = scheduler.io();
|
||||||
|
|
||||||
rtio_mgt::startup(&io, &drtio_routing_table);
|
rtio_mgt::startup(&io, &drtio_routing_table, &up_destinations);
|
||||||
|
|
||||||
io.spawn(4096, mgmt::thread);
|
io.spawn(4096, mgmt::thread);
|
||||||
{
|
{
|
||||||
let drtio_routing_table = drtio_routing_table.clone();
|
let drtio_routing_table = drtio_routing_table.clone();
|
||||||
io.spawn(16384, move |io| { session::thread(io, &drtio_routing_table) });
|
let up_destinations = up_destinations.clone();
|
||||||
|
io.spawn(16384, move |io| { session::thread(io, &drtio_routing_table, &up_destinations) });
|
||||||
}
|
}
|
||||||
#[cfg(any(has_rtio_moninj, has_drtio))]
|
#[cfg(any(has_rtio_moninj, has_drtio))]
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,14 +47,16 @@ pub mod drtio {
|
||||||
use super::*;
|
use super::*;
|
||||||
use drtioaux;
|
use drtioaux;
|
||||||
|
|
||||||
pub fn startup(io: &Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>) {
|
pub fn startup(io: &Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::drtio_transceiver::stable_clkin_write(1);
|
csr::drtio_transceiver::stable_clkin_write(1);
|
||||||
}
|
}
|
||||||
let routing_table = routing_table.clone();
|
let routing_table = routing_table.clone();
|
||||||
|
let up_destinations = up_destinations.clone();
|
||||||
io.spawn(4096, move |io| {
|
io.spawn(4096, move |io| {
|
||||||
let routing_table = routing_table.borrow();
|
let routing_table = routing_table.borrow();
|
||||||
link_thread(io, &routing_table)
|
link_thread(io, &routing_table, &up_destinations);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,31 +208,46 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn destination_set_up(routing_table: &drtio_routing::RoutingTable,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
|
destination: u8, up: bool) {
|
||||||
|
let mut up_destinations = up_destinations.borrow_mut();
|
||||||
|
up_destinations[destination as usize] = up;
|
||||||
|
if up {
|
||||||
|
drtio_routing::interconnect_enable(routing_table, 0, destination);
|
||||||
|
info!("[DEST#{}] destination is up", destination);
|
||||||
|
} else {
|
||||||
|
drtio_routing::interconnect_disable(destination);
|
||||||
|
info!("[DEST#{}] destination is down", destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destination_up(up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>, destination: u8) -> bool {
|
||||||
|
let up_destinations = up_destinations.borrow();
|
||||||
|
up_destinations[destination as usize]
|
||||||
|
}
|
||||||
|
|
||||||
fn destination_survey(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
fn destination_survey(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
up_destinations: &mut [bool; drtio_routing::DEST_COUNT]) {
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>) {
|
||||||
for destination in 0..drtio_routing::DEST_COUNT {
|
for destination in 0..drtio_routing::DEST_COUNT {
|
||||||
let hop = routing_table.0[destination][0];
|
let hop = routing_table.0[destination][0];
|
||||||
|
let destination = destination as u8;
|
||||||
|
|
||||||
if hop == 0 {
|
if hop == 0 {
|
||||||
/* local RTIO */
|
/* local RTIO */
|
||||||
if !up_destinations[destination] {
|
if !destination_up(up_destinations, destination) {
|
||||||
info!("[DEST#{}] destination is up", destination);
|
destination_set_up(routing_table, up_destinations, destination, true);
|
||||||
up_destinations[destination] = true;
|
|
||||||
drtio_routing::interconnect_enable(routing_table, 0, destination as u8);
|
|
||||||
}
|
}
|
||||||
} else if hop as usize <= csr::DRTIO.len() {
|
} else if hop as usize <= csr::DRTIO.len() {
|
||||||
let linkno = hop - 1;
|
let linkno = hop - 1;
|
||||||
if up_destinations[destination] {
|
if destination_up(up_destinations, destination) {
|
||||||
if link_up(linkno) {
|
if link_up(linkno) {
|
||||||
drtioaux::send(linkno, &drtioaux::Packet::DestinationStatusRequest {
|
drtioaux::send(linkno, &drtioaux::Packet::DestinationStatusRequest {
|
||||||
destination: destination as u8
|
destination: destination
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
match recv_aux_timeout(io, linkno, 200) {
|
match recv_aux_timeout(io, linkno, 200) {
|
||||||
Ok(drtioaux::Packet::DestinationDownReply) => {
|
Ok(drtioaux::Packet::DestinationDownReply) =>
|
||||||
info!("[DEST#{}] destination is down", destination);
|
destination_set_up(routing_table, up_destinations, destination, false),
|
||||||
up_destinations[destination] = false;
|
|
||||||
drtio_routing::interconnect_disable(destination as u8);
|
|
||||||
},
|
|
||||||
Ok(drtioaux::Packet::DestinationOkReply) => (),
|
Ok(drtioaux::Packet::DestinationOkReply) => (),
|
||||||
Ok(drtioaux::Packet::DestinationSequenceErrorReply { channel }) =>
|
Ok(drtioaux::Packet::DestinationSequenceErrorReply { channel }) =>
|
||||||
error!("[DEST#{}] RTIO sequence error involving channel 0x{:04x}", destination, channel),
|
error!("[DEST#{}] RTIO sequence error involving channel 0x{:04x}", destination, channel),
|
||||||
|
@ -242,21 +259,17 @@ pub mod drtio {
|
||||||
Err(e) => error!("[DEST#{}] communication failed ({})", destination, e)
|
Err(e) => error!("[DEST#{}] communication failed ({})", destination, e)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info!("[DEST#{}] destination is down", destination);
|
destination_set_up(routing_table, up_destinations, destination, false);
|
||||||
up_destinations[destination] = false;
|
|
||||||
drtio_routing::interconnect_disable(destination as u8);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if link_up(linkno) {
|
if link_up(linkno) {
|
||||||
drtioaux::send(linkno, &drtioaux::Packet::DestinationStatusRequest {
|
drtioaux::send(linkno, &drtioaux::Packet::DestinationStatusRequest {
|
||||||
destination: destination as u8
|
destination: destination
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
match recv_aux_timeout(io, linkno, 200) {
|
match recv_aux_timeout(io, linkno, 200) {
|
||||||
Ok(drtioaux::Packet::DestinationDownReply) => (),
|
Ok(drtioaux::Packet::DestinationDownReply) => (),
|
||||||
Ok(drtioaux::Packet::DestinationOkReply) => {
|
Ok(drtioaux::Packet::DestinationOkReply) => {
|
||||||
info!("[DEST#{}] destination is up", destination);
|
destination_set_up(routing_table, up_destinations, destination, true);
|
||||||
up_destinations[destination] = true;
|
|
||||||
drtio_routing::interconnect_enable(routing_table, 0, destination as u8);
|
|
||||||
init_buffer_space(destination as u8, linkno);
|
init_buffer_space(destination as u8, linkno);
|
||||||
},
|
},
|
||||||
Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet),
|
Ok(packet) => error!("[DEST#{}] received unexpected aux packet: {:?}", destination, packet),
|
||||||
|
@ -268,8 +281,8 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_thread(io: Io, routing_table: &drtio_routing::RoutingTable) {
|
pub fn link_thread(io: Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
let mut up_destinations = [false; drtio_routing::DEST_COUNT];
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>) {
|
||||||
loop {
|
loop {
|
||||||
for linkno in 0..csr::DRTIO.len() {
|
for linkno in 0..csr::DRTIO.len() {
|
||||||
let linkno = linkno as u8;
|
let linkno = linkno as u8;
|
||||||
|
@ -306,7 +319,7 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
destination_survey(&io, routing_table, &mut up_destinations);
|
destination_survey(&io, routing_table, up_destinations);
|
||||||
io.sleep(200).unwrap();
|
io.sleep(200).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,7 +344,8 @@ pub mod drtio {
|
||||||
pub mod drtio {
|
pub mod drtio {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn startup(_io: &Io, _routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>) {}
|
pub fn startup(_io: &Io, _routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
|
_up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>) {}
|
||||||
pub fn init() {}
|
pub fn init() {}
|
||||||
pub fn link_up(_linkno: u8) -> bool { false }
|
pub fn link_up(_linkno: u8) -> bool { false }
|
||||||
}
|
}
|
||||||
|
@ -358,7 +372,8 @@ fn async_error_thread(io: Io) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn startup(io: &Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>) {
|
pub fn startup(io: &Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>) {
|
||||||
#[cfg(has_rtio_crg)]
|
#[cfg(has_rtio_crg)]
|
||||||
{
|
{
|
||||||
#[cfg(has_rtio_clock_switch)]
|
#[cfg(has_rtio_clock_switch)]
|
||||||
|
@ -398,7 +413,7 @@ pub fn startup(io: &Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drtio::startup(io, &routing_table);
|
drtio::startup(io, routing_table, up_destinations);
|
||||||
init_core(true);
|
init_core(true);
|
||||||
io.spawn(4096, async_error_thread);
|
io.spawn(4096, async_error_thread);
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,9 @@ fn process_host_message(io: &Io,
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_kern_message(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
fn process_kern_message(io: &Io,
|
||||||
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
mut stream: Option<&mut TcpStream>,
|
mut stream: Option<&mut TcpStream>,
|
||||||
session: &mut Session) -> Result<bool, Error<SchedError>> {
|
session: &mut Session) -> Result<bool, Error<SchedError>> {
|
||||||
kern_recv_notrace(io, |request| {
|
kern_recv_notrace(io, |request| {
|
||||||
|
@ -343,7 +345,7 @@ fn process_kern_message(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
|
|
||||||
kern_recv_dotrace(request);
|
kern_recv_dotrace(request);
|
||||||
|
|
||||||
if kern_hwreq::process_kern_hwreq(io, routing_table, request)? {
|
if kern_hwreq::process_kern_hwreq(io, routing_table, up_destinations, request)? {
|
||||||
return Ok(false)
|
return Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +494,9 @@ fn process_kern_queued_rpc(stream: &mut TcpStream,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
fn host_kernel_worker(io: &Io,
|
||||||
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
congress: &mut Congress) -> Result<(), Error<SchedError>> {
|
congress: &mut Congress) -> Result<(), Error<SchedError>> {
|
||||||
let mut session = Session::new(congress);
|
let mut session = Session::new(congress);
|
||||||
|
@ -509,7 +513,9 @@ fn host_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
if mailbox::receive() != 0 {
|
if mailbox::receive() != 0 {
|
||||||
process_kern_message(io, routing_table, Some(stream), &mut session)?;
|
process_kern_message(io,
|
||||||
|
routing_table, up_destinations,
|
||||||
|
Some(stream), &mut session)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.kernel_state == KernelState::Running {
|
if session.kernel_state == KernelState::Running {
|
||||||
|
@ -528,7 +534,9 @@ fn host_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flash_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
fn flash_kernel_worker(io: &Io,
|
||||||
|
routing_table: &drtio_routing::RoutingTable,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
congress: &mut Congress,
|
congress: &mut Congress,
|
||||||
config_key: &str) -> Result<(), Error<SchedError>> {
|
config_key: &str) -> Result<(), Error<SchedError>> {
|
||||||
let mut session = Session::new(congress);
|
let mut session = Session::new(congress);
|
||||||
|
@ -551,7 +559,7 @@ fn flash_kernel_worker(io: &Io, routing_table: &drtio_routing::RoutingTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
if mailbox::receive() != 0 {
|
if mailbox::receive() != 0 {
|
||||||
if process_kern_message(io, routing_table, None, &mut session)? {
|
if process_kern_message(io, routing_table, up_destinations, None, &mut session)? {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -583,7 +591,8 @@ fn respawn<F>(io: &Io, handle: &mut Option<ThreadHandle>, f: F)
|
||||||
*handle = Some(io.spawn(16384, f))
|
*handle = Some(io.spawn(16384, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>) {
|
pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
|
up_destinations: &Urc<RefCell<[bool; drtio_routing::DEST_COUNT]>>) {
|
||||||
let listener = TcpListener::new(&io, 65535);
|
let listener = TcpListener::new(&io, 65535);
|
||||||
listener.listen(1381).expect("session: cannot listen");
|
listener.listen(1381).expect("session: cannot listen");
|
||||||
info!("accepting network sessions");
|
info!("accepting network sessions");
|
||||||
|
@ -593,12 +602,13 @@ pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>)
|
||||||
let mut kernel_thread = None;
|
let mut kernel_thread = None;
|
||||||
{
|
{
|
||||||
let routing_table = routing_table.clone();
|
let routing_table = routing_table.clone();
|
||||||
|
let up_destinations = up_destinations.clone();
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
let routing_table = routing_table.borrow();
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
info!("running startup kernel");
|
info!("running startup kernel");
|
||||||
match flash_kernel_worker(&io, &routing_table, &mut congress, "startup_kernel") {
|
match flash_kernel_worker(&io, &routing_table, &up_destinations, &mut congress, "startup_kernel") {
|
||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
info!("startup kernel finished"),
|
info!("startup kernel finished"),
|
||||||
Err(Error::KernelNotFound) =>
|
Err(Error::KernelNotFound) =>
|
||||||
|
@ -628,13 +638,14 @@ pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>)
|
||||||
info!("new connection from {}", stream.remote_endpoint());
|
info!("new connection from {}", stream.remote_endpoint());
|
||||||
|
|
||||||
let routing_table = routing_table.clone();
|
let routing_table = routing_table.clone();
|
||||||
|
let up_destinations = up_destinations.clone();
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
let stream = stream.into_handle();
|
let stream = stream.into_handle();
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
let routing_table = routing_table.borrow();
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
let mut stream = TcpStream::from_handle(&io, stream);
|
let mut stream = TcpStream::from_handle(&io, stream);
|
||||||
match host_kernel_worker(&io, &routing_table, &mut stream, &mut *congress) {
|
match host_kernel_worker(&io, &routing_table, &up_destinations, &mut stream, &mut *congress) {
|
||||||
Ok(()) => (),
|
Ok(()) => (),
|
||||||
Err(Error::Protocol(host::Error::Io(IoError::UnexpectedEnd))) =>
|
Err(Error::Protocol(host::Error::Io(IoError::UnexpectedEnd))) =>
|
||||||
info!("connection closed"),
|
info!("connection closed"),
|
||||||
|
@ -653,11 +664,12 @@ pub fn thread(io: Io, routing_table: &Urc<RefCell<drtio_routing::RoutingTable>>)
|
||||||
info!("no connection, starting idle kernel");
|
info!("no connection, starting idle kernel");
|
||||||
|
|
||||||
let routing_table = routing_table.clone();
|
let routing_table = routing_table.clone();
|
||||||
|
let up_destinations = up_destinations.clone();
|
||||||
let congress = congress.clone();
|
let congress = congress.clone();
|
||||||
respawn(&io, &mut kernel_thread, move |io| {
|
respawn(&io, &mut kernel_thread, move |io| {
|
||||||
let routing_table = routing_table.borrow();
|
let routing_table = routing_table.borrow();
|
||||||
let mut congress = congress.borrow_mut();
|
let mut congress = congress.borrow_mut();
|
||||||
match flash_kernel_worker(&io, &routing_table, &mut *congress, "idle_kernel") {
|
match flash_kernel_worker(&io, &routing_table, &up_destinations, &mut *congress, "idle_kernel") {
|
||||||
Ok(()) =>
|
Ok(()) =>
|
||||||
info!("idle kernel finished, standing by"),
|
info!("idle kernel finished, standing by"),
|
||||||
Err(Error::Protocol(host::Error::Io(
|
Err(Error::Protocol(host::Error::Io(
|
||||||
|
|
|
@ -190,7 +190,7 @@ 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 the ``artiq_coremgmt`` command.
|
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 the ``artiq_coremgmt`` command.
|
||||||
|
|
||||||
For DRTIO systems, the startup kernel should wait until the desired links are up, using :meth:`artiq.coredevice.Core.get_drtio_link_status`.
|
For DRTIO systems, the startup kernel should wait until the desired destinations (including local RTIO) are up, using :meth:`artiq.coredevice.Core.get_rtio_destination_status`.
|
||||||
|
|
||||||
* (optional) Select the RTIO clock source
|
* (optional) Select the RTIO clock source
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue