OpenTitanUARTDriver: fix missing unlock

Bug: 233102476

Writing >CIRCULAR_BUFFER_CAPACITY bytes to the uart will hang because
of a missing unlock of the tx_mutex.

While here add a shell test command that was used to debug the issue
(but don't enable it by default).

Change-Id: I3e35001a653fe2659fb1534e4100727b69f662a1
GitOrigin-RevId: 550b35c88328dcbd1f87dd8e0209b1faabf7f931
This commit is contained in:
Sam Leffler
2022-06-29 01:29:15 +00:00
parent 4ca13e9088
commit 02e1b40885
4 changed files with 49 additions and 0 deletions

View File

@@ -30,6 +30,7 @@ TEST_ML_COORDINATOR = []
TEST_PANIC = []
TEST_SECURITY_COORDINATOR = []
TEST_TIMER_SERVICE = []
TEST_UART = []
[dependencies]
crc = { version = "1.4.0", default_features = false }

View File

@@ -44,6 +44,8 @@ mod test_panic;
mod test_security_coordinator;
#[cfg(feature = "TEST_TIMER_SERVICE")]
mod test_timer_service;
#[cfg(feature = "TEST_UART")]
mod test_uart;
extern "C" {
static SELF_CNODE: seL4_CPtr;
@@ -144,6 +146,8 @@ pub fn repl<T: io::BufRead>(
test_security_coordinator::add_cmds(&mut cmds);
#[cfg(feature = "TEST_TIMER_SERVICE")]
test_timer_service::add_cmds(&mut cmds);
#[cfg(feature = "TEST_UART")]
test_uart::add_cmds(&mut cmds);
let mut line_reader = LineReader::new();
loop {

View File

@@ -0,0 +1,43 @@
// UART driver shell test commands
use core::fmt::Write;
use crate::CmdFn;
use crate::CommandError;
use crate::HashMap;
use kata_io as io;
// NB: not exported by driver so may diverge
const CIRCULAR_BUFFER_CAPACITY: usize = 512;
pub fn add_cmds(cmds: &mut HashMap::<&str, CmdFn>) {
cmds.extend([
("test_uart", uart_command as CmdFn),
]);
}
/// Exercise the UART driver.
fn uart_command(
_args: &mut dyn Iterator<Item = &str>,
_input: &mut dyn io::BufRead,
output: &mut dyn io::Write,
_builtin_cpio: &[u8],
) -> Result<(), CommandError> {
// Just like the kata shell prompt.
const TESTING: &str = "testing...";
output.write_str(TESTING)?;
output.write_str(&"\n")?;
// Fill the UART driver circular buffer.
let not_too_long = "ok".repeat(CIRCULAR_BUFFER_CAPACITY / 2);
output.write_str(&not_too_long)?;
output.write_str(&"\n")?;
// Overflow the UART driver circular buffer.
let too_long = "no".repeat((CIRCULAR_BUFFER_CAPACITY / 2) + 1);
output.write_str(&too_long)?;
writeln!(output, "Success!")?;
Ok(())
}

View File

@@ -226,6 +226,7 @@ int write_write(size_t available) {
while (cursor < cursor_limit) {
LOCK(tx_mutex);
if (circular_buffer_remaining(&tx_buf) == 0) {
UNLOCK(tx_mutex);
break;
}
for (; cursor < cursor_limit; ++cursor) {