From 6803fc2966ec381f2a25933ba558dc93f2d2a72a Mon Sep 17 00:00:00 2001 From: Krish Dandiwala Date: Fri, 24 Jul 2026 14:34:10 -0400 Subject: [PATCH] feat: minimal SMC GB300 support --- crates/bmc-explorer/src/hw/mod.rs | 1 + .../bmc-explorer/src/hw/supermicro_gb300.rs | 29 ++++++++++++++ crates/bmc-explorer/src/lib.rs | 38 +++++++++++++++---- .../integration/supermicro_gb300_explore.rs | 16 ++++++++ .../bmc-mock/src/hw/supermicro_gb300_nvl.rs | 13 ++++--- 5 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 crates/bmc-explorer/src/hw/supermicro_gb300.rs diff --git a/crates/bmc-explorer/src/hw/mod.rs b/crates/bmc-explorer/src/hw/mod.rs index 2105cb7a7c..08f75db3ff 100644 --- a/crates/bmc-explorer/src/hw/mod.rs +++ b/crates/bmc-explorer/src/hw/mod.rs @@ -27,6 +27,7 @@ pub mod lenovo; pub mod lenovo_ami; pub mod lenovo_gb300; pub mod supermicro; +pub mod supermicro_gb300; pub mod vera_rubin; pub mod viking; diff --git a/crates/bmc-explorer/src/hw/supermicro_gb300.rs b/crates/bmc-explorer/src/hw/supermicro_gb300.rs new file mode 100644 index 0000000000..6f300423cc --- /dev/null +++ b/crates/bmc-explorer/src/hw/supermicro_gb300.rs @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use crate::hw::BiosAttr; + +/// Setup attributes exposed by the Supermicro OpenBMC firmware on GB300. +/// +/// Unlike GB200, this platform does not expose `TPM`, `EmbeddedUefiShell`, or +/// `SecureBootEnable`. `SecurityDeviceSupport` is its TPM control, while the +/// PCIe option ROMs must be enabled for the host to expose the DPU boot target. +pub const EXPECTED_BIOS_ATTRS: [BiosAttr; 3] = [ + BiosAttr::new_str("SecurityDeviceSupport", "Enabled"), + BiosAttr::new_bool("Socket0Pcie6DisableOptionROM", false), + BiosAttr::new_bool("Socket1Pcie6DisableOptionROM", false), +]; diff --git a/crates/bmc-explorer/src/lib.rs b/crates/bmc-explorer/src/lib.rs index c5d3d441ec..ed0dff68ce 100644 --- a/crates/bmc-explorer/src/lib.rs +++ b/crates/bmc-explorer/src/lib.rs @@ -387,9 +387,7 @@ pub(crate) fn hw_type( { return Some(hw::HwType::DgxGb300); } - // SMC GB300: Supermicro host BMC. The tray scrape shows ServiceRoot vendor "Supermicro" - // (Product "GB NVL", no OEM key), so the vendor string carries it -- no chassis helper - // needed. See gb300-firmus-ingestion/triangulation-matrix.md. + // SMC GB300: Supermicro OpenBMC host. if root.vendor() == Some(Vendor::new("Supermicro")) { return Some(hw::HwType::SupermicroGb300); } @@ -1056,11 +1054,10 @@ fn machine_setup_status( } } - hw::HwType::DgxGb300 | hw::HwType::SupermicroGb300 => { - // GB300 platforms (DGX on the NVIDIA "GB BMC", SMC on a Supermicro OpenBMC) share - // the platform-level setup expectations: secure boot off and boot order by MAC. - // TODO(gb300): add per-ODM EXPECTED_BIOS_ATTRS tables once each GB300 tray's - // BIOS is characterized; until then no BIOS-attr verification is applied. + hw::HwType::DgxGb300 => { + // DGX GB300 on the NVIDIA "GB BMC" uses the platform-level setup expectations: + // secure boot off and boot order by MAC. + // TODO(dgx-gb300): add EXPECTED_BIOS_ATTRS once the tray BIOS is characterized. if explored_system .secure_boot_status() .is_ok_and(|s| s.is_enabled) @@ -1086,6 +1083,31 @@ fn machine_setup_status( } } } + + hw::HwType::SupermicroGb300 => { + // Supermicro GB300 uses the GBx00 OpenBMC flow, but its firmware does not expose + // SecureBootEnable or EmbeddedUefiShell. Verify only the controls present in the + // real tray: TPM support and the DPU-facing PCIe option ROMs. + diffs.extend( + hw::supermicro_gb300::EXPECTED_BIOS_ATTRS + .iter() + .flat_map(|expected| explored_system.verify_bios_attr(expected)), + ); + if let Some(mac) = boot_interface_mac { + let actual = explored_system.boot_order_first_option(); + let mac_str = format!("/MAC({},", mac.to_string().replace(":", "")); + let expected = explored_system.boot_options.iter().find(|option| { + option.uefi_device_path().is_some_and(|path| { + path.inner().contains(&mac_str) + && path.inner().contains("/IPv4(") + && path.inner().ends_with("/Uri()") + }) + }); + if let Some(diff) = compare_boot_options(expected, actual) { + diffs.push(diff) + } + } + } } MachineSetupStatus { diff --git a/crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs b/crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs index 9537d65b8d..7b3ed7e784 100644 --- a/crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs +++ b/crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs @@ -54,4 +54,20 @@ async fn explore_supermicro_gb300() { ); assert!(!report.systems.is_empty(), "systems must be present"); assert!(!report.chassis.is_empty(), "chassis must be present"); + + let setup = report + .machine_setup_status + .expect("SMC GB300 must report machine setup status"); + assert!(!setup.is_done); + assert_eq!( + setup + .diffs + .iter() + .map(|diff| diff.key.as_str()) + .collect::>(), + [ + "Socket0Pcie6DisableOptionROM", + "Socket1Pcie6DisableOptionROM", + ] + ); } diff --git a/crates/bmc-mock/src/hw/supermicro_gb300_nvl.rs b/crates/bmc-mock/src/hw/supermicro_gb300_nvl.rs index 6a3c05e3d9..354131f6cc 100644 --- a/crates/bmc-mock/src/hw/supermicro_gb300_nvl.rs +++ b/crates/bmc-mock/src/hw/supermicro_gb300_nvl.rs @@ -193,7 +193,9 @@ impl SupermicroGB300Nvl<'_> { model: Some("GB NVL".into()), oem: redfish::computer_system::Oem::Generic, callbacks: Some(callbacks), - secure_boot_available: true, + // This firmware exposes the SecureBoot resource but omits + // SecureBootEnable, so there is no usable status to report. + secure_boot_available: false, serial_console: Some( redfish::serial_console::builder() .max_concurrent_sessions(1) @@ -299,12 +301,13 @@ impl SupermicroGB300Nvl<'_> { } fn base_bios(system_id: &str) -> serde_json::Value { - // libredfish uses this attribute to detect whether this BMC spells the - // enabled TPM state as "Enable" or "Enabled" before building its setup - // request. The suffixed key and value mirror a real Supermicro fixture. + // Security device support is already enabled; the DPU-facing option ROMs + // still need to be enabled by clearing their DisableOptionROM controls. redfish::bios::builder(&redfish::bios::resource(system_id)) .attributes(json!({ - "SecurityDeviceSupport_005A": "Enable", + "SecurityDeviceSupport": "Enabled", + "Socket0Pcie6DisableOptionROM": true, + "Socket1Pcie6DisableOptionROM": true, })) .build() }