|  | // 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) | 
|  | } | 
|  | } |