Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Poseidon - update with new release #10

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ serde-hex = "0.1.0"
thiserror = "1.0"
num-bigint = "0.4"
num-traits = "0.2.15"
simple-logging = "2.0.2"
async-std = "1.12.0"
2 changes: 1 addition & 1 deletion configs/c1100_cfg.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
"ctrl_dfx_decoupler_baseaddr": "0x04090000",
"dma_baseaddr": "0x0000000000000000",
"dma_hbicap_baseaddr": "0x1000000000000000"
}
}
12 changes: 12 additions & 0 deletions configs/u250_cfg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"ctrl_baseaddr": "0x00000000",
"ctrl_cms_baseaddr": "0x04000000",
"ctrl_qspi_baseaddr": "0x04040000",
"ctrl_hbicap_baseaddr": "0x04050000",
"ctrl_mgmt_ram_baseaddr": "0x04060000",
"ctrl_firewall_baseaddr": "0x04070000",
"dma_firewall_baseaddr": "0x04080000",
"ctrl_dfx_decoupler_baseaddr": "0x04090000",
"dma_baseaddr": "0x0000100000000000",
"dma_hbicap_baseaddr": "0x1000000000000000"
}
194 changes: 191 additions & 3 deletions src/driver_client/dclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use crate::{
driver_client::dclient_code::*,
error::*,
ingo_hash::dma_buffer::DmaBuffer,
utils::{deserialize_hex, open_channel, AccessFlags},
};
use serde::Deserialize;
Expand All @@ -26,7 +27,7 @@ pub trait ParametersAPI {
/// The generic type parameters `T`, `P`, `I`, and `O` represent
/// the primitive type, parameter for initialization, input data, and output data respectively.
/// All methods return a `Result` indicating success or failure.
pub trait DriverPrimitive<T, P, I, O> {
pub trait DriverPrimitive<T, P, I, O, R> {
/// The `new` method creates a new instance of the driver primitive type with the given primitive type and driver client.
fn new(ptype: T, dclient: DriverClient) -> Self;
/// The `loaded_binary_parameters` method returns
Expand All @@ -43,7 +44,7 @@ pub trait DriverPrimitive<T, P, I, O> {
fn wait_result(&self) -> Result<()>;
/// The `result` method returns the output data from the driver primitive,
/// optionally with a specific parameter. If there is no output data available, it returns `None`.
fn result(&self, _param: Option<usize>) -> Result<Option<O>>;
fn result(&self, _param: Option<R>) -> Result<Option<O>>;
}

/// The [`DriverConfig`] is a struct that defines a set of 64-bit unsigned integer (`u64`)
Expand Down Expand Up @@ -84,6 +85,12 @@ impl DriverConfig {
let reader = std::io::BufReader::new(file);
serde_json::from_reader(reader).unwrap()
}

pub fn driver_client_u250_cfg() -> Self {
let file = std::fs::File::open("configs/u250_cfg.json").expect("");
let reader = std::io::BufReader::new(file);
serde_json::from_reader(reader).unwrap()
}
}

/// The [`DriverClient`] is described bunch of addreses on FPGA which called [`DriverConfig`] also
Expand Down Expand Up @@ -171,7 +178,7 @@ impl DriverClient {
ctrl_reg.unwrap() | 1 << 27,
)?;
Ok(())
}
}

// HBICAP
/// Checking HBICAP status register. Return `true` if zero (previous operation done) and
Expand Down Expand Up @@ -290,6 +297,16 @@ impl DriverClient {
}
}

pub fn set_dma_firewall_prescale(&self, pre_scale: i32) -> Result<()> {
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved
self.ctrl_write(
self.cfg.dma_firewall_baseaddr,
0x230 as u64,
&pre_scale.to_le_bytes(),
)?;

Ok(())
}

