Skip to content

earlgrey/hwe: implement interactive CLI framework and peripheral hierarchies (sys, gpio, usb, flash) - #453

Open
anthonychen1251 wants to merge 10 commits into
OpenPRoT:earlgrey-hwefrom
anthonychen1251:hwe-cli-feat
Open

earlgrey/hwe: implement interactive CLI framework and peripheral hierarchies (sys, gpio, usb, flash)#453
anthonychen1251 wants to merge 10 commits into
OpenPRoT:earlgrey-hwefrom
anthonychen1251:hwe-cli-feat

Conversation

@anthonychen1251

Copy link
Copy Markdown

This PR introduces an interactive command-line interface (CLI) to the OpenPRoT Earl Grey HWE firmware. The CLI is exposed simultaneously over physical UART0 and USB CDC-ACM virtual serial transports, allowing developers and automated test harnesses to inspect and manipulate chip state, GPIO pads, USB routing, and SPI flash memory.

Command Hierarchies

  1. Root Dispatcher & Help (help)

    • Hierarchical subcommand routing with command suggestions and formatted help listings.
    • Unadorned prompt (hwe> ) preserved across transports.
  2. System Hierarchy (sys)

    • sys help: Displays available system subcommands.
    • sys info: Queries sysmgr for chip version, active ROM_EXT/app slots, and reset reasons.
    • sys id: Retrieves and prints the 256-bit OpenTitan device ID formatted in hex.
    • sys reset: Requests a software reboot via sysmgr IPC.
  3. GPIO Hierarchy (gpio)

    • gpio list: Enumerates all configured GPIO pins with active direction, pad name, and pin states.
    • gpio read <pin>: Reads digital input, output, and OE states.
    • gpio write <pin> <0|1>: Drives output level with immediate hardware readback confirmation.
    • gpio config <pin> <in|out|inout> [none|pullup|pulldown]: Configures pin direction and internal pull resistors.
    • gpio attr <pin> <od|pp>: Configures pad open-drain vs. push-pull drive mode.
    • Supports numeric pin indices (e.g. 0..31), schematic signal names (e.g. RST_CTRL0_N, EXT_DEBUG_N), and package pad names (e.g. IOA0, IOC6).
  4. USB Hierarchy (usb)

    • usb help: Displays available USB subcommands.
    • usb info: Reports VBUS cable presence state, active multiplexer route, and pin mapping.
    • usb mux <host|device>: Configures the physical USB multiplexer selection line (USB_MUX_CTRL).
  5. SPI Flash Hierarchy (flash)

    • flash help: Displays available SPI flash subcommands.
    • flash info: Inspects SPI multiplexer status, active route (target vs host), pin assignments, and WP lines.
    • flash mux <en|dis>: Controls the external SPI flash multiplexer enable line (SPI_MUX_EN_N).
    • flash route <target|host>: Sets SPI routing between the DUT and upstream programmer (SPI_MUX_CTRL).
    • flash read-id [0|1]: Executes JEDEC Read ID (0x9F) via flash_server over SPI host, decoding manufacturer, device model, and density with upstream collision protection.

Extend Earl Grey pinmux `PadConfig` to support `slew_rate` and
`drive_strength` attributes with WARL (writes-any-reads-legal)
semantics.

Signed-off-by: Anthony Chen <antchen@google.com>
Reuse the flash_server implementation from the transport firmware in HWE
to unify flash service handling across applications.

Signed-off-by: Anthony Chen <antchen@google.com>
@anthonychen1251 anthonychen1251 changed the title earlgrey/hwe: implement interactive CLI framework and peripheral hierarchies (sys, gpio, usb, flash)This PR introduces a zero-allocation, interactive command-line interface (CLI) to the OpenPRoT Earl Grey HWE (Hardware Engineer) firmware. The CLI is exposed simultaneously over physical UART0 and USB CDC-ACM virtual serial transports, allowing developers and automated test harnesses to inspect and manipulate chip state, GPIO pads, USB routing, and SPI flash memory. earlgrey/hwe: implement interactive CLI framework and peripheral hierarchies (sys, gpio, usb, flash) Aug 31, 2026
- CommandLineBuffer: zero-allocation line editor with in-place VT100
  backspace cooking and overflow protection
- Single Authority in logmgr: centralize character cooking and prompt
  synchronization for both UART0 and USB CDC-ACM
- Safe buffer partitioning: split IPC buffers to guarantee zero-copy
  and prevent overflow on character expansion
- System IPC: register CLI_PLATFORM and CLI_USB channels with
  non-blocking event loop integration

Signed-off-by: Anthony Chen <antchen@google.com>
Add support for emitting unadorned (bare) string events without log level
or timestamp metadata using the `util_zfmt::raw!` macro.

- Add `raw!` macro supporting string literals and &str expressions
- Export Format, FormatSpec, and FormatType from zfmt
- Update render_event to append CRLF only for structured EventHeader and StreamStart
  events, preserving bare events exactly as formatted by the sender
- Update transport logmgr and usbmgr to rely on rendered event payloads without
  redundantly appending trailing CRLF

