mod communication;
mod creation;
pub mod eth_addr;
mod grayskull;
mod hl_comms;
mod init;
mod remote;
mod spi;
mod wormhole;
pub use communication::chip_comms::{
axi_translate, ArcIf, AxiData, AxiError, ChipComms, MemorySlice, MemorySlices,
};
pub use communication::chip_interface::ChipInterface;
pub use grayskull::Grayskull;
pub use hl_comms::{HlComms, HlCommsInterface};
pub use init::status::InitStatus;
pub use init::{
status::{CommsStatus, ComponentStatusInfo},
wait_for_init, CallReason, ChipDetectState, InitError,
};
use luwen_core::Arch;
pub use wormhole::Wormhole;
use crate::arc_msg::TypedArcMsg;
pub use crate::arc_msg::{ArcMsg, ArcMsgOk};
use crate::{arc_msg::ArcMsgAddr, error::PlatformError, DeviceInfo};
#[derive(Debug)]
pub struct ArcMsgOptions {
pub msg: ArcMsg,
pub wait_for_done: bool,
pub timeout: std::time::Duration,
pub use_second_mailbox: bool,
pub addrs: Option<ArcMsgAddr>,
}
impl Default for ArcMsgOptions {
fn default() -> Self {
Self {
msg: ArcMsg::Typed(TypedArcMsg::Nop),
wait_for_done: true,
timeout: std::time::Duration::from_secs(1),
use_second_mailbox: false,
addrs: None,
}
}
}
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct NeighbouringChip {
pub local_noc_addr: (u8, u8),
pub remote_noc_addr: (u8, u8),
pub eth_addr: crate::EthAddr,
}
#[derive(Default, Debug)]
pub struct Telemetry {
pub board_id: u64,
pub smbus_tx_enum_version: u32,
pub smbus_tx_device_id: u32,
pub smbus_tx_asic_ro: u32,
pub smbus_tx_asic_idd: u32,
pub smbus_tx_board_id_high: u32,
pub smbus_tx_board_id_low: u32,
pub smbus_tx_arc0_fw_version: u32,
pub smbus_tx_arc1_fw_version: u32,
pub smbus_tx_arc2_fw_version: u32,
pub smbus_tx_arc3_fw_version: u32,
pub smbus_tx_spibootrom_fw_version: u32,
pub smbus_tx_eth_fw_version: u32,
pub smbus_tx_m3_bl_fw_version: u32,
pub smbus_tx_m3_app_fw_version: u32,
pub smbus_tx_ddr_speed: Option<u32>,
pub smbus_tx_ddr_status: u32,
pub smbus_tx_eth_status0: u32,
pub smbus_tx_eth_status1: u32,
pub smbus_tx_pcie_status: u32,
pub smbus_tx_faults: u32,
pub smbus_tx_arc0_health: u32,
pub smbus_tx_arc1_health: u32,
pub smbus_tx_arc2_health: u32,
pub smbus_tx_arc3_health: u32,
pub smbus_tx_fan_speed: u32,
pub smbus_tx_aiclk: u32,
pub smbus_tx_axiclk: u32,
pub smbus_tx_arcclk: u32,
pub smbus_tx_throttler: u32,
pub smbus_tx_vcore: u32,
pub smbus_tx_asic_temperature: u32,
pub smbus_tx_vreg_temperature: u32,
pub smbus_tx_board_temperature: u32,
pub smbus_tx_tdp: u32,
pub smbus_tx_tdc: u32,
pub smbus_tx_vdd_limits: u32,
pub smbus_tx_thm_limits: u32,
pub smbus_tx_wh_fw_date: u32,
pub smbus_tx_asic_tmon0: u32,
pub smbus_tx_asic_tmon1: u32,
pub smbus_tx_mvddq_power: u32,
pub smbus_tx_gddr_train_temp0: u32,
pub smbus_tx_gddr_train_temp1: u32,
pub smbus_tx_asic_power: Option<u32>,
pub smbus_tx_aux_status: Option<u32>,
pub smbus_tx_boot_date: u32,
pub smbus_tx_rt_seconds: u32,
pub smbus_tx_eth_debug_status0: u32,
pub smbus_tx_eth_debug_status1: u32,
pub smbus_tx_tt_flash_version: u32,
}
impl Telemetry {
pub fn firmware_date(&self) -> String {
let year = (self.smbus_tx_wh_fw_date >> 28 & 0xF) + 2020;
let month = (self.smbus_tx_wh_fw_date >> 24) & 0xF;
let day = (self.smbus_tx_wh_fw_date >> 16) & 0xFF;
let _hour = (self.smbus_tx_wh_fw_date >> 8) & 0xFF;
let _minute = self.smbus_tx_wh_fw_date & 0xFF;
format!("{:04}-{:02}-{:02}", year, month, day)
}
pub fn arc_fw_version(&self) -> String {
let major = (self.smbus_tx_arc0_fw_version >> 16) & 0xFF;
let minor = (self.smbus_tx_arc0_fw_version >> 8) & 0xFF;
let patch = (self.smbus_tx_arc0_fw_version >> 0) & 0xFF;
format!("{}.{}.{}", major, minor, patch)
}
pub fn eth_fw_version(&self) -> String {
let major = (self.smbus_tx_eth_fw_version >> 16) & 0x0FF;
let minor = (self.smbus_tx_eth_fw_version >> 12) & 0x00F;
let patch = (self.smbus_tx_eth_fw_version >> 0) & 0xFFF;
format!("{}.{}.{}", major, minor, patch)
}
pub fn board_serial_number(&self) -> u64 {
((self.smbus_tx_board_id_high as u64) << 32) | self.smbus_tx_board_id_low as u64
}
pub fn board_serial_number_hex(&self) -> String {
format!("{:016x}", self.board_serial_number())
}
pub fn try_board_type(&self) -> Option<&'static str> {
let serial_num = self.board_serial_number();
let output = match (serial_num >> 36) & 0xFFFFF {
0x1 => match (serial_num >> 32) & 0xF {
0x2 => "E300_R2",
0x3 | 0x4 => "E300_R3",
_ => return None,
},
0x3 => "e150",
0x7 => "e75",
0x8 => "NEBULA_CB",
0xA => "e300",
0xB => "GALAXY",
0x14 => "n300",
0x18 => "n150",
_ => return None,
};
Some(output)
}
pub fn board_type(&self) -> &'static str {
self.try_board_type().unwrap_or("UNSUPPORTED")
}
pub fn ai_clk(&self) -> u32 {
self.smbus_tx_aiclk & 0xffff
}
pub fn axi_clk(&self) -> u32 {
self.smbus_tx_axiclk
}
pub fn arc_clk(&self) -> u32 {
self.smbus_tx_arcclk
}
pub fn voltage(&self) -> f64 {
self.smbus_tx_vcore as f64 / 1000.0
}
pub fn asic_temperature(&self) -> f64 {
((self.smbus_tx_asic_temperature & 0xffff) >> 4) as f64
}
pub fn vreg_temperature(&self) -> f64 {
(self.smbus_tx_vreg_temperature & 0xffff) as f64
}
pub fn inlet_temperature(&self) -> f64 {
((self.smbus_tx_board_temperature >> 0x10) & 0xff) as f64
}
pub fn outlet_temperature1(&self) -> f64 {
((self.smbus_tx_board_temperature >> 0x08) & 0xff) as f64
}
pub fn outlet_temperature2(&self) -> f64 {
((self.smbus_tx_board_temperature >> 0x00) & 0xff) as f64
}
pub fn power(&self) -> f64 {
(self.smbus_tx_tdp & 0xffff) as f64
}
pub fn current(&self) -> f64 {
(self.smbus_tx_tdc & 0xffff) as f64
}
}
pub enum ChipInitResult {
NoError,
ErrorContinue,
ErrorAbort,
}
pub trait ChipImpl: HlComms + Send + Sync + 'static {
fn update_init_state(
&mut self,
status: &mut InitStatus,
) -> Result<ChipInitResult, PlatformError>;
fn get_arch(&self) -> Arch;
fn get_telemetry(&self) -> Result<Telemetry, PlatformError>;
fn arc_msg(&self, msg: ArcMsgOptions) -> Result<ArcMsgOk, PlatformError>;
fn get_neighbouring_chips(&self) -> Result<Vec<NeighbouringChip>, PlatformError>;
fn as_any(&self) -> &dyn std::any::Any;
fn get_device_info(&self) -> Result<Option<DeviceInfo>, PlatformError>;
}
pub struct Chip {
pub inner: Box<dyn ChipImpl>,
}
impl From<Box<dyn ChipImpl>> for Chip {
fn from(inner: Box<dyn ChipImpl>) -> Self {
Self { inner }
}
}
impl Chip {
pub fn as_wh(&self) -> Option<&Wormhole> {
self.inner.as_any().downcast_ref::<Wormhole>()
}
pub fn as_gs(&self) -> Option<&Grayskull> {
self.inner.as_any().downcast_ref::<Grayskull>()
}
}
impl HlComms for Chip {
fn comms_obj(&self) -> (&dyn ChipComms, &dyn ChipInterface) {
self.inner.comms_obj()
}
}
impl ChipImpl for Chip {
fn update_init_state(
&mut self,
status: &mut InitStatus,
) -> Result<ChipInitResult, PlatformError> {
self.inner.update_init_state(status)
}
fn get_arch(&self) -> Arch {
self.inner.get_arch()
}
fn arc_msg(&self, msg: ArcMsgOptions) -> Result<ArcMsgOk, PlatformError> {
self.inner.arc_msg(msg)
}
fn get_neighbouring_chips(&self) -> Result<Vec<NeighbouringChip>, PlatformError> {
self.inner.get_neighbouring_chips()
}
fn as_any(&self) -> &dyn std::any::Any {
self.inner.as_any()
}
fn get_telemetry(&self) -> Result<Telemetry, PlatformError> {
self.inner.get_telemetry()
}
fn get_device_info(&self) -> Result<Option<DeviceInfo>, PlatformError> {
self.inner.get_device_info()
}
}