blob: 644f1d7197892c67beb33f3fe634c9f0104508b1 [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 erased_serde::Serialize;
use std::any::Any;
use std::collections::HashMap;
use std::path::PathBuf;
use structopt::StructOpt;
use opentitanlib::app::command::CommandDispatch;
use opentitanlib::app::TransportWrapper;
use opentitanlib::io::emu::{EmuState, EmuValue};
use opentitanlib::transport::Capability;
#[derive(Debug, StructOpt)]
/// Get State of Emulator instance
pub struct EmuGetState {}
#[derive(serde::Serialize)]
pub struct EmuGetStateResult {
pub state: EmuState,
}
impl CommandDispatch for EmuGetState {
fn run(
&self,
_context: &dyn Any,
transport: &TransportWrapper,
) -> Result<Option<Box<dyn Serialize>>> {
transport
.capabilities()?
.request(Capability::EMULATOR)
.ok()?;
let emulator = transport.emulator()?;
let state = emulator.get_state()?;
Ok(Some(Box::new(EmuGetStateResult { state })))
}
}
#[derive(Debug, StructOpt)]
/// Start Emulator instance
pub struct EmuStart {
#[structopt(
long,
help = "Reset all presistent storage (For example: flash, otp, eeprom) to factory state"
)]
pub factory_reset: bool,
#[structopt(long, help = "Emulator executable file name")]
pub emulator_exec: Option<String>,
#[structopt(
long,
help = "List of application names that will be provided in flash images"
)]
pub apps_list: Option<Vec<String>>,
#[structopt(
long,
parse(from_os_str),
help = "List of file paths representing Flash images"
)]
pub flash_list: Option<Vec<PathBuf>>,
#[structopt(
long,
parse(from_os_str),
help = "Path to file representing Emulator version state"
)]
pub version_init_state: Option<PathBuf>,
#[structopt(
long,
parse(from_os_str),
help = "Path to file representing PMU initial state"
)]
pub pmu_init_state: Option<PathBuf>,
}
fn pack_args(
args_map: &mut HashMap<String, EmuValue>,
key: &str,
value: &Option<impl Into<EmuValue> + Clone>,
) {
if let Some(value) = value {
args_map.insert(key.to_string(), value.clone().into());
}
}
impl CommandDispatch for EmuStart {
fn run(
&self,
_context: &dyn Any,
transport: &TransportWrapper,
) -> Result<Option<Box<dyn Serialize>>> {
transport
.capabilities()?
.request(Capability::EMULATOR)
.ok()?;
let emulator = transport.emulator()?;
let mut args: HashMap<String, EmuValue> = HashMap::new();
pack_args(&mut args, "exec", &self.emulator_exec);
pack_args(&mut args, "apps", &self.apps_list);
pack_args(&mut args, "flash", &self.flash_list);
pack_args(&mut args, "version_init_state", &self.version_init_state);
pack_args(&mut args, "pmu_init_state", &self.pmu_init_state);
emulator.start(self.factory_reset, &args)?;
Ok(None)
}
}
#[derive(Debug, StructOpt)]
/// Stop Emulator instance
pub struct EmuStop {}
impl CommandDispatch for EmuStop {
fn run(
&self,
_context: &dyn Any,
transport: &TransportWrapper,
) -> Result<Option<Box<dyn Serialize>>> {
transport
.capabilities()?
.request(Capability::EMULATOR)
.ok()?;
let emulator = transport.emulator()?;
emulator.stop()?;
Ok(None)
}
}
#[derive(Debug, StructOpt, CommandDispatch)]
/// Commands for interacting with Emulator instance
pub enum EmuCommand {
State(EmuGetState),
Start(EmuStart),
Stop(EmuStop),
}