pub fn unblock_firewalls(&self) -> Result<()> {
self.set_firewall_block(self.cfg.ctrl_firewall_baseaddr, false)?;
self.set_firewall_block(self.cfg.dma_firewall_baseaddr, false)?;
Expand Down Expand Up @@ -495,6 +512,23 @@ impl DriverClient {
Ok(read_data)
}

pub fn dma_read_into<T: Debug + Into<u64> + Copy>(
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved
&self,
base_address: u64,
offset: T,
// todo: add optional size
buffer: &mut DmaBuffer,
) {
self.dma_c2h_read
.read_exact_at(buffer.as_mut_slice(), base_address + offset.into())
.map_err(|e| DriverClientError::ReadError {
offset: format!("{:?}", offset),
source: e,
});

crate::getter_log!(buffer, offset);
}

/// The method for writing data from host memory into FPGA.
///
/// The location is determined by adding the `offset` to the `base_address`.
Expand Down Expand Up @@ -602,6 +636,160 @@ impl DriverClient {

log::info!("DMA Firewall Status: {:#X?}", ret_dma.unwrap());
}

// ==== sensor data ====>

fn get_cms_control_reg(&self) -> u32 {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;
let data = self.ctrl_read_u32(ctrl_cms_baseaddr, 0x0018 as u64).unwrap();

return data
}

fn set_cms_control_reg(&self, data: u32) {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

self.ctrl_write_u32(ctrl_cms_baseaddr, 0x0018 as u64, data);
}

pub fn reset_sensor_data(&self) {
let ctrl_reg = self.get_cms_control_reg();
self.set_cms_control_reg(ctrl_reg | 1)
}

/// Monitor the temperature of a device.
///
/// This function reads the instantaneous, average, and maximum temperatures
/// from the device's control monitor system (CMS). The temperatures are
/// read from specific addresses defined in the CMS_ADDR enumeration.
///
/// # Examples
///
/// ```no_run
/// let device = Device::new();
/// match device.monitor_temperature() {
/// Ok((inst, avg, max)) => println!("Instant: {}, Average: {}, Max: {}", inst, avg, max),
/// Err(e) => println!("Error reading temperatures: {}", e),
/// }
/// ```
///
/// # Errors
///
/// This function will return an error if there is a problem reading
/// any of the temperature values from the CMS.
///
/// # Returns
///
/// A tuple of three `u32` values representing the instantaneous,
/// average, and maximum temperatures, respectively, if successful.
///
/// ```
pub fn monitor_temperature(&self) -> Result<(u32, u32, u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

let temp_max = self
.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::TEMP_MAX)
.unwrap();
let temp_avg = self
.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::TEMP_AVG)
.unwrap();
let temp_inst = self
.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::TEMP_INST)
.unwrap();

Ok((temp_inst, temp_avg, temp_max))
}

fn get_12v_aux_voltage(&self) -> Result<(u32,u32,u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

let voltage_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::AUX_12V_VOLTAGE_MAX).unwrap();
let voltage_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::AUX_12V_VOLTAGE_AVG).unwrap();
let voltage_inst = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::AUX_12V_VOLTAGE_INST).unwrap();
return Ok((voltage_inst / 1000, voltage_avg / 1000, voltage_max / 1000))
}

fn get_12v_aux_current(&self) -> Result<(u32,u32,u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;
let current_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::AUX_12V_CURRENT_MAX).unwrap();
let current_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::AUX_12V_CURRENT_AVG).unwrap();
let current_inst = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::AUX_12V_CURRENT_INST).unwrap();

return Ok((current_inst / 1000, current_avg / 1000, current_max / 1000))
}

fn get_12v_pex_voltage(&self) -> Result<(u32,u32,u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

let voltage_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_12V_VOLTAGE_MAX).unwrap();
let voltage_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_12V_VOLTAGE_AVG).unwrap();
let voltage_inst = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_12V_VOLTAGE_INST).unwrap();

return Ok((voltage_inst / 1000, voltage_avg / 1000, voltage_max / 1000))
}

fn get_12v_pex_current(&self) -> Result<(u32,u32,u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

let current_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_12V_CURRENT_MAX).unwrap();
let current_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_12V_CURRENT_AVG).unwrap();
let current_inst = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_12V_CURRENT_INST).unwrap();

return Ok((current_inst / 1000, current_avg / 1000, current_max / 1000))
}

fn get_3v3_pex_voltage(&self) -> Result<(u32,u32,u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

let voltage_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_3v3_VOLTAGE_MAX).unwrap();
let voltage_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_3v3_VOLTAGE_AVG).unwrap();
let voltage_inst = self.ctrl_read_u32(ctrl_cms_baseaddr,CMS_ADDR::PEX_3v3_VOLTAGE_INST).unwrap();

return Ok((voltage_inst / 1000, voltage_avg / 1000, voltage_max / 1000))
}

fn get_3v3_pex_current(&self) -> Result<(u32,u32,u32)> {
let ctrl_cms_baseaddr = self.cfg.ctrl_cms_baseaddr + CMS_ADDR::ADDR_SENSOR_OFFSET as u64;

let current_max = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_3v3_CURRENT_MAX).unwrap();
let current_avg = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_3v3_CURRENT_AVG).unwrap();
let current_inst = self.ctrl_read_u32(ctrl_cms_baseaddr, CMS_ADDR::PEX_3v3_CURRENT_INST).unwrap();

return Ok((current_inst / 1000, current_avg / 1000, current_max / 1000))
}

fn get_aux_power(&self) -> Result<(u32,u32,u32)> {
let aux_v = self.get_12v_aux_voltage().unwrap();
let aux_i = self.get_12v_aux_current().unwrap();

return Ok((aux_v.0 * aux_i.0, aux_v.1 * aux_i.1, aux_v.2 * aux_i.2))
}

fn get_pex_12v_power(&self) -> Result<(u32,u32,u32)> {
let pex_12v_v = self.get_12v_pex_voltage().unwrap();
let pex_12v_i = self.get_12v_pex_current().unwrap();

return Ok((pex_12v_v.0 * pex_12v_i.0, pex_12v_v.0 * pex_12v_i.0, pex_12v_v.0 * pex_12v_i.0))
}

