Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8c7f519
start trying to use James' PMBus capabilities for VPD registers
hawkw Aug 18, 2026
e29735a
add thing for reading PMBus VPDs from a device into a buffer
hawkw Aug 18, 2026
dbc18e1
wire it up
hawkw Aug 19, 2026
b441939
redo vpd reader to work with
hawkw Aug 27, 2026
96bddd2
oops
hawkw Aug 28, 2026
ac6c206
draw much of the remaining owl
hawkw Aug 28, 2026
0dceceb
wip other VPD types
hawkw Aug 28, 2026
586f4df
reticulating
hawkw Aug 28, 2026
a610f19
normal eeproms work now
hawkw Aug 28, 2026
dc271be
roll pmbus for new stuff
hawkw Aug 28, 2026
29f488f
do the temp sensors
hawkw Aug 28, 2026
26691f4
post merge fixy-uppy
hawkw Aug 29, 2026
ecbafac
fix gimletlet
hawkw Aug 29, 2026
86e8ea0
tidy up a bit
hawkw Aug 31, 2026
442ef5f
also use that here
hawkw Sep 1, 2026
dd37bff
make EEPROM VPD config more explicit
hawkw Sep 3, 2026
1631cf8
fix bonus whitespace
hawkw Sep 3, 2026
49935cb
oops the toml keys are hyphenated
hawkw Sep 3, 2026
b349e0b
blarg
hawkw Sep 3, 2026
4d25c9b
update MGS, fix some stuff
hawkw Sep 3, 2026
417731c
renaming things, also support tmp116
hawkw Sep 3, 2026
f361de9
update mgs
hawkw Sep 4, 2026
d344334
use fixed tmp117 driver
hawkw Sep 4, 2026
494735e
update to oxidecomputer/pmbus@944715988b5be0173bd357e67d749cdd71dc5d2c
hawkw Sep 4, 2026
28918a9
add a quick ringbuf
hawkw Sep 4, 2026
74eb7a7
handle register naks nicer
hawkw Sep 4, 2026
0ac4418
you cant type lol
hawkw Sep 4, 2026
3d985c9
oxidecomputer/management-gatway-service@438cd185666d5f164548885873f0f…
hawkw Sep 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/cosmo/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ mux = 1
segment = 7
address = 0b1010_000
device = "at24csw080"
eeprom-vpd = "sled-fan-tray"
description = "Fan VPD"
refdes = ["J34", "U1"]
name = "fan_vpd"
Expand Down
1 change: 1 addition & 0 deletions app/gimlet/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ mux = 1
segment = 3
address = 0b1010_000
device = "at24csw080"
eeprom-vpd = "sled-fan-tray"
description = "Fan VPD"
refdes = ["J180", "U1"]
name = "fan_vpd"
Expand Down
80 changes: 80 additions & 0 deletions build/i2c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ struct I2cController {
// a controller *and* a named bus), so the validation code should go to
// additional lengths to assure that these mistakes are caught in compilation.
//

#[derive(Clone, Debug, Deserialize, PartialOrd, Ord, Eq, PartialEq)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
#[allow(dead_code)]
Expand Down Expand Up @@ -108,6 +109,12 @@ struct I2cDevice {
/// description of device
description: String,

/// if this is an EEPROM, configures the format for VPD read from this
/// EEPROM.
///
/// providing a value for this is valid only if `device = "at24csw080"`.
eeprom_vpd: Option<EepromVpd>,

/// reference designator, if any
refdes: Option<Refdes>,

Expand Down Expand Up @@ -577,6 +584,25 @@ impl std::fmt::Display for Sensor {
}
}

#[derive(
Copy,
Clone,
Deserialize,
Debug,
PartialEq,
Eq,
Hash,
Ord,
PartialOrd,
Default,
)]
#[serde(rename_all = "kebab-case")]
pub enum EepromVpd {
#[default]
SingleBarcode,
SledFanTray,
}

