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>
376 lines
11 KiB
C
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;
|