APBUART — Serial port¶
GRLIB APBUART (GR712RC §10 / GRLIB IP §28). The primary serial console; the only path between guest software and the host.
| Property | Value |
|---|---|
| Default MMIO base | 0x80000100 |
| MMIO window size | 0x100 |
| Default IRQ | 3 |
| RX FIFO depth | 8 (Decision 18) |
| TX FIFO | not modelled (immediate drain) |
| Source file | src/peripherals/src/apbuart.cpp |
Register map¶
| Offset | Name | Access | Description |
|---|---|---|---|
0x00 |
DATA | R/W | Data register: read pops RX FIFO, write enqueues TX byte |
0x04 |
STATUS | R/(W to clear flags) | Status flags |
0x08 |
CTRL | R/W | Control flags (TE/RE/PE/PS/IE/RI/TI/LB/EC/FA/DB) |
0x0C |
SCALER | R/W | Baud-rate scaler (no observable effect) |
All registers are 32-bit. Byte and half-word accesses return
AlignmentError.
Control register¶
| Bit | Name | Description |
|---|---|---|
| 0 | RE | Receiver enable |
| 1 | TE | Transmitter enable (Decision 22 — without this bit, TX is silently dropped) |
| 2 | RI | Receive interrupt enable |
| 3 | TI | Transmit interrupt enable |
| 4 | PS | Parity select |
| 5 | PE | Parity enable |
| 6 | FL | Flow control enable |
| 7 | LB | Loopback enable |
| 8 | EC | External clock select (no effect) |
| 9 | TF | Transmit FIFO interrupt |
| 10 | RF | Receive FIFO interrupt |
| 11 | DB | Debug enable |
| 31 | FA | FIFOs available (read-only 1) |
Important: RTEMS sets TE=1 during BSP init. Raw assembly tests
must do this explicitly or no output will appear (Decision 22). The
canonical fixture is tests/asm/hello_uart.S.
Status register¶
| Bit | Name | Description |
|---|---|---|
| 0 | DR | Data ready (RX FIFO non-empty) |
| 1 | TS | Transmitter shift register empty |
| 2 | TE | Transmitter empty (always 1, since TX has no FIFO) |
| 3 | BR | Break received |
| 4 | OV | Overrun (a byte arrived while RX FIFO was full) |
| 5 | PE | Parity error |
| 6 | FE | Framing error |
| 7 | ER | Errored |
| 26 | TF | TX FIFO full (always 0) |
| 27 | RF | RX FIFO full |
| 31 | FA | FIFOs available (always 1) |
Bits 4–7 are W0C (write 0 to clear).
RX path¶
- The runtime calls
tick()every quantum. tick()callsctx_.chardev->receive(byte)non-blockingly.- If a byte is available and the FIFO has room, push it. Otherwise
set
STATUS.OVand drop it. - If
CTRL.RE && CTRL.RI && fifo non-empty, raise IRQ.
CPU reads from DATA:
- If FIFO empty → return
0(per GRLIB convention). - Otherwise pop the head, lower the IRQ if the FIFO becomes empty.
TX path¶
CPU writes to DATA:
- If
CTRL.TE == 0→ silently drop the byte (Decision 22). - Otherwise call
ctx_.chardev->transmit(byte)immediately. - If
CTRL.TI == 1, raise IRQ.
There is no TX FIFO and no per-byte timing. The byte hits the host the same simulated cycle it was written.
Reset state¶
STATUS = 0x86(TS=1, TE=1, FA=1).CTRL = 0.SCALER = 0.- RX FIFO empty.
Tests¶
tests/unit/test_apbuart.cpp— register coverage, FIFO push/pop, overrun, IRQ raise on RI, TX dropped without TE, MMIO alignment rejection.tests/integration/test_hello_uart_elf.cpp— drives the assembly fixture end-to-end.- The RTEMS hello-world boot test depends on this peripheral.