UART Device Driver

---
config:
  layout: dagre
---
flowchart LR
 subgraph P["caller side"]
    direction TB
        USER_IO["user process<br><br>read(fd)<br>write(fd)"]
        KERNEL_OUT["kernel output<br><br>printf<br>console echo"]
  end
 subgraph C["console boundary"]
    direction TB
        DEVSW["devsw[CONSOLE]<br><br>read = consoleread<br>write = consolewrite"]
        CONSOLE["console.c<br><br>line buffering<br>consoleintr(c)<br>consoleread / consolewrite"]
  end
 subgraph U["UART driver interface"]
    direction TB
        UARTINIT["uartinit()<br><br>configure 16550a UART<br>enable RX/TX interrupts"]
        UARTOUT["UART output path<br><br>uartwrite<br>uartputc_sync"]
        UARTINTR["uartintr()<br><br>handle RX-ready<br>handle TX-ready"]
  end
 subgraph S["UART driver state"]
    direction TB
        TXSTATE["TX state<br><br>tx_lock<br>tx_busy<br>tx_chan"]
  end
 subgraph H["UART hardware source"]
    direction TB
        UART_REGS["16550a UART registers<br><br>RHR / THR<br>IER / ISR<br>LSR"]
        UART_IRQ["UART0_IRQ<br><br>external interrupt"]
  end
 subgraph I["interrupt delivery"]
    direction TB
        PLIC_PATH["PLIC + devintr()<br><br>claim UART IRQ<br>call uartintr<br>complete IRQ"]
  end
    USER_IO -- console fd read/write --> DEVSW
    DEVSW -- dispatches to --> CONSOLE
    CONSOLE -- consolewrite sends bytes --> UARTOUT
    KERNEL_OUT -- direct/synchronous output --> UARTOUT
    UARTINIT -- configures --> UART_REGS
    UARTOUT -- writes THR / checks LSR --> UART_REGS
    UARTOUT -- uses --> TXSTATE
    UART_REGS -- input ready or TX ready --> UART_IRQ
    UART_IRQ -- external interrupt --> PLIC_PATH
    PLIC_PATH -- calls --> UARTINTR
    UARTINTR -- reads/writes UART registers --> UART_REGS
    UARTINTR -- updates TX completion --> TXSTATE
    UARTINTR -- passes input chars upward --> CONSOLE

     USER_IO:::process
     KERNEL_OUT:::process
     DEVSW:::iface
     CONSOLE:::iface
     UARTINIT:::iface
     UARTOUT:::iface
     UARTINTR:::iface
     TXSTATE:::source
     UART_REGS:::source
     UART_IRQ:::source
     PLIC_PATH:::backend
    classDef process fill:#F3EFE2,stroke:#111,stroke-width:2px,color:#111
    classDef source fill:#E9F1FF,stroke:#111,stroke-width:2px,color:#111
    classDef iface fill:#EDE7D4,stroke:#111,stroke-width:2px,color:#111
    classDef backend fill:#F8F8F8,stroke:#111,stroke-width:2px,color:#111