From e36390a662764faf3b38e8f6196e8f77d1b5d00f Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 3 Sep 2008 20:35:43 +0000 Subject: 2008-09-03 Joel Sherrill * Makefile.am, configure.ac, console/alloc360.c, console/console.c, console/console.h, console/m68360.h, console/mc68360_scc.c, console/ns16550cfg.c, console/rsPMCQ1.c, console/rsPMCQ1.h, include/bsp.h, irq/irq_init.c, vme/VMEConfig.h: Initiate update and testing. Add missing files. Does not run hello yet. * console/debugio.c, console/polled_io.c, irq/openpic_xxx_irq.c: New files. --- c/src/lib/libbsp/powerpc/ep1a/ChangeLog | 9 + c/src/lib/libbsp/powerpc/ep1a/Makefile.am | 2 +- c/src/lib/libbsp/powerpc/ep1a/configure.ac | 14 + c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c | 9 +- c/src/lib/libbsp/powerpc/ep1a/console/console.c | 81 +- c/src/lib/libbsp/powerpc/ep1a/console/console.h | 4 +- c/src/lib/libbsp/powerpc/ep1a/console/debugio.c | 113 ++ c/src/lib/libbsp/powerpc/ep1a/console/m68360.h | 15 +- .../lib/libbsp/powerpc/ep1a/console/mc68360_scc.c | 202 +++- c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c | 11 +- c/src/lib/libbsp/powerpc/ep1a/console/polled_io.c | 1130 ++++++++++++++++++++ c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c | 61 +- c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h | 37 +- c/src/lib/libbsp/powerpc/ep1a/include/bsp.h | 4 +- c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c | 2 + .../lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c | 293 +++++ c/src/lib/libbsp/powerpc/ep1a/vme/VMEConfig.h | 16 +- 17 files changed, 1939 insertions(+), 64 deletions(-) create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/debugio.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/console/polled_io.c create mode 100644 c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c diff --git a/c/src/lib/libbsp/powerpc/ep1a/ChangeLog b/c/src/lib/libbsp/powerpc/ep1a/ChangeLog index eaca7b19be..cdd76a627f 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/ChangeLog +++ b/c/src/lib/libbsp/powerpc/ep1a/ChangeLog @@ -1,3 +1,12 @@ +2008-09-03 Joel Sherrill + + * Makefile.am, configure.ac, console/alloc360.c, console/console.c, + console/console.h, console/m68360.h, console/mc68360_scc.c, + console/ns16550cfg.c, console/rsPMCQ1.c, console/rsPMCQ1.h, + include/bsp.h, irq/irq_init.c, vme/VMEConfig.h: Initiate update and + testing. Add missing files. Does not run hello yet. + * console/debugio.c, console/polled_io.c, irq/openpic_xxx_irq.c: New files. + 2008-08-20 Ralf Corsépius * console/mc68360_scc.c, console/rsPMCQ1.c, console/rsPMCQ1.h, diff --git a/c/src/lib/libbsp/powerpc/ep1a/Makefile.am b/c/src/lib/libbsp/powerpc/ep1a/Makefile.am index 4c1a6c57e0..4bc2e600cf 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/Makefile.am +++ b/c/src/lib/libbsp/powerpc/ep1a/Makefile.am @@ -54,7 +54,7 @@ include_bsp_HEADERS += ../../powerpc/shared/irq/irq.h \ ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/ppc_exc_bspsupp.h \ ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/vectors.h \ ../../../libcpu/@RTEMS_CPU@/@exceptions@/bspsupport/irq_supp.h -irq_SOURCES = irq/irq_init.c ../shared/irq/openpic_i8259_irq.c ../../powerpc/shared/irq/i8259.c +irq_SOURCES = irq/irq_init.c irq/openpic_xxx_irq.c ../../powerpc/shared/irq/i8259.c include_bsp_HEADERS += ../../shared/vmeUniverse/vmeUniverse.h \ vme/VMEConfig.h \ diff --git a/c/src/lib/libbsp/powerpc/ep1a/configure.ac b/c/src/lib/libbsp/powerpc/ep1a/configure.ac index f164195d8a..3bed523245 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/configure.ac +++ b/c/src/lib/libbsp/powerpc/ep1a/configure.ac @@ -15,6 +15,20 @@ RTEMS_PROG_CC_FOR_TARGET([-ansi -fasm]) RTEMS_CANONICALIZE_TOOLS RTEMS_PROG_CCAS +RTEMS_BSPOPTS_SET([PPC_USE_DATA_CACHE],[*],[0]) +RTEMS_BSPOPTS_HELP([PPC_USE_DATA_CACHE], +[If defined, then the PowerPC specific code in RTEMS will use + data cache instructions to optimize the context switch code. + This code can conflict with debuggers or emulators. It is known + to break the Corelis PowerPC emulator with at least some combinations + of PowerPC 603e revisions and emulator versions. + The BSP actually contains the call that enables this.]) + +RTEMS_BSPOPTS_SET([INSTRUCTION_CACHE_ENABLE],[*],[0]) +RTEMS_BSPOPTS_HELP([INSTRUCTION_CACHE_ENABLE], +[If defined, the instruction cache will be enabled after address translation + is turned on.]) + RTEMS_BSPOPTS_SET([CONSOLE_USE_INTERRUPTS],[*],[0]) RTEMS_BSPOPTS_HELP([CONSOLE_USE_INTERRUPTS], [whether using console interrupts]) diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c b/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c index 1ed1aca3f4..0d1b31b729 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c +++ b/c/src/lib/libbsp/powerpc/ep1a/console/alloc360.c @@ -7,7 +7,7 @@ * Saskatoon, Saskatchewan, CANADA * eric@skatter.usask.ca * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -24,11 +24,18 @@ #include "rsPMCQ1.h" #include + +#define DEBUG_PRINT 1 + void M360SetupMemory( M68360_t ptr ){ volatile m360_t *m360; m360 = ptr->m360; +#if DEBUG_PRINT +printk("m360->mcr:0x%08x Q1_360_SIM_MCR:0x%08x\n", + (unsigned int)&(m360->mcr), ((unsigned int)m360+Q1_360_SIM_MCR)); +#endif ptr->bdregions[0].base = (char *)&m360->dpram1[0]; ptr->bdregions[0].size = sizeof m360->dpram1; ptr->bdregions[0].used = 0; diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/console.c b/c/src/lib/libbsp/powerpc/ep1a/console/console.c index 5b3d2b3654..8c0367c7f6 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/console.c +++ b/c/src/lib/libbsp/powerpc/ep1a/console/console.c @@ -1,9 +1,9 @@ -/* +/*XXX * This file contains the TTY driver for the ep1a * * This driver uses the termios pseudo driver. * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -241,6 +241,83 @@ rtems_device_driver console_initialize( return RTEMS_SUCCESSFUL; } +#if 0 +/* PAGE + * + * DEBUG_puts + * + * This should be safe in the event of an error. It attempts to ensure + * that no TX empty interrupts occur while it is doing polled IO. Then + * it restores the state of that external interrupt. + * + * Input parameters: + * string - pointer to debug output string + * + * Output parameters: NONE + * + * Return values: NONE + */ + +void DEBUG_puts( + char *string +) +{ + char *s; + unsigned32 Irql; + + rtems_interrupt_disable(Irql); + + for ( s = string ; *s ; s++ ) + { + Console_Port_Tbl[Console_Port_Minor].pDeviceFns-> + deviceWritePolled(Console_Port_Minor, *s); + } + + rtems_interrupt_enable(Irql); +} + +/* PAGE + * + * DEBUG_puth + * + * This should be safe in the event of an error. It attempts to ensure + * that no TX empty interrupts occur while it is doing polled IO. Then + * it restores the state of that external interrupt. + * + * Input parameters: + * ulHexNum - value to display + * + * Output parameters: NONE + * + * Return values: NONE + */ +void +DEBUG_puth( + unsigned32 ulHexNum + ) +{ + unsigned long i,d; + unsigned32 Irql; + + rtems_interrupt_disable(Irql); + + Console_Port_Tbl[Console_Port_Minor].pDeviceFns-> + deviceWritePolled(Console_Port_Minor, '0'); + Console_Port_Tbl[Console_Port_Minor].pDeviceFns-> + deviceWritePolled(Console_Port_Minor, 'x'); + + for(i=32;i;) + { + i-=4; + d=(ulHexNum>>i)&0xf; + Console_Port_Tbl[Console_Port_Minor].pDeviceFns-> + deviceWritePolled(Console_Port_Minor, + (d<=9) ? d+'0' : d+'a'-0xa); + } + + rtems_interrupt_enable(Irql); +} +#endif /* const char arg to be compatible with BSP_output_char decl. */ void diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/console.h b/c/src/lib/libbsp/powerpc/ep1a/console/console.h index 1ea45595bd..f55d59d54c 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/console.h +++ b/c/src/lib/libbsp/powerpc/ep1a/console/console.h @@ -17,7 +17,7 @@ * no support for this code. * * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -25,7 +25,7 @@ * http://www.rtems.com/license/LICENSE. * * $Id$ -*/ + */ #include #include diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/debugio.c b/c/src/lib/libbsp/powerpc/ep1a/console/debugio.c new file mode 100644 index 0000000000..f38f51ee9c --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ep1a/console/debugio.c @@ -0,0 +1,113 @@ +/* + * This file contains the debug IO support. + * + * COPYRIGHT (c) 1998 by Radstone Technology + * + * + * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY + * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK + * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU. + * + * You are hereby granted permission to use, copy, modify, and distribute + * this file, provided that this notice, plus the above copyright notice + * and disclaimer, appears in all copies. Radstone Technology will provide + * no support for this code. + * + * COPYRIGHT (c) 1989-1997. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * debugio.c,v 1.2.4.1 2003/09/04 18:45:11 joel Exp + */ + +#include +#include +#include +#include +#include + +#include + +/* + * Load configuration table + */ + +extern console_data Console_Port_Data[]; +extern rtems_device_minor_number Console_Port_Minor; + +/* PAGE + * + * DEBUG_puts + * + * This should be safe in the event of an error. It attempts to ensure + * that no TX empty interrupts occur while it is doing polled IO. Then + * it restores the state of that external interrupt. + * + * Input parameters: + * string - pointer to debug output string + * + * Output parameters: NONE + * + * Return values: NONE + */ + +void DEBUG_puts( + char *string +) +{ + char *s; + unsigned32 Irql; + + rtems_interrupt_disable(Irql); + + for ( s = string ; *s ; s++ ) { + Console_Port_Tbl[Console_Port_Minor].pDeviceFns-> + deviceWritePolled(Console_Port_Minor, *s); + } + + rtems_interrupt_enable(Irql); +} + +/* PAGE + * + * DEBUG_puth + * + * This should be safe in the event of an error. It attempts to ensure + * that no TX empty interrupts occur while it is doing polled IO. Then + * it restores the state of that external interrupt. + * + * Input parameters: + * ulHexNum - value to display + * + * Output parameters: NONE + * + * Return values: NONE + */ + +void DEBUG_puth( + unsigned32 ulHexNum +) +{ + unsigned long i,d; + unsigned32 Irql; + void (*poll)(int minor, char cChar); + + poll = Console_Port_Tbl[Console_Port_Minor].pDeviceFns->deviceWritePolled; + + rtems_interrupt_disable(Irql); + + (*poll)(Console_Port_Minor, '0'); + (*poll)(Console_Port_Minor, 'x'); + + for ( i=32 ; i ; ) { + i -= 4; + d = (ulHexNum>>i)&0xf; + (*poll)(Console_Port_Minor, (d<=9) ? d+'0' : d+'a'-0xa); + } + rtems_interrupt_enable(Irql); +} + diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h b/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h index b5c972107a..c1077f482e 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h +++ b/c/src/lib/libbsp/powerpc/ep1a/console/m68360.h @@ -48,15 +48,22 @@ typedef struct m360MEMCRegisters_ { #define M360_GSMR_RFW 0x00000020 + +#define M360_GSMR_RINV 0x02000000 +#define M360_GSMR_TINV 0x01000000 #define M360_GSMR_TDCR_16X 0x00020000 #define M360_GSMR_RDCR_16X 0x00008000 -#define M360_GSMR_MODE_UART 0x00000004 #define M360_GSMR_DIAG_LLOOP 0x00000040 #define M360_GSMR_ENR 0x00000020 #define M360_GSMR_ENT 0x00000010 +#define M360_GSMR_MODE_UART 0x00000004 #define M360_PSMR_FLC 0x8000 -#define M360_PSMR_SL 0x4000 +#define M360_PSMR_SL_1 0x0000 +#define M360_PSMR_SL_2 0x4000 +#define M360_PSMR_CL5 0x0000 +#define M360_PSMR_CL6 0x1000 +#define M360_PSMR_CL7 0x2000 #define M360_PSMR_CL8 0x3000 #define M360_PSMR_UM_NORMAL 0x0000 #define M360_PSMR_FRZ 0x0200 @@ -970,4 +977,8 @@ void *M360AllocateBufferDescriptors (M68360_t ptr, int count); void M360ExecuteRISC( volatile m360_t *m360, uint16_t command); int mc68360_scc_create_chip( PPMCQ1BoardData BoardData, uint8_t int_vector ); +#if 0 +extern volatile m360_t *m360; +#endif + #endif /* __MC68360_h */ diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c b/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c index 80bc6b8c2a..975e9a6104 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c +++ b/c/src/lib/libbsp/powerpc/ep1a/console/mc68360_scc.c @@ -1,6 +1,7 @@ -/* This file contains the termios TTY driver for the Motorola MC68360 SCC ports. +/* This file contains the termios TTY driver for the + * Motorola MC68360 SCC ports. * - * COPYRIGHT (c) 1989-1999. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -22,23 +23,33 @@ #include #include #include -#include #include -#define MC68360_LENGHT_SIZE 100 -int mc68360_length_array[ MC68360_LENGHT_SIZE ]; +#if 0 +#define DEBUG_360 +#endif + +#if 1 /* XXX */ +int EP1A_READ_LENGTH_GREATER_THAN_1 = 0; + +#define MC68360_LENGTH_SIZE 400 +int mc68360_length_array[ MC68360_LENGTH_SIZE ]; int mc68360_length_count=0; void mc68360_Show_length_array(void) { int i; - for (i=0; i 4096) + { + div16 = 1; + divisor = (divisor + 8) / 16; + } + return(M360_BRG_EN | M360_BRG_EXTC_BRGCLK | + ((divisor - 1) << 1) | div16); +#endif /* * configure baud rate generator for 16x bit rate, where..... @@ -214,7 +239,7 @@ mc68360_sccBRGC(int baud, int m360_clock_rate) * none * * * **************************************************************************/ -void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle ) +void mc68360_sccInterruptHandler( M68360_t chip ) { volatile m360_t *m360; int port; @@ -223,13 +248,22 @@ void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle ) int i; char data; int clear_isr; - M68360_t chip = (M68360_t)handle; + +#ifdef DEBUG_360 + printk("mc68360_sccInterruptHandler\n"); +#endif for (port=0; port<4; port++) { clear_isr = FALSE; m360 = chip->m360; + /* + * XXX - Can we add something here to check if this is our interrupt. + * XXX - We need a parameter here so that we know which 360 instead of + * looping through them all! + */ + /* * Handle a RX interrupt. */ @@ -241,6 +275,9 @@ void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle ) while ((status & M360_BD_EMPTY) == 0) { length= scc_read16("sccRxBd->length",&chip->port[port].sccRxBd->length); +if (length > 1) + EP1A_READ_LENGTH_GREATER_THAN_1 = length; + for (i=0;iport[port].rxBuf[i]; rtems_termios_enqueue_raw_characters( @@ -265,9 +302,13 @@ void mc68360_sccInterruptHandler( rtems_irq_hdl_param handle ) if ((status & M360_BD_EMPTY) == 0) { scc_write16("sccTxBd->status",&chip->port[port].sccTxBd->status,0); +#if 1 rtems_termios_dequeue_characters( Console_Port_Data[chip->port[port].minor].termios_data, chip->port[port].sccTxBd->length); +#else + mc68360_scc_write_support_int(chip->port[port].minor,"*****", 5); +#endif } } @@ -293,10 +334,57 @@ int mc68360_scc_open( void * arg ) { + M68360_serial_ports_t ptr; + volatile m360_t *m360; + uint32_t data; + +#ifdef DEBUG_360 + printk("mc68360_scc_open %d\n", minor); +#endif + + + ptr = Console_Port_Tbl[minor].pDeviceParams; + m360 = ptr->chip->m360; + + /* + * Enable the receiver and the transmitter. + */ + + SYNC(); + data = scc_read32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l); + scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l, + (data | M360_GSMR_ENR | M360_GSMR_ENT) ); + + data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK ); + data &= (~PMCQ1_INT_MASK_QUICC); + PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK, data ); + + data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS ); + data &= (~PMCQ1_INT_STATUS_QUICC); + PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS, data ); return RTEMS_SUCCESSFUL; } +uint32_t mc68360_scc_calculate_pbdat( M68360_t chip ) +{ + uint32_t i; + uint32_t pbdat_data; + int minor; + uint32_t type422data[4] = { + 0x00440, 0x00880, 0x10100, 0x20200 + }; + + pbdat_data = 0x3; + for (i=0; i<4; i++) { + minor = chip->port[i].minor; + if mc68360_scc_Is_422( minor ) + pbdat_data |= type422data[i]; + } + + return pbdat_data; +} + /* * mc68360_scc_initialize_interrupts * @@ -320,6 +408,7 @@ void mc68360_scc_initialize_interrupts(int minor) ptr = Console_Port_Tbl[minor].pDeviceParams; m360 = ptr->chip->m360; + #ifdef DEBUG_360 printk("m360 0x%08x baseaddr 0x%08x\n", m360, ptr->chip->board_data->baseaddr); @@ -337,8 +426,8 @@ void mc68360_scc_initialize_interrupts(int minor) */ data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE ); SYNC(); - data |= (PMCQ1_DRIVER_ENABLE_3 | PMCQ1_DRIVER_ENABLE_2 | - PMCQ1_DRIVER_ENABLE_1 | PMCQ1_DRIVER_ENABLE_0); + data = data & ~(PMCQ1_DRIVER_ENABLE_3 | PMCQ1_DRIVER_ENABLE_2 | + PMCQ1_DRIVER_ENABLE_1 | PMCQ1_DRIVER_ENABLE_0); PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE, data); data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_DRIVER_ENABLE ); SYNC(); @@ -383,10 +472,21 @@ void mc68360_scc_initialize_interrupts(int minor) /* * XXX */ + +#if 0 scc_write32( "pbpar", &m360->pbpar, 0x00000000 ); scc_write32( "pbdir", &m360->pbdir, 0x0003ffff ); scc_write32( "pbdat", &m360->pbdat, 0x0000003f ); SYNC(); +#else + data = mc68360_scc_calculate_pbdat( ptr->chip ); + scc_write32( "pbpar", &m360->pbpar, 0x00000000 ); + scc_write32( "pbdat", &m360->pbdat, data ); + SYNC(); + scc_write32( "pbdir", &m360->pbdir, 0x0003fc3 ); + SYNC(); +#endif + /* * XXX @@ -529,6 +629,7 @@ void mc68360_scc_initialize_interrupts(int minor) (M360_PSMR_CL8 | M360_PSMR_UM_NORMAL | M360_PSMR_TPM_ODD) ); SYNC(); +#if 0 /* XXX - ??? */ /* * Enable the receiver and the transmitter. */ @@ -536,7 +637,7 @@ void mc68360_scc_initialize_interrupts(int minor) SYNC(); data = scc_read32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l); scc_write32( "pSCCR->gsmr_l", &ptr->pSCCR->gsmr_l, - (data | M360_GSMR_ENR | M360_GSMR_ENT) ); + (data | M360_GSMR_ENR | M360_GSMR_ENT) ); data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_MASK ); data &= (~PMCQ1_INT_MASK_QUICC); @@ -545,6 +646,7 @@ void mc68360_scc_initialize_interrupts(int minor) data = PMCQ1_Read_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS ); data &= (~PMCQ1_INT_STATUS_QUICC); PMCQ1_Write_EPLD(ptr->chip->board_data->baseaddr, PMCQ1_INT_STATUS, data ); +#endif } /* @@ -562,10 +664,12 @@ int mc68360_scc_write_support_int( rtems_interrupt_level Irql; M68360_serial_ports_t ptr; +#if 1 mc68360_length_array[ mc68360_length_count ] = len; mc68360_length_count++; - if ( mc68360_length_count >= MC68360_LENGHT_SIZE ) + if ( mc68360_length_count >= MC68360_LENGTH_SIZE ) mc68360_length_count=0; +#endif ptr = Console_Port_Tbl[minor].pDeviceParams; @@ -634,12 +738,41 @@ int mc68360_scc_set_attributes( int baud; volatile m360_t *m360; M68360_serial_ports_t ptr; + uint16_t value; + +#ifdef DEBUG_360 +printk("mc68360_scc_set_attributes\n"); +#endif ptr = Console_Port_Tbl[minor].pDeviceParams; m360 = ptr->chip->m360; - baud = termios_baud_to_number(t->c_cflag & CBAUD); - if (baud > 0) { + switch (t->c_cflag & CBAUD) + { + case B50: baud = 50; break; + case B75: baud = 75; break; + case B110: baud = 110; break; + case B134: baud = 134; break; + case B150: baud = 150; break; + case B200: baud = 200; break; + case B300: baud = 300; break; + case B600: baud = 600; break; + case B1200: baud = 1200; break; + case B1800: baud = 1800; break; + case B2400: baud = 2400; break; + case B4800: baud = 4800; break; + case B9600: baud = 9600; break; + case B19200: baud = 19200; break; + case B38400: baud = 38400; break; + case B57600: baud = 57600; break; + case B115200: baud = 115200; break; + case B230400: baud = 230400; break; + case B460800: baud = 460800; break; + default: baud = -1; break; + } + + if (baud > 0) + { scc_write32( "pBRGC", ptr->pBRGC, @@ -647,6 +780,47 @@ int mc68360_scc_set_attributes( ); } + /* Initial value of PSMR should be 0 */ + value = M360_PSMR_UM_NORMAL; + + /* set the number of data bits, 8 is most common */ + if (t->c_cflag & CSIZE) /* was it specified? */ + { + switch (t->c_cflag & CSIZE) { + case CS5: value |= M360_PSMR_CL5; break; + case CS6: value |= M360_PSMR_CL6; break; + case CS7: value |= M360_PSMR_CL7; break; + case CS8: value |= M360_PSMR_CL8; break; + } + } else { + value |= M360_PSMR_CL8; /* default to 8 data bits */ + } + + /* the number of stop bits */ + if (t->c_cflag & CSTOPB) + value |= M360_PSMR_SL_2; /* Two stop bits */ + else + value |= M360_PSMR_SL_1; /* One stop bit */ + + /* Set Parity M360_PSMR_PEN bit should be clear on no parity so + * do nothing in that case + */ + if (t->c_cflag & PARENB) /* enable parity detection? */ + { + value |= M360_PSMR_PEN; + if (t->c_cflag & PARODD){ + value |= M360_PSMR_RPM_ODD; /* select odd parity */ + value |= M360_PSMR_TPM_ODD; + } else { + value |= M360_PSMR_RPM_EVEN; /* select even parity */ + value |= M360_PSMR_TPM_EVEN; + } + } + + SYNC(); + scc_write16( "pSCCR->psmr", &ptr->pSCCR->psmr, value ); + SYNC(); + return 0; } diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c index a09fb4da65..a91bc0a7a3 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c +++ b/c/src/lib/libbsp/powerpc/ep1a/console/ns16550cfg.c @@ -1,4 +1,4 @@ -/* +/* * This include file contains all console driver definations for the nc16550 * * COPYRIGHT (c) 1989-1999. @@ -26,7 +26,7 @@ uint8_t Read_ns16550_register( uint8_t ucRegNum ) { - struct uart_reg *p = (struct uart_reg *)ulCtrlPort; +volatile struct uart_reg *p = (volatile struct uart_reg *)ulCtrlPort; uint8_t ucData; ucData = p[ucRegNum].reg; asm volatile("sync"); @@ -39,9 +39,12 @@ void Write_ns16550_register( uint8_t ucData ) { - struct uart_reg *p = (struct uart_reg *)ulCtrlPort; + volatile struct uart_reg *p = (volatile struct uart_reg *)ulCtrlPort; volatile int i; p[ucRegNum].reg = ucData; asm volatile("sync"); - for (i=0;i<0x08ff;i++); + asm volatile("isync"); + asm volatile("eieio"); + for (i=0;i<0x08ff;i++) + asm volatile("isync"); } diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/polled_io.c b/c/src/lib/libbsp/powerpc/ep1a/console/polled_io.c new file mode 100644 index 0000000000..9093456fcf --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ep1a/console/polled_io.c @@ -0,0 +1,1130 @@ +/* + * polled_io.c -- Basic input/output for early boot + * + * Copyright (C) 1998, 1999 Gabriel Paubert, paubert@iram.es + * + * Modified to compile in RTEMS development environment + * by Eric Valette + * + * Copyright (C) 1999 Eric Valette. valette@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * polled_io.c,v 1.4.2.3 2003/09/04 18:45:20 joel Exp + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if 0 +#ifdef BSP_KBD_IOBASE +#define USE_KBD_SUPPORT +#endif +#ifdef BSP_VGA_IOBASE +#define USE_VGA_SUPPORT +#endif + +#ifdef USE_KBD_SUPPORT +#include "keyboard.h" +#endif +#include "console.inl" + +#ifdef __BOOT__ +extern void boot_udelay(); +void * __palloc(u_long); +void pfree(void *); +#else +#include +#endif + +typedef unsigned long long u64; +typedef long long s64; +typedef unsigned int u32; + +#ifndef __BOOT__ +BSP_output_char_function_type BSP_output_char = debug_putc_onlcr; +#endif + +#ifdef USE_KBD_SUPPORT +unsigned short plain_map[NR_KEYS] = { + 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, + 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, + 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +unsigned short shift_map[NR_KEYS] = { + 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, + 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, + 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, + 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +unsigned short altgr_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, + 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, + 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73, + 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76, + 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911, + 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, + 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +unsigned short ctrl_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e, + 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, + 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a, + 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +unsigned short shift_ctrl_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +unsigned short alt_map[NR_KEYS] = { + 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836, + 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b, + 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c, + 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907, + 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901, + 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +unsigned short ctrl_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504, + 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a, + 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +ushort *key_maps[MAX_NR_KEYMAPS] = { + plain_map, shift_map, altgr_map, 0, + ctrl_map, shift_ctrl_map, 0, 0, + alt_map, 0, 0, 0, + ctrl_alt_map, 0 +}; + +unsigned int keymap_count = 7; + +/* + * Philosophy: most people do not define more strings, but they who do + * often want quite a lot of string space. So, we statically allocate + * the default and allocate dynamically in chunks of 512 bytes. + */ + +char func_buf[] = { + '\033', '[', '[', 'A', 0, + '\033', '[', '[', 'B', 0, + '\033', '[', '[', 'C', 0, + '\033', '[', '[', 'D', 0, + '\033', '[', '[', 'E', 0, + '\033', '[', '1', '7', '~', 0, + '\033', '[', '1', '8', '~', 0, + '\033', '[', '1', '9', '~', 0, + '\033', '[', '2', '0', '~', 0, + '\033', '[', '2', '1', '~', 0, + '\033', '[', '2', '3', '~', 0, + '\033', '[', '2', '4', '~', 0, + '\033', '[', '2', '5', '~', 0, + '\033', '[', '2', '6', '~', 0, + '\033', '[', '2', '8', '~', 0, + '\033', '[', '2', '9', '~', 0, + '\033', '[', '3', '1', '~', 0, + '\033', '[', '3', '2', '~', 0, + '\033', '[', '3', '3', '~', 0, + '\033', '[', '3', '4', '~', 0, + '\033', '[', '1', '~', 0, + '\033', '[', '2', '~', 0, + '\033', '[', '3', '~', 0, + '\033', '[', '4', '~', 0, + '\033', '[', '5', '~', 0, + '\033', '[', '6', '~', 0, + '\033', '[', 'M', 0, + '\033', '[', 'P', 0, +}; + +char *funcbufptr = func_buf; +int funcbufsize = sizeof(func_buf); +int funcbufleft = 0; /* space left */ + +char *func_table[MAX_NR_FUNC] = { + func_buf + 0, + func_buf + 5, + func_buf + 10, + func_buf + 15, + func_buf + 20, + func_buf + 25, + func_buf + 31, + func_buf + 37, + func_buf + 43, + func_buf + 49, + func_buf + 55, + func_buf + 61, + func_buf + 67, + func_buf + 73, + func_buf + 79, + func_buf + 85, + func_buf + 91, + func_buf + 97, + func_buf + 103, + func_buf + 109, + func_buf + 115, + func_buf + 120, + func_buf + 125, + func_buf + 130, + func_buf + 135, + func_buf + 140, + func_buf + 145, + 0, + 0, + func_buf + 149, + 0, +}; + +struct kbdiacr { + unsigned char diacr, base, result; +}; + +struct kbdiacr accent_table[MAX_DIACR] = { + {'`', 'A', '\300'}, {'`', 'a', '\340'}, + {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, + {'^', 'A', '\302'}, {'^', 'a', '\342'}, + {'~', 'A', '\303'}, {'~', 'a', '\343'}, + {'"', 'A', '\304'}, {'"', 'a', '\344'}, + {'O', 'A', '\305'}, {'o', 'a', '\345'}, + {'0', 'A', '\305'}, {'0', 'a', '\345'}, + {'A', 'A', '\305'}, {'a', 'a', '\345'}, + {'A', 'E', '\306'}, {'a', 'e', '\346'}, + {',', 'C', '\307'}, {',', 'c', '\347'}, + {'`', 'E', '\310'}, {'`', 'e', '\350'}, + {'\'', 'E', '\311'}, {'\'', 'e', '\351'}, + {'^', 'E', '\312'}, {'^', 'e', '\352'}, + {'"', 'E', '\313'}, {'"', 'e', '\353'}, + {'`', 'I', '\314'}, {'`', 'i', '\354'}, + {'\'', 'I', '\315'}, {'\'', 'i', '\355'}, + {'^', 'I', '\316'}, {'^', 'i', '\356'}, + {'"', 'I', '\317'}, {'"', 'i', '\357'}, + {'-', 'D', '\320'}, {'-', 'd', '\360'}, + {'~', 'N', '\321'}, {'~', 'n', '\361'}, + {'`', 'O', '\322'}, {'`', 'o', '\362'}, + {'\'', 'O', '\323'}, {'\'', 'o', '\363'}, + {'^', 'O', '\324'}, {'^', 'o', '\364'}, + {'~', 'O', '\325'}, {'~', 'o', '\365'}, + {'"', 'O', '\326'}, {'"', 'o', '\366'}, + {'/', 'O', '\330'}, {'/', 'o', '\370'}, + {'`', 'U', '\331'}, {'`', 'u', '\371'}, + {'\'', 'U', '\332'}, {'\'', 'u', '\372'}, + {'^', 'U', '\333'}, {'^', 'u', '\373'}, + {'"', 'U', '\334'}, {'"', 'u', '\374'}, + {'\'', 'Y', '\335'}, {'\'', 'y', '\375'}, + {'T', 'H', '\336'}, {'t', 'h', '\376'}, + {'s', 's', '\337'}, {'"', 'y', '\377'}, + {'s', 'z', '\337'}, {'i', 'j', '\377'}, +}; + +unsigned int accent_table_size = 68; + + + + +/* These #defines have been copied from drivers/char/pc_keyb.h, by + * Martin Mares (mj@ucw.cz). + * converted to offsets by Till Straumann + */ +#define KBD_STATUS_REG 0x4 /* Status register (R) */ +#define KBD_CNTL_REG 0x4 /* Controller command register (W) */ +#define KBD_DATA_REG 0x0 /* Keyboard data register (R/W) */ + +/* + * Keyboard Controller Commands + */ + +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ + +/* + * Keyboard Commands + */ + +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ +#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ +#define KBD_CMD_RESET 0xFF /* Reset */ + +/* + * Keyboard Replies + */ + +#define KBD_REPLY_POR 0xAA /* Power on reset */ +#define KBD_REPLY_ACK 0xFA /* Command ACK */ +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ + +/* + * Status Register Bits + */ + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ +#define KBD_STAT_PERR 0x80 /* Parity error */ + +/* + * Controller Mode Register Bits + */ + +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ +#define KBD_MODE_SYS 0x04 /* The system flag (?) */ +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ +#define KBD_MODE_RFU 0x80 + +SPR_RW(DEC) +SPR_RO(PVR) + +#endif /* USE_KBD_SUPPORT */ + + +/* Early messages after mm init but before console init are kept in log + * buffers. + */ +#define PAGE_LOG_CHARS (PAGE_SIZE-sizeof(int)-sizeof(u_long)-1) + +typedef struct _console_log { + struct _console_log *next; + int offset; + u_char data[PAGE_LOG_CHARS]; +} console_log; + +#ifdef STATIC_LOG_ALLOC + +#define STATIC_LOG_DATA_PAGE_NB 3 + +static u_char log_page_pool [STATIC_LOG_DATA_PAGE_NB * PAGE_SIZE]; + +#endif +#endif + +static board_memory_map mem_map = { + (__io_ptr) _IO_BASE, /* from libcpu/io.h */ + (__io_ptr) _ISA_MEM_BASE, +}; + +board_memory_map *ptr_mem_map = &mem_map; + +#if 0 +struct _console_global_data { + console_log *log; + int vacuum_sent; + int lines; + int cols; + int orig_x; + int orig_y; + u_char shfts, ctls, alts, caps; +} console_global_data = {NULL, 0, 25, 80, 0, 24, 0, 0, 0, 0}; + +typedef struct console_io { + void (*putc) (const u_char); + int (*getc) (void); + int (*tstc) (void); +}console_io; + +extern console_io* curIo; + +void debug_putc(const u_char c) +{ + curIo->putc(c); +} + +/* const char arg to be compatible with BSP_output_char decl. */ +void +debug_putc_onlcr(const char c) +{ + if ('\n'==c) + debug_putc('\r'); + debug_putc(c); +} + +int debug_getc(void) +{ + return curIo->getc(); +} + +int debug_tstc(void) +{ + return curIo->tstc(); +} + +#define vidmem ((__io_ptr)(ptr_mem_map->isa_mem_base+0xb8000)) + +void vacuum_putc(u_char c) { + console_global_data.vacuum_sent++; +} + +int vacuum_getc(void) { + return -1; +} + +int vacuum_tstc(void) { + return 0; +} + +/* + * COM1 NS16550 support + */ + +#define rbr 0 +#define ier 1 +#define fcr 2 +#define lcr 3 +#define mcr 4 +#define lsr 5 +#define msr 6 +#define scr 7 +#define thr rbr +#define iir fcr +#define dll rbr +#define dlm ier + +#define LSR_DR 0x01 /* Data ready */ +#define LSR_OE 0x02 /* Overrun */ +#define LSR_PE 0x04 /* Parity error */ +#define LSR_FE 0x08 /* Framing error */ +#define LSR_BI 0x10 /* Break */ +#define LSR_THRE 0x20 /* Xmit holding register empty */ +#define LSR_TEMT 0x40 /* Xmitter empty */ +#define LSR_ERR 0x80 /* Error */ + + +#ifdef STATIC_LOG_ALLOC +static int global_index = 0; + +static void *__palloc(int s) +{ + if (global_index ==( STATIC_LOG_DATA_PAGE_NB - 1) ) return (void*) 0; + return (void*) &(log_page_pool [PAGE_SIZE * global_index++]); +} + +static void pfree(void* p) +{ + --global_index; +} +#endif + + +void log_putc(const u_char c) { + console_log *l; + for(l=console_global_data.log; l; l=l->next) { + if (l->offsetnext; p=p->next); + p->next = l; + } + } + l->data[l->offset++] = c; +} + +/* This puts is non standard since it does not automatically add a newline + * at the end. So it is made private to avoid confusion in other files. + */ +static +void puts(const u_char *s) +{ + char c; + + while ( ( c = *s++ ) != '\0' ) { + debug_putc_onlcr((const char)c); + } +} + + +static +void flush_log(void) { + console_log *p, *next; + if (console_global_data.vacuum_sent) { +#ifdef TRACE_FLUSH_LOG + printk("%d characters sent into oblivion before MM init!\n", + console_global_data.vacuum_sent); +#endif + } + for(p=console_global_data.log; p; p=next) { + puts(p->data); + next = p->next; + pfree(p); + } +} + +#ifndef INL_CONSOLE_INB +#error "BSP probably didn't define a console port" +#endif + +void serial_putc(const u_char c) +{ + while ((INL_CONSOLE_INB(lsr) & LSR_THRE) == 0) ; + INL_CONSOLE_OUTB(thr, c); +} + +int serial_getc(void) +{ + while ((INL_CONSOLE_INB(lsr) & LSR_DR) == 0) ; + return (INL_CONSOLE_INB(rbr)); +} + +int serial_tstc(void) +{ + return ((INL_CONSOLE_INB(lsr) & LSR_DR) != 0); +} + +#ifdef USE_VGA_SUPPORT +static void scroll(void) +{ + int i; + + memcpy ( (u_char *)vidmem, (u_char *)vidmem + console_global_data.cols * 2, + ( console_global_data.lines - 1 ) * console_global_data.cols * 2 ); + for ( i = ( console_global_data.lines - 1 ) * console_global_data.cols * 2; + i < console_global_data.lines * console_global_data.cols * 2; + i += 2 ) + vidmem[i] = ' '; +} + +/* + * cursor() sets an offset (0-1999) into the 80x25 text area + */ +static void +cursor(int x, int y) +{ + int pos = console_global_data.cols*y + x; + vga_outb(14, 0x14); + vga_outb(0x15, pos>>8); + vga_outb(0x14, 15); + vga_outb(0x15, pos); +} + +void +vga_putc(const u_char c) +{ + int x,y; + + x = console_global_data.orig_x; + y = console_global_data.orig_y; + + if ( c == '\n' ) { + if ( ++y >= console_global_data.lines ) { + scroll(); + y--; + } + } else if (c == '\b') { + if (x > 0) { + x--; + } + } else if (c == '\r') { + x = 0; + } else { + vidmem [ ( x + console_global_data.cols * y ) * 2 ] = c; + if ( ++x >= console_global_data.cols ) { + x = 0; + if ( ++y >= console_global_data.lines ) { + scroll(); + y--; + } + } + } + + cursor(x, y); + + console_global_data.orig_x = x; + console_global_data.orig_y = y; +} +#endif /* USE_VGA_SUPPORT */ + +#ifdef USE_KBD_SUPPORT +/* Keyboard support */ +static int kbd_getc(void) +{ + unsigned char dt, brk, val; + unsigned code; +loop: + while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; + + dt = kbd_inb(KBD_DATA_REG); + + brk = dt & 0x80; /* brk == 1 on key release */ + dt = dt & 0x7f; /* keycode */ + + if (console_global_data.shfts) + code = shift_map[dt]; + else if (console_global_data.ctls) + code = ctrl_map[dt]; + else + code = plain_map[dt]; + + val = KVAL(code); + switch (KTYP(code) & 0x0f) { + case KT_LATIN: + if (brk) + break; + if (console_global_data.alts) + val |= 0x80; + if (val == 0x7f) /* map delete to backspace */ + val = '\b'; + return val; + + case KT_LETTER: + if (brk) + break; + if (console_global_data.caps) + val -= 'a'-'A'; + return val; + + case KT_SPEC: + if (brk) + break; + if (val == KVAL(K_CAPS)) + console_global_data.caps = !console_global_data.caps; + else if (val == KVAL(K_ENTER)) { +enter: /* Wait for key up */ + while (1) { + while((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0) ; + dt = kbd_inb(KBD_DATA_REG); + if (dt & 0x80) /* key up */ break; + } + return 10; + } + break; + + case KT_PAD: + if (brk) + break; + if (val < 10) + return val; + if (val == KVAL(K_PENTER)) + goto enter; + break; + + case KT_SHIFT: + switch (val) { + case KG_SHIFT: + case KG_SHIFTL: + case KG_SHIFTR: + console_global_data.shfts = brk ? 0 : 1; + break; + case KG_ALT: + case KG_ALTGR: + console_global_data.alts = brk ? 0 : 1; + break; + case KG_CTRL: + case KG_CTRLL: + case KG_CTRLR: + console_global_data.ctls = brk ? 0 : 1; + break; + } + break; + + case KT_LOCK: + switch (val) { + case KG_SHIFT: + case KG_SHIFTL: + case KG_SHIFTR: + if (brk) + console_global_data.shfts = !console_global_data.shfts; + break; + case KG_ALT: + case KG_ALTGR: + if (brk) + console_global_data.alts = !console_global_data.alts; + break; + case KG_CTRL: + case KG_CTRLL: + case KG_CTRLR: + if (brk) + console_global_data.ctls = !console_global_data.ctls; + break; + } + break; + } + /* if (brk) return (0); */ /* Ignore initial 'key up' codes */ + goto loop; +} + +static int kbd_get(int ms) { + int status, data; + while(1) { + status = kbd_inb(KBD_STATUS_REG); + if (status & KBD_STAT_OBF) { + data = kbd_inb(KBD_DATA_REG); + if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) + return -1; + else + return data; + } + if (--ms < 0) return -1; +#ifdef __BOOT__ + boot_udelay(1000); +#else + rtems_bsp_delay(1000); +#endif + } +} + +static void kbd_put(u_char c, int ms, int port) { + while (kbd_inb(KBD_STATUS_REG) & KBD_STAT_IBF) { + if (--ms < 0) return; +#ifdef __BOOT__ + boot_udelay(1000); +#else + rtems_bsp_delay(1000); +#endif + } + kbd_outb(port, c); +} + +int kbdreset(void) +{ + int c; + + /* Flush all pending data */ + while(kbd_get(10) != -1); + + /* Send self-test */ + kbd_put(KBD_CCMD_SELF_TEST, 10, KBD_CNTL_REG); + c = kbd_get(1000); + if (c != 0x55) return 1; + + /* Enable then reset the KB */ + kbd_put(KBD_CCMD_KBD_ENABLE, 10, KBD_CNTL_REG); + + while (1) { + kbd_put(KBD_CMD_RESET, 10, KBD_DATA_REG); + c = kbd_get(1000); + if (c == KBD_REPLY_ACK) break; + if (c != KBD_REPLY_RESEND) return 2; + } + + if (kbd_get(1000) != KBD_REPLY_POR) return 3; + + /* Disable the keyboard while setting up the controller */ + kbd_put(KBD_CMD_DISABLE, 10, KBD_DATA_REG); + if (kbd_get(10)!=KBD_REPLY_ACK) return 4; + + /* Enable interrupts and keyboard controller */ + kbd_put(KBD_CCMD_WRITE_MODE, 10, KBD_CNTL_REG); + kbd_put(KBD_MODE_KBD_INT | KBD_MODE_SYS | + KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC, + 10, KBD_DATA_REG); + + /* Reenable the keyboard */ + kbd_put(KBD_CMD_ENABLE, 10, KBD_DATA_REG); + if (kbd_get(10)!=KBD_REPLY_ACK) return 5; + + return 0; +} + +int kbd_tstc(void) +{ + return ((kbd_inb(KBD_STATUS_REG) & KBD_STAT_OBF) != 0); +} +#endif /* USE_KBD_SUPPORT */ + +const struct console_io +vacuum_console_functions = { + vacuum_putc, + vacuum_getc, + vacuum_tstc +}; + +static const struct console_io +log_console_functions = { + log_putc, + vacuum_getc, + vacuum_tstc +} +, +serial_console_functions = { + serial_putc, + serial_getc, + serial_tstc +} +#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT) +, +vga_console_functions = { + vga_putc, + kbd_getc, + kbd_tstc +} +#endif +; + +console_io* curIo = (console_io*) &vacuum_console_functions; + +int select_console(ioType t) { + static ioType curType = CONSOLE_VACUUM; + + switch (t) { + case CONSOLE_VACUUM : curIo = (console_io*)&vacuum_console_functions; break; + case CONSOLE_LOG : curIo = (console_io*)&log_console_functions; break; + case CONSOLE_SERIAL : curIo = (console_io*)&serial_console_functions; break; +#if defined(USE_KBD_SUPPORT) && defined(USE_VGA_SUPPORT) + case CONSOLE_VGA : curIo = (console_io*)&vga_console_functions; break; +#endif + default : curIo = (console_io*)&vacuum_console_functions;break; + } + if (curType == CONSOLE_LOG) flush_log(); + curType = t; + return 0; +} + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + + +/* provide this for the bootloader only; otherwise + * use libcpu implementation + */ +#if defined(__BOOT__) +static int skip_atoi(const char **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +/* Based on linux/lib/vsprintf.c and modified to suit our needs, + * bloat has been limited since we basically only need %u, %x, %s and %c. + * But we need 64 bit values ! + */ +int k_vsprintf(char *buf, const char *fmt, va_list args); + +int printk(const char *fmt, ...) { + va_list args; + int i; + /* Should not be a problem with 8kB of stack */ + char buf[1024]; + + va_start(args, fmt); + i = k_vsprintf(buf, fmt, args); + va_end(args); + puts(buf); + return i; +} + +#endif + +/* Necessary to avoid including a library, and GCC won't do this inline. */ +#define div10(num, rmd) \ +do { u32 t1, t2, t3; \ + asm("lis %4,0xcccd; " \ + "addi %4,%4,0xffffcccd; " /* Build 0xcccccccd */ \ + "mulhwu %3,%0+1,%4; " /* (num.l*cst.l).h */ \ + "mullw %2,%0,%4; " /* (num.h*cst.l).l */ \ + "addc %3,%3,%2; " \ + "mulhwu %2,%0,%4; " /* (num.h*cst.l).h */ \ + "addi %4,%4,-1; " /* Build 0xcccccccc */ \ + "mullw %1,%0,%4; " /* (num.h*cst.h).l */ \ + "adde %2,%2,%1; " \ + "mulhwu %1,%0,%4; " /* (num.h*cst.h).h */ \ + "addze %1,%1; " \ + "mullw %0,%0+1,%4; " /* (num.l*cst.h).l */ \ + "addc %3,%3,%0; " \ + "mulhwu %0,%0+1,%4; " /* (num.l*cst.h).h */ \ + "adde %2,%2,%0; " \ + "addze %1,%1; " \ + "srwi %2,%2,3; " \ + "srwi %0,%1,3; " \ + "rlwimi %2,%1,29,0,2; " \ + "mulli %4,%2,10; " \ + "sub %4,%0+1,%4; " \ + "mr %0+1,%2; " : \ + "=r" (num), "=&r" (t1), "=&r" (t2), "=&r"(t3), "=&b" (rmd) : \ + "0" (num)); \ + \ +} while(0); + +#define SIGN 1 /* unsigned/signed long */ +#define LARGE 2 /* use 'ABCDEF' instead of 'abcdef' */ +#define HEX 4 /* hexadecimal instead of decimal */ +#define ADDR 8 /* Value is an addres (p) */ +#define ZEROPAD 16 /* pad with zero */ +#define HALF 32 +#define LONG 64 /* long argument */ +#define LLONG 128 /* 64 bit argument */ + +#if defined(__BOOT__) +static char * number(char * str, int size, int type, u64 num) +{ + char fill,sign,tmp[24]; + const char *digits="0123456789abcdef"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEF"; + fill = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if ((s64)num <0) { + sign = '-'; + num = -num; + size--; + } + } + + i = 0; + do { + unsigned rem; + if (type&HEX) { + rem = num & 0x0f; + num >>=4; + } else { + div10(num, rem); + } + tmp[i++] = digits[rem]; + } while (num != 0); + + size -= i; + if (!(type&(ZEROPAD))) + while(size-->0) + *str++ = ' '; + if (sign) + *str++ = sign; + + while (size-- > 0) + *str++ = fill; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + return str; +} + +int k_vsprintf(char *buf, const char *fmt, va_list args) +{ + int len; + u64 num; + int i; + char * str; + const char *s; + + int flags; /* flags to number() and private */ + + int field_width; /* width of output field */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags, only 0 padding needed */ + flags = 0; + if (*++fmt == '0' ) { + flags |= ZEROPAD; + fmt++; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + + /* get the conversion qualifier */ + if (*fmt == 'h') { + flags |= HALF; + fmt++; + } else if (*fmt == 'L') { + flags |= LLONG; + fmt++; + } else if (*fmt == 'l') { + flags |= LONG; + fmt++; + } + + switch (*fmt) { + case 'c': + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; + + case 's': + s = va_arg(args, char *); + len = strlen(s); + + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + } + flags |= ZEROPAD|HEX|ADDR; + break; + + case 'X': + flags |= LARGE; + case 'x': + flags |= HEX; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; + } + /* This ugly code tries to minimize the number of va_arg() + * since they expand to a lot of code on PPC under the SYSV + * calling conventions (but not with -mcall-aix which has + * other problems). Arguments have at least the size of a + * long allocated, and we use this fact to minimize bloat. + * (and pointers are assimilated to unsigned long too). + */ + if (sizeof(long long) > sizeof(long) && flags & LLONG) + num = va_arg(args, unsigned long long); + else { + u_long n = va_arg(args, unsigned long); + if (flags & HALF) { + if (flags & SIGN) + n = (short) n; + else + n = (unsigned short) n; + } else if (! flags & LONG) { + /* Here the compiler correctly removes this + * do nothing code on 32 bit PPC. + */ + if (flags & SIGN) + n = (int) n; + else + n = (unsigned) n; + } + if (flags & SIGN) num = (long) n; else num = n; + } + str = number(str, field_width, flags, num); + } + *str = '\0'; + return str-buf; +} +#endif +#endif diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c index 45fb72f6c3..764ab53eb1 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c +++ b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.c @@ -41,7 +41,7 @@ call rsPMCQ1Init() to perform ba sic initialisation of the PMCQ1's. #include "m68360.h" /* defines */ -#if 0 +#if 1 #define DEBUG_360 #endif @@ -115,9 +115,10 @@ void rsPMCQ1_scc_nullFunc(void) {} void rsPMCQ1Int( void *ptr ) { - unsigned long status; - unsigned long status1; - unsigned long mask; + unsigned long status; + unsigned long status1; + unsigned long mask; + uint32_t data; PPMCQ1BoardData boardData = ptr; status = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS ); @@ -129,7 +130,7 @@ void rsPMCQ1Int( void *ptr ) if (boardData->quiccInt) { boardData->quiccInt(boardData->quiccArg); } else { - *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC; + *(volatile unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_QUICC; } } @@ -138,16 +139,25 @@ void rsPMCQ1Int( void *ptr ) /* If there is a handler call it otherwise mask the interrupt */ if (boardData->maInt) { boardData->maInt(boardData->maArg); + + data = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS ); + data &= (~PMCQ1_INT_STATUS_MA); + PMCQ1_Write_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS, data ); + } else { - *(unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA; + *(volatile unsigned long *)(boardData->baseaddr + PMCQ1_INT_MASK) |= PMCQ1_INT_MASK_MA; } } + RTEMS_COMPILER_MEMORY_BARRIER(); + /* Clear Interrupt on QSPAN */ - *(unsigned long *)(boardData->bridgeaddr + 0x600) = 0x00001000; + *(volatile unsigned long *)(boardData->bridgeaddr + 0x600) = 0x00001000; /* read back the status register to ensure that the pci write has completed */ status1 = *(volatile unsigned long *)(boardData->bridgeaddr + 0x600); + RTEMS_COMPILER_MEMORY_BARRIER(); + } @@ -165,12 +175,13 @@ unsigned int rsPMCQ1MaIntConnect ( unsigned long busNo, /* Pci Bus number of PMCQ1 */ unsigned long slotNo, /* Pci Slot number of PMCQ1 */ unsigned long funcNo, /* Pci Function number of PMCQ1 */ - rtems_irq_hdl routine,/* interrupt routine */ - rtems_irq_hdl_param arg /* argument to pass to interrupt routine */ + FUNCION_PTR routine,/* interrupt routine */ + int arg /* argument to pass to interrupt routine */ ) { PPMCQ1BoardData boardData; - unsigned int status = RTEMS_IO_ERROR; + uint32_t data; + unsigned int status = RTEMS_IO_ERROR; for (boardData = pmcq1BoardData; boardData; boardData = boardData->pNext) { @@ -179,6 +190,15 @@ unsigned int rsPMCQ1MaIntConnect ( { boardData->maInt = routine; boardData->maArg = arg; + + data = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_MASK ); + data &= (~PMCQ1_INT_MASK_MA); + PMCQ1_Write_EPLD(boardData->baseaddr, PMCQ1_INT_MASK, data ); + + data = PMCQ1_Read_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS ); + data &= (~PMCQ1_INT_STATUS_MA); + PMCQ1_Write_EPLD(boardData->baseaddr, PMCQ1_INT_STATUS, data ); + status = RTEMS_SUCCESSFUL; break; } @@ -234,8 +254,8 @@ unsigned int rsPMCQ1QuiccIntConnect( unsigned long busNo, /* Pci Bus number of PMCQ1 */ unsigned long slotNo, /* Pci Slot number of PMCQ1 */ unsigned long funcNo, /* Pci Function number of PMCQ1 */ - rtems_irq_hdl routine,/* interrupt routine */ - rtems_irq_hdl_param arg /* argument to pass to interrupt routine */ + FUNCION_PTR routine,/* interrupt routine */ + int arg /* argument to pass to interrupt routine */ ) { PPMCQ1BoardData boardData; @@ -303,20 +323,19 @@ unsigned int rsPMCQ1Init(void) { int busNo; int slotNo; - uint32_t baseaddr = 0; - uint32_t bridgeaddr = 0; + unsigned int baseaddr = 0; + unsigned int bridgeaddr = 0; unsigned long pbti0_ctl; int i; unsigned char int_vector; int fun; - uint32_t temp; + int temp; PPMCQ1BoardData boardData; rtems_irq_connect_data IrqData = {0, rsPMCQ1Int, - NULL, - (rtems_irq_enable)rsPMCQ1_scc_nullFunc, - (rtems_irq_disable)rsPMCQ1_scc_nullFunc, - (rtems_irq_is_enabled)rsPMCQ1_scc_nullFunc, + rsPMCQ1_scc_nullFunc, + rsPMCQ1_scc_nullFunc, + rsPMCQ1_scc_nullFunc, NULL}; if (rsPMCQ1Initialized) @@ -436,7 +455,7 @@ unsigned int rsPMCQ1Init(void) #ifdef DEBUG_360 printk("PMCQ1 int_vector %d\n", int_vector); #endif - IrqData.name = (rtems_irq_number)((unsigned int)BSP_PCI_IRQ0 + int_vector); + IrqData.name = ((unsigned int)BSP_PCI_IRQ0 + int_vector); IrqData.handle = boardData; if (!BSP_install_rtems_shared_irq_handler (&IrqData)) { printk("Error installing interrupt handler!\n"); @@ -474,7 +493,7 @@ unsigned int rsPMCQ1Init(void) unsigned int rsPMCQ1Commission( unsigned long busNo, unsigned long slotNo ) { unsigned int status = RTEMS_IO_ERROR; - uint32_t bridgeaddr = 0; + uint32_t bridgeaddr = 0; unsigned long val; int i; uint32_t venId1; diff --git a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h index ecc939e56e..c6ba7d05bb 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h +++ b/c/src/lib/libbsp/powerpc/ep1a/console/rsPMCQ1.h @@ -21,6 +21,9 @@ * */ +#include +#include + /* modification history -------------------- @@ -30,9 +33,6 @@ #ifndef __INCPMCQ1H #define __INCPMCQ1H -#include -#include - /* * PMCQ1 definitions */ @@ -96,8 +96,8 @@ #define PMCQ1_RAM 0x00200000 /* -#define PMCQ1_Read_EPLD( _base, _reg ) ( *((unsigned long *) ((uint32_t)_base + _reg)) ) -#define PMCQ1_Write_EPLD( _base, _reg, _data ) *((unsigned long *) ((uint32_t)_base + _reg)) = _data +#define PMCQ1_Read_EPLD( _base, _reg ) ( *((unsigned long *) ((unsigned32)_base + _reg)) ) +#define PMCQ1_Write_EPLD( _base, _reg, _data ) *((unsigned long *) ((unsigned32)_base + _reg)) = _data */ uint32_t PMCQ1_Read_EPLD( uint32_t base, uint32_t reg ); void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data ); @@ -108,6 +108,7 @@ void PMCQ1_Write_EPLD( uint32_t base, uint32_t reg, uint32_t data ); #define QSPAN2_INT_STATUS 0x00000600 +typedef void (*FUNCION_PTR) (int); #define PCI_ID(v, d) ((d << 16) | v) @@ -130,10 +131,10 @@ typedef struct _PMCQ1BoardData unsigned long funcNo; unsigned long baseaddr; unsigned long bridgeaddr; - rtems_irq_hdl quiccInt; - rtems_irq_hdl_param quiccArg; - rtems_irq_hdl maInt; - rtems_irq_hdl_param maArg; + FUNCION_PTR quiccInt; + int quiccArg; + FUNCION_PTR maInt; + int maArg; } PMCQ1BoardData, *PPMCQ1BoardData; extern PPMCQ1BoardData pmcq1BoardData; @@ -141,8 +142,20 @@ extern PPMCQ1BoardData pmcq1BoardData; /* * Function declarations */ -extern unsigned int rsPMCQ1QuiccIntConnect( - unsigned long busNo, unsigned long slotNo,unsigned long funcNo, rtems_irq_hdl routine,rtems_irq_hdl_param arg ); -extern unsigned int rsPMCQ1Init(void); +extern unsigned int rsPMCQ1QuiccIntConnect( + unsigned long busNo, + unsigned long slotNo, + unsigned long funcNo, + FUNCION_PTR routine, + int arg +); +unsigned int rsPMCQ1Init(); +unsigned int rsPMCQ1MaIntConnect ( + unsigned long busNo, /* Pci Bus number of PMCQ1 */ + unsigned long slotNo, /* Pci Slot number of PMCQ1 */ + unsigned long funcNo, /* Pci Function number of PMCQ1 */ + FUNCION_PTR routine,/* interrupt routine */ + int arg /* argument to pass to interrupt routine */ +); #endif /* __INCPMCQ1H */ diff --git a/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h b/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h index 27f5d4a352..c73243d2ba 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h +++ b/c/src/lib/libbsp/powerpc/ep1a/include/bsp.h @@ -36,12 +36,12 @@ /* address of our ram on the PCI bus */ #define PCI_DRAM_OFFSET CHRP_PCI_DRAM_OFFSET #define PCI_MEM_BASE 0x80000000 -#define PCI_MEM_BASE_ADJUSTMENT 0 - +#define PCI_MEM_BASE_ADJUSTMENT 0 /* address of our ram on the PCI bus */ #define PCI_DRAM_OFFSET CHRP_PCI_DRAM_OFFSET /* offset of pci memory as seen from the CPU */ +#undef PCI_MEM_BASE #define PCI_MEM_BASE 0x00000000 /* Override the default values for the following DEFAULT */ diff --git a/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c b/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c index a9f702c076..b9ed2ccc47 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c +++ b/c/src/lib/libbsp/powerpc/ep1a/irq/irq_init.c @@ -35,6 +35,7 @@ /* #define SHOW_ISA_PCI_BRIDGE_SETTINGS */ +#define TRACE_IRQ_INIT /* * default on/off function @@ -184,6 +185,7 @@ void BSP_rtems_irq_mng_init(unsigned cpuId) initial_config.irqBase = BSP_LOWEST_OFFSET; initial_config.irqPrioTbl = irqPrioTable; +printk("Call BSP_rtems_irq_mngt_set\n"); if (!BSP_rtems_irq_mngt_set(&initial_config)) { /* * put something here that will show the failure... diff --git a/c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c b/c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c new file mode 100644 index 0000000000..791500083b --- /dev/null +++ b/c/src/lib/libbsp/powerpc/ep1a/irq/openpic_xxx_irq.c @@ -0,0 +1,293 @@ +/* + * + * This file contains the i8259/openpic-specific implementation of the function described in irq.h + * + * Copyright (C) 1998, 1999 valette@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* for printk */ +#define RAVEN_INTR_ACK_REG 0xfeff0030 + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ +/* + * pointer to the mask representing the additionnal irq vectors + * that must be disabled when a particular entry is activated. + * They will be dynamically computed from the priority table given + * in BSP_rtems_irq_mngt_set(); + * CAUTION : this table is accessed directly by interrupt routine + * prologue. + */ +rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER]; +#endif + +/* + * default handler connected on each irq after bsp initialization + */ +static rtems_irq_connect_data default_rtems_entry; + +static rtems_irq_connect_data* rtems_hdl_tbl; + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ +/* + * Check if IRQ is an ISA IRQ + */ +static inline int is_isa_irq(const rtems_irq_number irqLine) +{ + return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) + ); +} +#endif + +/* + * Check if IRQ is an OPENPIC IRQ + */ +static inline int is_pci_irq(const rtems_irq_number irqLine) +{ + return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET) + ); +} + +/* + * ------------------------ RTEMS Irq helper functions ---------------- + */ + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ +/* + * Caution : this function assumes the variable "*config" + * is already set and that the tables it contains are still valid + * and accessible. + */ +static void compute_i8259_masks_from_prio (rtems_irq_global_settings* config) +{ + int i; + int j; + /* + * Always mask at least current interrupt to prevent re-entrance + */ + for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) { + * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i); + for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) { + /* + * Mask interrupts at i8259 level that have a lower priority + */ + if (config->irqPrioTbl [i] > config->irqPrioTbl [j]) { + * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j); + } + } + } +} +#endif + +void +BSP_enable_irq_at_pic(const rtems_irq_number name) +{ +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if (is_isa_irq(name)) { + /* + * Enable interrupt at PIC level + */ +printk("ERROR BSP_irq_enable_at_i8259s Being Called for %d\n", (int)name); + BSP_irq_enable_at_i8259s ((int) name); + } +#endif + + if (is_pci_irq(name)) { + /* + * Enable interrupt at OPENPIC level + */ +printk(" openpic_enable_irq %d\n", (int)name ); + openpic_enable_irq ((int) name); + } +} + +int +BSP_disable_irq_at_pic(const rtems_irq_number name) +{ +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if (is_isa_irq(name)) { + /* + * disable interrupt at PIC level + */ + return BSP_irq_disable_at_i8259s ((int) name); + } +#endif + if (is_pci_irq(name)) { + /* + * disable interrupt at OPENPIC level + */ + return openpic_disable_irq ((int) name ); + } + return -1; +} + +/* + * RTEMS Global Interrupt Handler Management Routines + */ +int BSP_setup_the_pic(rtems_irq_global_settings* config) +{ + int i; + /* + * Store various code accelerators + */ + default_rtems_entry = config->defaultEntry; + rtems_hdl_tbl = config->irqHdlTbl; + + /* + * set up internal tables used by rtems interrupt prologue + */ +#if 0 +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + /* + * start with ISA IRQ + */ + compute_i8259_masks_from_prio (config); + + for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) { + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + BSP_irq_enable_at_i8259s (i); + } + else { + BSP_irq_disable_at_i8259s (i); + } + } + + if ( BSP_ISA_IRQ_NUMBER > 0 ) { + /* + * must enable slave pic anyway + */ + BSP_irq_enable_at_i8259s (2); + } +#endif +#endif + + /* + * continue with PCI IRQ + */ + for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) { + /* + * Note that openpic_set_priority() sets the TASK priority of the PIC + */ + openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET, + config->irqPrioTbl[i]); + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + openpic_enable_irq ((int) i ); + } + else { + openpic_disable_irq ((int) i ); + } + } + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if ( BSP_ISA_IRQ_NUMBER > 0 ) { + /* + * Must enable PCI/ISA bridge IRQ + */ + openpic_enable_irq (0); + } +#endif + + return 1; +} + +int _BSP_vme_bridge_irq = -1; + +unsigned BSP_spuriousIntr = 0; + +/* + * High level IRQ handler called from shared_raw_irq_code_entry + */ +int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum) +{ + register unsigned int irq; +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + register unsigned isaIntr; /* boolean */ + register unsigned oldMask = 0; /* old isa pic masks */ + register unsigned newMask; /* new isa pic masks */ +#endif + + if (excNum == ASM_DEC_VECTOR) { +/* printk("ASM_DEC_VECTOR\n"); */ + bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl); + + return 0; + + } + irq = openpic_irq(0); + if (irq == OPENPIC_VEC_SPURIOUS) { +/* printk("OPENPIC_VEC_SPURIOUS interrupt %d\n", OPENPIC_VEC_SPURIOUS ); */ + ++BSP_spuriousIntr; + return 0; + } + + /* some BSPs might want to use a different numbering... */ + irq = irq - OPENPIC_VEC_SOURCE + BSP_PCI_IRQ_LOWEST_OFFSET; +/* printk("OpenPic Irq: %d\n", irq); */ + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ); + if (isaIntr) { +/* printk("BSP_PCI_ISA_BRIDGE_IRQ\n"); */ + /* + * Acknowledge and read 8259 vector + */ + irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG); + /* + * store current PIC mask + */ + oldMask = i8259s_cache; + newMask = oldMask | irq_mask_or_tbl [irq]; + i8259s_cache = newMask; + outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); + outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); + BSP_irq_ack_at_i8259s (irq); + openpic_eoi(0); + } +#endif + + + /* dispatch handlers */ +/* printk("dispatch\n"); */ +irq -=16; + bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl); +/* printk("Back from dispatch\n"); */ + +#ifdef BSP_PCI_ISA_BRIDGE_IRQ + if (isaIntr) {\ + i8259s_cache = oldMask; + outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); + outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); + } + else +#endif + { +#ifdef BSP_PCI_VME_DRIVER_DOES_EOI + /* leave it to the VME bridge driver to do EOI, so + * it can re-enable the openpic while handling + * VME interrupts (-> VME priorities in software) + */ + if (_BSP_vme_bridge_irq != irq) +#endif + openpic_eoi(0); + } + return 0; +} diff --git a/c/src/lib/libbsp/powerpc/ep1a/vme/VMEConfig.h b/c/src/lib/libbsp/powerpc/ep1a/vme/VMEConfig.h index 5f01241ee5..8492733a2d 100644 --- a/c/src/lib/libbsp/powerpc/ep1a/vme/VMEConfig.h +++ b/c/src/lib/libbsp/powerpc/ep1a/vme/VMEConfig.h @@ -63,9 +63,9 @@ */ #undef BSP_VME_BAT_IDX -#define _VME_A32_WIN0_ON_PCI 0x10000000 -#define _VME_A24_ON_PCI 0x1f000000 -#define _VME_A16_ON_PCI 0x1fff0000 +#define _VME_A32_WIN0_ON_PCI 0x90000000 +#define _VME_A24_ON_PCI 0x9f000000 +#define _VME_A16_ON_PCI 0x9fff0000 /* start of the A32 window on the VME bus * TODO: this should perhaps be a configuration option @@ -77,6 +77,16 @@ * at _VME_DRAM_OFFSET */ #undef _VME_DRAM_OFFSET +#define _VME_DRAM_OFFSET 0xc0000000 +#define _VME_DRAM_32_OFFSET1 0x20000000 +#define _VME_DRAM_32_OFFSET2 0x20b00000 +#define _VME_DRAM_24_OFFSET1 0x00000000 +#define _VME_DRAM_24_OFFSET2 0x00100000 +#define _VME_DRAM_16_OFFSET1 0x00000000 +#define _VME_DRAM_16_OFFSET2 0x00008000 + +#define _VME_A24_SIZE 0x00100000 +#define _VME_A16_SIZE 0x00008000 #undef _VME_CSR_ON_PCI -- cgit v1.2.3