From e97e0e0886a2075ef1be095e0a07f0e7a15e8b12 Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Mon, 22 Sep 2008 11:46:15 +0000 Subject: [PATCH] Include required header files. Removed support for old PowerPC exception handling. Various fixes for interrupt related routines. Added support for BSPs with IRQ extension API. --- c/src/libchip/serial/ns16550.c | 270 +++++++++++++++---------------- c/src/libchip/serial/ns16550_p.h | 4 +- c/src/libchip/serial/serial.h | 2 + 3 files changed, 130 insertions(+), 146 deletions(-) diff --git a/c/src/libchip/serial/ns16550.c b/c/src/libchip/serial/ns16550.c index 32f7f5b467..58dd7909be 100644 --- a/c/src/libchip/serial/ns16550.c +++ b/c/src/libchip/serial/ns16550.c @@ -20,16 +20,33 @@ * This driver uses the termios pseudo driver. */ +#include + #include #include -#include #include +#include #include #include -#include + +#include + #include "ns16550_p.h" +#ifdef BSP_FEATURE_IRQ_EXTENSION + /* Nothing to do */ +#elif defined BSP_FEATURE_IRQ_LEGACY + /* Nothing to do */ +#elif defined __PPC__ + #define BSP_FEATURE_IRQ_LEGACY + #ifdef BSP_SHARED_HANDLER_SUPPORT + #define BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT + #endif +#else + #warning No interrupt support available +#endif + /* * Flow control is only supported when using interrupts */ @@ -68,14 +85,6 @@ console_fns ns16550_fns_polled = { false /* deviceOutputUsesInterrupts */ }; -#if defined(__PPC__) -#ifdef _OLD_EXCEPTIONS -extern void set_vector( rtems_isr_entry, rtems_vector_number, int ); -#else -#include -#endif -#endif - /* * ns16550_init */ @@ -92,6 +101,11 @@ NS16550_STATIC void ns16550_init(int minor) pns16550Context=(ns16550_context *)malloc(sizeof(ns16550_context)); + if (pns16550Context == NULL) { + printk( "%s: Error: Not enough memory\n", __func__); + rtems_fatal_error_occurred( 0xdeadbeef); + } + Console_Port_Data[minor].pDeviceContext=(void *)pns16550Context; pns16550Context->ucModemCtrl=SP_MODEM_IRQ; @@ -117,8 +131,8 @@ NS16550_STATIC void ns16550_init(int minor) (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte); /* XXX */ - (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff); - (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff); + (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, (uint8_t) (ulBaudDivisor & 0xffU)); + (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (uint8_t) ((ulBaudDivisor >> 8) & 0xffU)); /* Clear the divisor latch and set the character size to eight bits */ /* with one stop bit and no parity checking. */ @@ -441,10 +455,11 @@ NS16550_STATIC int ns16550_set_attributes( * This routine is the console interrupt handler for A port. */ -NS16550_STATIC void ns16550_process( - int minor -) +NS16550_STATIC void ns16550_process( int minor) { + console_tbl *c = &Console_Port_Tbl [minor]; + console_data *d = &Console_Port_Data [minor]; + uint32_t pNS16550; volatile uint8_t ucLineStatus; volatile uint8_t ucInterruptId; @@ -452,22 +467,22 @@ NS16550_STATIC void ns16550_process( getRegister_f getReg; setRegister_f setReg; - pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1; - getReg = Console_Port_Tbl[minor].getRegister; - setReg = Console_Port_Tbl[minor].setRegister; + pNS16550 = c->ulCtrlPort1; + getReg = c->getRegister; + setReg = c->setRegister; do { /* * Deal with any received characters */ - while(true) { + while (true) { ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); - if(~ucLineStatus & SP_LSR_RDY) { + if (~ucLineStatus & SP_LSR_RDY) { break; } cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER); rtems_termios_enqueue_raw_characters( - Console_Port_Data[minor].termios_data, + d->termios_data, &cChar, 1 ); @@ -477,82 +492,31 @@ NS16550_STATIC void ns16550_process( * TX all the characters we can */ - while(true) { - ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); - if(~ucLineStatus & SP_LSR_THOLD) { - /* - * We'll get another interrupt when - * the transmitter holding reg. becomes - * free again - */ - break; - } - -#if 0 - /* XXX flow control not completely supported in libchip */ - - if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_RTSCTS) { - ns16550_negate_RTS(minor); - } -#endif - - rtems_termios_dequeue_characters(Console_Port_Data[minor].termios_data, 1); - if (rtems_termios_dequeue_characters( - Console_Port_Data[minor].termios_data, 1)) { - if (Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_RTSCTS) { - ns16550_negate_RTS(minor); - } - Console_Port_Data[minor].bActive = FALSE; - ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX); + while (true) { + ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); + if (~ucLineStatus & SP_LSR_THOLD) { + /* + * We'll get another interrupt when + * the transmitter holding reg. becomes + * free again + */ break; } - ucInterruptId = (*getReg)(pNS16550, NS16550_INTERRUPT_ID); + if (rtems_termios_dequeue_characters( d->termios_data, 1) == 0) { + if (c->pDeviceFlow != &ns16550_flow_RTSCTS) { + ns16550_negate_RTS(minor); + } + d->bActive = false; + ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX); + break; + } } + + ucInterruptId = (*getReg)(pNS16550, NS16550_INTERRUPT_ID); } while((ucInterruptId&0xf)!=0x1); } -#if defined(__PPC__) -#ifdef _OLD_EXCEPTIONS - -/* - * ns16550_isr - */ - -NS16550_STATIC rtems_isr ns16550_isr( - rtems_vector_number vector -) -{ - int minor; - - for(minor=0;minorbActive = false; + + #ifdef BSP_FEATURE_IRQ_EXTENSION + { + rtems_status_code sc = RTEMS_SUCCESSFUL; + sc = rtems_interrupt_handler_install( + c->ulIntVector, + "NS16550", + RTEMS_INTERRUPT_SHARED, + ns16550_isr, + (void *) minor + ); + if (sc != RTEMS_SUCCESSFUL) { + /* FIXME */ + printk( "%s: Error: Install interrupt handler\n", __func__); + rtems_fatal_error_occurred( 0xdeadbeef); + } + } + #elif defined BSP_FEATURE_IRQ_LEGACY + { + int rv = 0; + #ifdef BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT + rtems_irq_connect_data cd = { + c->ulIntVector, + ns16550_isr, + (void *) minor + NULL, + NULL, + NULL, + NULL + }; + rv = BSP_install_rtems_shared_irq_handler( &cd); + #else + rtems_irq_connect_data cd = { + c->ulIntVector, + ns16550_isr, + (void *) minor + NULL, + NULL, + NULL + }; + rv = BSP_install_rtems_irq_handler( &cd); + #endif + if (rv == 0) { + /* FIXME */ + printk( "%s: Error: Install interrupt handler\n", __func__); + rtems_fatal_error_occurred( 0xdeadbeef); + } + } + #endif - ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR); + ns16550_enable_interrupts( minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX); } -#else - -NS16550_STATIC void ns16550_initialize_interrupts(int minor) -{ -#ifdef BSP_SHARED_HANDLER_SUPPORT - rtems_irq_connect_data IrqData = {0, - ns16550_isr, - &Console_Port_Data[minor], - NULL, - NULL, - NULL, - NULL - }; -#else - rtems_irq_connect_data IrqData = {0, - ns16550_isr, - &Console_Port_Data[minor], - NULL, - NULL, - NULL - }; -#endif - - ns16550_init(minor); - - Console_Port_Data[minor].bActive = FALSE; - - IrqData.name = (rtems_irq_number)(Console_Port_Tbl[minor].ulIntVector ); - -#ifdef BSP_SHARED_HANDLER_SUPPORT - if (!BSP_install_rtems_shared_irq_handler (&IrqData)) { -#else - if (!BSP_install_rtems_irq_handler(&IrqData)) { -#endif - printk("Error installing interrupt handler!\n"); - rtems_fatal_error_occurred(1); - } - - ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR); -} - -#endif -#endif /* * ns16550_write_support_int @@ -667,8 +651,8 @@ NS16550_STATIC int ns16550_write_support_int( } rtems_interrupt_disable(Irql); - if ( Console_Port_Data[minor].bActive == FALSE) { - Console_Port_Data[minor].bActive = TRUE; + if ( Console_Port_Data[minor].bActive == false) { + Console_Port_Data[minor].bActive = true; ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR); } (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, *buf); diff --git a/c/src/libchip/serial/ns16550_p.h b/c/src/libchip/serial/ns16550_p.h index 6f4b9ed257..57c386384d 100644 --- a/c/src/libchip/serial/ns16550_p.h +++ b/c/src/libchip/serial/ns16550_p.h @@ -27,9 +27,7 @@ extern "C" { * will show up in the symbol table. */ -#define NS16550_STATIC - -/* #define NS16550_STATIC static */ +#define NS16550_STATIC static /* * Define serial port read registers structure. diff --git a/c/src/libchip/serial/serial.h b/c/src/libchip/serial/serial.h index 089d583e3a..7d906965d0 100644 --- a/c/src/libchip/serial/serial.h +++ b/c/src/libchip/serial/serial.h @@ -16,6 +16,8 @@ #ifndef __LIBCHIP_SERIAL_h #define __LIBCHIP_SERIAL_h +#include +#include #include /*