universalisos/kernel/drivers/uart.h
Fábio Coutada 9540b0528c feat(universalisos): PikeOS-style Phase B/C device drivers + Phase D microkernel
Phase B (Core Device Support) — all drivers verified in QEMU:
- Network: virtio-net cleanup, RTL8139, E1000, clause-22 MDIO PHY management,
  CAN bus, industrial protocols (Modbus/Profibus/EtherCAT), controller probe+dispatch
- Block storage: RAM disk backend (write->read->verify PASSED), virtio-blk transport,
  backend dispatch, real MBR+GPT partition parsers, SD/eMMC command framework
- GPIO: PL061 (verified), I2C: DesignWare (verified), SPI: PL022 (verified)

Phase C (Advanced Features):
- PCI: FULL PikeOS ARMv7 replica — transport-agnostic uos_pci_ops, config-address
  encoding, BAR sizing, capability walk, enumeration+bridge recursion, MSI/MSI-X
- USB: PikeOS-style layered stack — usb.h contract, usb_core.cpp (enumeration
  state machine), usb_ehci.cpp (EHCI transport)
- Display: FULL 1:1 PikeOS fbcon replica + copied font_8x16

Build foundation fixes:
- Freestanding aeabi_runtime.cpp (__aeabi_uidiv/__aeabi_uldivmod)
- PikeOS-style flat 4GB MMU section map + proper enable (unblocked device MMIO)
- guest.h MAX_GUEST_IMAGE_SIZE 256MB->16MB (BSS was 259MB)
- C/C++ linkage fixes, duplicate-virtio_net_init, MMIO access-size handling

Phase D (PikeOS ARMv7 Microkernel Port):
- D-1: Per-VM address spaces — cloned pgdirs, ASID-tagged TLB, 4K page walker,
  isolation PASSED (two guests, same VA->different PAs), guest fault recovery
- D-2: IRQ dispatch backbone — 1024-slot dispatch table, real GICv2 hardware
  (GICD_CTLR/GICC_CTLR/GICC_PMR/GICC_IAR/GICC_EOIR), arm_irq_handler wired
- D-3: Time subsystem — CNTVCT ns-since-boot, CNTP periodic ticker via D-2
- D-4: KDEV framework — linker-section driver registration, uos_kdev_init_all,
  name lookup
- D-5: VFP/NEON — lazy enable (undef trap->CPACR+FPEXC.EN), FPEXC=0x40000000
- D-6: SMP — per-CPU state, MPIDR, IPI/SGI framework (reschedule+TLB flush)

All uos_ naming (PikeOS p4_ convention adapted). Compiles -Werror freestanding C++17.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-09 09:10:53 +01:00

376 lines
11 KiB
C

