The ChorusOS system provides a driver framework, allowing the third-party programmer to develop device drivers on top of a binary distribution of the ChorusOS operating system. The driver framework provides a well-defined, structured, and easy-to-use environment to develop both new drivers and client applications for existing drivers.
Host bus drivers written with the driver framework are specific to the reference target board, meaning that they are portable within that target family (UltraSPARC, PowerPC, Intel x86 processor families). Drivers that occupy a higher place in the hierarchical bus structure (sub-bus drivers and device drivers) are usually portable between target families.
Device Driver implementation is based on services, provided by a set of APIs, such as Peripheral Component Interconnect (PCI) or Industry Standard Architecture (ISA), which allow the developer to choose the optimizability and portability of the driver they create. This allows the driver to be written to the parent bus class, and not to the underlying platform. Drivers written within the driver framework may also take advantage of processor-specific services, allowing maximum optimization for a particular target family.
Using the driver framework to build bus and device drivers in the ChorusOS operating system provides the following benefits:
A structured framework, easing the task of building drivers
The hierarchical structure of drivers in the driver framework mirrors the hardware structure
Ensures compliance and functionality within the ChorusOS operating system
Enables the user to develop multi-bus device drivers, which may run on all buses supporting the common bus driver interface
Drivers built with the driver framework are homogeneous across various system profiles (flat memory, protected memory, virtual memory)
Allows dynamic configuration (and reconfiguration) needed for plug-and-play, hot-plug, and hot-swap support
Supports the binary driver model
The APIs are version resilient
The bus and drivers are adaptive (in terms of the memory footprint and complexity) to the various system profiles and customer requirements
Supports the dynamic loading and unloading of driver components
Meets real-time requirements, by providing non-blocking (asynchronous) run-time APIs
In the ChorusOS operating system, a driver entity is a software abstraction of the physical bus or device. Creating a device driver using the driver framework allows the device or bus to be represented and managed by the ChorusOS operating system. The hierarchical structure of the driver software within the ChorusOS operating system mirrors the structure of the physical device or bus.
Each device or bus is represented by its own driver. A driver's component code is linked separately from the microkernel as a supervisor actor, with the device-specific code strongly localized in the corresponding device driver.
Driver components are organized, through a service-provider/user relationship, into hierarchical layers which mirror the hardware bus or device connections.
The ChorusOS operating system diver framework can be considered in two ways:
A hierarchical set of APIs that defines the services provided for and used by each bus or device driver at each layer of the architecture. This approach ensures portability and functionality across various platforms and continued validity of drivers across subsequent system releases.
A set of mechanisms implemented by the ChorusOS microkernel, ensuring compliance and synchronicity with the ChorusOS operating system architecture and methods.
The driver framwork architecture is shown in the following figure.
For details regarding the driver framework, see the ChorusOS 5.0 Board Support Package Developer's Guide.
One of the key attributes allowing portability and modularity of devices constructed using the driver framework is the hierarchical structure of the APIs, which can also be seen as the layered interface. Within this model, all calls to the microkernel are performed through the Driver Kernel Interface (DKI) API, while all calls between drivers are handled through the Device Driver Interface (DDI) API.
The DKI interface defines all services provided by the microkernel to driver components. Following the layered interface model, all services implemented by the DKI are called by the drivers, and take place in the microkernel.
The DKI provides two types of services:
Common DKI services common to all platforms and processors, usable by all drivers, no matter what layer in the hierarchical model they inhabit. These services are globally designated by the DKI class name.
Processor family specific DKI (FDKI) services.
Common DKI services cover:
Synchronization through the DKI thread
Device tree
Driver registry
Device registry
General purpose memory allocation
Timeout
Precise busy wait
Special-purpose physical memory allocation
System event management
Global interrupts masking
Specific I/O services
Processor family specific DKI (FDKI) services cover:
Processor interrupts management
Processor caches management
Processor specific I/O services
Physical to virtual memory mapping
All DKI services are implemented as part of the embedded system library (libebd.s.a). Most of them are implemented as microkernel system calls. The intro(9DKI) man page gives an entry point to a detailed description of all DKI APIs.
The DKI API is summarized in the following table:
Function |
Description |
---|---|
dataCacheBlockFlush() |
Cache management |
dataCacheBlockFlush_powerpc() |
PowerPC cache management |
dataCacheBlockInvalidate() |
Cache management |
dataCacheBlockInvalidate_powerpc() |
PowerPC cache management |
dataCacheBlockInvalidate() |
Cache management |
dataCacheBlockInvalidate_powerpc() |
PowerPC cache management |
dataCacheInvalidate() |
Cache management |
dataCacheInvalidate_powerpc() |
PowerPC cache management |
dcacheBlockFlush() |
Cache management |
dcacheBlockFlush_usparc() |
UltraSPARC cache management |
dcacheFlush() |
Cache management |
dcacheFlush_usparc() |
UltraSPARC cache management |
dcacheLineFlush() |
Cache management |
dcacheLineFlush_usparc() |
UltraSPARC cache management |
DISABLE_PREEMPT() |
Thread preemption disabling |
dtreeNodeAlloc() |
Device tree operations |
dtreeNodeChild() |
Device tree operations |
dtreeNodeDetach() |
Device tree operations |
dtreeNodeFind() |
Device tree operations |
dtreeNodeFree() |
Device tree operations |
dtreeNodeFree() |
Device tree operations |
dtreeNodePeer() |
Device tree operations |
dtreeNodeRoot() |
Device tree operations |
dtreePropAdd() |
Device tree operations |
dtreePropAlloc() |
Device tree operations |
dtreePropAttach() |
Device tree operations |
dtreePropDetach() |
Device tree operations |
dtreePropFind() |
Device tree operations |
dtreePropFindNext() |
Device tree operations |
dtreePropFree() |
Device tree operations |
dtreePropLength() |
Device tree operations |
dtreePropName() |
Device tree operations |
dtreePropValue() |
Device tree operations |
eieio() |
I/O services |
eieio_powerpc() |
PowerPC specific I/O services |
ENABLE_PREEMPT() |
Thread preemption enabling |
hrt() |
High Resolution Timer |
icacheBlockInval() |
Cache management |
icacheBlockInval_usparc() |
UltraSPARC cache management |
icacheInval() |
Cache management |
icacheInval_usparc() |
UltraSPARC cache management |
icacheLineInval() |
Cache management |
icacheLineInval_usparc() |
UltraSPARC cache management |
imsIntrMask_f() |
Global interrupt masking |
imsIntrUnmask_f() |
Global interrupt masking |
instCacheBlockInvalidate() |
Cache management |
instCacheBlockInvalidate_powerpc() |
PowerPC cache management |
instCacheBlockInvalidate_powerpc() |
PowerPC cache management |
instCacheInvalidate() |
Cache management |
instCacheInvalidate_powerpc() |
PowerPC cache management |
ioLoad16() |
I/O services |
ioLoad16_x86() |
Intel x86 specific I/O services |
ioLoad32() |
I/O services |
ioLoad32_x86() |
Intel x86 specific I/O services |
ioLoad8() |
I/O services |
ioLoad8_x86() |
Intel x86 specific I/O services |
ioRead16() |
I/O services |
ioRead16_x86() |
Intel x86 specific I/O services |
ioRead32() |
I/O services |
ioRead32_x86() |
Intel x86 specific I/O services |
ioRead8() |
I/O services |
ioRead8_x86() |
Intel x86 specific I/O services |
ioStore16() |
I/O services |
ioStore16_x86() |
Intel x86 specific I/O services |
ioStore32() |
I/O services |
ioStore32_x86() |
Intel x86 specific I/O services |
ioStore8() |
I/O services |
ioStore8_x86() |
Intel x86 specific I/O services |
ioWrite16() |
I/O services |
ioWrite16_x86() |
Intel x86 specific I/O services |
ioWrite32() |
I/O services |
ioWrite32_x86() |
Intel x86 specific I/O services |
ioWrite8() |
I/O services |
ioWrite8_x86() |
Intel x86 specific I/O services |
loadSwap_16() |
Specific I/O services |
loadSwap_32() |
Specific I/O services |
loadSwap_64() |
Specific I/O services |
loadSwapEieio_16() |
I/O services |
loadSwapEieio_16_powerpc() |
PowerPC specific I/O services |
loadSwapEieio_32() |
I/O services |
loadSwapEieio_32_powerpc() |
PowerPC specific I/O services |
loadSwap_sync_16_usparc() |
UltraSparc specific I/O services |
loadSwap_sync_32_usparc() |
UltraSparc specific I/O services |
loadSwap_sync_64_usparc() |
UltraSparc specific I/O services |
load_sync_16_usparc() |
UltraSparc specific I/O services |
load_sync_32_usparc() |
UltraSparc specific I/O services |
load_sync_64_usparc() |
UltraSparc specific I/O services |
load_sync_8_usparc() |
UltraSparc specific I/O services |
storeSwap_16() |
Specific I/O services |
storeSwap_32() |
Specific I/O services |
storeSwap_64() |
Specific I/O services |
storeSwapEieio_16() |
I/O services |
storeSwapEieio_16_powerpc() |
PowerPC specific I/O services |
storeSwapEieio_32() |
I/O services |
storeSwapEieio_32_powerpc() |
PowerPC specific I/O services |
storeSwap_sync_16_usparc() |
UltraSparc specific I/O services |
storeSwap_sync_32_usparc() |
UltraSparc specific I/O services |
storeSwap_sync_64_usparc() |
UltraSparc specific I/O services |
store_sync_16_usparc() |
UltraSparc specific I/O services |
store_sync_32_usparc() |
UltraSparc specific I/O services |
store_sync_64_usparc() |
UltraSparc specific I/O services |
store_sync_8_usparc() |
UltraSparc specific I/O services |
svAsyncExcepAttach() |
Asynchronous exceptions management |
svAsyncExcepAttach_usparc() |
UltraSPARC asynchronous exceptions management |
svAsyncExcepDetach_usparc() |
UltraSPARC aynchronous exceptions management |
svDeviceAlloc() |
Device registry operations |
svDeviceEntry() |
Device registry operations |
svDeviceEvent() |
Device registry operations |
svDeviceFree() |
Device registry operations |
svDeviceLookup() |
Device registry operations |
svDeviceNewCancel() |
Device registry operations |
svDeviceNewNotify() |
Device registry operations |
svDeviceRegister() |
Device registry operations |
svDeviceRelease() |
Device registry operations |
svDeviceUnregister() |
Device registry operations |
svDkiClose() |
System event management |
svDkiEvent() |
System event management |
svDkiInitLevel() |
Two-stage microkernel initialization |
svDkiloRemap() |
Change debug link device address |
svDkiThreadCall() |
Microkernel initialization level |
svDkiOpen() |
System event management |
svDkiThreadCall() |
Call a routine in the DKI thread context; trigger a routine in the DKI thread context; cancel a routine in the DKI thread context |
svDkiThreadCancel() |
Call a routine in the DKI thread context; trigger a routine in the DKI thread context; cancel a routine in the DKI thread context |
svDkiThreadTrigger() |
Call a routine in the DKI thread context; trigger a routine in the DKI thread context; cancel a routine in the DKI thread context |
svDriverCap() |
Driver registry operations |
svDriverEntry() |
Driver registry operations |
svDriverLookupFirst() |
Driver registry operations |
svDriverLookupNext() |
Driver registry operations |
svDriverRegister() |
Driver registry operations |
svDriverRelease() |
Driver registry operations |
svDriverUnregister() |
Driver registry operations |
svIntrAttach() |
Interrupts management |
svIntrAttach_powerpc() |
PowerPC interrupts management |
svIntrAttach_usparc() |
UltraSPARC interrupts management |
svIntrAttach_x86() |
Intel x86 interrupts management |
svIntrCtxGet() |
Interrupts management |
svIntrCtxGet_powerpc() |
PowerPC interrupts management |
svIntrCtxGet_usparc() |
UltraSPARC interrupts management |
svIntrCtxGet_x86() |
Intel x86 interrupts management |
svIntrDetach() |
Interrupts management |
svIntrDetach_powerpc() |
PowerPC interrupts management |
svIntrDetach_usparc() |
UltraSPARC interrupts management |
svIntrDetach_x86() |
Intel x86 interrupts management |
svMemAlloc() |
A general purpose memory allocator |
svMemFree() |
A general purpose memory allocator |
svPhysAlloc() |
A special purpose physical memory allocator |
svPhysFree() |
A special purpose physical memory allocator |
svPhysMap() |
Physical to virtual memory mapping |
svPhysMap_powerpc() |
PowerPC physical to virtual memory mapping |
svPhysUnmap_usparc() |
UltraSPARC physical to virtual memory mapping |
svSoftIntrAttach_usparc() |
UltraSPARC interrupts management |
svSoftIntrDetach_usparc() |
UltraSPARC interrupts management |
svTimeoutCancel() |
Timeout operations |
svTimeoutGetRes() |
Timeout operations |
svTimeoutSet() |
Timeout operations |
swap_16() |
Specific I/O services |
swap_32() |
Specific I/O services |
swap_64() |
Specific I/O services |
swapEieio_16() |
I/O services |
swapEieio_16_powerpc() |
PowerPC I/O services |
swapEieio_32() |
I/O services |
swapEieio_32_powerpc() |
PowerPC I/O services |
usecBusyWait() |
Precise busy wait service |
vmMapToPhys() |
Physical to virtual memory mapping |
vmMapToPhys_powerpc() |
PowerPC physical to virtual memory mapping |
vmMapToPhys_usparc() |
UltraSPARC physical to virtual memory mapping |
vmMapToPhys_x86() |
Intel x86 physical to virtual memory mapping |
The DDI defines several layers of interface between different layers of device drivers in the driver hierarchy. Typically an API is defined for each class of bus or device, as a part of the DDI.
The DDI API is summarized in the following table:
Function |
Description |
---|---|
ata() |
ATA bus driver interface |
bench() |
Bench device driver interface |
bus() |
Common bus driver interface |
buscom() |
Bus communication driver interface |
busFi() |
Common bus Fault Injection driver interface |
busmux() |
Bus multiplexor driver interface |
cdrom() |
CD-ROM driver interface |
diag() |
Diagnostic driver interface |
disk() |
Hard disk device driver interface |
diskStat() |
Hard disk statistics |
ether() |
Ethernet device driver interface |
ettherStat() |
Ethernet statistics |
flash() |
Flash device driver interface |
flashCtl() |
Flash control device driver interface |
flashStat() |
Flash statistics |
generic_ata() |
Generic ATA bus master driver interface for PCI IDE devices |
gpio() |
gpio bus driver interface |
HSC() |
Hot swap controller driver interface |
isa() |
ISA bus driver interface |
isaFi() |
ISA fault injection driver interface |
keyboard() |
Keyboard device driver interface |
mngt() |
Management driver interface |
mouse() |
Mouse device driver interface |
netFrame() |
Generic representation of network frames |
pci() |
PCI bus driver interface |
pciFi() |
PCI fault injection driver interface |
pcimngr() |
PCI resource manager driver interface |
pcmcia() |
CMCIA bus driver interface |
quicc() |
QUICC bus driver interface |
ric() |
RIC device driver interface |
rtc() |
RTC device driver interface |
timer() |
TIMER device driver interface |
tx39() |
TX39 bus driver interface |
uart() |
UART device driver interface |
uartStat() |
UART statistics |
wdtimer() |
Watchdog timer device driver interface |
The ChorusOS operating system DDI and DKI support software interrupts, also known as soft interrupts. Soft interrupts are not initiated by a hardware device, but rather are initiated by software. Handlers for these interrupts must also be added to and removed from the system. Soft interrupt handlers run in the interrupt context and therefore can be used to do many of the tasks that belong to an interrupt handler.
The software interrupt API (SOFTINTR) is summarized in the following table:
Function |
Description |
---|---|
svSoftIntrDeclare() |
Declares a software interrupt descriptor |
svSoftIntrTrigger() |
Triggers execution of a software interrupt |
svSoftIntrForget() |
Detaches a previously declared software interrupt |
For details, see the SOFTINTR(5FEA) man page.
The ChorusOS device driver framework provides many drivers. Most of these drivers, unless stated otherwise, are generic, non-platform-specific drivers and can be used regardless of platform since they use either common bus driver interface or bus-specific (not platform-specific) services.
The following drivers are implemented in the ChorusOS operating system:
Driver |
Description |
---|---|
|
am29xxx compatible flash driver |
|
ATA disk device driver |
|
ns16x50 device driver |
|
|
|
Sun cheerio 10/100Mbps Ethernet device driver |
|
dec2115x PCI-to-PCI bridges family, PCI bus driver |
|
dec21x4x Ethernet device driver |
|
Sun PCI/ISA bridge driver |
|
3Com etherlinkIII Ethernet device driver |
|
Watchdog timer device driver for devices logically programmed in Altera epf6016/epf8020a PLD |
|
Epic100 PCI Ethernet device driver |
|
Motorola memory controller, common bus driver and flash control driver |
|
QUICC FCC controller Ethernet device driver |
|
Generic ATA device driver for PCI based IDE controller |
|
i8042 PS/2 keyboard/mouse controller |
|
Intel i8237 DMA driver |
|
Intel i8254 timer device driver |
|
Intel i8259 timer PIC driver |
|
Intel 28F016SA compatible flash driver |
|
Intel 28fxxx compatible flash driver |
|
Intel i386AT generic ISA bus driver |
|
Intel i386AT generic PCI/ISA bridge, ISA bus driver |
|
IT8368E PCMCIA controller |
|
SGS m48txx real time clock, NVRAM and watchdog device driver |
|
Motorola mc146818 real time clock device driver |
|
ne2000 Ethernet device driver |
|
Generic ns16x50 compatible UART device driver |
|
Intel i386AT generic PCI bridge, PCI bus driver |
|
PCI configuration space parser driver |
|
PCI enumerator driver |
|
PCI fault injection pseudo-driver |
|
PCI resource manager auxiliary driver |
|
QUICC bus driver for Motorola mpc8260 micro-controllers |
|
QUICC bus driver for Motorola mpc8xx micro-controllers |
|
Motorola PCI host bridge, PCI bus driver |
|
Sun reset, interrupt and clock controller |
|
Sun PCI host bridge, PCI bus driver |
|
QUICC SCC controller Ethernet device driver |
|
QUICC SCC controller UART device driver |
|
Sun advanced PCI-to-PCI bridge driver |
|
Implements the ISA Ethernet device driver interface |
|
SMC91 family Ethernet device driver |
|
QUICC SMC controller UART device driver |
|
PowerPC timebase and decrementer timer device driver |
|
TX3922 bus driver |
|
TX39 UART device driver |
|
vt82c586 VIA Technologies PCI-to-ISA bridge, ISA bus driver |
|
ATA bus driver for VIA Tech VT82C586 IDE controller |
|
Winbond PCI/ISA bridge, ISA bus driver |
|
ATA bus driver for Winbond W83C553 IDE controller |
|
z8536/mcp750 hardware related constants |
|
Generic z85x30 hardware related constants |