[ottool] Add weak/strong gpio support to transports
Currently, only verilator supports modelling detecting weak/strong
inputs.
Signed-off-by: Chris Frantz <cfrantz@google.com>
diff --git a/sw/host/opentitanlib/src/app/config/opentitan_verilator.json b/sw/host/opentitanlib/src/app/config/opentitan_verilator.json
index f6c093b..53eebaf 100644
--- a/sw/host/opentitanlib/src/app/config/opentitan_verilator.json
+++ b/sw/host/opentitanlib/src/app/config/opentitan_verilator.json
@@ -17,6 +17,10 @@
{ "name": "IOR11", "alias_of": "11" },
{ "name": "IOR12", "alias_of": "12" },
{ "name": "IOR13", "alias_of": "13" }
+
+ { "name": "IOC0", "alias_of": "22" }
+ { "name": "IOC1", "alias_of": "23" }
+ { "name": "IOC2", "alias_of": "24" }
],
"uarts": [
{
diff --git a/sw/host/opentitanlib/src/io/gpio.rs b/sw/host/opentitanlib/src/io/gpio.rs
index 2ad00d6..9eb321a 100644
--- a/sw/host/opentitanlib/src/io/gpio.rs
+++ b/sw/host/opentitanlib/src/io/gpio.rs
@@ -43,6 +43,7 @@
pub enum PinMode {
Input,
PushPull,
+ WeakPushPull,
OpenDrain,
}
}
diff --git a/sw/host/opentitanlib/src/transport/cw310/gpio.rs b/sw/host/opentitanlib/src/transport/cw310/gpio.rs
index cde936a..b1cfc08 100644
--- a/sw/host/opentitanlib/src/transport/cw310/gpio.rs
+++ b/sw/host/opentitanlib/src/transport/cw310/gpio.rs
@@ -42,6 +42,7 @@
PinMode::Input => usb.pin_set_output(&self.pinname, false)?,
PinMode::PushPull => usb.pin_set_output(&self.pinname, true)?,
PinMode::OpenDrain => return Err(GpioError::UnsupportedPinMode(mode).into()),
+ PinMode::WeakPushPull => return Err(GpioError::UnsupportedPinMode(mode).into()),
}
Ok(())
}
diff --git a/sw/host/opentitanlib/src/transport/hyperdebug/gpio.rs b/sw/host/opentitanlib/src/transport/hyperdebug/gpio.rs
index 8d2d1e7..955fe6d 100644
--- a/sw/host/opentitanlib/src/transport/hyperdebug/gpio.rs
+++ b/sw/host/opentitanlib/src/transport/hyperdebug/gpio.rs
@@ -5,7 +5,7 @@
use anyhow::Result;
use std::rc::Rc;
-use crate::io::gpio::{GpioPin, PinMode, PullMode};
+use crate::io::gpio::{GpioError, GpioPin, PinMode, PullMode};
use crate::transport::hyperdebug::Inner;
use crate::transport::TransportError;
@@ -53,6 +53,7 @@
PinMode::Input => "input",
PinMode::OpenDrain => "opendrain",
PinMode::PushPull => "pushpull",
+ PinMode::WeakPushPull => return Err(GpioError::UnsupportedPinMode(mode).into()),
}
),
|_| {},
diff --git a/sw/host/opentitanlib/src/transport/ti50emulator/gpio.rs b/sw/host/opentitanlib/src/transport/ti50emulator/gpio.rs
index f131df8..552d9f1 100644
--- a/sw/host/opentitanlib/src/transport/ti50emulator/gpio.rs
+++ b/sw/host/opentitanlib/src/transport/ti50emulator/gpio.rs
@@ -134,6 +134,8 @@
match (state.pin_mode, state.pull_mode, state.value) {
(Some(PinMode::PushPull), _, false) => Logic::StrongZero,
(Some(PinMode::PushPull), _, true) => Logic::StrongOne,
+ (Some(PinMode::WeakPushPull), _, false) => Logic::WeakZero,
+ (Some(PinMode::WeakPushPull), _, true) => Logic::WeakOne,
(Some(PinMode::OpenDrain), _, false) => Logic::StrongZero,
(Some(PinMode::OpenDrain), PullMode::PullUp, true) => Logic::WeakOne,
(Some(PinMode::OpenDrain), PullMode::PullDown, true) => Logic::WeakZero,
diff --git a/sw/host/opentitanlib/src/transport/ultradebug/gpio.rs b/sw/host/opentitanlib/src/transport/ultradebug/gpio.rs
index f36848a..c3fdaf1 100644
--- a/sw/host/opentitanlib/src/transport/ultradebug/gpio.rs
+++ b/sw/host/opentitanlib/src/transport/ultradebug/gpio.rs
@@ -91,6 +91,7 @@
let direction = match mode {
PinMode::Input => false,
PinMode::PushPull => true,
+ PinMode::WeakPushPull => return Err(GpioError::UnsupportedPinMode(mode).into()),
PinMode::OpenDrain => return Err(GpioError::UnsupportedPinMode(mode).into()),
};
self.device
diff --git a/sw/host/opentitanlib/src/transport/verilator/gpio.rs b/sw/host/opentitanlib/src/transport/verilator/gpio.rs
index 630c8f3..6f42840 100644
--- a/sw/host/opentitanlib/src/transport/verilator/gpio.rs
+++ b/sw/host/opentitanlib/src/transport/verilator/gpio.rs
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
use anyhow::{ensure, Context, Result};
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::fs::{File, OpenOptions};
use std::io::{self, ErrorKind, Read, Write};
@@ -17,11 +17,16 @@
pub struct VerilatorGpioPin {
inner: Rc<RefCell<Inner>>,
pinname: u8,
+ pinmode: Cell<PinMode>,
}
impl VerilatorGpioPin {
pub(crate) fn new(inner: Rc<RefCell<Inner>>, pinname: u8) -> Rc<Self> {
- Rc::new(VerilatorGpioPin { inner, pinname })
+ Rc::new(VerilatorGpioPin {
+ inner,
+ pinname,
+ pinmode: Cell::new(PinMode::PushPull),
+ })
}
}
@@ -33,11 +38,19 @@
fn write(&self, value: bool) -> Result<()> {
let mut inner = self.inner.borrow_mut();
- inner.gpio.set(self.pinname, value)
+ inner.gpio.set(
+ self.pinname,
+ value,
+ self.pinmode.get() == PinMode::WeakPushPull,
+ )
}
- fn set_mode(&self, _mode: PinMode) -> Result<()> {
- log::warn!("set_mode not implemented");
+ fn set_mode(&self, mode: PinMode) -> Result<()> {
+ ensure!(
+ mode != PinMode::OpenDrain,
+ GpioError::UnsupportedPinMode(mode)
+ );
+ self.pinmode.set(mode);
Ok(())
}
@@ -81,8 +94,8 @@
);
for (i, val) in buf.iter().enumerate() {
self.rval = match val {
- b'0' => self.rval & !(1 << 31 - i),
- b'1' => self.rval | 1 << 31 - i,
+ b'0' => self.rval & !(1 << (31 - i)),
+ b'1' => self.rval | 1 << (31 - i),
b'\n' | b'X' => self.rval,
_ => {
return Err(GpioError::Generic(format!(
@@ -112,11 +125,12 @@
Ok(self.rval & (1 << index) != 0)
}
- fn set(&mut self, index: u8, val: bool) -> Result<()> {
+ fn set(&mut self, index: u8, val: bool, weak: bool) -> Result<()> {
+ let weak = if weak { "w" } else { "" };
let command = if val {
- format!("h{}\n", index)
+ format!("{}h{}\n", weak, index)
} else {
- format!("l{}\n", index)
+ format!("{}l{}\n", weak, index)
};
self.write
.write(command.as_bytes())
diff --git a/sw/host/opentitanlib/src/transport/verilator/transport.rs b/sw/host/opentitanlib/src/transport/verilator/transport.rs
index 0e318dc..fea4f0c 100644
--- a/sw/host/opentitanlib/src/transport/verilator/transport.rs
+++ b/sw/host/opentitanlib/src/transport/verilator/transport.rs
@@ -67,10 +67,7 @@
spi_file: spi,
gpio_read_file: gpio_rd,
gpio_write_file: gpio_wr,
- inner: Rc::new(RefCell::new(Inner {
- uart: None,
- gpio: gpio,
- })),
+ inner: Rc::new(RefCell::new(Inner { uart: None, gpio })),
})
}