diff --git a/sw/warpshell/Cargo.toml b/sw/warpshell/Cargo.toml index 61e1241..ceda2cc 100644 --- a/sw/warpshell/Cargo.toml +++ b/sw/warpshell/Cargo.toml @@ -12,4 +12,6 @@ name = "warpshell-cli" path = "src/warpshell-cli/warpshell-cli.rs" [dependencies] -anyhow = "1.0" \ No newline at end of file +anyhow = "1.0" +clap = {version = "4.0.27", features = ["derive"]} +sha2 = "0.10.6" diff --git a/sw/warpshell/src/modules/cms.rs b/sw/warpshell/src/modules/cms.rs index 0af99de..ad01aeb 100644 --- a/sw/warpshell/src/modules/cms.rs +++ b/sw/warpshell/src/modules/cms.rs @@ -1,11 +1,16 @@ use super::io::{ReadWritable, ReadWritableAddressSpace, Readable, Writable}; +// enum Device { + +// } + pub struct Cms<'a> { pub ctrl: ReadWritableAddressSpace<'a>, } // -- REGISTER MAP ---------------------------------------------------------------------------------------------------- // Alveo Card Management Solution Subsystem v4.0 +const SUPPORTED_REG_MAP_ID: u32 = 0x74736574; const O_MB_RESETN_REG: u64 = 0x02_0000; const O_HOST_INTC: u64 = 0x02_2000; @@ -14,27 +19,42 @@ const O_REG_MAP: u64 = 0x02_8000; const O_REG_MAP_ID: u64 = 0x0000; const O_FW_VERSION_REG: u64 = 0x0004; const O_STATUS_REG: u64 = 0x0008; -const O_ERROR_REG: u64 = 0x000c; +const O_ERROR_REG: u64 = 0x000C; const O_PROFILE_NAME_REG: u64 = 0x0014; const O_CONTROL_REG: u64 = 0x0018; const O_12V_PEX_MAX_REG: u64 = 0x0020; const O_12V_PEX_AVG_REG: u64 = 0x0024; const O_12V_PEX_INS_REG: u64 = 0x0028; -const O_3V3_PEX_MAX_REG: u64 = 0x002c; +const O_3V3_PEX_MAX_REG: u64 = 0x002C; const O_3V3_PEX_AVG_REG: u64 = 0x0030; const O_3V3_PEX_INS_REG: u64 = 0x0034; const O_3V3_AUX_MAX_REG: u64 = 0x0038; -const O_3V3_AUX_AVG_REG: u64 = 0x003c; +const O_3V3_AUX_AVG_REG: u64 = 0x003C; const O_3V3_AUX_INS_REG: u64 = 0x0040; const O_12V_AUX_MAX_REG: u64 = 0x0044; const O_12V_AUX_AVG_REG: u64 = 0x0048; -const O_12V_AUX_INS_REG: u64 = 0x004c; +const O_12V_AUX_INS_REG: u64 = 0x004C; const O_DDR4_VPP_BTM_MAX_REG: u64 = 0x0050; const O_DDR4_VPP_BTM_AVG_REG: u64 = 0x0054; const O_DDR4_VPP_BTM_INS_REG: u64 = 0x0058; -const O_SYS_5V5_MAX_REG: u64 = 0x005c; +const O_SYS_5V5_MAX_REG: u64 = 0x005C; const O_SYS_5V5_AVG_REG: u64 = 0x0060; const O_SYS_5V5_INS_REG: u64 = 0x0064; +const O_VCC1V2_TOP_MAX_REG: u64 = 0x0068; +const O_VCC1V2_TOP_AVG_REG: u64 = 0x006C; +const O_VCC1V2_TOP_INS_REG: u64 = 0x0070; + +const O_FPGA_TEMP_MAX_REG: u64 = 0x00F8; +const O_FPGA_TEMP_AVG_REG: u64 = 0x00FC; +const O_FPGA_TEMP_INS_REG: u64 = 0x0100; + +const O_HBM_TEMP1_MAX_REG: u64 = 0x0260; +const O_HBM_TEMP1_AVG_REG: u64 = 0x0264; +const O_HBM_TEMP1_INS_REG: u64 = 0x0268; + +const O_HBM_TEMP2_MAX_REG: u64 = 0x02B4; +const O_HBM_TEMP2_AVG_REG: u64 = 0x02B8; +const O_HBM_TEMP2_INS_REG: u64 = 0x02BC; const O_HOST_STATUS2_REG: u64 = 0x030c; // -------------------------------------------------------------------------------------------------------------------- @@ -55,6 +75,12 @@ impl<'a> Cms<'a> { while !ready { ready = (self.ctrl.read_u32(O_REG_MAP + O_HOST_STATUS2_REG) & 1) == 1; } + // Make sure the CMS version is supported + assert_eq!(self.get_reg_map_id(), SUPPORTED_REG_MAP_ID); + + self.reset_sensor_avg(); + // TODO: Check if we are on HBM board... + self.enable_hbm_temp_monitoring(); } pub fn get_reg_map_id(&self) -> u32 { @@ -69,6 +95,45 @@ impl<'a> Cms<'a> { self.ctrl.read_u32(O_REG_MAP + O_PROFILE_NAME_REG) } + pub fn get_ctrl_reg(&self) -> u32 { + self.ctrl.read_u32(O_REG_MAP + O_CONTROL_REG) + } + + pub fn set_ctrl_reg(&self, data: u32) { + self.ctrl.write_u32(data, O_REG_MAP + O_CONTROL_REG); + } + + pub fn enable_hbm_temp_monitoring(&self) { + let ctrl_reg = self.get_ctrl_reg(); + self.set_ctrl_reg(ctrl_reg | 1 << 27); + } + + pub fn reset_sensor_avg(&self) { + let ctrl_reg = self.get_ctrl_reg(); + self.set_ctrl_reg(ctrl_reg | 1); + } + + pub fn get_fpga_temp(&self) -> (u32, u32, u32) { + let max = self.ctrl.read_u32(O_REG_MAP + O_FPGA_TEMP_MAX_REG); + let avg = self.ctrl.read_u32(O_REG_MAP + O_FPGA_TEMP_AVG_REG); + let ins = self.ctrl.read_u32(O_REG_MAP + O_FPGA_TEMP_INS_REG); + (max, avg, ins) + } + + pub fn get_hbm_0_temp(&self) -> (u32, u32, u32) { + let max = self.ctrl.read_u32(O_REG_MAP + O_HBM_TEMP1_MAX_REG); + let avg = self.ctrl.read_u32(O_REG_MAP + O_HBM_TEMP1_AVG_REG); + let ins = self.ctrl.read_u32(O_REG_MAP + O_HBM_TEMP1_INS_REG); + (max, avg, ins) + } + + pub fn get_hbm_1_temp(&self) -> (u32, u32, u32) { + let max = self.ctrl.read_u32(O_REG_MAP + O_HBM_TEMP2_MAX_REG); + let avg = self.ctrl.read_u32(O_REG_MAP + O_HBM_TEMP2_AVG_REG); + let ins = self.ctrl.read_u32(O_REG_MAP + O_HBM_TEMP2_INS_REG); + (max, avg, ins) + } + pub fn print_info(&self) { println!("REG_MAP_ID: {:#010x}", self.get_reg_map_id()); println!("FW_VERSION: {:#010x}", self.get_fw_version()); diff --git a/sw/warpshell/src/modules/dfx_decoupler.rs b/sw/warpshell/src/modules/dfx_decoupler.rs new file mode 100644 index 0000000..6c8ea4d --- /dev/null +++ b/sw/warpshell/src/modules/dfx_decoupler.rs @@ -0,0 +1 @@ +// TODO: diff --git a/sw/warpshell/src/modules/io.rs b/sw/warpshell/src/modules/io.rs index a3e4ddf..4239cf1 100644 --- a/sw/warpshell/src/modules/io.rs +++ b/sw/warpshell/src/modules/io.rs @@ -12,6 +12,12 @@ pub trait Readable { self.read(&mut buf, offset); u64::from_le_bytes(buf) } + + fn read_u128(&self, offset: u64) -> u128 { + let mut buf: [u8; 16] = [0; 16]; + self.read(&mut buf, offset); + u128::from_le_bytes(buf) + } } pub trait Writable { @@ -24,6 +30,10 @@ pub trait Writable { fn write_u64(&self, data: u64, offset: u64) { self.write(&data.to_le_bytes(), offset) } + + fn write_u128(&self, data: u128, offset: u64) { + self.write(&data.to_le_bytes(), offset) + } } pub trait ReadWritable: Readable + Writable {} diff --git a/sw/warpshell/src/modules/xilinx/mod.rs b/sw/warpshell/src/modules/xilinx/mod.rs deleted file mode 100644 index e69de29..0000000 diff --git a/sw/warpshell/src/shells/mod.rs b/sw/warpshell/src/shells/mod.rs index 87fbb8f..947d9d8 100644 --- a/sw/warpshell/src/shells/mod.rs +++ b/sw/warpshell/src/shells/mod.rs @@ -1 +1,2 @@ +pub mod warpshell; pub mod xilinx_u55n_xdma_std; diff --git a/sw/warpshell/src/shells/warpshell.rs b/sw/warpshell/src/shells/warpshell.rs new file mode 100644 index 0000000..776567a --- /dev/null +++ b/sw/warpshell/src/shells/warpshell.rs @@ -0,0 +1,5 @@ +pub trait Warpshell { + fn init(&self); + // pub fn print_info(); + fn load_raw_user_image(&self, image: &[u8]); +} diff --git a/sw/warpshell/src/shells/xilinx_u55n_xdma_std.rs b/sw/warpshell/src/shells/xilinx_u55n_xdma_std.rs index b3c31d0..b275db2 100644 --- a/sw/warpshell/src/shells/xilinx_u55n_xdma_std.rs +++ b/sw/warpshell/src/shells/xilinx_u55n_xdma_std.rs @@ -2,6 +2,8 @@ use anyhow::{Result, anyhow}; use crate::modules::{xdma::Xdma, axi_firewall::AxiFirewall, cms::Cms}; +use super::warpshell::Warpshell; + pub struct XilinxU55nXdmaStd<'a> { pub xdma: &'a Xdma, pub cms: Cms<'a>, @@ -38,8 +40,14 @@ impl<'a> XilinxU55nXdmaStd<'a> { dma_firewall: AxiFirewall::new(&xdma.user[0], CTRL_DMA_FIREWALL_BASEADDR) }) } +} - pub fn init(&self) { +impl<'a> Warpshell for XilinxU55nXdmaStd<'a> { + fn init(&self) { self.cms.init(); } -} + + fn load_raw_user_image(&self, image: &[u8]) { + todo!() + } +} \ No newline at end of file diff --git a/sw/warpshell/src/warpshell-cli/warpshell-cli.rs b/sw/warpshell/src/warpshell-cli/warpshell-cli.rs index 15ff3c8..37508de 100644 --- a/sw/warpshell/src/warpshell-cli/warpshell-cli.rs +++ b/sw/warpshell/src/warpshell-cli/warpshell-cli.rs @@ -1,15 +1,30 @@ +use clap::Parser; use warpshell::{shells::xilinx_u55n_xdma_std::XilinxU55nXdmaStd, modules::xdma::Xdma}; +#[derive(Parser,Default,Debug)] +struct Args { + command: String +} + fn main() { - println!("Detecting XDMA..."); - let xdma = Xdma::new(0); - println!("Initializing Warpshell..."); - let shell = XilinxU55nXdmaStd::new(&xdma).unwrap(); - shell.init(); - println!("--[CMS]----------------------------"); - shell.cms.print_info(); - println!("--[CTRL_FIREWALL]------------------"); - shell.dma_firewall.print_status(); - println!("--[DMA_FIREWALL]-------------------"); - shell.dma_firewall.print_status(); + let args = Args::parse(); + match args.command.as_str() { + "load-user-image" => println!("LOAD USER IMAGE"), + "get-fpga-temp" => println!("FPGA TEMP"), + "get-hbm-temp" => println!("HBM TEMP"), + "get-board-power" => println!("BOARD POWER"), + _ => println!("Invalid Command") + } + + // println!("Detecting XDMA..."); + // let xdma = Xdma::new(0); + // println!("Initializing Warpshell..."); + // let shell = XilinxU55nXdmaStd::new(&xdma).unwrap(); + // shell.init(); + // println!("--[CMS]----------------------------"); + // shell.cms.print_info(); + // println!("--[CTRL_FIREWALL]------------------"); + // shell.dma_firewall.print_status(); + // println!("--[DMA_FIREWALL]-------------------"); + // shell.dma_firewall.print_status(); }