blob: 5100c31ab300576563b3cbcaeef462946ca6a6d1 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
use anyhow::Result;
use serde_annotate::Annotate;
use std::path::{Path, PathBuf};
use std::time::Duration;
use structopt::StructOpt;
use crate::app::{self, TransportWrapper};
use crate::transport::common::fpga::FpgaProgram;
use crate::util::rom_detect::RomKind;
/// Load a bitstream into the FPGA.
#[derive(Debug, StructOpt)]
pub struct LoadBitstream {
#[structopt(long, help = "The bitstream to load for the test")]
pub bitstream: Option<PathBuf>,
#[structopt(
long,
possible_values = &RomKind::variants(),
case_insensitive = true,
help = "OpenTitan ROM type"
)]
pub rom_kind: Option<RomKind>,
#[structopt(long, parse(try_from_str=humantime::parse_duration), default_value="50ms", help = "Duration of the reset pulse.")]
pub rom_reset_pulse: Duration,
#[structopt(long, parse(try_from_str=humantime::parse_duration), default_value="2s", help = "Duration of ROM detection timeout")]
pub rom_timeout: Duration,
}
impl LoadBitstream {
pub fn init(&self, transport: &TransportWrapper) -> Result<Option<Box<dyn Annotate>>> {
if let Some(bitstream) = &self.bitstream {
self.load(transport, bitstream)
} else {
Ok(None)
}
}
pub fn load(
&self,
transport: &TransportWrapper,
file: &Path,
) -> Result<Option<Box<dyn Annotate>>> {
log::info!("Loading bitstream: {:?}", file);
let payload = std::fs::read(file)?;
let progress = app::progress_bar(payload.len() as u64);
let pfunc = Box::new(move |_, chunk| {
progress.inc(chunk as u64);
});
let operation = FpgaProgram {
bitstream: payload,
rom_kind: self.rom_kind,
rom_reset_pulse: self.rom_reset_pulse,
rom_timeout: self.rom_timeout,
progress: Some(pfunc),
};
transport.dispatch(&operation)
}
}