From c9b005a9d2ed95bb1ab16fbc0c823c12a5c58b26 Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Sun, 9 Jul 2006 10:05:27 +0000 Subject: applied patches for PR1117/1118/1119/1120 --- aclocal/bsp-alias.m4 | 1 + aclocal/check-bsps.m4 | 2 +- c/src/lib/libbsp/powerpc/gen5200/Makefile.am | 6 +- .../powerpc/gen5200/bestcomm/bestcomm_glue.c | 8 +- c/src/lib/libbsp/powerpc/gen5200/bsp_specs | 6 +- c/src/lib/libbsp/powerpc/gen5200/console/console.c | 77 ++- c/src/lib/libbsp/powerpc/gen5200/include/bsp.h | 26 +- c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h | 3 + c/src/lib/libbsp/powerpc/gen5200/include/tm27.h | 59 +- c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c | 719 ++++++++++++++------- c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h | 78 ++- .../libbsp/powerpc/gen5200/network_5200/network.c | 323 +++++++-- c/src/lib/libbsp/powerpc/gen5200/preinstall.am | 10 +- c/src/lib/libbsp/powerpc/gen5200/start/start.S | 25 +- c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c | 4 +- c/src/libchip/ide/ata.c | 5 +- c/src/libchip/ide/ata.h | 4 +- cpukit/libblock/include/rtems/bdbuf.h | 3 + cpukit/libblock/src/bdbuf.c | 11 +- cpukit/libcsupport/include/sys/cdefs.h | 4 + cpukit/libfs/src/imfs/imfs.h | 10 +- cpukit/libfs/src/imfs/imfs_initsupp.c | 38 ++ cpukit/libmisc/shell/shell.c | 9 + cpukit/libnetworking/netinet/tcp_var.h | 2 + cpukit/libnetworking/sys/linker_set.h | 2 +- cpukit/sapi/include/confdefs.h | 75 ++- make/custom/mpc8260ads.cfg | 2 +- testsuites/samples/fileio/system.h | 25 +- 28 files changed, 1142 insertions(+), 395 deletions(-) diff --git a/aclocal/bsp-alias.m4 b/aclocal/bsp-alias.m4 index 0eeb916ed1..337f43145d 100644 --- a/aclocal/bsp-alias.m4 +++ b/aclocal/bsp-alias.m4 @@ -25,6 +25,7 @@ AC_DEFUN([_RTEMS_BSP_ALIAS], pc586) $2=pc386 ;; # i386 - PC with Pentium pc686) $2=pc386 ;; # i386 - PC with PentiumPro pck6) $2=pc386 ;; # i386 - PC with K6 + brs5l*) $2=gen5200 ;; # MPC5200 based board pm520*) $2=gen5200 ;; # MPC5200 based board simcpu32) $2=sim68000 ;; # BSVC CPU32 variant simsh7032) $2=shsim ;; # SH7032 simulator diff --git a/aclocal/check-bsps.m4 b/aclocal/check-bsps.m4 index d126ac6576..0a9d969699 100644 --- a/aclocal/check-bsps.m4 +++ b/aclocal/check-bsps.m4 @@ -26,7 +26,7 @@ AC_MSG_CHECKING([for available BSPs]) bsps="$bsps mbx860_002" bsps="$bsps mbx860_005b" ;; - gen5200) bsps="pm520_cr825 pm520_ze30";; + gen5200) bsps="pm520_cr825 pm520_ze30 brs5l";; motorola_powerpc) bsps="mvme2307 mcp750 mtx603e mvme2100";; pc386) bsps="pc386 pc386dx pc486 pc586 pc686 pck6";; erc32) bsps="erc32 erc32nfp sis";; diff --git a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am index ca9461ec6a..dff93494e5 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/Makefile.am +++ b/c/src/lib/libbsp/powerpc/gen5200/Makefile.am @@ -29,7 +29,7 @@ start.$(OBJEXT): start/start.S $(CPPASCOMPILE) -DASM -o $@ -c $< project_lib_DATA = start.$(OBJEXT) -dist_project_lib_DATA += startup/linkcmds startup/linkcmds.pm520 +dist_project_lib_DATA += startup/linkcmds.brs5l startup/linkcmds.pm520 noinst_PROGRAMS += bestcomm.rel bestcomm_rel_SOURCES = bestcomm/include/ppctypes.h \ @@ -90,11 +90,13 @@ noinst_PROGRAMS += nvram.rel nvram_rel_SOURCES = nvram/nvram.c nvram/nvram.h nvram/m93cxx.h nvram_rel_CPPFLAGS = $(AM_CPPFLAGS) nvram_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +include_bsp_HEADERS += nvram/nvram.h noinst_PROGRAMS += slicetimer.rel slicetimer_rel_SOURCES = slicetimer/slicetimer.c slicetimer/slicetimer.h slicetimer_rel_CPPFLAGS = $(AM_CPPFLAGS) slicetimer_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +include_bsp_HEADERS += slicetimer/slicetimer.h noinst_PROGRAMS += tod.rel tod_rel_SOURCES = tod/todcfg.c tod/pcf8563.c tod/pcf8563.h \ @@ -108,7 +110,7 @@ noinst_PROGRAMS += startup.rel startup_rel_SOURCES = ../../shared/bspclean.c ../../shared/bsplibc.c \ ../../shared/bsppost.c startup/bspstart.c ../../shared/bootcard.c \ ../../shared/main.c ../../shared/sbrk.c \ - ../../shared/gnatinstallhandler.c startup/cpuinit.c + ../../shared/gnatinstallhandler.c startup/cpuinit.c start/start.S startup_rel_CPPFLAGS = $(AM_CPPFLAGS) startup_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) diff --git a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c index bbde4ea848..00f5a59172 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c +++ b/c/src/lib/libbsp/powerpc/gen5200/bestcomm/bestcomm_glue.c @@ -46,12 +46,15 @@ void bestcomm_glue_irq_enable | none | \*=========================================================================*/ { + rtems_interrupt_level level; if (0 != ((1UL<rb_tb >> 24); - nb_overflow = rtems_termios_enqueue_raw_characters((void *)ttyp[minor], (char *)&c, (int)1); - - channel_info[minor].rx_characters++; + if (ttyp[minor] != NULL) { + nb_overflow = rtems_termios_enqueue_raw_characters((void *)ttyp[minor], (char *)&c, (int)1); + channel_info[minor].rx_characters++; + } #ifndef SINGLE_CHAR_MODE } @@ -364,16 +366,17 @@ static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle) */ psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_TX_RDY); + if (ttyp[minor] != NULL) { #ifndef SINGLE_CHAR_MODE - rtems_termios_dequeue_characters((void *)ttyp[minor], channel_info[minor].cur_tx_len); + rtems_termios_dequeue_characters((void *)ttyp[minor], channel_info[minor].cur_tx_len); - channel_info[minor].tx_characters += channel_info[minor].cur_tx_len; + channel_info[minor].tx_characters += channel_info[minor].cur_tx_len; #else - rtems_termios_dequeue_characters((void *)ttyp[minor], (int)1); + rtems_termios_dequeue_characters((void *)ttyp[minor], (int)1); - channel_info[minor].tx_characters++; + channel_info[minor].tx_characters++; #endif - + } } if(isr & ISR_ERROR) @@ -403,10 +406,10 @@ static void mpc5200_psc_interrupt_handler(rtems_irq_hdl_param handle) void mpc5200_psc_enable(const rtems_irq_connect_data* ptr) { struct mpc5200_psc *psc; int minor = mpc5200_psc_irqname_to_minor(ptr->name); - + if (minor >= 0) { psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - psc->isr_imr = channel_info[minor].shadow_imr |= + psc->isr_imr = channel_info[minor].shadow_imr |= (IMR_RX_RDY_FULL | IMR_TX_RDY); } } @@ -415,10 +418,10 @@ void mpc5200_psc_enable(const rtems_irq_connect_data* ptr) { void mpc5200_psc_disable(const rtems_irq_connect_data* ptr) { struct mpc5200_psc *psc; int minor = mpc5200_psc_irqname_to_minor(ptr->name); - + if (minor >= 0) { psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); - psc->isr_imr = channel_info[minor].shadow_imr &= + psc->isr_imr = channel_info[minor].shadow_imr &= ~(IMR_RX_RDY_FULL | IMR_TX_RDY); } } @@ -427,7 +430,7 @@ void mpc5200_psc_disable(const rtems_irq_connect_data* ptr) { int mpc5200_psc_isOn(const rtems_irq_connect_data* ptr) { struct mpc5200_psc *psc; int minor = mpc5200_psc_irqname_to_minor(ptr->name); - + if (minor >= 0) { psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); return ((psc->isr_imr & IMR_RX_RDY_FULL) & (psc->isr_imr & IMR_TX_RDY)); @@ -443,7 +446,7 @@ static rtems_irq_connect_data consoleIrqData; void mpc5200_uart_psc_initialize(int minor) { uint32_t baud_divider; - struct mpc5200_psc *psc = + struct mpc5200_psc *psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); /* @@ -504,7 +507,7 @@ void mpc5200_uart_psc_initialize(int minor) { /* * Set lower timer counter */ - + psc->ctlr = baud_divider & 0x0000ffff; /* @@ -572,7 +575,7 @@ void mpc5200_uart_psc_initialize(int minor) { int mpc5200_uart_pollRead(int minor) { unsigned char c; - struct mpc5200_psc *psc = + struct mpc5200_psc *psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); if(psc->sr_csr & (1 << 8)) @@ -588,7 +591,7 @@ int mpc5200_uart_pollRead(int minor) int mpc5200_uart_pollWrite(int minor, const char *buf, int len) { const char *tmp_buf = buf; - struct mpc5200_psc *psc = + struct mpc5200_psc *psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); while(len--) @@ -614,7 +617,7 @@ int mpc5200_uart_write(int minor, const char *buf, int len) { int frame_len = len; const char *frame_buf = buf; - struct mpc5200_psc *psc = + struct mpc5200_psc *psc = (struct mpc5200_psc *)(&mpc5200.psc[psc_minor_to_regset[minor]]); /* @@ -684,30 +687,37 @@ rtems_device_driver console_initialize(rtems_device_major_number major, rtems_de rtems_status_code status; rtems_device_minor_number console_minor; char dev_name[] = "/dev/ttyx"; + uint32_t tty_num = 0; + /* * Always use and set up TERMIOS */ console_minor = PSC1_MINOR; rtems_termios_initialize(); - for (console_minor = PSC1_MINOR; - console_minor < PSC1_MINOR + NUM_PORTS; - console_minor++) { - /* - * check, whether UART is available for this board - */ + for (console_minor = PSC1_MINOR; + console_minor < PSC1_MINOR + NUM_PORTS; + console_minor++) { + /* + * check, whether UART is available for this board + */ if (0 != ((1 << console_minor) & (mpc5200_uart_avail_mask))) { /* * Do device-specific initialization and registration for Motorola IceCube */ mpc5200_uart_psc_initialize(console_minor); /* /dev/tty0 */ - dev_name[8] = '0' + console_minor - PSC1_MINOR; + dev_name[8] = '0' + tty_num; status = rtems_io_register_name (dev_name, major, console_minor); - + if(status != RTEMS_SUCCESSFUL) - rtems_fatal_error_occurred(status); + { + rtems_fatal_error_occurred(status); + } + + tty_num++; } } + /* Now register the RTEMS console */ status = rtems_io_register_name ("/dev/console", major, PSC1_MINOR); @@ -780,8 +790,9 @@ rtems_device_driver console_close(rtems_device_major_number major, rtems_device_ if ( minor > NUM_PORTS-1 ) return RTEMS_INVALID_NUMBER; - return rtems_termios_close( arg ); + ttyp[minor] = NULL; /* mark for int handler: tty no longer open */ + return rtems_termios_close( arg ); return 0; } diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h b/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h index 998349c55f..f106e8b3c2 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h +++ b/c/src/lib/libbsp/powerpc/gen5200/include/bsp.h @@ -61,13 +61,15 @@ */ /* ROM definitions (2 MB) */ #define ROM_START 0xFFE00000 -#define ROM_END 0xFFFFFFFF +#define ROM_SIZE 0x00200000 +#define ROM_END (ROM_START+ROM_SIZE-1) #define BOOT_START ROM_START #define BOOT_END ROM_END /* SDRAM definitions (256 MB) */ -#define RAM_START 0x00000000 -#define RAM_END 0x0FFFFFFF +#define RAM_START 0x00000000 +#define RAM_SIZE 0x10000000 +#define RAM_END (RAM_START+RAM_SIZE-1) /* DPRAM definitions (64 KB) */ #define DPRAM_START 0xFF000000 @@ -198,7 +200,8 @@ void bsp_cleanup(void); #define UARTS_USE_TERMIOS_INT 1 /* ata modes */ -#undef ATA_USE_INT +/* #undef ATA_USE_INT */ +#define ATA_USE_INT /* clock settings */ #if defined(HAS_UBOOT) @@ -211,6 +214,21 @@ void bsp_cleanup(void); #define G2_CLOCK 231000000 /* 231 MHz */ #endif +/* + * Convert decrement value to tenths of microsecnds (used by + * shared timer driver). + * + * + CPU has a XLB_CLOCK bus, + * + There are 4 bus cycles per click + * + We return value in 1/10 microsecond units. + * Modified following equation to integer equation to remove + * floating point math. + * (int) ((float)(_value) / ((XLB_CLOCK/1000000 * 0.1) / 4.0)) + */ + +#define BSP_Convert_decrementer( _value ) \ + (int) (((_value) * 4000) / (XLB_CLOCK/10000)) + /* slicetimer settings */ #define USE_SLICETIMER_0 TRUE #define USE_SLICETIMER_1 FALSE diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h b/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h index 748eb77d70..adcdc06392 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h +++ b/c/src/lib/libbsp/powerpc/gen5200/include/mpc5200.h @@ -300,12 +300,15 @@ typedef struct mpc5200_ #define GPT_STATUS_RESET 0x0000000F #define GPT_STATUS_TEXP (1 << 3) #define GPT_STATUS_PIN (1 << 8) +#define GPT_EMSEL_GPIO_DIR (2 << 4) +#define GPT_EMSEL_GPIO_OUT (1 << 4) #define GPT_EMSEL_GPIO_OUT_HIGH (3 << 4) #define GPT_EMSEL_TIMER_MS_GPIO (4 << 0) #define GPT_EMSEL_GPIO_IN (0 << 0) #define GPT_EMSEL_CE (1 << 12) #define GPT_EMSEL_ST_CONT (1 << 10) #define GPT_EMSEL_INTEN (1 << 8) +#define GPT_EMSEL_WDEN (1 << 15) #define GPT0 0 #define GPT1 1 diff --git a/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h b/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h index d938e07f6e..2c85c3156e 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h +++ b/c/src/lib/libbsp/powerpc/gen5200/include/tm27.h @@ -15,28 +15,49 @@ #ifndef __tm27_h #define __tm27_h +#include + /* * Stuff for Time Test 27 */ -#define MUST_WAIT_FOR_INTERRUPT 0 - -#define Install_tm27_vector( handler ) \ - do { \ - static rtems_irq_connect_data scIrqData = { \ - PPC_IRQ_SCALL, \ - (rtems_irq_hdl) handler, \ - NULL, \ - NULL, \ - NULL \ - }; \ - BSP_install_rtems_irq_handler (&scIrqData); \ - } while(0) - -#define Cause_tm27_intr() asm volatile ("sc") - -#define Clear_tm27_intr() /* empty */ - -#define Lower_tm27_intr() /* empty */ +#define MUST_WAIT_FOR_INTERRUPT 1 + +void nullFunc() {} + +static rtems_irq_connect_data clockIrqData = {BSP_DECREMENTER, + 0, + (rtems_irq_enable)nullFunc, + (rtems_irq_disable)nullFunc, + (rtems_irq_is_enabled) nullFunc}; +void Install_tm27_vector(void (*_handler)()) +{ + clockIrqData.hdl = _handler; + if (!BSP_install_rtems_irq_handler (&clockIrqData)) { + printk("Error installing clock interrupt handler!\n"); + rtems_fatal_error_occurred(1); + } +} + +#define Cause_tm27_intr() \ + do { \ + uint32_t _clicks = 8; \ + asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \ + } while (0) + +#define Clear_tm27_intr() \ + do { \ + uint32_t _clicks = 0xffffffff; \ + asm volatile( "mtdec %0" : "=r" ((_clicks)) : "r" ((_clicks)) ); \ + } while (0) + +#define Lower_tm27_intr() \ + do { \ + uint32_t _msr = 0; \ + _ISR_Set_level( 0 ); \ + asm volatile( "mfmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \ + _msr |= 0x8002; \ + asm volatile( "mtmsr %0 ;" : "=r" (_msr) : "r" (_msr) ); \ + } while (0) #endif diff --git a/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c index 857a160b9b..c107e9e37f 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c +++ b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.c @@ -30,8 +30,107 @@ /* #define MSCAN_LOOPBACK */ +volatile uint32_t tx_int_wr_count = 0; + struct mpc5200_rx_cntrl mpc5200_mscan_rx_cntrl[MPC5200_CAN_NO]; -static struct mscan_channel_info chan_info[MPC5200_CAN_NO]; +volatile static struct mscan_channel_info chan_info[MPC5200_CAN_NO]; + +/* time segmant table */ +uint8_t can_time_segment_table[CAN_MAX_NO_OF_TQ - MIN_NO_OF_TQ + 1][NO_OF_TABLE_ENTRIES] = { + +/* Total no. of time quantas */ /* Time Segment 1*/ /* Time Segment 2 */ /* Sync: Jump width */ +{ 7, 4, 2, 1 }, +{ 8, 5, 2, 1 }, +{ 9, 6, 2, 2 }, +{ 10, 6, 3, 2 }, +{ 11, 7, 3, 2 }, +{ 12, 8, 3, 2 }, +{ 13, 8, 4, 2 }, +{ 14, 9, 4, 2 }, +{ 15, 10, 4, 2 }, +{ 16, 10, 5, 2 }, +{ 17, 11, 5, 2 }, +{ 18, 12, 5, 2 }, +{ 19, 12, 6, 2 }, +{ 20, 13, 6, 2 }, +{ 21, 14, 6, 2 }, +{ 22, 14, 7, 2 }, +{ 23, 15, 7, 2 }, +{ 24, 15, 8, 2 }, +{ 25, 16, 8, 2 }}; + + +/* + * MPC5x00 MSCAN tx ring buffer function to get a can message buffer from the head of the tx ring buffer + */ +volatile static struct can_message * get_tx_buffer(struct mscan_channel_info *chan) + { + /* define a temp. mess ptr. */ + volatile struct can_message * tmp_mess_ptr = NULL, *temp_head_ptr; + + /* set temp. head pointer */ + temp_head_ptr = chan->tx_ring_buf.head_ptr; + + /* check buffer empty condition */ + if(temp_head_ptr != chan->tx_ring_buf.tail_ptr) + { + + /* current buffer head. ptr. */ + tmp_mess_ptr = temp_head_ptr; + + /* increment the head pointer */ + temp_head_ptr++; + + /* check for wrap around condition */ + if(temp_head_ptr > chan->tx_ring_buf.buf_ptr + NO_OF_MSCAN_TX_BUFF) + { + + /* set head ptr. to the begin of the ring buffer */ + temp_head_ptr = chan->tx_ring_buf.buf_ptr; + + } + + /* end of crtical section restore head ptr. */ + chan->tx_ring_buf.head_ptr = temp_head_ptr; + } + + /* return the current head pointer */ + return tmp_mess_ptr; + } + +/* + * MPC5x00 MSCAN tx ring buffer function to write a can message buffer to the tail of the tx ring buffer + */ +volatile static struct can_message * fill_tx_buffer(struct mscan_channel_info *chan, struct can_message * mess_ptr) + { + /* define a temp. mess ptr. to the entry which follows the current tail entry */ + struct can_message * tmp_mess_ptr = chan->tx_ring_buf.tail_ptr + 1; + + /* check for the wrap around condition */ + if(tmp_mess_ptr > chan->tx_ring_buf.buf_ptr + NO_OF_MSCAN_TX_BUFF) + { + /* set temp. mess. ptr to the begin of the ring buffer */ + tmp_mess_ptr = chan->tx_ring_buf.buf_ptr; + } + + /* check buffer full condition */ + if(tmp_mess_ptr == chan->tx_ring_buf.head_ptr) + { + /* return NULL in case buffer is full */ + return NULL; + } + else + { + /* copy the can mess. to the tail of the buffer */ + memcpy((void *)chan->tx_ring_buf.tail_ptr, (void *)mess_ptr, sizeof(struct can_message)); + + /* set new tail equal to temp. mess. ptr. */ + chan->tx_ring_buf.tail_ptr = tmp_mess_ptr; + } + + /* return the actual tail ptr. (next free entry) */ + return chan->tx_ring_buf.tail_ptr; + } /* * MPC5x00 MSCAN interrupt handler @@ -41,24 +140,110 @@ static void mpc5200_mscan_interrupt_handler(rtems_irq_hdl_param handle) rtems_status_code status; mscan_handle *mscan_hdl = (mscan_handle *)handle; struct mscan_channel_info *chan = &chan_info[mscan_hdl->mscan_channel]; - struct can_message rx_mess, *rx_mess_ptr; + struct can_message rx_mess, *rx_mess_ptr, *tx_mess_ptr; volatile struct mpc5200_mscan *mscan = chan->regs; + register uint8_t idx; /* - handle tx interrupts + handle tx ring buffer */ - /* check and disable tx interrupt for message buffer 0 */ - if(mscan->tier & MSCAN_TX_BUFF0) - mscan->tier &= ~(MSCAN_TX_BUFF0); + /* loop over all 3 tx buffers */ + for(idx = TFLG_TXE0; idx <= TFLG_TXE2; idx=idx<<1) + { + + /* check for tx buffer vacation */ + if((mscan->tflg) & idx) + { + + /* try to get a message */ + tx_mess_ptr = get_tx_buffer(chan); + + /* check for new tx message */ + if(tx_mess_ptr != NULL) + { + + /* select the tx buffer */ + mscan->bsel = idx; + + /* check for toucan interface */ + if((mscan_hdl->toucan_callback) == NULL) + { + + /* set tx id */ + mscan->txidr0 = SET_IDR0(tx_mess_ptr->mess_id); + mscan->txidr1 = SET_IDR1(tx_mess_ptr->mess_id); + mscan->txidr2 = 0; + mscan->txidr3 = 0; + + /* insert dlc into mscan register */ + mscan->txdlr = (uint8_t)((tx_mess_ptr->mess_len) & 0x000F); + } + + /* select one free tx buffer if TOUCAN not registered) */ + if(((mscan_hdl->toucan_callback) == NULL) || (((mscan_hdl->toucan_callback) != NULL) && ((tx_mess_ptr->toucan_tx_id) == idx))) + { + + /* set tx id */ + mscan->txidr0 = SET_IDR0(tx_mess_ptr->mess_id); + mscan->txidr1 = SET_IDR1(tx_mess_ptr->mess_id); + mscan->txidr2 = 0; + mscan->txidr3 = 0; + + /* insert dlc into mscan register */ + mscan->txdlr = (uint8_t)((tx_mess_ptr->mess_len) & 0x000F); + + /* copy tx data to MSCAN registers */ + switch(mscan->txdlr) + { + case 8: + mscan->txdsr7 = tx_mess_ptr->mess_data[7]; + case 7: + mscan->txdsr6 = tx_mess_ptr->mess_data[6]; + case 6: + mscan->txdsr5 = tx_mess_ptr->mess_data[5]; + case 5: + mscan->txdsr4 = tx_mess_ptr->mess_data[4]; + case 4: + mscan->txdsr3 = tx_mess_ptr->mess_data[3]; + case 3: + mscan->txdsr2 = tx_mess_ptr->mess_data[2]; + case 2: + mscan->txdsr1 = tx_mess_ptr->mess_data[1]; + case 1: + mscan->txdsr0 = tx_mess_ptr->mess_data[0]; + break; + default: + break; + } + + /* enable message buffer specific interrupt */ + mscan->tier |= mscan->bsel; + + /* start transfer */ + mscan->tflg = mscan->bsel; + + /* release counting semaphore of tx ring buffer */ + rtems_semaphore_release((rtems_id)(chan->tx_rb_sid)); + + tx_int_wr_count++; - /* check and disable tx interrupt for message buffer 1 */ - if(mscan->tier & MSCAN_TX_BUFF1) - mscan->tier &= ~(MSCAN_TX_BUFF1); + } + else + { - /* check and disable tx interrupt for message buffer 2 */ - if(mscan->tier & MSCAN_TX_BUFF2) - mscan->tier &= ~(MSCAN_TX_BUFF2); + /* refill the tx ring buffer with the message */ + fill_tx_buffer(chan, tx_mess_ptr); + + } + } + else + { + /* reset interrupt enable bit */ + mscan->tier &= ~(idx); + } + } + } /* handle rx interrupts @@ -84,24 +269,17 @@ static void mpc5200_mscan_interrupt_handler(rtems_irq_hdl_param handle) /* check the rx fliter-match indicators (16-bit filter mode) */ /* in case of more than one hit, lower hit has priority */ - switch((mscan->idac) & 0x7) + idx = (mscan->idac) & 0x7; + switch(idx) { case 0: - rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[0]); - break; - - case 1: - rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[1]); - break; - + case 1: case 2: - rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[2]); - break; - - case 3: - rx_mess_ptr = (struct can_message *)&(mpc5200_mscan_rx_cntrl[MSCAN_A].can_rx_message[3]); - break; + case 3: + rx_mess_ptr = + (struct can_message *)&(mpc5200_mscan_rx_cntrl[mscan_hdl->mscan_channel].can_rx_message[idx]); + break; /* this case should never happen */ default: @@ -530,34 +708,71 @@ void mpc5200_mscan_wait_sync(volatile struct mpc5200_mscan *mscan) /* [01]:SLPRQ 0 : No Sleep Mode Request */ /* [00]:INITRQ 0 : No init. Mode Request */ /* wait for MSCAN A_/_B bus synch. */ - while(!((mscan->ctl0) & CTL0_SYNCH)); +#if 0 /* we don't have a need to wait for sync. */ + while(!((mscan->ctl0) & CTL0_SYNCH)); +#endif return; } +/* calculate the can clock prescaler value */ +uint8_t prescaler_calculation(uint32_t can_bit_rate, uint32_t can_clock_frq, uint8_t *tq_no) { + +/* local variables */ +uint8_t tq_no_min_dev = 0; +uint32_t frq_tq, frq_dev, frq_dev_min = 0xFFFFFFFF; + +/* loop through all values of time quantas */ +for(*tq_no = CAN_MAX_NO_OF_TQ; *tq_no >= MIN_NO_OF_TQ; (*tq_no)--) { + + /* calculate time quanta freq. */ + frq_tq = *tq_no * can_bit_rate; + + /* calculate the deviation from requested tq freq. */ + frq_dev = can_clock_frq%frq_tq; + + /* check the deviation freq. */ + if(frq_dev == 0) { + + /* return if best match (zero deviation) */ + return (uint8_t)(can_clock_frq/frq_tq); + } + else + { + + /* check for minimum of freq. deviation */ + if(frq_dev < frq_dev_min) { + + /* recognize the minimum freq. deviation */ + frq_dev_min = frq_dev; + + /* recognize the no. of time quantas */ + tq_no_min_dev = *tq_no; + } + } + } + +/* return the optimized prescaler value */ + *tq_no = tq_no_min_dev; + return (uint8_t)(can_clock_frq/(tq_no_min_dev * can_bit_rate)); +} /* * MPC5x00 MSCAN set up the bit timing */ -void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *mscan) +void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *mscan, uint32_t can_bit_rate, uint32_t can_clock_frq) { uint32_t prescale_val = 0; - uint32_t tq_num; - uint32_t sync_seg,tseg1,tseg2; - - if(IPB_CLOCK%(CAN_BIT_RATE * CAN_MAX_NO_OF_TQ)) - prescale_val = (IPB_CLOCK/(CAN_BIT_RATE * (CAN_MAX_NO_OF_TQ*2/3))) + 1; - else - prescale_val = IPB_CLOCK/(CAN_BIT_RATE* (CAN_MAX_NO_OF_TQ*2/3)); - - tq_num = ((IPB_CLOCK/prescale_val)+CAN_BIT_RATE/2)/CAN_BIT_RATE; - /* - * XXX: make this table controlled according to MPC5200UM/Rev.3,Table 19-34 - */ - sync_seg = 2; - tseg2 = (tq_num-sync_seg)/6; - tseg1 = tq_num - sync_seg - tseg2; + uint8_t tq_no, tseg_1, tseg_2, sseg; + + /* get optimized prescaler value */ + prescale_val = prescaler_calculation(can_bit_rate, can_clock_frq, &tq_no); + + /* get time segment length from time segment table */ + tseg_1 = can_time_segment_table[tq_no - MIN_NO_OF_TQ][TSEG_1]; + tseg_2 = can_time_segment_table[tq_no - MIN_NO_OF_TQ][TSEG_2]; + sseg = can_time_segment_table[tq_no - MIN_NO_OF_TQ][SJW]; /* Bus Timing Register 0 MSCAN_A/_B ------------------------------*/ /* [07]:SJW1 1 : Synchronization jump width, Bit1 */ @@ -569,7 +784,7 @@ void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *msca /* [02]:BRP2 1 : Baud Rate Prescaler, Bit 2 */ /* [01]:BRP1 0 : Baud Rate Prescaler, Bit 1 */ /* [00]:BRP0 1 : Baud Rate Prescaler, Bit 0 */ - mscan->btr0 |= (BTR0_SJW(sync_seg-1) | BTR0_BRP(prescale_val - 1)); + mscan->btr0 = (BTR0_SJW(sseg-1) | BTR0_BRP(prescale_val-1)); /* Bus Timing Register 1 MSCAN_A/_B ------------------------------*/ /* [07]:SAMP 0 : One Sample per bit */ @@ -581,8 +796,7 @@ void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *msca /* [02]:TSEG12 1 : Time Segment 1, Bit 2 */ /* [01]:TSEG11 1 : Time Segment 1, Bit 1 */ /* [00]:TSEG10 0 : Time Segment 1, Bit 0 */ - mscan->btr1 &= ~(BTR1_SAMP); - mscan->btr1 |= (BTR1_TSEG_22_20(tseg2-1) | BTR1_TSEG_13_10(tseg1-1)); + mscan->btr1 = (BTR1_TSEG_22_20(tseg_2-1) | BTR1_TSEG_13_10(tseg_1-1)); return; @@ -594,7 +808,10 @@ void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *msca */ void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *mscan) { - mpc5200_mscan_perform_bit_time_settings(mscan); + + /* perform all can bit time settings */ + mpc5200_mscan_perform_bit_time_settings(mscan,CAN_BIT_RATE,IPB_CLOCK); + /* Control Register 1 --------------------------------------------*/ /* [07]:CANE 0 : MSCAN Module is disabled */ /* [06]:CLKSRC 0 : Clock Source -> IPB_CLOCK (bsp.h) */ @@ -634,25 +851,15 @@ void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *msc mscan->idac &= ~(IDAC_IDAM1); mscan->idac |= (IDAC_IDAM0); - /* initialize rx filter masks: only accept exact matches */ - mscan->idmr0 = 0x00; - mscan->idmr1 = 0x00; - mscan->idmr2 = 0x00; - mscan->idmr3 = 0x00; - mscan->idmr4 = 0x00; - mscan->idmr5 = 0x00; - mscan->idmr6 = 0x00; - mscan->idmr7 = 0x00; - - /* initialize rx filters: set to illegal values, so no matches occure */ - mscan->idar0 = 0xff; - mscan->idar1 = 0xff; - mscan->idar2 = 0xff; - mscan->idar3 = 0xff; - mscan->idar4 = 0xff; - mscan->idar5 = 0xff; - mscan->idar6 = 0xff; - mscan->idar7 = 0xff; + /* initialize rx filter masks (16 bit) */ + mscan->idmr0 = SET_IDMR0(0x07FF); + mscan->idmr1 = SET_IDMR1(0x07FF); + mscan->idmr2 = SET_IDMR2(0x07FF); + mscan->idmr3 = SET_IDMR3(0x07FF); + mscan->idmr4 = SET_IDMR4(0x07FF); + mscan->idmr5 = SET_IDMR5(0x07FF); + mscan->idmr6 = SET_IDMR6(0x07FF); + mscan->idmr7 = SET_IDMR7(0x07FF); /* Control Register 1 --------------------------------------------*/ /* [07]:CANE 0->1 : MSCAN Module is enabled */ @@ -719,36 +926,44 @@ rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number minor, uint8_ switch(mode) { + case MSCAN_INIT_NORMAL_MODE: + /* if not already set enter init mode */ + mpc5200_mscan_enter_init_mode(mscan); + /* perform initialization which has to be done in init mode */ + mpc5200_mscan_perform_init_mode_settings(mscan); + break; + case MSCAN_NORMAL_MODE: /* if not already set enter init mode */ mpc5200_mscan_enter_init_mode(mscan); if((chan->mode) == MSCAN_INITIALIZED_MODE) + { + /* perform initialization which has to be done in init mode */ mpc5200_mscan_perform_init_mode_settings(mscan); - else + } + + if((chan->mode) == MSCAN_SLEEP_MODE) + { + /* exit sleep mode */ mpc5200_mscan_exit_sleep_mode(mscan); + } - /* exit init mode */ + /* exit init mode */ mpc5200_mscan_exit_init_mode(mscan); /* enable ints. */ mpc5200_mscan_int_enable(mscan); /* wait for bus sync. */ mpc5200_mscan_wait_sync(mscan); - return RTEMS_SUCCESSFUL; break; case MSCAN_SLEEP_MODE: - /* enable ints. */ + /* disable ints. */ mpc5200_mscan_int_disable(mscan); - /* if not already set enter init mode */ - mpc5200_mscan_enter_init_mode(mscan); /* exit sleep mode */ mpc5200_mscan_enter_sleep_mode(mscan); - /* exit init mode */ - mpc5200_mscan_exit_init_mode(mscan); - return RTEMS_SUCCESSFUL; break; default: @@ -773,26 +988,55 @@ rtems_status_code mscan_channel_initialize(rtems_device_major_number major, rtem rtems_status_code status; struct mscan_channel_info *chan = &chan_info[minor]; + /* set registers according to MSCAN channel information */ switch(minor) { case MSCAN_A: chan->rx_qname = rtems_build_name ('C', 'N', 'A', 'Q'); + chan->tx_rb_sname = rtems_build_name ('C', 'N', 'A', 'S'); /* register RTEMS device names for MSCAN A */ - if((status = rtems_io_register_name (MSCAN_A_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL) + if((status = rtems_io_register_name (MSCAN_A_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL) + return status; + + /* register RTEMS device names for MSCAN 0 */ + if((status = rtems_io_register_name (MSCAN_0_DEV_NAME, major, MSCAN_A)) != RTEMS_SUCCESSFUL) return status; + /* allocate the space for MSCAN A tx ring buffer */ + if(((chan->tx_ring_buf.buf_ptr) = malloc(sizeof(struct can_message)*(NO_OF_MSCAN_TX_BUFF+1))) != NULL) + { + chan->tx_ring_buf.head_ptr = chan->tx_ring_buf.tail_ptr = chan->tx_ring_buf.buf_ptr; + } + else + { + return RTEMS_UNSATISFIED; + } break; case MSCAN_B: chan->rx_qname = rtems_build_name ('C', 'N', 'B', 'Q'); + chan->tx_rb_sname = rtems_build_name ('C', 'N', 'B', 'S'); /* register RTEMS device names for MSCAN B */ if((status = rtems_io_register_name (MSCAN_B_DEV_NAME, major, MSCAN_B)) != RTEMS_SUCCESSFUL) return status; + /* register RTEMS device names for MSCAN 1 */ + if((status = rtems_io_register_name (MSCAN_1_DEV_NAME, major, MSCAN_B)) != RTEMS_SUCCESSFUL) + return status; + + /* allocate the space for MSCAN B tx ring buffer */ + if(((chan->tx_ring_buf.buf_ptr) = malloc(sizeof(struct can_message)*(NO_OF_MSCAN_TX_BUFF+1))) != NULL) + { + chan->tx_ring_buf.head_ptr = chan->tx_ring_buf.tail_ptr = chan->tx_ring_buf.buf_ptr; + } + else + { + return RTEMS_UNSATISFIED; + } break; default: @@ -800,27 +1044,30 @@ rtems_status_code mscan_channel_initialize(rtems_device_major_number major, rtem break; } - /* create RTEMS rx message queue for MSCAN A */ - if((status = rtems_message_queue_create(chan->rx_qname, - (uint32_t) NO_OF_MSCAN_A_RX_BUFF, - (uint32_t) MSCAN_MESSAGE_SIZE(sizeof(struct can_message)), - (rtems_attribute) RTEMS_LOCAL | RTEMS_FIFO, - (rtems_id *)&(chan->rx_qid))) - != RTEMS_SUCCESSFUL) - { - return status; - - } - - /* Set up interrupts MSCAN A */ + /* create RTEMS rx message queue */ + status = rtems_message_queue_create(chan->rx_qname, + (uint32_t) NO_OF_MSCAN_RX_BUFF, + (uint32_t) MSCAN_MESSAGE_SIZE(sizeof(struct can_message)), + (rtems_attribute) RTEMS_LOCAL | RTEMS_FIFO, + (rtems_id *)&(chan->rx_qid)); + + /* create counting RTEMS tx ring buffer semaphore */ + status = rtems_semaphore_create(chan->tx_rb_sname, + (uint32_t)(NO_OF_MSCAN_TX_BUFF), + RTEMS_COUNTING_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL, + (rtems_task_priority)0, + (rtems_id *)&(chan->tx_rb_sid)); + + /* Set up interrupts */ if(!BSP_install_rtems_irq_handler(&(mpc5200_mscan_irq_data[minor]))) rtems_panic("Can't attach MPC5x00 MSCAN interrupt handler %d\n", minor); /* basic setup for channel info. struct. */ - chan->regs = (struct mpc5200_mscan *)&(mpc5200.mscan[minor]); - chan->int_rx_err = 0; - chan->id_extended = FALSE; - chan->mode = MSCAN_INITIALIZED_MODE; + chan->regs = (struct mpc5200_mscan *)&(mpc5200.mscan[minor]); + chan->int_rx_err = 0; + chan->id_extended = FALSE; + chan->mode = MSCAN_INITIALIZED_MODE; + chan->tx_buf_no = NO_OF_MSCAN_TX_BUFF; return status; @@ -844,10 +1091,10 @@ rtems_device_driver mscan_initialize(rtems_device_major_number major, if((status = mscan_channel_initialize(major,MSCAN_B)) != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred(status); - if((status = mpc5200_mscan_set_mode(MSCAN_A, MSCAN_NORMAL_MODE)) != RTEMS_SUCCESSFUL) + if((status = mpc5200_mscan_set_mode(MSCAN_A, MSCAN_INIT_NORMAL_MODE)) != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred(status); - if((status = mpc5200_mscan_set_mode(MSCAN_B, MSCAN_NORMAL_MODE)) != RTEMS_SUCCESSFUL) + if((status = mpc5200_mscan_set_mode(MSCAN_B, MSCAN_INIT_NORMAL_MODE)) != RTEMS_SUCCESSFUL) rtems_fatal_error_occurred(status); return status; @@ -863,7 +1110,7 @@ rtems_device_driver mscan_open( rtems_device_major_number major, void * arg ) { - rtems_status_code status; + rtems_status_code status = RTEMS_SUCCESSFUL; struct mscan_channel_info *chan = NULL; switch(minor) @@ -879,8 +1126,14 @@ rtems_device_driver mscan_open( rtems_device_major_number major, break; } - /* if not already set enter init mode */ - status = mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE); + + /* check mode */ + if((chan->mode) == MSCAN_SLEEP_MODE) + { + + /* if not already set enter init mode */ + status = mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE); + } return status; @@ -947,6 +1200,15 @@ rtems_device_driver mscan_read( rtems_device_major_number major, break; } + + /* end init mode if it is first read */ + if((chan->mode) == MSCAN_INIT_NORMAL_MODE) + { + + /* if not already set enter init mode */ + mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE); + } + if((status = rtems_message_queue_receive(chan->rx_qid, (void *)(rx_mess), (uint32_t *)&message_size, @@ -978,16 +1240,16 @@ rtems_device_driver mscan_write( rtems_device_major_number major, void * arg ) { - rtems_libio_rw_args_t *parms = (rtems_libio_rw_args_t *)arg; - struct mscan_tx_parms *tx_parms = (struct mscan_tx_parms *)(parms->buffer); - struct can_message *tx_mess = (struct can_message *)(tx_parms->tx_mess); - struct mscan_channel_info *chan = NULL; - mscan_handle *mscan_hdl = NULL; - volatile struct mpc5200_mscan *mscan = NULL; + rtems_status_code status; + rtems_libio_rw_args_t *parms = (rtems_libio_rw_args_t *)arg; + struct mscan_tx_parms *tx_parms = (struct mscan_tx_parms *)(parms->buffer); + struct can_message *tx_mess = (struct can_message *)(tx_parms->tx_mess); + struct mscan_channel_info *chan = NULL; + mscan_handle *mscan_hdl = NULL; + volatile struct mpc5200_mscan *mscan = NULL; switch(minor) { - case MSCAN_A: case MSCAN_B: chan = &chan_info[minor]; @@ -1000,118 +1262,39 @@ rtems_device_driver mscan_write( rtems_device_major_number major, break; } - /* select one free tx buffer (TOUCAN not registered) */ - if((mscan_hdl->toucan_callback) == NULL) - { - - if(mscan->tflg & MSCAN_TX_BUFF2) - mscan->bsel = MSCAN_TX_BUFF2; - - if(mscan->tflg & MSCAN_TX_BUFF1) - mscan->bsel = MSCAN_TX_BUFF1; - - if(mscan->tflg & MSCAN_TX_BUFF0) - mscan->bsel = MSCAN_TX_BUFF0; - } - else + /* end init mode if it is first write */ + if((chan->mode) == MSCAN_INIT_NORMAL_MODE) { - /* select a specific, preconfigured tx buffer (TOUCAN registered) */ - switch(tx_parms->tx_id) - { - - case 0: - if(mscan->tflg & MSCAN_TX_BUFF0) - mscan->bsel = MSCAN_TX_BUFF0; - break; - - case 1: - if(mscan->tflg & MSCAN_TX_BUFF1) - mscan->bsel = MSCAN_TX_BUFF1; - break; - - case 2: - if(mscan->tflg & MSCAN_TX_BUFF2) - mscan->bsel = MSCAN_TX_BUFF2; - break; - - default: - break; - - } - + /* if not already set enter init mode */ + mpc5200_mscan_set_mode(minor, MSCAN_NORMAL_MODE); } - /* if no tx buffer is available, teminate the write request */ - if(!(mscan->bsel)) - { - - parms->bytes_moved = 0; - return RTEMS_UNSATISFIED; - - } + /* preset moved bytes */ + parms->bytes_moved = 0; - /* prepare tx id and dlc (TOUCAN not initialized) */ - if((mscan_hdl->toucan_callback) == NULL) + /* obtain counting semaphore of tx ring buffer */ + if((status = rtems_semaphore_obtain((rtems_id)(chan->tx_rb_sid), + RTEMS_NO_WAIT, + (rtems_interval)0)) + == RTEMS_SUCCESSFUL) { - /* check for tx length */ - if((tx_mess->mess_len) & 0x000F) - { + /* append the TOUCAN tx_id to the mess. due to interrupt handling */ + tx_mess->toucan_tx_id = tx_parms->tx_id; - /* set tx id */ - mscan->txidr0 = SET_IDR0(tx_mess->mess_id); - mscan->txidr1 = SET_IDR1(tx_mess->mess_id); - mscan->txidr2 = 0; - mscan->txidr3 = 0; + /* fill the tx ring buffer with the message */ + fill_tx_buffer(chan, tx_mess); - /* insert dlc into mscan register */ - mscan->txdlr = (uint8_t)((tx_mess->mess_len) & 0x000F); - - } - else - { + /* enable message buffer specific interrupt */ + mscan->tier |= (TIER_TXEI0 | TIER_TXEI1 | TIER_TXEI2); - parms->bytes_moved = 0; - return RTEMS_UNSATISFIED; - - } - - } - - /* copy tx data to MSCAN registers */ - switch(mscan->txdlr) - { - - case 8: - mscan->txdsr7 = tx_mess->mess_data[7]; - case 7: - mscan->txdsr6 = tx_mess->mess_data[6]; - case 6: - mscan->txdsr5 = tx_mess->mess_data[5]; - case 5: - mscan->txdsr4 = tx_mess->mess_data[4]; - case 4: - mscan->txdsr3 = tx_mess->mess_data[3]; - case 3: - mscan->txdsr2 = tx_mess->mess_data[2]; - case 2: - mscan->txdsr1 = tx_mess->mess_data[1]; - case 1: - mscan->txdsr0 = tx_mess->mess_data[0]; - break; - default: - break; + /* calculate moved bytes */ + parms->bytes_moved = (tx_mess->mess_len) & 0x000F; } - /* enable message buffer specific interrupt */ - mscan->tier |= mscan->bsel; - - /* start transfer */ - mscan->tflg = mscan->bsel; - - return RTEMS_SUCCESSFUL; + return status; } @@ -1124,12 +1307,14 @@ rtems_device_driver mscan_control( rtems_device_major_number major, void * arg ) { + rtems_status_code status; uint16_t tx_id; - rtems_libio_ioctl_args_t *parms = (rtems_libio_ioctl_args_t *)arg; - struct mscan_ctrl_parms *ctrl_parms = (struct mscan_ctrl_parms *)(parms->buffer); - struct mscan_channel_info *chan = NULL; - mscan_handle *mscan_hdl = NULL; - volatile struct mpc5200_mscan *mscan = NULL; + rtems_libio_ioctl_args_t *parms = (rtems_libio_ioctl_args_t *)arg; + struct mscan_ctrl_parms *ctrl_parms = (struct mscan_ctrl_parms *)(parms->buffer); + struct mscan_channel_info *chan = NULL; + mscan_handle *mscan_hdl = NULL; + volatile struct mpc5200_mscan *mscan = NULL; + uint8_t tx_buf_count = 0; switch(minor) { @@ -1239,23 +1424,23 @@ rtems_device_driver mscan_control( rtems_device_major_number major, { case RX_BUFFER_0: - mscan->idmr0 = SET_IDR0(ctrl_parms->ctrl_id_mask); - mscan->idmr1 = SET_IDR1(ctrl_parms->ctrl_id_mask); + mscan->idmr0 = SET_IDMR0(ctrl_parms->ctrl_id_mask); + mscan->idmr1 = SET_IDMR1(ctrl_parms->ctrl_id_mask); break; case RX_BUFFER_1: - mscan->idmr2 = SET_IDR2(ctrl_parms->ctrl_id_mask); - mscan->idmr3 = SET_IDR3(ctrl_parms->ctrl_id_mask); + mscan->idmr2 = SET_IDMR2(ctrl_parms->ctrl_id_mask); + mscan->idmr3 = SET_IDMR3(ctrl_parms->ctrl_id_mask); break; case RX_BUFFER_2: - mscan->idmr4 = SET_IDR4(ctrl_parms->ctrl_id_mask); - mscan->idmr5 = SET_IDR5(ctrl_parms->ctrl_id_mask); + mscan->idmr4 = SET_IDMR4(ctrl_parms->ctrl_id_mask); + mscan->idmr5 = SET_IDMR5(ctrl_parms->ctrl_id_mask); break; case RX_BUFFER_3: - mscan->idmr6 = SET_IDR6(ctrl_parms->ctrl_id_mask); - mscan->idmr7 = SET_IDR7(ctrl_parms->ctrl_id_mask); + mscan->idmr6 = SET_IDMR6(ctrl_parms->ctrl_id_mask); + mscan->idmr7 = SET_IDMR7(ctrl_parms->ctrl_id_mask); break; default: @@ -1281,19 +1466,19 @@ rtems_device_driver mscan_control( rtems_device_major_number major, { case RX_BUFFER_0: - ctrl_parms->ctrl_id_mask = GET_IDR0(mscan->idmr0) | GET_IDR1(mscan->idmr1); + ctrl_parms->ctrl_id_mask = GET_IDMR0(mscan->idmr0) | GET_IDMR1(mscan->idmr1); break; case RX_BUFFER_1: - ctrl_parms->ctrl_id_mask = GET_IDR2(mscan->idmr2) | GET_IDR3(mscan->idmr3); + ctrl_parms->ctrl_id_mask = GET_IDMR2(mscan->idmr2) | GET_IDMR3(mscan->idmr3); break; case RX_BUFFER_2: - ctrl_parms->ctrl_id_mask = GET_IDR4(mscan->idmr4) | GET_IDR5(mscan->idmr5); + ctrl_parms->ctrl_id_mask = GET_IDMR4(mscan->idmr4) | GET_IDMR5(mscan->idmr5); break; case RX_BUFFER_3: - ctrl_parms->ctrl_id_mask = GET_IDR6(mscan->idmr6) | GET_IDR7(mscan->idmr7); + ctrl_parms->ctrl_id_mask = GET_IDMR6(mscan->idmr6) | GET_IDMR7(mscan->idmr7); break; default: @@ -1339,6 +1524,98 @@ rtems_device_driver mscan_control( rtems_device_major_number major, break; + /* set can bitrate */ + case MSCAN_SET_BAUDRATE: + + /* check bitrate settings */ + if(((ctrl_parms->ctrl_can_bitrate) >= CAN_BIT_RATE_MIN) && ((ctrl_parms->ctrl_can_bitrate) <= CAN_BIT_RATE_MAX)) { + + /* enter init mode */ + mpc5200_mscan_enter_init_mode(mscan); + + /* perform all can bit time settings */ + mpc5200_mscan_perform_bit_time_settings(mscan,(uint32_t)(ctrl_parms->ctrl_can_bitrate),IPB_CLOCK); + + /* exit init mode and perform further initialization which is required in the normal mode */ + mpc5200_mscan_exit_init_mode(mscan); + + /* enable ints. */ + mpc5200_mscan_int_enable(mscan); + + /* wait for bus sync. */ + mpc5200_mscan_wait_sync(mscan); + + return RTEMS_SUCCESSFUL; + } + else { + + return RTEMS_UNSATISFIED; + } + + break; + + case SET_TX_BUF_NO: + + /* check for different settings of tx ring buffer */ + if((tx_buf_count = chan->tx_buf_no) != (uint8_t)(ctrl_parms->ctrl_tx_buf_no)) + { + + /* preset the channel specific no of messages in the tx ring buffer */ + tx_buf_count = chan->tx_buf_no; + + /* try to obtain all of the tx ring buffers */ + while(tx_buf_count > 0) + { + + /* obtain semaphore of all tx ring buffers */ + if((status = rtems_semaphore_obtain((rtems_id)(chan->tx_rb_sid), + RTEMS_WAIT, + (rtems_interval)10)) + == RTEMS_SUCCESSFUL) + { + + tx_buf_count--; + + } + + } + + /* free the former tx ring buffer */ + free((void *)chan->tx_ring_buf.buf_ptr); + + /* allocate the tx ring buffer with new size */ + if(((chan->tx_ring_buf.buf_ptr) = malloc(sizeof(struct can_message)*((uint8_t)(ctrl_parms->ctrl_tx_buf_no)+1))) != NULL) + { + chan->tx_ring_buf.head_ptr = chan->tx_ring_buf.tail_ptr = chan->tx_ring_buf.buf_ptr; + } + else + { + return RTEMS_UNSATISFIED; + } + + /* set the new amount of tx buffers */ + chan->tx_buf_no = (uint8_t)(ctrl_parms->ctrl_tx_buf_no); + + /* release the semaphore of all tx ring buffers */ + while(tx_buf_count < chan->tx_buf_no) + { + + /* obtain semaphore of all tx ring buffers */ + rtems_semaphore_release((rtems_id)(chan->tx_rb_sid)); + + tx_buf_count++; + + } + + } + else + { + + return RTEMS_SUCCESSFUL; + + } + break; + default: break; diff --git a/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h index 7b70a55d25..8e0eef6a36 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h +++ b/c/src/lib/libbsp/powerpc/gen5200/mscan/mscan.h @@ -26,6 +26,11 @@ extern "C" { #endif +#define MIN_NO_OF_TQ 7 +#define NO_OF_TABLE_ENTRIES 4 +#define TSEG_1 1 +#define TSEG_2 2 +#define SJW 3 #define MSCAN_MAX_DATA_BYTES 8 #define MSCAN_RX_BUFF_NUM 4 @@ -34,13 +39,19 @@ extern "C" { #define MSCAN_A_DEV_NAME "/dev/mscana" #define MSCAN_B_DEV_NAME "/dev/mscanb" +#define MSCAN_0_DEV_NAME "/dev/mscan0" +#define MSCAN_1_DEV_NAME "/dev/mscan1" #define MSCAN_A 0 #define MSCAN_B 1 -#define MSCAN_INITIALIZED_MODE 0 -#define MSCAN_INIT_NORMAL_MODE 1 -#define MSCAN_NORMAL_MODE 2 -#define MSCAN_SLEEP_MODE 4 +#define MSCAN_NON_INITIALIZED_MODE 0 +#define MSCAN_INITIALIZED_MODE 1 +#define MSCAN_INIT_NORMAL_MODE 2 +#define MSCAN_NORMAL_MODE 4 +#define MSCAN_SLEEP_MODE 8 + +#define CAN_BIT_RATE_MAX 1000000 +#define CAN_BIT_RATE_MIN 100000 #define CAN_BIT_RATE 100000 #define CAN_MAX_NO_OF_TQ 25 @@ -54,7 +65,10 @@ extern "C" { #define MSCAN_GET_RX_ID_MASK 4 #define MSCAN_SET_TX_ID 5 #define MSCAN_GET_TX_ID 6 + #define TOUCAN_MSCAN_INIT 7 +#define MSCAN_SET_BAUDRATE 8 +#define SET_TX_BUF_NO 9 #define MSCAN_RX_BUFF_NOACTIVE (0 << 4) #define MSCAN_RX_BUFF_EMPTY (1 << 6) @@ -62,8 +76,7 @@ extern "C" { #define MSCAN_RX_BUFF_OVERRUN ((MSCAN_RX_BUFF_EMPTY) | (MSCAN_RX_BUFF_FULL)) #define MSCAN_RX_BUFF_BUSY (1 << 4) -#define MSCAN_A_MBUFF_MASK 0x07 -#define MSCAN_B_MBUFF_MASK 0x07 +#define MSCAN_MBUFF_MASK 0x07 #define MSCAN_TX_BUFF0 (1 << 0) #define MSCAN_TX_BUFF1 (1 << 1) @@ -175,7 +188,7 @@ extern "C" { #define SET_IDR7(u16) SET_IDR1(u16) #define GET_IDR0(u16) ((uint16_t) ((u16) << 3)) -#define GET_IDR1(u16) ((uint16_t)((u16) >> 5)) +#define GET_IDR1(u16) ((uint16_t)(((u16) >> 5)&0x0007)) #define GET_IDR2(u16) GET_IDR0(u16) #define GET_IDR3(u16) GET_IDR1(u16) @@ -186,8 +199,31 @@ extern "C" { #define GET_IDR6(u16) GET_IDR0(u16) #define GET_IDR7(u16) GET_IDR1(u16) -#define NO_OF_MSCAN_A_RX_BUFF 20 -#define NO_OF_MSCAN_B_RX_BUFF 20 +#define SET_IDMR0(u16) ((uint8_t)((u16) >> 3)) +#define SET_IDMR1(u16) ((uint8_t)((((u16) & 0x0007) << 5))|0x001F) + +#define SET_IDMR2(u16) SET_IDMR0(u16) +#define SET_IDMR3(u16) SET_IDMR1(u16) + +#define SET_IDMR4(u16) SET_IDMR0(u16) +#define SET_IDMR5(u16) SET_IDMR1(u16) + +#define SET_IDMR6(u16) SET_IDMR0(u16) +#define SET_IDMR7(u16) SET_IDMR1(u16) + +#define GET_IDMR0(u16) ((uint16_t) ((u16) << 3)) +#define GET_IDMR1(u16) ((uint16_t)(((u16) >> 5)&0x0007)) + +#define GET_IDMR2(u16) GET_IDMR0(u16) +#define GET_IDMR3(u16) GET_IDMR1(u16) + +#define GET_IDMR4(u16) GET_IDMR0(u16) +#define GET_IDMR5(u16) GET_IDMR1(u16) + +#define GET_IDMR6(u16) GET_IDMR0(u16) +#define GET_IDMR7(u16) GET_IDMR1(u16) + +#define NO_OF_MSCAN_RX_BUFF 20 #define MSCAN_MESSAGE_SIZE(size) (((size)%CPU_ALIGNMENT) ? (((size) + CPU_ALIGNMENT)-((size) + CPU_ALIGNMENT)%CPU_ALIGNMENT) : (size)) #define TX_BUFFER_0 0 @@ -199,6 +235,11 @@ extern "C" { #define RX_BUFFER_2 2 #define RX_BUFFER_3 3 +#define NO_OF_MSCAN_TX_BUFF 20 +#define RING_BUFFER_EMPTY(rbuff) ((((rbuff)->head) == ((rbuff)->tail)) ? TRUE : FALSE) +#define RING_BUFFER_FULL(rbuff) ((((rbuff)->head) == ((rbuff)->tail)) ? TRUE : FALSE) + + typedef struct _mscan_handle { uint8_t mscan_channel; @@ -212,22 +253,33 @@ struct can_message uint16_t mess_time_stamp; uint8_t mess_data[MSCAN_MAX_DATA_BYTES]; uint8_t mess_len; + uint32_t toucan_tx_id; }; +volatile struct ring_buf + { + volatile struct can_message *buf_ptr; + volatile struct can_message *head_ptr; + volatile struct can_message *tail_ptr; + }; + struct mpc5200_rx_cntrl { struct can_message can_rx_message[MSCAN_RX_BUFF_NUM]; }; - struct mscan_channel_info { volatile struct mpc5200_mscan *regs; uint32_t int_rx_err; - rtems_id rx_qid; + rtems_id rx_qid; uint32_t rx_qname; + rtems_id tx_rb_sid; + uint32_t tx_rb_sname; uint8_t id_extended; uint8_t mode; + uint8_t tx_buf_no; + volatile struct ring_buf tx_ring_buf; }; struct mscan_rx_parms @@ -248,6 +300,8 @@ struct mscan_ctrl_parms uint32_t ctrl_id; uint32_t ctrl_id_mask; uint8_t ctrl_reg_no; + uint8_t ctrl_tx_buf_no; + uint32_t ctrl_can_bitrate; void (*toucan_cb_fnc)(int16_t); }; @@ -304,6 +358,8 @@ void mpc5200_mscan_perform_init_mode_settings(volatile struct mpc5200_mscan *); void mpc5200_mscan_perform_normal_mode_settings(volatile struct mpc5200_mscan *); rtems_status_code mpc5200_mscan_set_mode(rtems_device_minor_number, uint8_t); rtems_status_code mscan_channel_initialize(rtems_device_major_number, rtems_device_minor_number); +uint8_t prescaler_calculation(uint32_t, uint32_t, uint8_t *); +void mpc5200_mscan_perform_bit_time_settings(volatile struct mpc5200_mscan *, uint32_t, uint32_t); #ifdef __cplusplus diff --git a/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c b/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c index 3a5dada349..e105cff4ca 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c +++ b/c/src/lib/libbsp/powerpc/gen5200/network_5200/network.c @@ -78,8 +78,8 @@ #define SDMA_BD_TFD 0x08000000 /*< Transmit Frame Done */ #define SDMA_BD_INT 0x04000000 /*< Interrupt on frame done */ -#define SDMA_BD_RX_NUM 32 /* Number of receive buffer descriptors */ -#define SDMA_BD_TX_NUM 48 /* Number of transmit buffer descriptors */ +#define SDMA_BD_RX_NUM 64 /* Number of receive buffer descriptors */ +#define SDMA_BD_TX_NUM 64 /* Number of transmit buffer descriptors */ #define SET_BD_STATUS(bd, stat) { \ (bd)->Status &= 0x0000ffff; \ @@ -127,6 +127,7 @@ static TaskId txTaskId; /* SDMA TX task ID */ * This must *not* be the same event used by the TCP/IP task synchronization. */ #define INTERRUPT_EVENT RTEMS_EVENT_1 +#define FATAL_INT_EVENT RTEMS_EVENT_3 /* * RTEMS event used to start transmit daemon. @@ -197,6 +198,10 @@ typedef struct mpc5200_buffer_desc_ } mpc5200_buffer_desc_t; +#define FEC_INTR_MASK_USED \ +(FEC_INTR_LCEN |FEC_INTR_CRLEN |\ + FEC_INTR_XFUNEN|FEC_INTR_XFERREN|FEC_INTR_RFERREN) + /* * Device data */ @@ -235,11 +240,10 @@ struct mpc5200_enet_struct { unsigned long txRetryLimit; }; -uint8_t tx_shadow_buffer[TX_BUF_COUNT][(ETHER_MAX_LEN+3)&~3]; - static struct mpc5200_enet_struct enet_driver[NIFACES]; extern int taskTable; +static void mpc5200_fec_restart(struct mpc5200_enet_struct *sc); @@ -279,6 +283,30 @@ static void mpc5200_fec_rx_bd_init(struct mpc5200_enet_struct *sc) { } } +/* + * Function: mpc5200_fec_rx_bd_cleanup + * + * Description: put all mbufs pending in rx BDs back to buffer pool + * + * Returns: void + * + */ +static void mpc5200_fec_rx_bd_cleanup(struct mpc5200_enet_struct *sc) { + int rxBdIndex; + struct mbuf *m,*n; + + /* + * Drain RX buffer descriptor ring. + */ + for( rxBdIndex = 0; rxBdIndex < sc->rxBdCount; rxBdIndex++ ) { + n = sc->rxMbuf[rxBdIndex]; + while (n != NULL) { + m = n; + MFREE(m,n); + } + } +} + /* * Function: MPC5200_eth_addr_filter_set * @@ -492,6 +520,7 @@ static int mpc5200_eth_mii_write(struct mpc5200_enet_struct *sc, unsigned char p * */ static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) { + volatile int delay; /* * Clear FIFO status registers */ @@ -499,8 +528,12 @@ static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) { mpc5200.tfifo_status &= FEC_FIFO_STAT_ERROR; /* - * + * reset the FIFOs */ + mpc5200.reset_cntrl = 0x03000000; + + for (delay = 0;delay < 16*4;delay++) {}; + mpc5200.reset_cntrl = 0x01000000; /* @@ -511,7 +544,7 @@ static int mpc5200_fec_reset(struct mpc5200_enet_struct *sc) { /* * wait at least 16 clock cycles */ - rtems_task_wake_after(2); + for (delay = 0;delay < 16*4;delay++) {}; return TRUE; } @@ -554,9 +587,9 @@ void mpc5200_fec_off(struct mpc5200_enet_struct *sc) #endif /* ETH_DEBUG */ /* - * mask FEC chip interrupts + * block FEC chip interrupts */ - mpc5200.imask = FEC_INTR_MASK_ALL; + mpc5200.imask = 0; /* * issue graceful stop command to the FEC transmitter if necessary @@ -565,6 +598,7 @@ void mpc5200_fec_off(struct mpc5200_enet_struct *sc) /* * wait for graceful stop to register + * FIXME: add rtems_task_wake_after here, if it takes to long */ while((counter--) && (!(mpc5200.ievent & FEC_INTR_GRA))); @@ -584,19 +618,56 @@ void mpc5200_fec_off(struct mpc5200_enet_struct *sc) */ mpc5200.ecntrl &= ~(FEC_ECNTRL_OE | FEC_ECNTRL_EN); - } + /* + * cleanup all buffers + */ + mpc5200_fec_rx_bd_cleanup(sc); + } /* - * MPC5200 SmartComm ethernet interrupt handler + * MPC5200 FEC interrupt handler */ -void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused) - { +void mpc5200_fec_irq_handler(rtems_irq_hdl_param handle) +{ + struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *) handle; volatile uint32_t ievent; ievent = mpc5200.ievent; + mpc5200.ievent = ievent; + /* + * check errors, update statistics + */ + if (ievent & FEC_INTR_LATE_COL) { + sc->txLateCollision++; + } + if (ievent & FEC_INTR_COL_RETRY) { + sc->txRetryLimit++; + } + if (ievent & FEC_INTR_XFIFO_UN) { + sc->txUnderrun++; + } + if (ievent & FEC_INTR_XFIFO_ERR) { + sc->txUnderrun++; + } + if (ievent & FEC_INTR_RFIFO_ERR) { + sc->rxOverrun++; + } + /* + * fatal error ocurred? + */ + if (ievent & (FEC_INTR_XFIFO_ERR | FEC_INTR_RFIFO_ERR)) { + mpc5200.imask &= ~(FEC_INTR_XFERREN | FEC_INTR_RFERREN); + rtems_event_send(enet_driver[0].rxDaemonTid, FATAL_INT_EVENT); + } +} +/* + * MPC5200 SmartComm ethernet interrupt handler + */ +void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused) + { /* Frame received? */ if(GET_SDMA_PENDINGBIT(FEC_RECV_TASK_NO)) { @@ -617,11 +688,6 @@ void mpc5200_smartcomm_rx_irq_handler(rtems_irq_hdl_param unused) */ void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused) { - volatile uint32_t ievent; - - ievent = mpc5200.ievent; - - /* Buffer transmitted or transmitter error? */ if(GET_SDMA_PENDINGBIT(FEC_XMIT_TASK_NO)) { @@ -652,7 +718,8 @@ void mpc5200_smartcomm_tx_irq_handler(rtems_irq_hdl_param unused) * Notes: * */ -static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc) +static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc, + boolean force) { struct mbuf *n; TaskBD1_t *bdRing = (TaskBD1_t *)TaskGetBDRing( txTaskId );; @@ -662,7 +729,7 @@ static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc) */ while ((sc->txBdActiveCount > 0) && - (bdRing[sc->txBdTail].Status == 0x0)) { + (force || (bdRing[sc->txBdTail].Status == 0x0))) { if (sc->txMbuf[sc->txBdTail] != NULL) { /* * NOTE: txMbuf can be NULL, if mbuf has been split into different BDs @@ -677,6 +744,37 @@ static void mpc5200_fec_retire_tbd(struct mpc5200_enet_struct *sc) } } + /* + * Function: mpc5200_fec_tx_bd_requeue + * + * Description: put buffers back to interface output queue + * + * Returns: void + * + * Notes: + * + */ +static void mpc5200_fec_tx_bd_requeue(struct mpc5200_enet_struct *sc) +{ + /* + * Clear already transmitted BDs first. Will not work calling same + * from fecExceptionHandler(TFINT). + */ + + while (sc->txBdActiveCount > 0) { + if (sc->txMbuf[sc->txBdHead] != NULL) { + /* + * NOTE: txMbuf can be NULL, if mbuf has been split into different BDs + */ + IF_PREPEND(&(sc->arpcom.ac_if.if_snd),sc->txMbuf[sc->txBdHead]); + sc->txMbuf[sc->txBdHead] = NULL; + } + sc->txBdActiveCount--; + if(--sc->txBdHead < 0) { + sc->txBdHead = sc->txBdCount-1; + } + } +} static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) { struct mpc5200_enet_struct *sc = ifp->if_softc; @@ -693,7 +791,7 @@ static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) { /* * Free up buffer descriptors */ - mpc5200_fec_retire_tbd(sc); + mpc5200_fec_retire_tbd(sc,FALSE); /* * Set up the transmit buffer descriptors. @@ -728,14 +826,14 @@ static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) { * last buffer descriptor in a frame can generate * an interrupt. */ - mpc5200_fec_retire_tbd(sc); + mpc5200_fec_retire_tbd(sc,FALSE); while((sc->txBdActiveCount + nAdded) == sc->txBdCount) { bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO); rtems_bsdnet_event_receive(INTERRUPT_EVENT, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &events); - mpc5200_fec_retire_tbd(sc); + mpc5200_fec_retire_tbd(sc,FALSE); } } @@ -768,10 +866,10 @@ static void mpc5200_fec_sendpacket(struct ifnet *ifp,struct mbuf *m) { status = ((m->m_next == NULL) ? TASK_BD_TFD | TASK_BD_INT : 0); - /* - * Don't set the READY flag till the - * whole packet has been readied. - */ + /* + * Don't set the READY flag till the + * whole packet has been readied. + */ if (firstBd != NULL) { status |= (uint32)SDMA_BD_MASK_READY; } @@ -821,11 +919,11 @@ void mpc5200_fec_txDaemon(void *arg) struct mbuf *m; rtems_event_set events; - for(;;) - { + for(;;) { /* * Wait for packet */ + bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO); rtems_bsdnet_event_receive(START_TRANSMIT_EVENT|INTERRUPT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, @@ -944,10 +1042,16 @@ static void mpc5200_fec_rxDaemon(void *arg){ */ bestcomm_glue_irq_enable(FEC_RECV_TASK_NO); - rtems_bsdnet_event_receive (INTERRUPT_EVENT, + rtems_bsdnet_event_receive (INTERRUPT_EVENT | FATAL_INT_EVENT, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &events); - + if (events & FATAL_INT_EVENT) { + /* + * fatal interrupt ocurred, so reinit fec and restart bestcomm tasks + */ + mpc5200_fec_restart(sc); + rxBdIndex = 0; + } } } @@ -965,8 +1069,6 @@ static void mpc5200_fec_rxDaemon(void *arg){ */ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc) { - int timeout; - unsigned short phyAddr = 0; /* * Reset mpc5200 FEC @@ -981,17 +1083,7 @@ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc) /* * Set interrupt mask register */ - mpc5200.imask = (FEC_INTR_HBEEN - | FEC_INTR_BREN - | FEC_INTR_BTEN - | FEC_INTR_GRAEN - | FEC_INTR_LATE_COL - | FEC_INTR_COL_RETRY - | FEC_INTR_XFIFO_UN - | FEC_INTR_XFIFO_ERR - | FEC_INTR_RFIFO_ERR - | FEC_INTR_TFINT - ); + mpc5200.imask = FEC_INTR_MASK_USED; /* * Set FEC-Lite receive control register (R_CNTRL) * frame length=1518, MII mode for 18-wire-transceiver @@ -1054,6 +1146,7 @@ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc) * enable CRC in finite state machine register */ mpc5200.xmit_fsm = FEC_FSM_CRC | FEC_FSM_ENFSM; + } /* * Initialize PHY(LXT971A): @@ -1075,7 +1168,16 @@ static void mpc5200_fec_initialize_hardware(struct mpc5200_enet_struct *sc) * Note: * The physical address is dependent on hardware configuration. * + * Returns: void + * + * Notes: + * */ +static void mpc5200_fec_initialize_phy(struct mpc5200_enet_struct *sc) + { + int timeout; + unsigned short phyAddr = 0; + /* * Reset PHY, then delay 300ns @@ -1180,14 +1282,14 @@ static void mpc5200_fec_tx_start(struct ifnet *ifp) /* * set up sdma tasks for ethernet */ -static void mpc5200_sdma_task_setup(void) { +static void mpc5200_sdma_task_setup(struct mpc5200_enet_struct *sc) { TaskSetupParamSet_t rxParam; /* RX task setup parameters */ TaskSetupParamSet_t txParam; /* TX task setup parameters */ /* * Setup the SDMA RX task. */ - rxParam.NumBD = SDMA_BD_RX_NUM; + rxParam.NumBD = sc->rxBdCount; rxParam.Size.MaxBuf = ETHER_MAX_LEN; rxParam.Initiator = 0; rxParam.StartAddrSrc = (uint32)&(mpc5200.rfifo_data); @@ -1201,7 +1303,7 @@ static void mpc5200_sdma_task_setup(void) { /* * Setup the TX task. */ - txParam.NumBD = SDMA_BD_TX_NUM; + txParam.NumBD = sc->txBdCount; txParam.Size.MaxBuf = ETHER_MAX_LEN; txParam.Initiator = 0; txParam.StartAddrSrc = (uint32)NULL; @@ -1215,6 +1317,23 @@ static void mpc5200_sdma_task_setup(void) { } +void mpc5200_fec_irq_on(const rtems_irq_connect_data* ptr) +{ + mpc5200.imask = FEC_INTR_MASK_USED; +} + + +int mpc5200_fec_irq_isOn(const rtems_irq_connect_data* ptr) +{ + return mpc5200.imask != 0; +} + + +void mpc5200_fec_irq_off(const rtems_irq_connect_data* ptr) +{ + mpc5200.imask = 0; +} + /* * Initialize and start the device @@ -1223,6 +1342,15 @@ static void mpc5200_fec_init(void *arg) { struct mpc5200_enet_struct *sc = (struct mpc5200_enet_struct *)arg; struct ifnet *ifp = &sc->arpcom.ac_if; + rtems_irq_connect_data fec_irq_data = { + BSP_SIU_IRQ_ETH, + mpc5200_fec_irq_handler, /* rtems_irq_hdl */ + (rtems_irq_hdl_param)sc, /* (rtems_irq_hdl_param) */ + mpc5200_fec_irq_on, /* (rtems_irq_enable) */ + mpc5200_fec_irq_off, /* (rtems_irq_disable) */ + mpc5200_fec_irq_isOn /* (rtems_irq_is_enabled) */ + }; + if(sc->txDaemonTid == 0) { @@ -1239,7 +1367,7 @@ static void mpc5200_fec_init(void *arg) bestcomm_glue_init(); - mpc5200_sdma_task_setup(); + mpc5200_sdma_task_setup(sc); /* * Set up interrupts @@ -1250,6 +1378,10 @@ static void mpc5200_fec_init(void *arg) bestcomm_glue_irq_install(FEC_XMIT_TASK_NO, mpc5200_smartcomm_tx_irq_handler, NULL); + if(!BSP_install_rtems_irq_handler (&fec_irq_data)) { + rtems_panic ("Can't attach MPC5x00 FEX interrupt handler\n"); + } + /* mpc5200_fec_tx_bd_init(sc); */ mpc5200_fec_rx_bd_init(sc); @@ -1257,6 +1389,10 @@ static void mpc5200_fec_init(void *arg) * reset and Set up mpc5200 FEC hardware */ mpc5200_fec_initialize_hardware(sc); + /* + * Set up the phy + */ + mpc5200_fec_initialize_phy(sc); /* * Set priority of different initiators */ @@ -1322,6 +1458,99 @@ static void enet_stats (struct mpc5200_enet_struct *sc) } +/* + * restart the driver, reinit the fec + * this function is responsible to reinitialize the FEC in case a fatal + * error has ocurred. This is needed, wen a RxFIFO Overrun or a TxFIFO underrun + * has ocurred. In these cases, the FEC is automatically disabled, and + * both FIFOs must be reset and the BestComm tasks must be restarted + * + * Note: the daemon tasks will continue to run + * (in fact this function will be called in the context of the rx daemon task) + */ +#define NEW_SDMA_SETUP + +static void mpc5200_fec_restart(struct mpc5200_enet_struct *sc) +{ + /* + * FIXME: bring Tx Daemon into idle state + */ +#ifdef NEW_SDMA_SETUP + /* + * cleanup remaining receive mbufs + */ + mpc5200_fec_rx_bd_cleanup(sc); +#endif + /* + * Stop SDMA tasks + */ + TaskStop( rxTaskId); + TaskStop( txTaskId); + /* + * FIXME: wait, until Tx Daemon is in idle state + */ + + /* + * Disable transmit / receive interrupts + */ + bestcomm_glue_irq_disable(FEC_XMIT_TASK_NO); + bestcomm_glue_irq_disable(FEC_RECV_TASK_NO); +#ifdef NEW_SDMA_SETUP + /* + * recycle pending tx buffers + * FIXME: try to extract pending Tx buffers + */ +#if 0 + mpc5200_fec_tx_bd_requeue(sc); +#else + mpc5200_fec_retire_tbd(sc,TRUE); +#endif +#endif + /* + * re-initialize the FEC hardware + */ + mpc5200_fec_initialize_hardware(sc); + +#ifdef NEW_SDMA_SETUP + /* + * completely reinitialize Bestcomm tasks + */ + mpc5200_sdma_task_setup(sc); + + /* + * reinit receive mbufs + */ + mpc5200_fec_rx_bd_init(sc); +#endif + /* + * Clear SmartDMA task interrupt pending bits. + */ + TaskIntClear( rxTaskId ); + + /* + * Enable the SmartDMA receive/transmit task. + */ + TaskStart( rxTaskId, 1, rxTaskId, 1 ); + TaskStart( txTaskId, 1, txTaskId, 1 ); + /* + * reenable rx/tx interrupts + */ + bestcomm_glue_irq_enable(FEC_XMIT_TASK_NO); + bestcomm_glue_irq_enable(FEC_RECV_TASK_NO); + /* + * (re-)init fec hardware + */ + mpc5200_fec_initialize_hardware(sc); + /* + * reenable fec FIFO error interrupts + */ + mpc5200.imask = FEC_INTR_MASK_USED; + /* + * Enable FEC-Lite controller + */ + mpc5200.ecntrl |= (FEC_ECNTRL_OE | FEC_ECNTRL_EN); +} + /* * Driver ioctl handler diff --git a/c/src/lib/libbsp/powerpc/gen5200/preinstall.am b/c/src/lib/libbsp/powerpc/gen5200/preinstall.am index 900011c2b1..2ec7b234a5 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/preinstall.am +++ b/c/src/lib/libbsp/powerpc/gen5200/preinstall.am @@ -77,9 +77,13 @@ $(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_LIB)/start.$(OBJEXT) TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT) -$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds -PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds +$(PROJECT_LIB)/linkcmds.brs5l: startup/linkcmds.brs5l $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.brs5l +PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.brs5l + +$(PROJECT_LIB)/linkcmds.pm520: startup/linkcmds.pm520 $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.pm520 +PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds.pm520 $(PROJECT_LIB)/linkcmds.pm520: startup/linkcmds.pm520 $(PROJECT_LIB)/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_LIB)/linkcmds.pm520 diff --git a/c/src/lib/libbsp/powerpc/gen5200/start/start.S b/c/src/lib/libbsp/powerpc/gen5200/start/start.S index 32892d490d..cfdff60d06 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/start/start.S +++ b/c/src/lib/libbsp/powerpc/gen5200/start/start.S @@ -111,8 +111,8 @@ .endm .macro LWI reg, value - lis \reg , \value@h - ori \reg , \reg, \value@l + lis \reg , (\value)@h + ori \reg , \reg, (\value)@l sync .endm @@ -286,7 +286,7 @@ start: -#ifdef RSM5LOG +#ifdef BRS5L LWI r30, CSBOOTROM_VAL stw r30, CSBOOTROM(r31) /* Set CSBOOTROM */ @@ -299,7 +299,9 @@ start: rlwinm r30, r30,17,15,31 stw r30, CS0STR(r31) /* Set CS0STR */ - LWI r30, ROM_END + lis r30, ROM_END@h + ori r30, r30, ROM_END@l + rlwinm r30, r30,17,15,31 stw r30, CS0STP(r31) /* Set CS0STP */ @@ -327,7 +329,7 @@ reloc_in_CS0: ori r30,r30,0x1a /* size code: bank is 128MByte */ stw r30,SDRAMCS0(r31) /* Set SDRAMCS0 */ - LWI r30,(RAM_END+1-RAM_START)/2 + LWI r30,(RAM_SIZE)>>1 ori r30,r30,0x1a /* size code: bank is 128MByte */ stw r30, SDRAMCS1(r31) /* Set SDRAMCS1 */ @@ -441,12 +443,13 @@ skip_ROM_start: stw r30,ADREN(r31) /* enable CS1 */ /* clear entire on chip SRAM (unique for ROM startup) */ - LWI r30, (MBAR+ONCHIP_SRAM_OFFSET) /* get start address of onchip SRAM */ + lis r30, (MBAR+ONCHIP_SRAM_OFFSET)@h /* get start address of onchip SRAM */ + ori r30,r30,(MBAR+ONCHIP_SRAM_OFFSET)@l LWI r29, ONCHIP_SRAM_SIZE /* get size of onchip SRAM */ bl clr_mem /* Clear onchip SRAM */ -#endif /* defined(RSM5LOG) */ +#endif /* defined(BRS5L) */ /* clear .bss section (unique for ROM startup) */ LWI r30, _bss_start /* get start address of bss section */ LWI r29, _bss_size /* get size of bss section */ @@ -522,7 +525,7 @@ SDRAM_init: LWI r30, 0xCCC70004 /* Burst2Read Prec.delay=0x8, Burst Write delay=0x8 */ stw r30, CFG2(r31) /* Burst Read2Write delay=0xB, Burst length=0x7, Read Tap=0x4 */ -#ifdef RSM5LOG +#ifdef BRS5L LWI r30, 0xD1470000 /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */ stw r30, CTRL(r31) /* Refresh counter=0xFFFF */ @@ -608,7 +611,7 @@ copy_image_byte: copy_image_end: blr -#endif /* defined(RSM5LOG) */ +#endif /* defined(BRS5L) */ FID_DCache: mflr r26 @@ -740,10 +743,6 @@ FPU_init: mtfsfi 6, 0 mtfsfi 7, 0 - - CLRBITS r30, r29, MSR_FP /* disable FPU and FPU exceptions */ - mtmsr r30 - blr SPRG_init: /* initialize registers */ diff --git a/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c b/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c index 376003756c..76e2922578 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c +++ b/c/src/lib/libbsp/powerpc/gen5200/tod/pcf8563.c @@ -148,7 +148,7 @@ pcf8563_get_time(int minor, rtems_time_of_day *time) v1 = info[PCF8563_DAY_ADR-PCF8563_SECOND_ADR] & PCF8563_DAY_MASK; time->day = From_BCD(v1); - v1 = info[PCF8563_HOUR_ADR-PCF8563_SECOND_ADR] & PCF8563_HOUR_ADR; + v1 = info[PCF8563_HOUR_ADR-PCF8563_SECOND_ADR] & PCF8563_HOUR_MASK; time->hour = From_BCD(v1); v1 = info[PCF8563_MINUTE_ADR-PCF8563_SECOND_ADR] & PCF8563_MINUTE_MASK; @@ -211,7 +211,7 @@ pcf8563_set_time(int minor, rtems_time_of_day *time) */ try = 0; do { - status = i2c_write(bus, addr, info, 8); + status = i2c_write(bus, addr, info,sizeof(info)); try++; } while ((status != I2C_SUCCESSFUL) && (try < 10)); diff --git a/c/src/libchip/ide/ata.c b/c/src/libchip/ide/ata.c index 8957abd630..6c765262e7 100644 --- a/c/src/libchip/ide/ata.c +++ b/c/src/libchip/ide/ata.c @@ -1012,6 +1012,7 @@ ata_initialize(rtems_device_major_number major, char name[ATA_MAX_NAME_LENGTH]; dev_t device; ata_int_st_t *int_st; + #if defined(ATA_USE_OLD_EXCEPTIONS) rtems_isr_entry old_isr; #else @@ -1045,7 +1046,9 @@ ata_initialize(rtems_device_major_number major, */ status = rtems_task_create( rtems_build_name ('A', 'T', 'A', 'T'), - ATA_DRIVER_TASK_PRIORITY, + ((ata_driver_task_priority > 0) + ? ata_driver_task_priority + : ATA_DRIVER_TASK_DEFAULT_PRIORITY), ATA_DRIVER_TASK_STACK_SIZE, RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_ASR | RTEMS_INTERRUPT_LEVEL(0), diff --git a/c/src/libchip/ide/ata.h b/c/src/libchip/ide/ata.h index 0a79b48ccd..3117c7e1c5 100644 --- a/c/src/libchip/ide/ata.h +++ b/c/src/libchip/ide/ata.h @@ -41,9 +41,9 @@ rtems_device_driver ata_initialize( * FIXME: should be configured more easy... */ #define ATA_DRIVER_MESSAGE_QUEUE_SIZE 50 -#define ATA_DRIVER_TASK_PRIORITY 140 #define ATA_DRIVER_TASK_STACK_SIZE 16*1024 - +#define ATA_DRIVER_TASK_DEFAULT_PRIORITY 140 + extern rtems_task_priority ata_driver_task_priority; #ifdef __cplusplus } #endif diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h index 0a10636966..c966b2836e 100644 --- a/cpukit/libblock/include/rtems/bdbuf.h +++ b/cpukit/libblock/include/rtems/bdbuf.h @@ -91,6 +91,9 @@ typedef struct rtems_bdbuf_config { extern rtems_bdbuf_config rtems_bdbuf_configuration[]; extern int rtems_bdbuf_configuration_size; +#define SWAPOUT_TASK_DEFAULT_PRIORITY 15 +extern rtems_task_priority swapout_task_priority; + /* rtems_bdbuf_init -- * Prepare buffering layer to work - initialize buffer descritors * and (if it is neccessary) buffers. Buffers will be allocated accoriding diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c index e388e5cea0..8fb7d515be 100644 --- a/cpukit/libblock/src/bdbuf.c +++ b/cpukit/libblock/src/bdbuf.c @@ -28,8 +28,7 @@ #define BLKDEV_FATAL_BDBUF_SWAPOUT BLKDEV_FATAL_ERROR(2) -#define SWAPOUT_PRIORITY 15 -#define SWAPOUT_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2) +#define SWAPOUT_TASK_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2) #define READ_MULTIPLE @@ -863,9 +862,11 @@ rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size) /* Create and start swapout task */ rc = rtems_task_create( - rtems_build_name('B', 'S', 'W', 'P'), - SWAPOUT_PRIORITY, - SWAPOUT_STACK_SIZE, + rtems_build_name('B', 'S', 'W', 'P'), + ((swapout_task_priority > 0) + ? swapout_task_priority + : SWAPOUT_TASK_DEFAULT_PRIORITY), + SWAPOUT_TASK_STACK_SIZE, RTEMS_DEFAULT_MODES | RTEMS_NO_PREEMPT, RTEMS_DEFAULT_ATTRIBUTES, &bd_ctx.swapout_task); diff --git a/cpukit/libcsupport/include/sys/cdefs.h b/cpukit/libcsupport/include/sys/cdefs.h index 26fb69ad3f..0cbc601929 100644 --- a/cpukit/libcsupport/include/sys/cdefs.h +++ b/cpukit/libcsupport/include/sys/cdefs.h @@ -116,6 +116,7 @@ #define __pure #define __pure2 #define __unused +#define __used #define __attribute__(x) #endif #if __GNUC__ == 2 && __GNUC_MINOR__ < 5 @@ -124,6 +125,7 @@ #define __pure __const #define __pure2 #define __unused +#define __used #endif #if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 #define __dead @@ -131,6 +133,7 @@ #define __pure #define __pure2 __attribute__((__const__)) #define __unused +#define __used #endif #if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3 #define __dead @@ -138,6 +141,7 @@ #define __pure #define __pure2 __attribute__((__const__)) #define __unused __attribute__((__unused__)) +#define __used __attribute__((__used__)) #endif #ifdef __GNUC__ diff --git a/cpukit/libfs/src/imfs/imfs.h b/cpukit/libfs/src/imfs/imfs.h index 67a154c0a2..a5e82a1579 100644 --- a/cpukit/libfs/src/imfs/imfs.h +++ b/cpukit/libfs/src/imfs/imfs.h @@ -80,7 +80,15 @@ typedef struct { * max_filesize with blocks of 512 is 1,082,195,456 */ -#define IMFS_MEMFILE_BYTES_PER_BLOCK 128 +#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK 128 + extern int imfs_rq_memfile_bytes_per_block; + /* + * FIXME: make and use derivates from this, + * a shift count and a mask + */ + extern int imfs_memfile_bytes_per_block; + +#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block #define IMFS_MEMFILE_BLOCK_SLOTS \ (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *)) diff --git a/cpukit/libfs/src/imfs/imfs_initsupp.c b/cpukit/libfs/src/imfs/imfs_initsupp.c index 6cfae62438..29b014d374 100644 --- a/cpukit/libfs/src/imfs/imfs_initsupp.c +++ b/cpukit/libfs/src/imfs/imfs_initsupp.c @@ -30,6 +30,37 @@ #include #endif +/* + * IMFS_determine_bytes_per_block + */ +int imfs_memfile_bytes_per_block = 0; + +static int IMFS_determine_bytes_per_block( + int *dest_bytes_per_block, + int requested_bytes_per_block, + int default_bytes_per_block +) +{ + rtems_boolean is_valid = FALSE; + int bit_mask; + /* + * check, whether requested bytes per block is valid + */ + for (bit_mask = 16; + !is_valid && (bit_mask <= 512); + bit_mask <<= 1) { + if (bit_mask == requested_bytes_per_block) { + is_valid = TRUE; + } + } + *dest_bytes_per_block = ((is_valid) + ? requested_bytes_per_block + : default_bytes_per_block); + return 0; + +} + + /* * IMFS_initialize */ @@ -44,6 +75,13 @@ int IMFS_initialize_support( IMFS_fs_info_t *fs_info; IMFS_jnode_t *jnode; + /* + * determine/check value for imfs_memfile_bytes_per_block + */ + IMFS_determine_bytes_per_block(&imfs_memfile_bytes_per_block, + imfs_rq_memfile_bytes_per_block, + IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK); + /* * Create the root node * diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c index 01a9c36ec8..5a67d5dd24 100644 --- a/cpukit/libmisc/shell/shell.c +++ b/cpukit/libmisc/shell/shell.c @@ -543,6 +543,15 @@ rtems_task shell_shell(rtems_task_argument task_argument) { rtems_current_user_env->euid= rtems_current_user_env->egid=0; + /* + * newlib delays the creation of default stdio 'til the + * first I/O operation, therefore we must perform dummy + * operations before we redirect stdio + */ + ftell(stdin); + ftell(stdout); + ftell(stderr); + stdin =fopen(devname,"r+"); if (!stdin) { diff --git a/cpukit/libnetworking/netinet/tcp_var.h b/cpukit/libnetworking/netinet/tcp_var.h index b7cd4ab655..4d5d9e6eaf 100644 --- a/cpukit/libnetworking/netinet/tcp_var.h +++ b/cpukit/libnetworking/netinet/tcp_var.h @@ -43,6 +43,7 @@ * Kernel variables for tcp. */ +#ifdef __BSD_VISIBLE /* * Tcp control block, one per tcp; fields: */ @@ -196,6 +197,7 @@ struct rmxp_tao { #define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb) #define intotw(ip) ((struct tcptw *)(ip)->inp_ppcb) #define sototcpcb(so) (intotcpcb(sotoinpcb(so))) +#endif /* __BSD_VISIBLE */ /* * The smoothed round-trip time and estimated variance diff --git a/cpukit/libnetworking/sys/linker_set.h b/cpukit/libnetworking/sys/linker_set.h index c79fe87f0b..a2354ed397 100644 --- a/cpukit/libnetworking/sys/linker_set.h +++ b/cpukit/libnetworking/sys/linker_set.h @@ -42,7 +42,7 @@ #ifdef __GNUC__ #define __MAKE_SET(set, sym) \ static void const * const __set_##set##_sym_##sym \ - __attribute((section("set_" #set))) __unused = &sym + __attribute((section("set_" #set))) __used = &sym #else /* !__GNUC__ */ #ifndef lint #error "This file needs to be compiled by GCC or lint" diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index d7dbc2ba1d..ae6ba1ada9 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -123,8 +123,15 @@ extern int rtems_telnetd_maximum_ptys; #include +#ifndef CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK +#define CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK \ + IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK +#endif #ifdef CONFIGURE_INIT + int imfs_rq_memfile_bytes_per_block = CONFIGURE_IMFS_MEMFILE_BYTES_PER_BLOCK; +#endif /* CONFIGURE_INIT */ +#ifdef CONFIGURE_INIT #ifndef CONFIGURE_HAS_OWN_MOUNT_TABLE rtems_filesystem_mount_table_t configuration_mount_table = { #ifdef CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM @@ -296,6 +303,18 @@ rtems_initialization_tasks_table Initialization_tasks[] = { #include #endif +#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER + /* the ide driver needs the ATA driver */ +# ifndef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER +# define CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER +# endif +#include +#endif + +#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER +#include +#endif + #ifndef CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE #ifdef CONFIGURE_INIT @@ -312,12 +331,20 @@ rtems_driver_address_table Device_drivers[] = { #ifdef CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER DEVNULL_DRIVER_TABLE_ENTRY, #endif +#ifdef CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER + IDE_CONTROLLER_DRIVER_TABLE_ENTRY, +#endif +#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + ATA_DRIVER_TABLE_ENTRY, +#endif #ifdef CONFIGURE_APPLICATION_NEEDS_NULL_DRIVER NULL_DRIVER_TABLE_ENTRY #elif !defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \ !defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER) && \ !defined(CONFIGURE_APPLICATION_NEEDS_RTC_DRIVER) && \ - !defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) + !defined(CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER) && \ + !defined(CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER) NULL_DRIVER_TABLE_ENTRY #endif }; @@ -346,6 +373,52 @@ rtems_driver_address_table Device_drivers[] = { #define CONFIGURE_MAXIMUM_DEVICES 20 #endif +#ifdef CONFIGURE_APPLICATION_NEEDS_ATA_DRIVER + /* + * configure the priority of the ATA driver task + */ +# ifndef CONFIGURE_ATA_DRIVER_TASK_PRIORITY +# define CONFIGURE_ATA_DRIVER_TASK_PRIORITY ATA_DRIVER_TASK_DEFAULT_PRIORITY +# endif +# ifdef CONFIGURE_INIT + rtems_task_priority ata_driver_task_priority + = CONFIGURE_ATA_DRIVER_TASK_PRIORITY; +# endif /* CONFIGURE_INIT */ +#endif + +/* + * add bdbuf configuration and values for swapout task priority + */ +#ifdef CONFIGURE_APPLICATION_NEEDS_LIBBLOCK +#include +/* + * configure the priority of the bdbuf swapout task + */ +#ifndef CONFIGURE_SWAPOUT_TASK_PRIORITY +#define CONFIGURE_SWAPOUT_TASK_PRIORITY SWAPOUT_TASK_DEFAULT_PRIORITY +#endif +#ifdef CONFIGURE_INIT + rtems_task_priority swapout_task_priority + = CONFIGURE_SWAPOUT_TASK_PRIORITY; +#endif /* CONFIGURE_INIT */ +#ifndef CONFIGURE_HAS_OWN_BDBUF_TABLE + +#ifndef CONFIGURE_BDBUF_BUFFER_COUNT +#define CONFIGURE_BDBUF_BUFFER_COUNT 64 +#endif /* CONFIGURE_BDBUF_BUFFER_COUNT */ + +#ifndef CONFIGURE_BDBUF_BUFFER_SIZE +#define CONFIGURE_BDBUF_BUFFER_SIZE 512 +#endif /* CONFIGURE_BDBUF_BUFFER_SIZE */ +#ifdef CONFIGURE_INIT +rtems_bdbuf_config rtems_bdbuf_configuration[] = { + {CONFIGURE_BDBUF_BUFFER_SIZE,CONFIGURE_BDBUF_BUFFER_COUNT,NULL} +}; +int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration) + /sizeof(rtems_bdbuf_configuration[0])); +#endif /* CONFIGURE_INIT */ +#endif /* CONFIGURE_HAS_OWN_BDBUF_TABLE */ +#endif /* CONFIGURE_APPLICATION_NEEDS_LIBBLOCK */ /* * Default Multiprocessing Configuration Table. The defaults are * appropriate for most of the RTEMS Multiprocessor Test Suite. Each diff --git a/make/custom/mpc8260ads.cfg b/make/custom/mpc8260ads.cfg index e7473ab638..ec74d4b03d 100644 --- a/make/custom/mpc8260ads.cfg +++ b/make/custom/mpc8260ads.cfg @@ -22,7 +22,7 @@ CPU_CFLAGS = -mcpu=603e -mstrict-align -Dmpc8260 # optimize flag: typically -0, could use -O4 or -fast # -O4 is ok for RTEMS # NOTE: some level of -O may be actually required by inline assembler -CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions +CFLAGS_OPTIMIZE_V=-O4 -fno-keep-inline-functions -g # The following are definitions of make-exe which will work using ld as # is currently required. It is expected that as of gcc 2.8, the end user diff --git a/testsuites/samples/fileio/system.h b/testsuites/samples/fileio/system.h index 3f1b22ca89..bbf515602a 100644 --- a/testsuites/samples/fileio/system.h +++ b/testsuites/samples/fileio/system.h @@ -32,31 +32,10 @@ rtems_task Init( #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_IDE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK #define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM -#define CONFIGURE_HAS_OWN_DEVICE_DRIVER_TABLE - -#ifdef CONFIGURE_INIT -rtems_driver_address_table Device_drivers[] = - { - CONSOLE_DRIVER_TABLE_ENTRY - ,CLOCK_DRIVER_TABLE_ENTRY -#ifdef RTEMS_BSP_HAS_IDE_DRIVER - ,IDE_CONTROLLER_DRIVER_TABLE_ENTRY - /* important: ATA driver must be after ide drivers */ - ,ATA_DRIVER_TABLE_ENTRY -#endif - }; - -#include -rtems_bdbuf_config rtems_bdbuf_configuration[] = { - {512,128,NULL} -}; -int rtems_bdbuf_configuration_size =( sizeof(rtems_bdbuf_configuration) - /sizeof(rtems_bdbuf_configuration[0])); -#endif - - /* * XXX: these values are higher than needed... */ -- cgit v1.2.3