|
| 1 | +// SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | +//! Sovereign GPU initialization JSON-RPC handler. |
| 3 | +//! |
| 4 | +//! Exposes `sovereign.init` — the staged diesel-engine pipeline that brings a |
| 5 | +//! VFIO-bound GPU from cold/warm state to compute-ready. |
| 6 | +
|
| 7 | +use crate::pure_jsonrpc::types::JsonRpcError; |
| 8 | +use serde_json::Value; |
| 9 | +use tracing::info; |
| 10 | + |
| 11 | +const DEFAULT_BAR0_SIZE: usize = 16 * 1024 * 1024; |
| 12 | + |
| 13 | +/// `sovereign.init` — Run the full sovereign init pipeline on a GPU. |
| 14 | +/// |
| 15 | +/// Opens BAR0 via sysfs, runs `cylinder::sovereign_init` stages, returns |
| 16 | +/// per-stage results. The GPU must be VFIO-bound (or unbound) with BAR0 |
| 17 | +/// accessible via `/sys/bus/pci/devices/{bdf}/resource0`. |
| 18 | +/// |
| 19 | +/// Params: |
| 20 | +/// - `bdf` (required): PCI BDF address (e.g. `"0000:4b:00.0"`) |
| 21 | +/// - `halt_before` (optional): Stop before a stage (`"pmc_enable"`, `"hbm2_training"`, |
| 22 | +/// `"kepler_pgraph_ungate"`, `"falcon_boot"`, `"gr_init"`, `"verify"`) |
| 23 | +/// - `skip_gr_init` (optional, default false): Skip GR init stage |
| 24 | +/// - `golden_state_path` (optional): Path to golden-state JSON for HBM2 replay |
| 25 | +/// - `vbios_rom_path` (optional): Path to raw VBIOS ROM dump |
| 26 | +/// - `sm_version` (optional): SM version override (auto-detected if omitted) |
| 27 | +/// - `fbpa_count` (optional): FBPA partition count override (auto-detected) |
| 28 | +pub fn sovereign_init(params: Option<&Value>) -> Result<Value, JsonRpcError> { |
| 29 | + let bdf = params |
| 30 | + .and_then(|p| p.get("bdf")) |
| 31 | + .and_then(Value::as_str) |
| 32 | + .ok_or_else(|| JsonRpcError::invalid_params("Missing 'bdf' string parameter"))?; |
| 33 | + |
| 34 | + info!(bdf = %bdf, "sovereign.init: opening BAR0"); |
| 35 | + |
| 36 | + let bar0 = toadstool_cylinder::vfio::device::MappedBar::from_sysfs_rw(bdf, DEFAULT_BAR0_SIZE) |
| 37 | + .map_err(|e| { |
| 38 | + JsonRpcError::internal_error(format!( |
| 39 | + "BAR0 open failed for {bdf}: {e}. Ensure vfio-pci is bound and resource0 is accessible." |
| 40 | + )) |
| 41 | + })?; |
| 42 | + |
| 43 | + let mut opts: toadstool_cylinder::vfio::sovereign_init::SovereignInitOptions = |
| 44 | + if let Some(p) = params { |
| 45 | + serde_json::from_value(p.clone()).unwrap_or_default() |
| 46 | + } else { |
| 47 | + Default::default() |
| 48 | + }; |
| 49 | + |
| 50 | + if let Some(path) = opts.golden_state_path.as_ref() { |
| 51 | + match std::fs::read_to_string(path) { |
| 52 | + Ok(json_str) => { |
| 53 | + if let Ok(pairs) = |
| 54 | + serde_json::from_str::<Vec<(usize, u32)>>(&json_str) |
| 55 | + { |
| 56 | + opts.golden_state = Some(pairs); |
| 57 | + } |
| 58 | + } |
| 59 | + Err(e) => { |
| 60 | + info!(path = %path, error = %e, "golden_state_path read failed, continuing without"); |
| 61 | + } |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | + if let Some(path) = opts.vbios_rom_path.as_ref() { |
| 66 | + match std::fs::read(path) { |
| 67 | + Ok(rom) => { |
| 68 | + opts.vbios_rom = Some(rom); |
| 69 | + } |
| 70 | + Err(e) => { |
| 71 | + info!(path = %path, error = %e, "vbios_rom_path read failed, continuing without"); |
| 72 | + } |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + let bridge = toadstool_cylinder::nv::gsp_bridge::StubGspBridge; |
| 77 | + |
| 78 | + info!(bdf = %bdf, halt_before = ?opts.halt_before, "sovereign.init: starting pipeline"); |
| 79 | + |
| 80 | + let result = toadstool_cylinder::vfio::sovereign_init::sovereign_init( |
| 81 | + &bar0, bdf, &opts, &bridge, |
| 82 | + ); |
| 83 | + |
| 84 | + info!( |
| 85 | + bdf = %bdf, |
| 86 | + all_ok = result.all_ok, |
| 87 | + compute_ready = result.compute_ready, |
| 88 | + total_ms = result.total_ms, |
| 89 | + stages = result.stages.len(), |
| 90 | + warm_detected = result.warm_detected, |
| 91 | + "sovereign.init: pipeline complete" |
| 92 | + ); |
| 93 | + |
| 94 | + serde_json::to_value(&result) |
| 95 | + .map_err(|e| JsonRpcError::internal_error(format!("serialization failed: {e}"))) |
| 96 | +} |
0 commit comments