2018-09-09 21:49:28 +08:00
|
|
|
use board_misoc::{csr, config};
|
2018-09-11 11:27:56 +08:00
|
|
|
use core::fmt;
|
2018-09-09 21:49:28 +08:00
|
|
|
|
|
|
|
pub const DEST_COUNT: usize = 256;
|
|
|
|
pub const MAX_HOPS: usize = 32;
|
|
|
|
pub const INVALID_HOP: u8 = 0xff;
|
|
|
|
|
|
|
|
pub struct RoutingTable([[u8; MAX_HOPS]; DEST_COUNT]);
|
|
|
|
|
|
|
|
impl RoutingTable {
|
|
|
|
// default routing table is for star topology with no hops
|
2018-09-10 20:16:42 +08:00
|
|
|
fn default_master(default_n_links: usize) -> RoutingTable {
|
2018-09-09 21:49:28 +08:00
|
|
|
let mut ret = RoutingTable([[INVALID_HOP; MAX_HOPS]; DEST_COUNT]);
|
2018-09-10 20:16:42 +08:00
|
|
|
for i in 0..default_n_links {
|
2018-09-09 21:49:28 +08:00
|
|
|
ret.0[i][0] = i as u8;
|
|
|
|
}
|
2018-09-10 20:16:42 +08:00
|
|
|
for i in 1..default_n_links {
|
2018-09-09 21:49:28 +08:00
|
|
|
ret.0[i][1] = 0x00;
|
|
|
|
}
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// satellites receive the routing table from the master
|
|
|
|
// by default, block everything
|
|
|
|
fn default_satellite() -> RoutingTable {
|
|
|
|
RoutingTable([[INVALID_HOP; MAX_HOPS]; DEST_COUNT])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-11 11:27:56 +08:00
|
|
|
impl fmt::Display for RoutingTable {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "RoutingTable {{")?;
|
|
|
|
for i in 0..DEST_COUNT {
|
|
|
|
if self.0[i][0] != INVALID_HOP {
|
|
|
|
write!(f, "{}:", i)?;
|
|
|
|
for j in 0..MAX_HOPS {
|
|
|
|
if self.0[i][j] == INVALID_HOP {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
write!(f, " {}", self.0[i][j])?;
|
|
|
|
}
|
|
|
|
write!(f, ";")?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
write!(f, " }}")?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-10 20:16:42 +08:00
|
|
|
pub fn config_routing_table(default_n_links: usize) -> RoutingTable {
|
|
|
|
let mut ret = RoutingTable::default_master(default_n_links);
|
2018-09-09 21:49:28 +08:00
|
|
|
let ok = config::read("routing_table", |result| {
|
|
|
|
if let Ok(data) = result {
|
|
|
|
if data.len() == DEST_COUNT*MAX_HOPS {
|
|
|
|
for i in 0..DEST_COUNT {
|
|
|
|
for j in 0..MAX_HOPS {
|
|
|
|
ret.0[i][j] = data[i*MAX_HOPS+j];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
false
|
|
|
|
});
|
|
|
|
if !ok {
|
|
|
|
warn!("could not read routing table from configuration, using default");
|
|
|
|
}
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn program_interconnect(rt: &RoutingTable, rank: u8)
|
|
|
|
{
|
|
|
|
for i in 0..DEST_COUNT {
|
|
|
|
let hop = rt.0[i][rank as usize];
|
|
|
|
unsafe {
|
|
|
|
csr::cri_con::routing_destination_write(i as _);
|
|
|
|
csr::cri_con::routing_hop_write(hop);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|