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>
127 lines
3.3 KiB
C
127 lines
3.3 KiB
C
/*
|
|
* Universalisos GPIO Driver
|
|
* Phase B Priority 6: Platform I/O - General Purpose I/O
|
|
*
|
|
* ARM PrimeCell PL061 GPIO controller (8-bit ports), as emulated by QEMU virt.
|
|
* Provides pin configuration, read/write, edge/level interrupts, and
|
|
* virtualization hooks for guest VM passthrough.
|
|
*
|
|
* MISRA C++ compliant, freestanding, no dynamic allocation.
|
|
*
|
|
* Author: PortugalFuturista Hypervisor Development Team
|
|
*/
|
|
|
|
#ifndef UNIVERSALISOS_DRIVERS_GPIO_H
|
|
#define UNIVERSALISOS_DRIVERS_GPIO_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* GPIO pin direction
|
|
*/
|
|
typedef enum {
|
|
GPIO_DIR_INPUT = 0,
|
|
GPIO_DIR_OUTPUT
|
|
} gpio_direction_t;
|
|
|
|
/**
|
|
* GPIO interrupt trigger mode
|
|
*/
|
|
typedef enum {
|
|
GPIO_INT_NONE = 0, /* Disable interrupts */
|
|
GPIO_INT_LEVEL_LOW, /* Level-sensitive, active low */
|
|
GPIO_INT_LEVEL_HIGH, /* Level-sensitive, active high */
|
|
GPIO_INT_EDGE_FALLING, /* Falling edge */
|
|
GPIO_INT_EDGE_RISING, /* Rising edge */
|
|
GPIO_INT_EDGE_BOTH /* Both edges */
|
|
} gpio_int_mode_t;
|
|
|
|
/**
|
|
* Maximum number of PL061 ports (one PL061 = 8 pins; virt exposes several)
|
|
*/
|
|
#define MAX_GPIO_PORTS 8
|
|
#define GPIO_PINS_PER_PORT 8
|
|
|
|
/**
|
|
* PL061 masked-data access: bits are accessed via address bits [9:2].
|
|
* Offset 0x3FC addresses all 8 bits at once.
|
|
*/
|
|
#define GPIO_DATA_ALL 0x3FCU
|
|
|
|
/**
|
|
* Initialize a PL061 GPIO port.
|
|
* @param port_id Logical port index (0..MAX_GPIO_PORTS-1)
|
|
* @param base_address MMIO base of the PL061 controller
|
|
* @return 0 on success, negative on error
|
|
*/
|
|
int gpio_init(uint8_t port_id, uint32_t base_address);
|
|
|
|
/**
|
|
* Configure pin direction(s).
|
|
* @param port_id Port index
|
|
* @param pin_mask Bitmask of pins to configure (1 = affected)
|
|
* @param direction Input or output
|
|
* @return 0 on success, negative on error
|
|
*/
|
|
int gpio_set_direction(uint8_t port_id, uint8_t pin_mask, gpio_direction_t direction);
|
|
|
|
/**
|
|
* Write to output pin(s). Only pins set in pin_mask are driven.
|
|
*/
|
|
int gpio_write(uint8_t port_id, uint8_t pin_mask, uint8_t value);
|
|
|
|
/**
|
|
* Read the current level of all 8 pins.
|
|
*/
|
|
int gpio_read(uint8_t port_id, uint8_t* value);
|
|
|
|
/**
|
|
* Configure interrupt trigger mode for a single pin.
|
|
*/
|
|
int gpio_config_interrupt(uint8_t port_id, uint8_t pin, gpio_int_mode_t mode);
|
|
|
|
/**
|
|
* Enable/disable the interrupt for a pin mask.
|
|
*/
|
|
int gpio_enable_interrupt(uint8_t port_id, uint8_t pin_mask, bool enable);
|
|
|
|
/**
|
|
* Acknowledge (clear) pending interrupts for a pin mask.
|
|
*/
|
|
int gpio_acknowledge_interrupt(uint8_t port_id, uint8_t pin_mask);
|
|
|
|
/**
|
|
* Read masked interrupt status (only enabled, pending interrupts).
|
|
*/
|
|
uint8_t gpio_get_interrupt_status(uint8_t port_id);
|
|
|
|
/**
|
|
* GPIO interrupt handler (called by the GIC dispatch for the port's IRQ).
|
|
*/
|
|
void gpio_interrupt_handler(uint8_t port_id);
|
|
|
|
/**
|
|
* Create a virtual GPIO port for a guest VM (passthrough subset).
|
|
* @param vm_id Owning VM
|
|
* @param physical_port_id Backing physical port
|
|
* @param allowed_mask Bitmask of pins the VM may access
|
|
* @return Virtual port id (>=0) on success, negative on error
|
|
*/
|
|
int gpio_create_virtual(uint32_t vm_id, uint8_t physical_port_id, uint8_t allowed_mask);
|
|
|
|
/**
|
|
* Driver init / self-test demonstration.
|
|
*/
|
|
void gpio_driver_init(void);
|
|
void gpio_driver_demo(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* UNIVERSALISOS_DRIVERS_GPIO_H */
|