diff options
Diffstat (limited to 'kernel/sio.c')
-rw-r--r-- | kernel/sio.c | 258 |
1 files changed, 127 insertions, 131 deletions
diff --git a/kernel/sio.c b/kernel/sio.c index fc20435..8bcc8a1 100644 --- a/kernel/sio.c +++ b/kernel/sio.c @@ -76,28 +76,28 @@ ** PRIVATE DEFINITIONS */ -#define BUF_SIZE 2048 +#define BUF_SIZE 2048 /* ** PRIVATE GLOBALS */ - // input character buffer -static char inbuffer[ BUF_SIZE ]; +// input character buffer +static char inbuffer[BUF_SIZE]; static char *inlast; static char *innext; static uint32_t incount; - // output character buffer -static char outbuffer[ BUF_SIZE ]; +// output character buffer +static char outbuffer[BUF_SIZE]; static char *outlast; static char *outnext; static uint32_t outcount; - // output control flag +// output control flag static int sending; - // interrupt register status +// interrupt register status static uint8_t ier; /* @@ -122,41 +122,40 @@ extern QTYPE QNAME; ** @param vector The interrupt vector number for this interrupt ** @param ecode The error code associated with this interrupt */ -static void sio_isr( int vector, int ecode ) { +static void sio_isr(int vector, int ecode) +{ int ch; #if TRACING_SIO_ISR - cio_puts( "SIO: int:" ); + cio_puts("SIO: int:"); #endif // // Must process all pending events; loop until the IRR // says there's nothing else to do. // - for(;;) { - + for (;;) { // get the "pending event" indicator - int iir = inb( UA4_IIR ) & UA4_IIR_INT_PRI_MASK; + int iir = inb(UA4_IIR) & UA4_IIR_INT_PRI_MASK; // process this event - switch( iir ) { - + switch (iir) { case UA4_IIR_LINE_STATUS: // shouldn't happen, but just in case.... - cio_printf( "** SIO int, LSR = %02x\n", inb(UA4_LSR) ); + cio_printf("** SIO int, LSR = %02x\n", inb(UA4_LSR)); break; case UA4_IIR_RX: #if TRACING_SIO_ISR - cio_puts( " RX" ); + cio_puts(" RX"); #endif // get the character - ch = inb( UA4_RXD ); - if( ch == '\r' ) { // map CR to LF + ch = inb(UA4_RXD); + if (ch == '\r') { // map CR to LF ch = '\n'; } #if TRACING_SIO_ISR - cio_printf( " ch %02x", ch ); + cio_printf(" ch %02x", ch); #endif #ifdef QNAME @@ -166,18 +165,18 @@ static void sio_isr( int vector, int ecode ) { // process and awaken the process. // - if( !QEMPTY(QNAME) ) { + if (!QEMPTY(QNAME)) { PCBTYPE *pcb; - QDEQUE( QNAME, pcb ); + QDEQUE(QNAME, pcb); // make sure we got a non-NULL result - assert( pcb ); + assert(pcb); // return char via arg #2 and count in EAX - char *buf = (char *) ARG(pcb,2); + char *buf = (char *)ARG(pcb, 2); *buf = ch & 0xff; RET(pcb) = 1; - SCHED( pcb ); + SCHED(pcb); } else { #endif /* QNAME */ @@ -187,7 +186,7 @@ static void sio_isr( int vector, int ecode ) { // if there is room, otherwise just ignore it. // - if( incount < BUF_SIZE ) { + if (incount < BUF_SIZE) { *inlast++ = ch; ++incount; } @@ -199,65 +198,64 @@ static void sio_isr( int vector, int ecode ) { case UA5_IIR_RX_FIFO: // shouldn't happen, but just in case.... - ch = inb( UA4_RXD ); - cio_printf( "** SIO FIFO timeout, RXD = %02x\n", ch ); + ch = inb(UA4_RXD); + cio_printf("** SIO FIFO timeout, RXD = %02x\n", ch); break; case UA4_IIR_TX: #if TRACING_SIO_ISR - cio_puts( " TX" ); + cio_puts(" TX"); #endif // if there is another character, send it - if( sending && outcount > 0 ) { + if (sending && outcount > 0) { #if TRACING_SIO_ISR - cio_printf( " ch %02x", *outnext ); + cio_printf(" ch %02x", *outnext); #endif - outb( UA4_TXD, *outnext ); + outb(UA4_TXD, *outnext); ++outnext; // wrap around if necessary - if( outnext >= (outbuffer + BUF_SIZE) ) { + if (outnext >= (outbuffer + BUF_SIZE)) { outnext = outbuffer; } --outcount; #if TRACING_SIO_ISR - cio_printf( " (outcount %d)", outcount ); + cio_printf(" (outcount %d)", outcount); #endif } else { #if TRACING_SIO_ISR - cio_puts( " EOS" ); + cio_puts(" EOS"); #endif // no more data - reset the output vars outcount = 0; outlast = outnext = outbuffer; sending = 0; // disable TX interrupts - sio_disable( SIO_TX ); + sio_disable(SIO_TX); } break; case UA4_IIR_NO_INT: #if TRACING_SIO_ISR - cio_puts( " EOI\n" ); + cio_puts(" EOI\n"); #endif // nothing to do - tell the PIC we're done - outb( PIC1_CMD, PIC_EOI ); + outb(PIC1_CMD, PIC_EOI); return; case UA4_IIR_MODEM_STATUS: // shouldn't happen, but just in case.... - cio_printf( "** SIO int, MSR = %02x\n", inb(UA4_MSR) ); + cio_printf("** SIO int, MSR = %02x\n", inb(UA4_MSR)); break; default: // uh-oh.... - sprint( b256, "sio isr: IIR %02x\n", ((uint32_t) iir) & 0xff ); - PANIC( 0, b256 ); + sprint(b256, "sio isr: IIR %02x\n", ((uint32_t)iir) & 0xff); + PANIC(0, b256); } - } // should never reach this point! - assert( false ); + assert(false); } /* @@ -269,27 +267,27 @@ static void sio_isr( int vector, int ecode ) { ** ** Initialize the UART chip. */ -void sio_init( void ) { - +void sio_init(void) +{ #if TRACING_INIT - cio_puts( " Sio" ); + cio_puts(" Sio"); #endif /* ** Initialize SIO variables. */ - memclr( (void *) inbuffer, sizeof(inbuffer) ); + memclr((void *)inbuffer, sizeof(inbuffer)); inlast = innext = inbuffer; incount = 0; - memclr( (void *) outbuffer, sizeof(outbuffer) ); + memclr((void *)outbuffer, sizeof(outbuffer)); outlast = outnext = outbuffer; outcount = 0; sending = 0; // queue of read-blocked processes - QCREATE( QNAME ); + QCREATE(QNAME); /* ** Next, initialize the UART. @@ -299,11 +297,11 @@ void sio_init( void ) { ** this is a bizarre little sequence of operations */ - outb( UA5_FCR, 0x20 ); - outb( UA5_FCR, UA5_FCR_FIFO_RESET ); // 0x00 - outb( UA5_FCR, UA5_FCR_FIFO_EN ); // 0x01 - outb( UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR ); // 0x03 - outb( UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR | UA5_FCR_TXSR ); // 0x07 + outb(UA5_FCR, 0x20); + outb(UA5_FCR, UA5_FCR_FIFO_RESET); // 0x00 + outb(UA5_FCR, UA5_FCR_FIFO_EN); // 0x01 + outb(UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR); // 0x03 + outb(UA5_FCR, UA5_FCR_FIFO_EN | UA5_FCR_RXSR | UA5_FCR_TXSR); // 0x07 /* ** disable interrupts @@ -312,36 +310,36 @@ void sio_init( void ) { ** called to switch them back on */ - outb( UA4_IER, 0 ); + outb(UA4_IER, 0); ier = 0; /* ** select the divisor latch registers and set the data rate */ - outb( UA4_LCR, UA4_LCR_DLAB ); - outb( UA4_DLL, BAUD_LOW_BYTE( DL_BAUD_9600 ) ); - outb( UA4_DLM, BAUD_HIGH_BYTE( DL_BAUD_9600 ) ); + outb(UA4_LCR, UA4_LCR_DLAB); + outb(UA4_DLL, BAUD_LOW_BYTE(DL_BAUD_9600)); + outb(UA4_DLM, BAUD_HIGH_BYTE(DL_BAUD_9600)); /* ** deselect the latch registers, by setting the data ** characteristics in the LCR */ - outb( UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY ); + outb(UA4_LCR, UA4_LCR_WLS_8 | UA4_LCR_1_STOP_BIT | UA4_LCR_NO_PARITY); /* ** Set the ISEN bit to enable the interrupt request signal, ** and the DTR and RTS bits to enable two-way communication. */ - outb( UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS ); + outb(UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS); /* ** Install our ISR */ - install_isr( VEC_COM1, sio_isr ); + install_isr(VEC_COM1, sio_isr); } /** @@ -355,7 +353,8 @@ void sio_init( void ) { ** ** @return the prior IER setting */ -uint8_t sio_enable( uint8_t which ) { +uint8_t sio_enable(uint8_t which) +{ uint8_t old; // remember the current status @@ -364,23 +363,23 @@ uint8_t sio_enable( uint8_t which ) { // figure out what to enable - if( which & SIO_TX ) { + if (which & SIO_TX) { ier |= UA4_IER_TX_IE; } - if( which & SIO_RX ) { + if (which & SIO_RX) { ier |= UA4_IER_RX_IE; } // if there was a change, make it - if( old != ier ) { - outb( UA4_IER, ier ); + if (old != ier) { + outb(UA4_IER, ier); } // return the prior settings - return( old ); + return (old); } /** @@ -394,7 +393,8 @@ uint8_t sio_enable( uint8_t which ) { ** ** @return the prior IER setting */ -uint8_t sio_disable( uint8_t which ) { +uint8_t sio_disable(uint8_t which) +{ uint8_t old; // remember the current status @@ -403,23 +403,23 @@ uint8_t sio_disable( uint8_t which ) { // figure out what to disable - if( which & SIO_TX ) { + if (which & SIO_TX) { ier &= ~UA4_IER_TX_IE; } - if( which & SIO_RX ) { + if (which & SIO_RX) { ier &= ~UA4_IER_RX_IE; } // if there was a change, make it - if( old != ier ) { - outb( UA4_IER, ier ); + if (old != ier) { + outb(UA4_IER, ier); } // return the prior settings - return( old ); + return (old); } /** @@ -431,8 +431,9 @@ uint8_t sio_disable( uint8_t which ) { ** ** @return the count of characters still in the input queue */ -int sio_inq_length( void ) { - return( incount ); +int sio_inq_length(void) +{ + return (incount); } /** @@ -444,7 +445,8 @@ int sio_inq_length( void ) { ** ** @return the next character, or -1 if no character is available */ -int sio_readc( void ) { +int sio_readc(void) +{ int ch; // assume there is no character available @@ -454,21 +456,18 @@ int sio_readc( void ) { // If there is a character, return it // - if( incount > 0 ) { - + if (incount > 0) { // take it out of the input buffer ch = ((int)(*innext++)) & 0xff; --incount; // reset the buffer variables if this was the last one - if( incount < 1 ) { + if (incount < 1) { inlast = innext = inbuffer; } - } - return( ch ); - + return (ch); } /** @@ -484,14 +483,15 @@ int sio_readc( void ) { ** @return the number of bytes copied, or 0 if no characters were available */ -int sio_read( char *buf, int length ) { +int sio_read(char *buf, int length) +{ char *ptr = buf; int copied = 0; // if there are no characters, just return 0 - if( incount < 1 ) { - return( 0 ); + if (incount < 1) { + return (0); } // @@ -499,9 +499,9 @@ int sio_read( char *buf, int length ) { // buffer as will fit. // - while( incount > 0 && copied < length ) { + while (incount > 0 && copied < length) { *ptr++ = *innext++ & 0xff; - if( innext > (inbuffer + BUF_SIZE) ) { + if (innext > (inbuffer + BUF_SIZE)) { innext = inbuffer; } --incount; @@ -510,16 +510,15 @@ int sio_read( char *buf, int length ) { // reset the input buffer if necessary - if( incount < 1 ) { + if (incount < 1) { inlast = innext = inbuffer; } // return the copy count - return( copied ); + return (copied); } - /** ** sio_writec( ch ) ** @@ -529,22 +528,21 @@ int sio_read( char *buf, int length ) { ** ** @param ch Character to be written (in the low-order 8 bits) */ -void sio_writec( int ch ){ - - +void sio_writec(int ch) +{ // // Must do LF -> CRLF mapping // - if( ch == '\n' ) { - sio_writec( '\r' ); + if (ch == '\n') { + sio_writec('\r'); } // // If we're currently transmitting, just add this to the buffer // - if( sending ) { + if (sending) { *outlast++ = ch; ++outcount; return; @@ -555,12 +553,11 @@ void sio_writec( int ch ){ // sending = 1; - outb( UA4_TXD, ch ); + outb(UA4_TXD, ch); // Also must enable transmitter interrupts - sio_enable( SIO_TX ); - + sio_enable(SIO_TX); } /** @@ -575,7 +572,8 @@ void sio_writec( int ch ){ ** ** @return the number of characters copied into the SIO output buffer */ -int sio_write( const char *buffer, int length ) { +int sio_write(const char *buffer, int length) +{ int first = *buffer; const char *ptr = buffer; int copied = 0; @@ -587,15 +585,15 @@ int sio_write( const char *buffer, int length ) { // sio_writec() to send the first one out. // - if( !sending ) { + if (!sending) { ptr += 1; copied++; } - while( copied < length && outcount < BUF_SIZE ) { + while (copied < length && outcount < BUF_SIZE) { *outlast++ = *ptr++; // wrap around if necessary - if( outlast >= (outbuffer + BUF_SIZE) ) { + if (outlast >= (outbuffer + BUF_SIZE)) { outlast = outbuffer; } ++outcount; @@ -608,15 +606,13 @@ int sio_write( const char *buffer, int length ) { // variables for us. // - if( !sending ) { - sio_writec( first ); + if (!sending) { + sio_writec(first); } // Return the transfer count - - return( copied ); - + return (copied); } /** @@ -630,13 +626,14 @@ int sio_write( const char *buffer, int length ) { ** ** @return the count of bytes transferred */ -int sio_puts( const char *buffer ) { - int n; // must be outside the loop so we can return it +int sio_puts(const char *buffer) +{ + int n; // must be outside the loop so we can return it - n = SLENGTH( buffer ); - sio_write( buffer, n ); + n = SLENGTH(buffer); + sio_write(buffer, n); - return( n ); + return (n); } /** @@ -651,44 +648,43 @@ int sio_puts( const char *buffer ) { ** of the queues) */ -void sio_dump( bool_t full ) { +void sio_dump(bool_t full) +{ int n; char *ptr; // dump basic info into the status region - cio_printf_at( 48, 0, - "SIO: IER %02x (%c%c%c) in %d ot %d", - ((uint32_t)ier) & 0xff, sending ? '*' : '.', - (ier & UA4_IER_TX_IE) ? 'T' : 't', - (ier & UA4_IER_RX_IE) ? 'R' : 'r', - incount, outcount ); + cio_printf_at(48, 0, "SIO: IER %02x (%c%c%c) in %d ot %d", + ((uint32_t)ier) & 0xff, sending ? '*' : '.', + (ier & UA4_IER_TX_IE) ? 'T' : 't', + (ier & UA4_IER_RX_IE) ? 'R' : 'r', incount, outcount); // if we're not doing a full dump, stop now - if( !full ) { + if (!full) { return; } // also want the queue contents, but we'll // dump them into the scrolling region - if( incount ) { - cio_puts( "SIO input queue: \"" ); + if (incount) { + cio_puts("SIO input queue: \""); ptr = innext; - for( n = 0; n < incount; ++n ) { - put_char_or_code( *ptr++ ); + for (n = 0; n < incount; ++n) { + put_char_or_code(*ptr++); } - cio_puts( "\"\n" ); + cio_puts("\"\n"); } - if( outcount ) { - cio_puts( "SIO output queue: \"" ); - cio_puts( " ot: \"" ); + if (outcount) { + cio_puts("SIO output queue: \""); + cio_puts(" ot: \""); ptr = outnext; - for( n = 0; n < outcount; ++n ) { - put_char_or_code( *ptr++ ); + for (n = 0; n < outcount; ++n) { + put_char_or_code(*ptr++); } - cio_puts( "\"\n" ); + cio_puts("\"\n"); } } |