From 69ed59f083a083fd96d08b5f6d54f2c80f267f03 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 14 May 2002 17:10:17 +0000 Subject: 2001-05-14 Till Straumann * bootloader/misc.c, console/Makefile.am, console/console.c, console/consoleIo.h, console/inch.c, console/polled_io.c, console/uart.c, console/uart.h, include/bsp.h, irq/Makefile.am, irq/irq.c, irq/irq.h, irq/irq_init.c, openpic/openpic.c, openpic/openpic.h, pci/Makefile.am, pci/pci.c, pci/pci.h, residual/Makefile.am, start/start.S, startup/bspstart.c, vectors/vectors.S, vectors/vectors.h, vectors/vectors_init.c: Per PR216, "libbsp/powerpc/shared" BSP has been modified considerably with the goal to make it more flexible and reusable by other BSPs. The main strategies were: - eliminate hardcoded base addresses; devices use offsets and a BSP defined base address. - separate functionality into different files (e.g. reboot from inch.c to reboot.c) which can be overridden by a 'derived' BSP. - separate initialization code into separate files (e.g. PCI bridge detection/initialization was separated from the more generic PCI access routines), also to make it easier for 'derived' BSPs to substitute their own initialization code. There are also a couple of enhancements and fixes: - IRQ handling code now has a hook for attaching a VME bridge. - OpenPIC is now explicitely initialized (polarities, senses). Eliminated the implicit assumption on the presence of an ISA PIC. - UART and console driver now supports more than 1 port. The current maximum of 2 can easily be extended by enlarging a table (it would even be easier if the ISR API was not broken by design). - fixed polled_io.c so it correctly supports console on COM2 - fixed TLB invalidation code (start.S). - exception handler prints a stack backtrace. - added BSP_pciFindDevice() to scan the pci bus for a particular vendor/device/instance. --- c/src/lib/libbsp/powerpc/shared/console/uart.c | 386 +++++++++---------------- 1 file changed, 138 insertions(+), 248 deletions(-) (limited to 'c/src/lib/libbsp/powerpc/shared/console/uart.c') diff --git a/c/src/lib/libbsp/powerpc/shared/console/uart.c b/c/src/lib/libbsp/powerpc/shared/console/uart.c index da44cc2e99..8ad744d06b 100644 --- a/c/src/lib/libbsp/powerpc/shared/console/uart.c +++ b/c/src/lib/libbsp/powerpc/shared/console/uart.c @@ -19,12 +19,42 @@ struct uart_data { + unsigned long ioBase; int hwFlow; int baud; }; -static struct uart_data uart_data[2]; +/* + * Initialization of BSP specific data. + * The constants are pulled in from a BSP + * specific file, whereas all of the code + * in this file is generic and makes no + * assumptions about addresses, irq vectors + * etc... + */ + +#define UART_UNSUPP ((unsigned long)(-1)) + +static struct uart_data uart_data[2] = { + { +#ifdef BSP_UART_IOBASE_COM1 + BSP_UART_IOBASE_COM1, +#else + UART_UNSUPP, +#endif + }, + { +#ifdef BSP_UART_IOBASE_COM2 + BSP_UART_IOBASE_COM2, +#else + UART_UNSUPP, +#endif + }, +}; +#define MAX_UARTS (sizeof(uart_data)/sizeof(uart_data[0])) +#define SANITY_CHECK(uart) \ + assert( MAX_UARTS > (unsigned)(uart) && uart_data[(uart)].ioBase != UART_UNSUPP ) /* * Macros to read/wirte register of uart, if configuration is * different just rewrite these macros @@ -33,31 +63,15 @@ static struct uart_data uart_data[2]; static inline unsigned char uread(int uart, unsigned int reg) { - register unsigned char val; - if(uart == 0) - { - inport_byte(COM1_BASE_IO+reg, val); - } - else - { - inport_byte(COM2_BASE_IO+reg, val); - } + return in_8((unsigned char*)(uart_data[uart].ioBase + reg)); - return val; } static inline void uwrite(int uart, int reg, unsigned int val) { - if(uart == 0) - { - outport_byte(COM1_BASE_IO+reg, val); - } - else - { - outport_byte(COM2_BASE_IO+reg, val); - } + out_8((unsigned char*)(uart_data[uart].ioBase + reg), val); } #ifdef UARTDEBUG @@ -103,7 +117,7 @@ BSP_uart_init(int uart, int baud, int hwFlow) unsigned char tmp; /* Sanity check */ - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); switch(baud) { @@ -166,7 +180,7 @@ BSP_uart_set_baud(int uart, int baud) unsigned char mcr, ier; /* Sanity check */ - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); /* * This function may be called whenever TERMIOS parameters @@ -197,7 +211,7 @@ void BSP_uart_intr_ctrl(int uart, int cmd) { - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); switch(cmd) { @@ -260,7 +274,7 @@ BSP_uart_throttle(int uart) { unsigned int mcr; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); if(!uart_data[uart].hwFlow) { @@ -281,7 +295,7 @@ BSP_uart_unthrottle(int uart) { unsigned int mcr; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); if(!uart_data[uart].hwFlow) { @@ -311,7 +325,7 @@ BSP_uart_polled_status(int uart) { unsigned char val; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); val = uread(uart, LSR); @@ -353,7 +367,7 @@ BSP_uart_polled_write(int uart, int val) unsigned char val1; /* Sanity check */ - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); for(;;) { @@ -394,7 +408,7 @@ BSP_uart_polled_read(int uart) { unsigned char val; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); for(;;) { @@ -415,20 +429,57 @@ BSP_poll_char_via_serial() return BSP_uart_polled_read(BSPConsolePort); } +static void +uart_noop(const rtems_irq_connect_data *unused) +{ + return; +} + +/* note that the IRQ names contain _ISA_ for legacy + * reasons. They can be any interrupt, depending + * on the particular BSP... + */ -/* ================ Termios support =================*/ +static int +uart_isr_is_on(const rtems_irq_connect_data *irq) +{ +int uart = (irq->name == BSP_ISA_UART_COM1_IRQ) ? + BSP_UART_COM1 : BSP_UART_COM2; + return uread(uart,IER); +} -static volatile int termios_stopped_com1 = 0; -static volatile int termios_tx_active_com1 = 0; -static void* termios_ttyp_com1 = NULL; -static char termios_tx_hold_com1 = 0; -static volatile char termios_tx_hold_valid_com1 = 0; +static int +doit(int uart, rtems_irq_hdl handler, int (*p)(const rtems_irq_connect_data*)) +{ + rtems_irq_connect_data d={0}; + d.name = (uart == BSP_UART_COM1) ? + BSP_ISA_UART_COM1_IRQ : BSP_ISA_UART_COM2_IRQ; + d.off = d.on = uart_noop; + d.isOn = uart_isr_is_on; + d.hdl = handler; + return p(&d); +} -static volatile int termios_stopped_com2 = 0; -static volatile int termios_tx_active_com2 = 0; -static void* termios_ttyp_com2 = NULL; -static char termios_tx_hold_com2 = 0; -static volatile char termios_tx_hold_valid_com2 = 0; +int +BSP_uart_install_isr(int uart, rtems_irq_hdl handler) +{ + return doit(uart, handler, BSP_install_rtems_irq_handler); +} + +int +BSP_uart_remove_isr(int uart, rtems_irq_hdl handler) +{ + return doit(uart, handler, BSP_remove_rtems_irq_handler); +} + + +/* ================ Termios support =================*/ + +static volatile int termios_stopped_com[2] = {0,0}; +static volatile int termios_tx_active_com[2] = {0,0}; +static void* termios_ttyp_com[2] = {NULL,NULL}; +static char termios_tx_hold_com[2] = {0,0}; +static volatile char termios_tx_hold_valid_com[2] = {0,0}; /* * Set channel parameters @@ -437,49 +488,30 @@ void BSP_uart_termios_set(int uart, void *ttyp) { unsigned char val; - assert(uart == BSP_UART_COM1 || uart == BSP_UART_COM2); + SANITY_CHECK(uart); - if(uart == BSP_UART_COM1) + if(uart_data[uart].hwFlow) { - if(uart_data[uart].hwFlow) - { - val = uread(uart, MSR); + val = uread(uart, MSR); - termios_stopped_com1 = (val & CTS) ? 0 : 1; - } - else - { - termios_stopped_com1 = 0; - } - termios_tx_active_com1 = 0; - termios_ttyp_com1 = ttyp; - termios_tx_hold_com1 = 0; - termios_tx_hold_valid_com1 = 0; + termios_stopped_com[uart] = (val & CTS) ? 0 : 1; } else - { - if(uart_data[uart].hwFlow) - { - val = uread(uart, MSR); - - termios_stopped_com2 = (val & CTS) ? 0 : 1; - } - else - { - termios_stopped_com2 = 0; - } - termios_tx_active_com2 = 0; - termios_ttyp_com2 = ttyp; - termios_tx_hold_com2 = 0; - termios_tx_hold_valid_com2 = 0; - } + { + termios_stopped_com[uart] = 0; + } + termios_tx_active_com[uart] = 0; + termios_ttyp_com[uart] = ttyp; + termios_tx_hold_com[uart] = 0; + termios_tx_hold_valid_com[uart] = 0; return; } int -BSP_uart_termios_write_com1(int minor, const char *buf, int len) +BSP_uart_termios_write_com(int minor, const char *buf, int len) { + int uart=minor; /* could differ, theoretically */ assert(buf != NULL); if(len <= 0) @@ -491,22 +523,22 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) /* assert((uread(BSP_UART_COM1, LSR) & THRE) != 0); */ - if(termios_stopped_com1) + if(termios_stopped_com[uart]) { /* CTS low */ - termios_tx_hold_com1 = *buf; - termios_tx_hold_valid_com1 = 1; + termios_tx_hold_com[uart] = *buf; + termios_tx_hold_valid_com[uart] = 1; return 0; } /* Write character */ - uwrite(BSP_UART_COM1, THR, *buf & 0xff); + uwrite(uart, THR, *buf & 0xff); /* Enable interrupts if necessary */ - if(!termios_tx_active_com1 && uart_data[BSP_UART_COM1].hwFlow) + if(!termios_tx_active_com[uart] && uart_data[uart].hwFlow) { - termios_tx_active_com1 = 1; - uwrite(BSP_UART_COM1, IER, + termios_tx_active_com[uart] = 1; + uwrite(uart, IER, (RECEIVE_ENABLE | TRANSMIT_ENABLE | RECEIVER_LINE_ST_ENABLE | @@ -514,10 +546,10 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) ) ); } - else if(!termios_tx_active_com1) + else if(!termios_tx_active_com[uart]) { - termios_tx_active_com1 = 1; - uwrite(BSP_UART_COM1, IER, + termios_tx_active_com[uart] = 1; + uwrite(uart, IER, (RECEIVE_ENABLE | TRANSMIT_ENABLE | RECEIVER_LINE_ST_ENABLE @@ -528,61 +560,8 @@ BSP_uart_termios_write_com1(int minor, const char *buf, int len) return 0; } -int -BSP_uart_termios_write_com2(int minor, const char *buf, int len) -{ - assert(buf != NULL); - - if(len <= 0) - { - return 0; - } - - - /* If there TX buffer is busy - something is royally screwed up */ - assert((uread(BSP_UART_COM2, LSR) & THRE) != 0); - - if(termios_stopped_com2) - { - /* CTS low */ - termios_tx_hold_com2 = *buf; - termios_tx_hold_valid_com2 = 1; - return 0; - } - - /* Write character */ - - uwrite(BSP_UART_COM2, THR, *buf & 0xff); - - /* Enable interrupts if necessary */ - if(!termios_tx_active_com2 && uart_data[BSP_UART_COM2].hwFlow) - { - termios_tx_active_com2 = 1; - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - } - else if(!termios_tx_active_com2) - { - termios_tx_active_com2 = 1; - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - TRANSMIT_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - } - - return 0; -} - - -void -BSP_uart_termios_isr_com1(void) +static void +BSP_uart_termios_isr_com(int uart) { unsigned char buf[40]; unsigned char val; @@ -592,29 +571,29 @@ BSP_uart_termios_isr_com1(void) for(;;) { - vect = uread(BSP_UART_COM1, IIR) & 0xf; + vect = uread(uart, IIR) & 0xf; switch(vect) { case MODEM_STATUS : - val = uread(BSP_UART_COM1, MSR); - if(uart_data[BSP_UART_COM1].hwFlow) + val = uread(uart, MSR); + if(uart_data[uart].hwFlow) { if(val & CTS) { /* CTS high */ - termios_stopped_com1 = 0; - if(termios_tx_hold_valid_com1) + termios_stopped_com[uart] = 0; + if(termios_tx_hold_valid_com[uart]) { - termios_tx_hold_valid_com1 = 0; - BSP_uart_termios_write_com1(0, &termios_tx_hold_com1, + termios_tx_hold_valid_com[uart] = 0; + BSP_uart_termios_write_com(uart, &termios_tx_hold_com[uart], 1); } } else { /* CTS low */ - termios_stopped_com1 = 1; + termios_stopped_com[uart] = 1; } } break; @@ -623,7 +602,7 @@ BSP_uart_termios_isr_com1(void) if(off != 0) { /* Update rx buffer */ - rtems_termios_enqueue_raw_characters(termios_ttyp_com1, + rtems_termios_enqueue_raw_characters(termios_ttyp_com[uart], (char *)buf, off); } @@ -634,38 +613,38 @@ BSP_uart_termios_isr_com1(void) * if there is nothing more to send. */ - ret = rtems_termios_dequeue_characters(termios_ttyp_com1, 1); + ret = rtems_termios_dequeue_characters(termios_ttyp_com[uart], 1); /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[BSP_UART_COM1].hwFlow) + if(ret == 0 && uart_data[uart].hwFlow) { - uwrite(BSP_UART_COM1, IER, + uwrite(uart, IER, (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE | MODEM_ENABLE ) ); - termios_tx_active_com1 = 0; + termios_tx_active_com[uart] = 0; } else if(ret == 0) { - uwrite(BSP_UART_COM1, IER, + uwrite(uart, IER, (RECEIVE_ENABLE | RECEIVER_LINE_ST_ENABLE ) ); - termios_tx_active_com1 = 0; + termios_tx_active_com[uart] = 0; } break; case RECEIVER_DATA_AVAIL : case CHARACTER_TIMEOUT_INDICATION: /* RX data ready */ assert(off < sizeof(buf)); - buf[off++] = uread(BSP_UART_COM1, RBR); + buf[off++] = uread(uart, RBR); break; case RECEIVER_ERROR: /* RX error: eat character */ - uartError(BSP_UART_COM1); + uartError(uart); break; default: /* Should not happen */ @@ -676,103 +655,14 @@ BSP_uart_termios_isr_com1(void) } void -BSP_uart_termios_isr_com2() +BSP_uart_termios_isr_com1(void) { - unsigned char buf[40]; - unsigned char val; - int off, ret, vect; - - off = 0; - - for(;;) - { - vect = uread(BSP_UART_COM2, IIR) & 0xf; - - switch(vect) - { - case MODEM_STATUS : - val = uread(BSP_UART_COM2, MSR); - if(uart_data[BSP_UART_COM2].hwFlow) - { - if(val & CTS) - { - /* CTS high */ - termios_stopped_com2 = 0; - if(termios_tx_hold_valid_com2) - { - termios_tx_hold_valid_com2 = 0; - BSP_uart_termios_write_com2(0, &termios_tx_hold_com2, - 1); - } - } - else - { - /* CTS low */ - termios_stopped_com2 = 1; - } - } - break; - case NO_MORE_INTR : - /* No more interrupts */ - if(off != 0) - { - /* Update rx buffer */ - rtems_termios_enqueue_raw_characters(termios_ttyp_com2, - (char *)buf, - off); - } - return; - case TRANSMITTER_HODING_REGISTER_EMPTY : - /* - * TX holding empty: we have to disable these interrupts - * if there is nothing more to send. - */ - - ret = rtems_termios_dequeue_characters(termios_ttyp_com2, 1); - - /* If nothing else to send disable interrupts */ - if(ret == 0 && uart_data[BSP_UART_COM2].hwFlow) - { - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE | - MODEM_ENABLE - ) - ); - termios_tx_active_com2 = 0; - } - else if(ret == 0) - { - uwrite(BSP_UART_COM2, IER, - (RECEIVE_ENABLE | - RECEIVER_LINE_ST_ENABLE - ) - ); - termios_tx_active_com2 = 0; - } - break; - case RECEIVER_DATA_AVAIL : - case CHARACTER_TIMEOUT_INDICATION: - /* RX data ready */ - assert(off < sizeof(buf)); - buf[off++] = uread(BSP_UART_COM2, RBR); - break; - case RECEIVER_ERROR: - /* RX error: eat character */ - uartError(BSP_UART_COM2); - break; - default: - /* Should not happen */ - assert(0); - return; - } - } + BSP_uart_termios_isr_com(BSP_UART_COM1); } - - - - - - +void +BSP_uart_termios_isr_com2(void) +{ + BSP_uart_termios_isr_com(BSP_UART_COM2); +} -- cgit v1.2.3