diff --git a/crates/bmc-explorer/src/hw/mod.rs b/crates/bmc-explorer/src/hw/mod.rs index d9019b52a1..a02d516a7f 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 vera_rubin; pub mod viking; #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -45,6 +46,7 @@ pub enum HwType { Viking, LiteonPowerShelf, NvSwitch, + VeraRubin, } impl HwType { @@ -66,6 +68,7 @@ impl HwType { Self::NvSwitch => Some(bmc_vendor::BMCVendor::Nvidia), Self::Supermicro => Some(bmc_vendor::BMCVendor::Supermicro), Self::Viking => Some(bmc_vendor::BMCVendor::Nvidia), + Self::VeraRubin => Some(bmc_vendor::BMCVendor::Nvidia), } } @@ -90,6 +93,8 @@ impl HwType { Self::NvSwitch => None, Self::Supermicro => None, Self::Viking => Some(BiosAttr::new_str("NvidiaInfiniteboot", "Enable")), + // Same EmbeddedUefiShell polarity as GB200 / libredfish NvidiaGBx00. + Self::VeraRubin => Some(BiosAttr::new_str("EmbeddedUefiShell", "Disabled")), } } } diff --git a/crates/bmc-explorer/src/hw/vera_rubin.rs b/crates/bmc-explorer/src/hw/vera_rubin.rs new file mode 100644 index 0000000000..1843f7ac44 --- /dev/null +++ b/crates/bmc-explorer/src/hw/vera_rubin.rs @@ -0,0 +1,27 @@ +/* + * 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; + +// Vera Rubin compute-tray host BMC: Systems/System_0, ServiceRoot Product "VR NVL72". +// Shares TPM / EmbeddedUefiShell with GB200; uses GpuExposeAsPcie instead of GB200's +// Socket{0,1}Pcie6DisableOptionROM knobs. +pub const EXPECTED_BIOS_ATTRS: [BiosAttr; 3] = [ + BiosAttr::new_str("TPM", "Enabled"), + BiosAttr::new_str("EmbeddedUefiShell", "Disabled"), + BiosAttr::new_bool("GpuExposeAsPcie", true), +]; diff --git a/crates/bmc-explorer/src/lib.rs b/crates/bmc-explorer/src/lib.rs index 40c4ad1a4a..eead776966 100644 --- a/crates/bmc-explorer/src/lib.rs +++ b/crates/bmc-explorer/src/lib.rs @@ -191,10 +191,12 @@ pub async fn nv_generate_exploration_report( ) => chassis.chassis.id().into_inner() == explored_system.system.id().into_inner(), // Provides only one Chassis. Some(hw::HwType::LenovoAmi) => true, - Some(hw::HwType::LenovoGb300 | hw::HwType::DgxGb300 | hw::HwType::SupermicroGb300) => { - let chassis_id = chassis.chassis.id().into_inner(); - chassis_id.starts_with("HGX_GPU_") - } + Some( + hw::HwType::LenovoGb300 + | hw::HwType::DgxGb300 + | hw::HwType::SupermicroGb300 + | hw::HwType::VeraRubin, + ) => chassis.chassis.id().into_inner().starts_with("HGX_GPU_"), // No meaningful PCIeDevices. Some( hw::HwType::Bluefield @@ -310,6 +312,9 @@ pub(crate) fn hw_type( "Supermicro" => Some(hw::HwType::Supermicro), "HPE" => Some(hw::HwType::Hpe), "Nvidia" if system.id().into_inner() == "Bluefield" => Some(hw::HwType::Bluefield), + "NVIDIA" if root.product() == Some(Product::new("VR NVL72")) => { + Some(hw::HwType::VeraRubin) + } "WIWYNN" | "NVIDIA" if root.product() == Some(Product::new("GB200 NVL")) || root.product() == Some(Product::new("GB BMC")) => @@ -903,6 +908,40 @@ fn machine_setup_status( } } + hw::HwType::VeraRubin => { + if explored_system + .secure_boot_status() + .is_ok_and(|s| s.is_enabled) + { + diffs.push(MachineSetupDiff { + key: "SecureBoot".to_string(), + expected: "false".to_string(), + actual: "true".to_string(), + }) + } + diffs.extend( + hw::vera_rubin::EXPECTED_BIOS_ATTRS + .iter() + .flat_map(|expected| explored_system.verify_bios_attr(expected)), + ); + if let Some(mac) = boot_interface_mac { + // Looking for UEFI Device path: + // VenHw(...)/.../MAC(020304050607,0x1)/IPv4(0.0.0.0)/Uri() + 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) + } + } + } + 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.