Serial Driver
The serial driver provides the console interface that's used to deliver
debug messages and interact with the system. The driver is contained in
the source file vx115_com.c, in the arch/arm/vx115 subdirectory. The
driver provides
several interfaces for use by various NetBSD subsystems: the standard
autoconfig functions, a set of character device functions, and
functions supporting console functionality.
Initialization
The serial driver provides the usual autoconfig match/attach functions:
-
vx115_com_match
-
vx115_com_attach
as well as the usual autoconfig attachment declaration:
CFATTACH_DECL(vx115_com, sizeof(struct vx115_com_softc), vx115_com_match, vx115_com_attach, NULL, NULL);
tty functions
These functions are assigned to fields in the serial driver's softc
structure's tty field. The tty structure is allocated during the attach
routine, and then partially initialized by assigning these function
pointers. The NetBSD tty subsystem handles further initialization (it
obtains a pointer to the tty struct using the vx115_com_tty( ) method
of the cdevsw struct). These functions handle the device-specific tty
operations.
- vx115_com_start
- used by the tty subsystem to start output
- assigned by the NetBSD tty subsystem during initialization to
be the t_linesw->l_start function of the tty struct, which is called
to transmit from the tty buffer
- get output parameters for the softc struct (the byte count and
output position in the tty output queue), for use by the interrupt
routines
- mark the driver as busy so the softc parameters won't be changed until transmission is done
- turn on transmit interrupts so output will begin
- actual output is performed from within interrupt routines
-
vx115_com_hwiflow
- used to provide HW flow control; not used on this platform
-
vx115_com_param
- used for termios parameter changes (baud rate, etc.)
cdevsw functions
These are the basic interface functions for character drivers in NetBSD.
-
vx115_com_open
- vx115_com_close
-
vx115_com_read
-
vx115_com_write
-
vx115_com_ioctl
-
vx115_com_stop
-
vx115_com_tty
-
vx115_com_poll
consdev functions
The consdev struct contains ponters to methods used for console input
and output. These functions are used for low-level operations like kernel
print statements. For example, the kernel printf function uses the following call sequence:
printf -> kprintf -> KPRINTF_PUTCHAR -> putchar -> v_putc -> cnputc -> cn_tab.cn_putc = vx115_com_cnputc
The functions are very low-level routines that just directly
write to or read from the serial interface.
- vx115_com_cngetc
- spin until there's a character in the receive FIFO, then read and and return the character
-
vx115_com_cnputc
- spin until there's room in the transmit FIFO, then write the supplied character to the FIFO
Interrupt routines
The interrupt routines handle the actual transfer of data between the
driver's buffers and the serial interface FIFO. The hardware routines
transfer between the hardware FIFO and the buffers, while the soft
interrupt routines interpret the data and finish transmission as needed.
Transmit
Transmission is done primarily through the hardware interrupt routine,
which is called whenever the transmit FIFO level falls below a
threshold. The soft interrupt routine is scheduled only when the
transmission is complete, and just synchronizes the tty buffer pointers
to account for the transmitted data and checks to see if new data has
become available for transmission, restarting transmission if so.
vx115_tx_hard
- while the transmit FIFO's not full
- copy data from the tty output
buffer to the FIFO and update the softc count and buffer pointer
- if the count is 0, transmission's complete
- turn off the transmit interrupts
- clear the sc_tx_busy flag, which will cause the soft interrupt routine to run
vx115_com_txsoft
- if the sc_tx_busy flag is clear, transmission is complete
- call ndflush to update the tty buffer pointers to account for the data transmitted
- call the tty t_linesw->l_start method to initiate a new transmission if new data is available
- this just directly calls the driver's vx115_com_start method
Receive
vx115_rx_hard
- while the receive FIFO's not empty and the driver receive buffer's not full
- copy data from the receive FIFO to the driver's receive
buffer and update the softc count and buffer pointer
- if the receive buffer's full, turn off receive interrupts
vx115_rx_soft
- while the receive buffer has characters
- read next character from receive buffer, check for framing, parity errors
- call the tty method t_linesw->l_rint to deliver the character to the tty layer
- update receive buffer pointers and count
- turn on receive interrupts if they're off and there's now room in buffer
Early initialization
Because it's desirable to have serial output
early in the boot process for debugging purposes during execution of
the initarm( ) routine, there's an early initialization of the serial driver in the init_arm( ) function.
Comments/questions: jsevy@cs.drexel.edu