#[derive(PartialEq)]
enum PowerDevices {
/// PMBus power devices
Expand Down Expand Up @@ -652,6 +678,9 @@ fn calculate_validate_drivers() -> Result<HashSet<String>> {
Ok(drivers)
}

pub const VPD_EEPROM_DEVICES: &[&str] = &["at24csw080"];
pub const VPD_TMP11X_DEVICES: &[&str] = &["tmp116", "tmp117"];

impl ConfigGenerator {
pub fn new_with_config(settings: CodegenSettings, i2c: I2cConfig) -> Self {
let mut controllers = vec![];
Expand Down Expand Up @@ -714,6 +743,17 @@ impl ConfigGenerator {
}
(_, _) => {}
}
if d.eeprom_vpd.is_some() {
assert!(
VPD_EEPROM_DEVICES.contains(&d.device.as_str()),
"device {} at address {:#x} is configured with an \
EEPROM VPD format, but it is not a supported EEPROM \
device (currently, we know about the following \
EEPROMs: {VPD_EEPROM_DEVICES:?})",
d.device,
d.address,
);
}
}
}

Expand Down Expand Up @@ -1171,10 +1211,48 @@ impl ConfigGenerator {
use userlib::TaskId;
"##
)?;
//
// Generate a function that looks up an `I2cDevice` based on its index
// in the order returned by `device_descriptions()`.
//
// This is used by the generated code in `task-validate-api` and
// `control-plane-agent`, such as when we construct an `I2cDevice handle
// in order to read VPD or PMBus registers from a device. These indices
// are also referenced by the lookup table of PMBus rail names to
// device indices in `control-plane-agent`.
//
let task_arg = if self.devices.is_empty() {
// If we are generating a `device_by_index` function that has no
// devices in it, this argument will be unused, so suppress clippy
// warnings about it.
"_task"
} else {
"task"
};
write!(
output,
r##"
#[allow(dead_code)]
#[allow(clippy::match_single_binding)]
pub fn device_by_index(
{task_arg}: TaskId,
index: usize,
) -> Option<I2cDevice> {{
match index {{"##,
)?;

for (index, device) in self.devices.iter().enumerate() {
let out = self.generate_device(device, 20);
Comment thread
hawkw marked this conversation as resolved.
writeln!(output, "{index} => Some({out}),")?;
}

write!(
output,
r##"
_ => None,
Comment thread
hawkw marked this conversation as resolved.
}}
}}

#[allow(dead_code)]
#[allow(clippy::match_single_binding)]
pub fn lookup_controller(index: usize) -> Option<Controller> {{
Expand Down Expand Up @@ -2008,6 +2086,7 @@ pub struct I2cDeviceDescription {
pub device_id: Option<String>,
pub name: Option<String>,
pub validate_with_raw_read: bool,
pub eeprom_vpd: Option<EepromVpd>,
/// If this is a PMBus device, this field contains additional data about the
/// PMBus device to be used for generating PMBus-y code.
pub pmbus: Option<PmbusDeviceDescription>,
Expand Down Expand Up @@ -2101,6 +2180,7 @@ pub fn device_descriptions() -> impl Iterator<Item = I2cDeviceDescription> {
device_id,
name: device.name,
validate_with_raw_read: device.validate_with_raw_read,
eeprom_vpd: device.eeprom_vpd,
pmbus,
}
},
Expand Down
7 changes: 5 additions & 2 deletions build/xtask/tests/i2c-codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ fn snapshot() {
Path::new("app/sidecar/rev-d-dev.toml"),
Path::new("app/observer/rev-a-dev.toml"),
Path::new("app/psc/rev-c-dev.toml"),
// Generating a Gimletlet image is interesting as Gimletlet is
// representative of boards which have no PMBus devices.
Path::new("app/gimletlet/app-meanwell.toml"),
];

// TODO: Some analysis and generation is gated in either `new_with_config`
Expand Down Expand Up @@ -90,7 +93,7 @@ fn snapshot() {
for (case, disp, f) in funcs {
let name = manifest.to_string_lossy().replace("/", "_");
let name = format!("{name}.{case}-{disp:?}");
snapshot_file::<()>(*manifest, &tempdir, disp, &name, *f);
snapshot_file::<()>(manifest, &tempdir, disp, &name, *f);
}

// Handle `generate_sensors` separately because it returns data in
Expand All @@ -101,7 +104,7 @@ fn snapshot() {
let name = format!("{name}.{case}-{disp:?}");

let desc = snapshot_file::<I2cSensorsDescription>(
*manifest,
manifest,
&tempdir,
&disp,
&name,
Expand Down
Loading
Loading