Signed-off-by: Anthony Chen <antchen@google.com>
Implement the zero-allocation hierarchical command dispatcher in the
platform service and integrate it into the HWE event loop, backed by
end-to-end tests covering both physical UART0 and USB CDC-ACM transports.

Signed-off-by: Anthony Chen <antchen@google.com>
Add the `gpio` command hierarchy to the platform service CLI, providing
direct inspection and manipulation of GPIO lines and pads over UART0 and
USB CDC-ACM virtual serial.

  - `gpio list`: lists configured pins with direction, pad name, and states.
  - `gpio read <pin>`: reads digital input, output, and OE levels.
  - `gpio write <pin> <0|1>`: drives output high/low with immediate readback.
  - `gpio config <pin> <in|out|inout> [none|pullup|pulldown]`: sets direction
    and pull resistors with readback.
  - `gpio attr <pin> <od|pp>`: sets pad open-drain or push-pull mode with
    immediate readback.
  - Flexible pin resolution: supports numeric index (0..31), signal names
    (e.g., RST_CTRL0_N, EXT_DEBUG_N), and pad identifiers (e.g., IOA0, IOC6).

Signed-off-by: Anthony Chen <antchen@google.com>
Add the `sys` command hierarchy to the platform service CLI:
  - `sys help`: displays available system subcommands.
  - `sys info`: queries `sysmgr` for chip info, ROM_EXT slot/version,
    active app slot, and reset reason.
  - `sys id`: displays OpenTitan 256-bit device ID formatted as hex.
  - `sys reset`: requests software reboot via `sysmgr` IPC.

Extend `host_cli_check.rs` with automated verification across both
UART0 console and USB CDC-ACM virtual serial transports.

Signed-off-by: Anthony Chen <antchen@google.com>
Add the `usb` command hierarchy to the platform service CLI:
  - `usb help`: displays available USB subcommands.
  - `usb info`: inspects and displays USB cable presence state,
    current multiplexer route (host vs device), and hardware pin mapping.
  - `usb mux <host|device>`: configures the physical USB multiplexer
    control line (`USB_MUX_CTRL`).

Extend `host_cli_check.rs` with automated verification across both
UART0 console and USB CDC-ACM virtual serial transports.

Signed-off-by: Anthony Chen <antchen@google.com>
…ead-id)

Add the `flash` command hierarchy to the platform service CLI:
  - `flash help`: displays available SPI flash subcommands.
  - `flash info`: inspects and displays SPI flash multiplexer status,
    active route (target vs host), pin assignments, and write protect lines.
  - `flash mux <en|dis>`: enables or disables the external SPI flash
    multiplexer (`SPI_MUX_EN_N`).
  - `flash route <target|host>`: configures the SPI multiplexer route
    selection line (`SPI_MUX_CTRL`).
  - `flash read-id [0|1]`: reads external SPI flash JEDEC ID (RDID 0x9F)
    and decodes manufacturer name, device model, and memory density.
    Includes conflict avoidance checking against active upstream routing.

Extend `services/flash` with `IPC_OP_FLASH_READ_ID` opcode and handler
in `flash_server` driving `SPI_HOST0` and `SPI_HOST1`.
Extend `host_cli_check.rs` with automated verification across both
UART0 console and USB CDC-ACM virtual serial transports.

Signed-off-by: Anthony Chen <antchen@google.com>
…g stall

When a message transmitted over USB CDC-ACM has a length that is an
exact multiple of the USB Full-Speed Maximum Packet Size (64 bytes),
transmission stalls on the device until the host sends data back
(e.g. typing Enter).

Root Cause:
1. Per USB 2.0, bulk IN transfers whose length is a multiple of
   wMaxPacketSize must be terminated with a Zero-Length Packet (ZLP) so
   the host controller knows the transfer is complete.
2. `cdc_acm::poll_transmit` requests `zlp = true` via
   `transfer_in_unaligned`.
3. In `usb_driver`, the driver checks:
`if zlp && pkt.len() == MAX_PACKET_SIZE && buf_pool.len() < 2 { break; }`
   requiring at least two hardware buffer slots to simultaneously queue
   the 64-byte data packet and the terminating ZLP.
4. `CdcAcmBuilder::eps()` previously configured `data_in_ep` with
   `buf_pool_size: 1`. Because the pool could never hold >= 2 buffers,
   the driver aborted queuing (returning 0 bytes queued), leaving the
   64-byte chunk unconsumed in `cdc_acm.tx_queue`.
5. Because `tx_queue` remained non-empty, `usbmgr` could not pull
   subsequent log events from `logmgr` and went to sleep in `object_wait`
   with no hardware transmission in flight, deadlocking the console until
   host interaction pushed input bytes into the buffer.

Fix:
Increase `data_in_ep` buffer pool size from 1 to 4. OpenTitan's `usbdev`
hardware provides 32 buffer slots, so allocating 4 slots for bulk data
IN easily accommodates simultaneous full-packet and ZLP transmissions
while leaving 11 slots available for EP0 control transfers.

Signed-off-by: Anthony Chen <antchen@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant