opentitanlib/util/
rom_detect.rs1use anyhow::Result;
6use regex::Regex;
7use std::time::Duration;
8use std::time::Instant;
9
10use crate::io::uart::Uart;
11use crate::uart::console::{ExitStatus, UartConsole};
12use crate::util::usr_access::usr_access_get;
13
14pub struct RomDetect {
15 usr_access: u32,
16 console: UartConsole,
17}
18
19impl RomDetect {
20 pub fn new(bitstream: &[u8], timeout: Option<Duration>) -> Result<RomDetect> {
21 Ok(RomDetect {
22 usr_access: usr_access_get(bitstream)?,
23 console: UartConsole {
24 timeout,
25 exit_success: Some(Regex::new(r"(\w*ROM):([^\r\n]+)[\r\n]").unwrap()),
26 ..Default::default()
27 },
28 })
29 }
30
31 pub fn detect(&mut self, uart: &dyn Uart) -> Result<bool> {
32 let t0 = Instant::now();
33 let rc = self.console.interact(uart, None, None)?;
34 let t1 = Instant::now();
35 log::debug!("detect exit={:?}, duration={:?}", rc, t1 - t0);
36 if let Some(cap) = self.console.captures(ExitStatus::ExitSuccess) {
37 log::info!("Current bitstream: {:?}", cap.get(0).unwrap().as_str());
38 let fpga = cap
39 .get(2)
40 .map(|v| u32::from_str_radix(v.as_str(), 16))
41 .unwrap()?;
42 return Ok(fpga == self.usr_access);
43 }
44 log::info!("Did not detect the ROM identification message.");
45 Ok(false)
46 }
47}