mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-07-22 09:51:48 +00:00
Splits UART tx/rx into separate CAmkES procedures
This ends the behavior where log messages would block on the prompt. This change does not fix the potential race on dataports if kata-uart-client read or write has multiple concurrent callers. A later change will protect those using CAmkES mutexes, although the alternative of having DebugConsole *own* the UART should also be considered. Change-Id: I8d5d8336cd58b9f22cca81ae6aca13b4ed57e7e4 GitOrigin-RevId: e781fd8454d22e0f829d788fe602e431551e259a
This commit is contained in:
parent
20c83f6777
commit
7c3cc70ab1
@ -6,9 +6,12 @@ import <SeL4DebugInterface.camkes>;
|
|||||||
|
|
||||||
component DebugConsole {
|
component DebugConsole {
|
||||||
control;
|
control;
|
||||||
uses uart_inf uart;
|
|
||||||
dataport Buf tx_dataport;
|
dataport Buf tx_dataport;
|
||||||
|
uses dataport_io_inf uart_tx;
|
||||||
|
|
||||||
dataport Buf rx_dataport;
|
dataport Buf rx_dataport;
|
||||||
|
uses dataport_io_inf uart_rx;
|
||||||
|
|
||||||
provides LoggerInterface logger;
|
provides LoggerInterface logger;
|
||||||
uses ProcessControlInterface proc_ctrl;
|
uses ProcessControlInterface proc_ctrl;
|
||||||
|
@ -8,8 +8,8 @@ use kata_io as io;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
static rx_dataport: *mut cty::c_uchar;
|
static rx_dataport: *mut cty::c_uchar;
|
||||||
static tx_dataport: *mut cty::c_uchar;
|
static tx_dataport: *mut cty::c_uchar;
|
||||||
fn uart_rx(n: cty::size_t);
|
fn uart_rx_update(n: cty::size_t);
|
||||||
fn uart_tx(n: cty::size_t);
|
fn uart_tx_update(n: cty::size_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console logging interface.
|
// Console logging interface.
|
||||||
@ -27,7 +27,7 @@ pub struct Rx {}
|
|||||||
impl io::Read for Rx {
|
impl io::Read for Rx {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
uart_rx(buf.len());
|
uart_rx_update(buf.len());
|
||||||
let port = core::slice::from_raw_parts(rx_dataport, buf.len());
|
let port = core::slice::from_raw_parts(rx_dataport, buf.len());
|
||||||
buf.copy_from_slice(&port);
|
buf.copy_from_slice(&port);
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ impl io::Write for Tx {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let port = core::slice::from_raw_parts_mut(tx_dataport, buf.len());
|
let port = core::slice::from_raw_parts_mut(tx_dataport, buf.len());
|
||||||
port.copy_from_slice(buf);
|
port.copy_from_slice(buf);
|
||||||
uart_tx(buf.len());
|
uart_tx_update(buf.len());
|
||||||
}
|
}
|
||||||
Ok(buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
component UartDriver {
|
component UartDriver {
|
||||||
dataport Buf mem;
|
dataport Buf mmio_region;
|
||||||
dataport Buf tx_dataport;
|
dataport Buf tx_dataport;
|
||||||
dataport Buf rx_dataport;
|
dataport Buf rx_dataport;
|
||||||
|
|
||||||
// consumes Interrupt interrupt;
|
provides dataport_io_inf uart_rx;
|
||||||
|
provides dataport_io_inf uart_tx;
|
||||||
provides uart_inf uart;
|
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,14 @@
|
|||||||
#include "opentitan/uart.h"
|
#include "opentitan/uart.h"
|
||||||
|
|
||||||
// Referenced by macros in the generated file opentitan/uart.h.
|
// Referenced by macros in the generated file opentitan/uart.h.
|
||||||
#define UART0_BASE_ADDR (void *)mem
|
#define UART0_BASE_ADDR (void *)mmio_region
|
||||||
|
|
||||||
// Frequency of the primary clock clk_i.
|
// Frequency of the primary clock clk_i.
|
||||||
#define CLK_FIXED_FREQ_HZ (24ull * 1000 * 1000)
|
#define CLK_FIXED_FREQ_HZ (24ull * 1000 * 1000)
|
||||||
|
|
||||||
#define REG32(addr) *((volatile uint32_t *)(addr))
|
#define REG32(addr) *((volatile uint32_t *)(addr))
|
||||||
|
|
||||||
void uart__init() {
|
void pre_init() {
|
||||||
// Computes NCO value corresponding to baud rate.
|
// Computes NCO value corresponding to baud rate.
|
||||||
// nco = 2^20 * baud / fclk (assuming NCO width is 16-bit)
|
// nco = 2^20 * baud / fclk (assuming NCO width is 16-bit)
|
||||||
uint64_t baud = 115200ull;
|
uint64_t baud = 115200ull;
|
||||||
@ -75,7 +75,7 @@ static int uart_tx_ready() {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_rx(size_t n) {
|
void uart_rx_update(size_t n) {
|
||||||
char *c = (char *)rx_dataport;
|
char *c = (char *)rx_dataport;
|
||||||
// TODO(mattharvey): Error return value for n > PAGE_SIZE
|
// TODO(mattharvey): Error return value for n > PAGE_SIZE
|
||||||
for (size_t i = 0; i < n && i < PAGE_SIZE; ++i) {
|
for (size_t i = 0; i < n && i < PAGE_SIZE; ++i) {
|
||||||
@ -87,7 +87,7 @@ void uart_rx(size_t n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_tx(size_t n) {
|
void uart_tx_update(size_t n) {
|
||||||
char *c = (char *)tx_dataport;
|
char *c = (char *)tx_dataport;
|
||||||
// TODO(mattharvey): Error return value for n > PAGE_SIZE
|
// TODO(mattharvey): Error return value for n > PAGE_SIZE
|
||||||
for (size_t i = 0; i < n && i < PAGE_SIZE; ++i) {
|
for (size_t i = 0; i < n && i < PAGE_SIZE; ++i) {
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
* @TAG(DATA61_BSD)
|
* @TAG(DATA61_BSD)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
procedure uart_inf {
|
procedure dataport_io_inf {
|
||||||
void rx(in size_t n);
|
void update(in size_t n);
|
||||||
void tx(in size_t n);
|
|
||||||
};
|
};
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
import <std_connector.camkes>;
|
import <std_connector.camkes>;
|
||||||
|
|
||||||
import "interfaces/uart.idl4";
|
import "interfaces/dataport_io.idl4";
|
||||||
import "interfaces/VectorCoreInterface.camkes";
|
import "interfaces/VectorCoreInterface.camkes";
|
||||||
import "components/UartDriver/UartDriver.camkes";
|
import "components/UartDriver/UartDriver.camkes";
|
||||||
import "components/DebugConsole/DebugConsole.camkes";
|
import "components/DebugConsole/DebugConsole.camkes";
|
||||||
@ -23,9 +23,9 @@ import "components/VectorCoreDriver/VectorCoreDriver.camkes";
|
|||||||
|
|
||||||
component UART {
|
component UART {
|
||||||
hardware;
|
hardware;
|
||||||
dataport Buf mem;
|
dataport Buf mmio_region;
|
||||||
// TODO(mattharvey): Make receives wait on interrupt.
|
|
||||||
// emits Interrupt interrupt;
|
emits Interrupt rx_watermark;
|
||||||
}
|
}
|
||||||
|
|
||||||
component VectorCoreHw {
|
component VectorCoreHw {
|
||||||
@ -35,22 +35,27 @@ component VectorCoreHw {
|
|||||||
|
|
||||||
assembly {
|
assembly {
|
||||||
composition {
|
composition {
|
||||||
component UART uart;
|
|
||||||
component UartDriver drv;
|
|
||||||
component DebugConsole debug_console;
|
|
||||||
component ProcessManager process_manager;
|
|
||||||
component SeL4Debug sel4debug;
|
component SeL4Debug sel4debug;
|
||||||
|
|
||||||
component VectorCoreHw vctop;
|
component VectorCoreHw vctop;
|
||||||
component VectorCoreDriver vc_drv;
|
component VectorCoreDriver vc_drv;
|
||||||
|
|
||||||
|
component UART uart;
|
||||||
|
component UartDriver uart_driver;
|
||||||
|
|
||||||
|
component ProcessManager process_manager;
|
||||||
component MlCoordinator ml_coordinator;
|
component MlCoordinator ml_coordinator;
|
||||||
|
component DebugConsole debug_console;
|
||||||
|
|
||||||
connection seL4HardwareMMIO uart_mem(from drv.mem, to uart.mem);
|
// UartDriver
|
||||||
connection seL4HardwareMMIO vc_csr(from vc_drv.csr, to vctop.csr);
|
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
|
||||||
|
to uart.mmio_region);
|
||||||
// TODO(mattharvey): Make receives wait on interrupt.
|
// TODO(mattharvey): Make receives wait on interrupt.
|
||||||
// connection seL4HardwareInterrupt uart_interrupt(
|
|
||||||
// from uart.interrupt, to drv.interrupt);
|
// VectorCoreDriver
|
||||||
connection seL4RPCCall uart_inf(from debug_console.uart, to drv.uart);
|
connection seL4HardwareMMIO vc_csr(from vc_drv.csr, to vctop.csr);
|
||||||
|
connection seL4RPCCall VectorCoreInterface(from ml_coordinator.vctop,
|
||||||
|
to vc_drv.vctop);
|
||||||
|
|
||||||
// Hookup ProcessManager to DebugConsole for shell commands.
|
// Hookup ProcessManager to DebugConsole for shell commands.
|
||||||
connection seL4RPCCall ProcessControlInterface(from debug_console.proc_ctrl,
|
connection seL4RPCCall ProcessControlInterface(from debug_console.proc_ctrl,
|
||||||
@ -58,6 +63,16 @@ assembly {
|
|||||||
connection seL4RPCCall PackageManagerInterface(from debug_console.pkg_mgmt,
|
connection seL4RPCCall PackageManagerInterface(from debug_console.pkg_mgmt,
|
||||||
to process_manager.pkg_mgmt);
|
to process_manager.pkg_mgmt);
|
||||||
|
|
||||||
|
// Connect the DebugConsole to the UartDriver.
|
||||||
|
connection seL4SharedData tx_channel(
|
||||||
|
from debug_console.tx_dataport, to uart_driver.tx_dataport);
|
||||||
|
connection seL4RPCCall tx_call(
|
||||||
|
from debug_console.uart_tx, to uart_driver.uart_tx);
|
||||||
|
connection seL4SharedData rx_channel(
|
||||||
|
from debug_console.rx_dataport, to uart_driver.rx_dataport);
|
||||||
|
connection seL4RPCCall rx_call(
|
||||||
|
from debug_console.uart_rx, to uart_driver.uart_rx);
|
||||||
|
|
||||||
// Connect the LoggerInterface to each component that needs to log
|
// Connect the LoggerInterface to each component that needs to log
|
||||||
// to the console.
|
// to the console.
|
||||||
connection seL4RPCCall LoggerInterface(from process_manager.logger,
|
connection seL4RPCCall LoggerInterface(from process_manager.logger,
|
||||||
@ -72,25 +87,17 @@ assembly {
|
|||||||
connection seL4RPCCall MlCoordinatorInterface(from debug_console.mlcoord,
|
connection seL4RPCCall MlCoordinatorInterface(from debug_console.mlcoord,
|
||||||
to ml_coordinator.mlcoord);
|
to ml_coordinator.mlcoord);
|
||||||
|
|
||||||
connection seL4RPCCall VectorCoreInterface(from ml_coordinator.vctop, to vc_drv.vctop);
|
|
||||||
|
|
||||||
connection seL4SharedData tx_channel(
|
|
||||||
from debug_console.tx_dataport, to drv.tx_dataport);
|
|
||||||
connection seL4SharedData rx_channel(
|
|
||||||
from debug_console.rx_dataport, to drv.rx_dataport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration {
|
configuration {
|
||||||
uart.mem_paddr = 0x40031000;
|
uart.mmio_region_paddr = 0x40031000;
|
||||||
uart.mem_size = 0x1000;
|
uart.mmio_region_size = 0x1000;
|
||||||
// seL4 claims 10 is bigger than irqMax if this is uncommented.
|
|
||||||
// uart.interrupt_irq_number = 10;
|
|
||||||
|
|
||||||
vctop.csr_paddr = 0x48000000;
|
vctop.csr_paddr = 0x48000000;
|
||||||
vctop.csr_size = 0x1000;
|
vctop.csr_size = 0x1000;
|
||||||
|
|
||||||
random.ID = 1;
|
random.ID = 1;
|
||||||
|
|
||||||
uart.integrity_label = "drv";
|
uart.integrity_label = "uart_driver";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user