/*
* Universalisos Complete Device Driver Implementation
* Phase 1: Communication Drivers - Complete UART Driver Implementation
*
* This implements complete UART driver functionality including:
* - Complete PL011 UART functionality
* - Interrupt-driven operation
* - DMA support
* - Flow control
* - Multiple UART instances
* - Universalisos configuration management
* - MISRA C++ compliance
*/
#ifndef UNIVERSALISOS_DRIVERS_UART_COMPLETE_H
#define UNIVERSALISOS_DRIVERS_UART_COMPLETE_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Universalisos UART configuration structure
* Based on type-1 hypervisor driver configuration schemas
*/
typedef struct {
// Basic configuration
uint32_t base_address; // Physical base address
uint32_t interrupt_number; // UART interrupt line
uint32_t clock_frequency; // UART clock in Hz
uint32_t baud_rate; // Baud rate (115200, 230400, etc.)
// UART parameters
uint8_t data_bits; // 5, 6, 7, or 8 data bits
uint8_t stop_bits; // 1 or 2 stop bits
uint8_t parity; // 0=none, 1=odd, 2=even
uint8_t flow_control; // 0=none, 1=RTS/CTS, 2=XON/XOFF
// Advanced features
bool dma_enabled; // DMA support enabled
uint8_t dma_channel; // DMA channel number
bool fifo_enabled; // FIFO support enabled
uint16_t fifo_trigger_level; // FIFO trigger level
// Buffer configuration
uint16_t tx_buffer_size; // Transmit buffer size
uint16_t rx_buffer_size; // Receive buffer size
// Safety parameters
uint8_t asil_level; // ASIL safety level (QM through D)
bool timeout_enabled; // Timeout detection
uint32_t timeout_ms; // Timeout in milliseconds
// State management
bool initialized; // Driver initialization state
bool enabled; // Driver enabled state
} universalis_uart_config_t;
/**
* UART statistics structure
* For monitoring and debugging
*/
typedef struct {
uint64_t bytes_transmitted; // Total bytes transmitted
uint64_t bytes_received; // Total bytes received
uint32_t tx_interrupts; // Transmit interrupts
uint32_t rx_interrupts; // Receive interrupts
uint32_t tx_errors; // Transmit errors
uint32_t rx_errors; // Receive errors
uint32_t dma_transfers; // DMA transfers completed
uint32_t fifo_overruns; // FIFO overrun errors
uint32_t framing_errors; // Framing errors
uint32_t parity_errors; // Parity errors
} universalis_uart_stats_t;
/**
* Virtual UART statistics structure
* Simplified version for external access
*/
typedef struct {
uint32_t vm_id;
uint8_t virtual_uart_id;
uint32_t mmio_base;
uint32_t physical_irq;
uint32_t virtual_irq;
bool enabled;
bool active;
uint64_t bytes_to_guest;
uint64_t bytes_from_guest;
uint32_t interrupts_injected;
} universalis_virtual_uart_stats_t;
/**
* UART device state
* Complete PikeOS-compatible state management
*/
typedef struct {
universalis_uart_config_t config; // Current configuration
universalis_uart_stats_t stats; // Statistics
uint8_t* tx_buffer; // Transmit buffer
uint8_t* rx_buffer; // Receive buffer
uint16_t tx_head; // Transmit buffer head
uint16_t tx_tail; // Transmit buffer tail
uint16_t rx_head; // Receive buffer head
uint16_t rx_tail; // Receive buffer tail
volatile bool tx_busy; // Transmit in progress
volatile bool rx_ready; // Data available
bool interrupt_enabled; // Interrupts enabled
} universalis_uart_state_t;
/**
* PL011 UART register offsets
* Complete register definitions for PikeOS parity
*/
#define PL011_DR 0x00 // Data Register
#define PL011_RSR 0x04 // Receive Status Register
#define PL011_FR 0x18 // Flag Register
#define PL011_ILPR 0x20 // IrDA Low-Power Counter
#define PL011_IBRD 0x24 // Integer Baud Rate
#define PL011_FBRD 0x28 // Fractional Baud Rate
#define PL011_LCR_H 0x2C // Line Control
#define PL011_CR 0x30 // Control Register
#define PL011_IFLS 0x34 // Interrupt FIFO Level
#define PL011_IMSC 0x38 // Interrupt Mask
#define PL011_RIS 0x3C // Raw Interrupt Status
#define PL011_MIS 0x40 // Masked Interrupt Status
#define PL011_ICR 0x44 // Interrupt Clear
#define PL011_DMARX 0x48 // DMA Receive
#define PL011_DMATX 0x4C // DMA Transmit
#define PL011_DMACTL 0x50 // DMA Control
// PL011 Flag Register bits
#define PL011_FR_TXFE (1 << 5) // Transmit FIFO empty
#define PL011_FR_RXFF (1 << 4) // Receive FIFO full
#define PL011_FR_TXFF (1 << 3) // Transmit FIFO full
#define PL011_FR_RXFE (1 << 2) // Receive FIFO empty
#define PL011_FR_BUSY (1 << 1) // UART busy
// PL011 Control Register bits
#define PL011_CR_UARTEN (1 << 0) // UART enable
#define PL011_CR_TXE (1 << 8) // Transmit enable
#define PL011_CR_RXE (1 << 9) // Receive enable
// PL011 Line Control Register bits
#define PL011_LCR_H_WLEN_8BIT (3 << 5) // 8-bit word length
#define PL011_LCR_H_WLEN_7BIT (2 << 5) // 7-bit word length
#define PL011_LCR_H_FEN (1 << 4) // Enable FIFOs
#define PL011_LCR_H_SPS (1 << 3) // Stick Parity
// PL011 Interrupt bits
#define PL011_INT_OE (1 << 10) // Overrun error
#define PL011_INT_BE (1 << 9) // Break error
#define PL011_INT_PE (1 << 8) // Parity error
#define PL011_INT_FE (1 << 7) // Framing error
#define PL011_INT_RT (1 << 6) // Receive timeout
#define PL011_INT_TX (1 << 5) // Transmit interrupt
#define PL011_INT_RX (1 << 4) // Receive interrupt
/**
* Complete PikeOS UART driver API
* Full PikeOS 5.0 compatibility interface
*/
/**
* Initialize UART driver with PikeOS-style configuration
* Returns: 0 on success, negative error code on failure
*/
int universalis_uart_init(const universalis_uart_config_t* config);
/**
* Deinitialize UART driver
*/
void universalis_uart_deinit(void);
/**
* Enable/disable UART
*/
int universalis_uart_enable(bool enable);
/**
* Configure UART parameters
* Returns: 0 on success, negative error code on failure
*/
int universalis_uart_configure(const universalis_uart_config_t* config);
/**
* Transmit data through UART
* Returns: number of bytes transmitted, or negative error code
*/
int universalis_uart_transmit(const uint8_t* data, size_t length);
/**
* Receive data from UART
* Returns: number of bytes received, or negative error code
*/
int universalis_uart_receive(uint8_t* data, size_t max_length);
/**
* Transmit data with timeout (PikeOS-style)
* Returns: number of bytes transmitted, or negative error code
*/
int universalis_uart_transmit_timeout(const uint8_t* data, size_t length, uint32_t timeout_ms);
/**
* Receive data with timeout (PikeOS-style)
* Returns: number of bytes received, or negative error code
*/
int universalis_uart_receive_timeout(uint8_t* data, size_t max_length, uint32_t timeout_ms);
/**
* Check if transmit buffer is empty
*/
bool universalis_uart_tx_empty(void);
/**
* Check if receive data is available
*/
bool universalis_uart_rx_ready(void);
/**
* Flush transmit buffer
*/
void universalis_uart_flush_tx(void);
/**
* Flush receive buffer
*/
void universalis_uart_flush_rx(void);
/**
* Get UART statistics
*/
void universalis_uart_get_stats(universalis_uart_stats_t* stats);
/**
* Reset UART statistics
*/
void universalis_uart_reset_stats(void);
/**
* UART interrupt handler (complete PikeOS implementation)
*/
void universalis_uart_interrupt_handler(void);
/**
* Set baud rate
*/
int universalis_uart_set_baudrate(uint32_t baud_rate);
/**
* Set flow control
*/
int universalis_uart_set_flow_control(uint8_t flow_control);
/**
* Enable/disable FIFO
*/
int universalis_uart_set_fifo(bool enable, uint16_t trigger_level);
/**
* Get current configuration
*/
void universalis_uart_get_config(universalis_uart_config_t* config);
/**
* Validate configuration (PikeOS safety pattern)
* Returns: true if configuration is valid
*/
bool universalis_uart_validate_config(const universalis_uart_config_t* config);
/**
* DMA operations for advanced throughput
*/
int universalis_uart_dma_transmit(const uint8_t* data, size_t length);
int universalis_uart_dma_receive(uint8_t* data, size_t max_length);
int universalis_uart_dma_enable(bool enable);
/**
* Virtual UART device operations
* Complete PikeOS virtual device support for guest VMs
*/
/**
* Create virtual UART device for a VM
* Returns: 0 on success, negative error code on failure
*/
int universalis_uart_create_virtual(uint32_t vm_id, uint8_t virtual_uart_id,
uint32_t mmio_base, uint32_t virtual_irq);
/**
* Virtual UART MMIO read handler
* Called when guest VM reads from virtual UART MMIO region
*/
uint32_t universalis_uart_virtual_mmio_read(uint32_t vm_id, uint8_t virtual_uart_id,
uint64_t offset, uint32_t size);
/**
* Virtual UART MMIO write handler
* Called when guest VM writes to virtual UART MMIO region
*/
void universalis_uart_virtual_mmio_write(uint32_t vm_id, uint8_t virtual_uart_id,
uint64_t offset, uint32_t value, uint32_t size);
/**
* Inject virtual interrupt to guest VM
*/
int universalis_uart_inject_interrupt(uint32_t vm_id, uint8_t virtual_uart_id);
/**
* Get virtual UART statistics
*/
int universalis_uart_get_virtual_stats(uint32_t vm_id, uint8_t virtual_uart_id,
universalis_virtual_uart_stats_t* stats);
/**
* Multiple UART instance support
* PikeOS supports multiple UART interfaces
*/
#define MAX_UART_INSTANCES 4
/**
* Initialize specific UART instance
*/
int universalis_uart_init_instance(uint8_t instance, const universalis_uart_config_t* config);
/**
* Get UART instance by base address
*/
int universalis_uart_get_instance(uint32_t base_address);
/**
* Switch to specific UART instance
*/
void universalis_uart_select_instance(uint8_t instance);
/**
* Safety-critical validation functions
* MISRA C++ compliant validation
*/
/**
* Validate transmit parameters
*/
bool universalis_uart_validate_tx_params(const uint8_t* data, size_t length);
/**
* Validate receive parameters
*/
bool universalis_uart_validate_rx_params(uint8_t* data, size_t max_length);
/**
* Check for UART errors
*/
uint32_t universalis_uart_check_errors(void);
/**
* Clear UART errors
*/
void universalis_uart_clear_errors(uint32_t error_mask);
#ifdef __cplusplus
}
#endif
#endif // UNIVERSALISOS_DRIVERS_UART_COMPLETE_H
// External declarations for driver integration
extern universalis_uart_state_t universalis_uart_states[MAX_UART_INSTANCES];
extern uint8_t universalis_current_uart_instance;
extern uint8_t universalis_initialized_uart_instances;