Kernelite 0.1.0
Kernelite is a minimalist, educational operating system kernel built from scratch. The project aims to recreate core components of the Linux architecture to explore the fundamentals of operating system design and hardware-software interaction.
Loading...
Searching...
No Matches
Macros | Functions
uart.c File Reference

PL011 UART driver implementation. More...

#include "uart.h"
#include "icu/icu.h"
#include <stdint.h>
Include dependency graph for uart.c:

Macros

#define UART_DR   0x00
 
#define UART_FR   0x18
 
#define UART_FR_TXFF   (1 << 5)
 
#define UART_FR_RXFE   (1 << 4)
 
#define UART_IMSC   0x038
 
#define UART_ICR   0x044
 
#define UART_IMSC_RXIM   (1U << 4)
 
#define UART_ICR_RXIC   (1U << 4)
 

Functions

static void pl011_putc (uart_device_t *dev, char chr)
 PL011 Specific putc implementation. Waits for space in the transmit FIFO, then writes the character to the data register.
 
static char pl011_getc (uart_device_t *dev)
 PL011 Specific getc implementation.
 
static void pl011_enable_rx_interrupt (uart_device_t *dev)
 Enable the PL011 UART receive interrupt.
 
static void pl011_clear_rx_interrupt (uart_device_t *dev)
 Clear the PL011 UART receive interrupt.
 
static void pl011_rx_handler (void *data)
 PL011 UART receive interrupt handler.
 
bool pl011_register_handler (uart_device_t *dev)
 Register the PL011 UART receive interrupt handler with the ICU.
 
void pl011_init (uart_device_t *dev, uintptr_t base)
 Initialize a UART device struct.
 

Detailed Description

PL011 UART driver implementation.

Implements polling-based putc/getc for the ARM PL011 UART and wires them into the uart_device_t hardware abstraction struct.

Author
Abhin Parekadan Jose
Date
2026-04-25

Macro Definition Documentation

◆ UART_DR

#define UART_DR   0x00

PL011 Data Register offset

◆ UART_FR

#define UART_FR   0x18

PL011 Flag Register offset

◆ UART_FR_RXFE

#define UART_FR_RXFE   (1 << 4)

Receive FIFO empty

◆ UART_FR_TXFF

#define UART_FR_TXFF   (1 << 5)

Transmit FIFO full

◆ UART_ICR

#define UART_ICR   0x044

PL011 Interrupt Clear Register offset

◆ UART_ICR_RXIC

#define UART_ICR_RXIC   (1U << 4)

Receive interrupt clear bit

◆ UART_IMSC

#define UART_IMSC   0x038

PL011 Interrupt Mask Set/Clear Register offset

◆ UART_IMSC_RXIM

#define UART_IMSC_RXIM   (1U << 4)

Receive interrupt mask bit

Function Documentation

◆ pl011_clear_rx_interrupt()

static void pl011_clear_rx_interrupt ( uart_device_t dev)
static

Clear the PL011 UART receive interrupt.

Writes to UARTICR to acknowledge and clear the receive interrupt. Must be called from the IRQ handler after reading the received character from UARTDR, otherwise the interrupt will immediately re-fire.

Parameters
devPointer to the UART device struct (mmio_base must be set).

◆ pl011_enable_rx_interrupt()

static void pl011_enable_rx_interrupt ( uart_device_t dev)
static

Enable the PL011 UART receive interrupt.

Sets the RXIM bit in UARTIMSC, causing the UART to assert its interrupt line when a character is received. The GIC must also be configured to forward INTID 33 (the UART SPI on QEMU virt) for the interrupt to reach the CPU.

Parameters
devPointer to the UART device struct (mmio_base must be set).

◆ pl011_getc()

static char pl011_getc ( uart_device_t dev)
static

PL011 Specific getc implementation.

Parameters
devPointer to the UART device struct (mmio_base must be set).
Returns
Character received.

◆ pl011_init()

void pl011_init ( uart_device_t dev,
uintptr_t  base 
)

Initialize a UART device struct.

Parameters
devPointer to the device struct to initialize.
baseMMIO base address.

◆ pl011_putc()

static void pl011_putc ( uart_device_t dev,
char  chr 
)
static

PL011 Specific putc implementation. Waits for space in the transmit FIFO, then writes the character to the data register.

Parameters
devPointer to the UART device struct (mmio_base must be set).
chrCharacter to transmit.

◆ pl011_register_handler()

bool pl011_register_handler ( uart_device_t dev)

Register the PL011 UART receive interrupt handler with the ICU.

Installs pl011_rx_handler into the ICU dispatch table for INTID 33 (the UART SPI on QEMU virt) and enables the interrupt in the GIC. After this call, any character received on the UART will trigger pl011_rx_handler which echoes it back.

Parameters
devPointer to the PL011 UART device struct to register. Passed as private_data to the handler on each invocation.
Returns
true if the handler was registered successfully, false if INTID 33 is already registered or GIC configuration failed.

◆ pl011_rx_handler()

static void pl011_rx_handler ( void *  data)
static

PL011 UART receive interrupt handler.

Invoked by the ICU dispatch table when INTID 33 (UART SPI on QEMU virt) fires. Reads one character from the UART receive FIFO and echoes it back by writing it to the transmit FIFO.

Parameters
dataOpaque pointer cast to uart_device_t, identifying which UART instance raised the interrupt.