fn get_pex_3v3_power(&self) -> Result<(u32,u32,u32)> {
let pex_3v3_v = self.get_3v3_pex_voltage().unwrap();
let pex_3v3_i = self.get_3v3_pex_current().unwrap();

return Ok((pex_3v3_v.0 * pex_3v3_i.0, pex_3v3_v.0 * pex_3v3_i.0, pex_3v3_v.0 * pex_3v3_i.0))
}

pub fn monitor_power(&self) -> Result<(u32,u32,u32)> {
let aux_p = self.get_aux_power().unwrap();
let pex_12v_p = self.get_pex_12v_power().unwrap();
let pex_3v3_p = self.get_pex_3v3_power().unwrap();

return Ok((
(aux_p.0 + pex_12v_p.0 + pex_3v3_p.0),
(aux_p.1 + pex_12v_p.1 + pex_3v3_p.1),
(aux_p.2 + pex_12v_p.2 + pex_3v3_p.2),
))
}

// ==== utils ====>
pub fn is_ctrl_field_expected_value<T: Debug + Into<u64> + Copy>(
Expand Down
32 changes: 32 additions & 0 deletions src/driver_client/dclient_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,40 @@ impl From<FIREWALL_ADDR> for u64 {
/// voltage and current, and also controls automatic thermal shutdown.
#[derive(Debug, Copy, Clone)]
pub enum CMS_ADDR {
ADDR_SENSOR_OFFSET = 0x028000,
// CMS
ADDR_CPU2HIF_CMS_INITIALIZE = 0x020000,
ADDR_HIF2CPU_CMS_CONTROL_REG = 0x0018,

// TEMPATURE
TEMP_MAX = 0x00F8,
TEMP_AVG = 0x00FC,
TEMP_INST = 0x0100,

// POWER
AUX_12V_VOLTAGE_MAX = 0x0044,
AUX_12V_VOLTAGE_AVG = 0x0048,
AUX_12V_VOLTAGE_INST = 0x004C,

AUX_12V_CURRENT_MAX = 0x00D4,
AUX_12V_CURRENT_AVG = 0x00D8,
AUX_12V_CURRENT_INST = 0x00DC,

PEX_12V_VOLTAGE_MAX = 0x0020,
PEX_12V_VOLTAGE_AVG = 0x0024,
PEX_12V_VOLTAGE_INST = 0x0028,

PEX_12V_CURRENT_MAX = 0x00C8,
PEX_12V_CURRENT_AVG = 0x00CC,
PEX_12V_CURRENT_INST = 0x00D0,

PEX_3v3_VOLTAGE_MAX = 0x002C,
PEX_3v3_VOLTAGE_AVG = 0x0030,
PEX_3v3_VOLTAGE_INST = 0x0034,

PEX_3v3_CURRENT_MAX = 0x0278,
PEX_3v3_CURRENT_AVG = 0x027C,
PEX_3v3_CURRENT_INST = 0x0280,
}
impl From<CMS_ADDR> for u64 {
fn from(addr: CMS_ADDR) -> Self {
Expand Down
59 changes: 59 additions & 0 deletions src/ingo_hash/dma_buffer.rs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file be moved to the driver_client folder since it more specific to the HW integration than the primitive itself?

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::mem;

#[repr(C, align(4096))]
pub struct Align4K([u8; 4096]);

#[derive(Debug)]
pub struct DmaBuffer(Vec<u8>);

impl DmaBuffer {
pub fn new<T>(n_bytes: usize) -> Self {
Self(unsafe { aligned_vec::<T>(n_bytes) })
}

pub fn extend_from_slice(&mut self, slice: &[u8]) {
self.0.extend_from_slice(slice);
}

pub fn as_slice(&self) -> &[u8] {
self.0.as_slice()
}

pub fn as_mut_slice(&mut self) -> &mut [u8] {
self.0.as_mut_slice()
}

pub fn get(&self) -> &Vec<u8> {
&self.0
}

pub fn get_mut(&mut self) -> &mut Vec<u8> {
&mut self.0
}

pub fn set_len(&mut self, num: usize) {
unsafe { self.0.set_len(num) }
}

pub fn len(&self) -> usize {
self.0.len()
}
}

pub unsafe fn aligned_vec<T>(n_bytes: usize) -> Vec<u8> {
let n_units = (n_bytes / mem::size_of::<T>()) + 1;

let mut aligned: Vec<T> = Vec::with_capacity(n_units);
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved

let ptr = aligned.as_mut_ptr();
let len_units = aligned.len();
let cap_units = aligned.capacity();

mem::forget(aligned);

Vec::from_raw_parts(
ptr as *mut u8,
len_units * mem::size_of::<T>(),
cap_units * mem::size_of::<T>(),
)
}
1 change: 1 addition & 0 deletions src/ingo_hash/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod dma_buffer;
pub mod hash_hw_code;
pub mod poseidon_api;
pub mod utils;
Loading