summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/tqm8xx
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-19 06:28:01 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-20 13:08:32 +0200
commitd7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc (patch)
treecaa54b4229e86a68c84ab5961af34e087dce5302 /c/src/lib/libbsp/powerpc/tqm8xx
parentbsps/powerpc: Move shared btimer support (diff)
downloadrtems-d7d66d7d4523b904c8ccc6aea3709dc0d5aa5bdc.tar.bz2
bsps: Move console drivers to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/tqm8xx')
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am2
-rw-r--r--c/src/lib/libbsp/powerpc/tqm8xx/console/console.c1115
2 files changed, 1 insertions, 1116 deletions
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am b/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am
index 9589d38e8d..1c0dfe5da3 100644
--- a/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/tqm8xx/Makefile.am
@@ -32,7 +32,7 @@ librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/shared/clock/clock.c
librtemsbsp_a_SOURCES +=../../../../../../bsps/powerpc/tqm8xx/clock/p_clock.c
# console
-librtemsbsp_a_SOURCES += console/console.c
+librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/tqm8xx/console/console.c
# spi
librtemsbsp_a_SOURCES += spi/spi.c
# timer
diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/console/console.c b/c/src/lib/libbsp/powerpc/tqm8xx/console/console.c
deleted file mode 100644
index 5a681b19fb..0000000000
--- a/c/src/lib/libbsp/powerpc/tqm8xx/console/console.c
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*===============================================================*\
-| Project: RTEMS TQM8xx BSP |
-+-----------------------------------------------------------------+
-| This file has been adapted to MPC8xx by |
-| Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> |
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-| |
-| See the other copyright notice below for the original parts. |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-| this file contains the console driver |
-\*===============================================================*/
-/* derived from: */
-/*
- * SMC1/2 SCC1..4 raw console serial I/O.
- * adapted to work with up to 4 SCC and 2 SMC
- *
- * This driver is an example of `TASK DRIVEN' `POLLING' or `INTERRUPT' I/O.
- *
- * To run with interrupt-driven I/O, ensure m8xx_smc1_interrupt
- * is set before calling the initialization routine.
- *
- * Author:
- * W. Eric Norum
- * Saskatchewan Accelerator Laboratory
- * University of Saskatchewan
- * Saskatoon, Saskatchewan, CANADA
- * eric@skatter.usask.ca
- *
- * COPYRIGHT (c) 1989-1998.
- * On-Line Applications Research Corporation (OAR).
- * Copyright assigned to U.S. Government, 1994.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.OARcorp.com/rtems/license.html.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include <rtems.h>
-#include <rtems/console.h>
-#include <rtems/libio.h>
-#include <rtems/termiostypes.h>
-#include <rtems/bspIo.h>
-#include <rtems/error.h>
-#include <rtems/irq.h>
-
-#include <bsp.h>
-#include <mpc8xx.h>
-#include <bsp/irq.h>
-
-/*
- * Interrupt-driven input buffer
- */
-#define RXBUFSIZE 16
-
-#define M8xx_SICR_BRG1 (0)
-#define M8xx_SICR_BRG2 (1)
-#define M8xx_SICR_BRG3 (2)
-#define M8xx_SICR_BRG4 (3)
-
-#define M8xx_SICR_SCCRX_MSK(scc) (( 7) << (((scc))*8+3))
-#define M8xx_SICR_SCCRX(scc,clk) ((clk) << (((scc))*8+3))
-
-#define M8xx_SICR_SCCTX_MSK(scc) (( 7) << (((scc))*8+0))
-#define M8xx_SICR_SCCTX(scc,clk) ((clk) << (((scc))*8+0))
-
-#define M8xx_SIMODE_SMCCS(smc,clk) ((clk) << ((smc)*16+12))
-#define M8xx_SIMODE_SMCCS_MSK(smc) M8xx_SIMODE_SMCCS(smc,7)
-
-#define CONS_CHN_CNT 6
-#define CONS_CHN_SCC1 0
-#define CONS_CHN_SCC2 1
-#define CONS_CHN_SCC3 2
-#define CONS_CHN_SCC4 3
-#define CONS_CHN_SMC1 4
-#define CONS_CHN_SMC2 5
-#define CONS_CHN_NONE -1
-
-/*
- * possible identifiers for bspopts.h: CONS_SxCy_MODE
- */
-#define CONS_MODE_UNUSED -1
-#define CONS_MODE_POLLED TERMIOS_POLLED
-#define CONS_MODE_IRQ TERMIOS_IRQ_DRIVEN
-
-#define CHN_IS_SCC(chan) ((chan) < CONS_CHN_SMC1)
-
-#define BRG_CNT 4
-
-#define MAX_IDL_DEFAULT 10
-#define DEVICEPREFIX "tty"
-
-/*
- * Interrupt-driven callback
- */
-static int m8xx_scc_mode[CONS_CHN_CNT];
-static void *sccttyp[CONS_CHN_CNT];
-typedef struct m8xx_console_chan_desc_s {
- bool is_scc; /* true for SCC */
- struct {
- volatile m8xxSCCparms_t *sccp;
- volatile m8xxSMCparms_t *smcp;
- } parms;
- struct {
- volatile m8xxSCCRegisters_t *sccr;
- volatile m8xxSMCRegisters_t *smcr;
- } regs;
- int ivec_src;
- int cr_chan_code;
- int brg_used;
-} m8xx_console_chan_desc_t;
-
-m8xx_console_chan_desc_t m8xx_console_chan_desc[CONS_CHN_CNT] = {
- /* SCC1 */
- {TRUE,
- {(m8xxSCCparms_t *)&(m8xx.scc1p),NULL},
- {&(m8xx.scc1),NULL},
- BSP_CPM_IRQ_SCC1,
- M8xx_CR_CHAN_SCC1,
- -1},
- /* SCC2 */
- {TRUE,
- {&(m8xx.scc2p),NULL},
- {&(m8xx.scc2),NULL},
- BSP_CPM_IRQ_SCC2,
- M8xx_CR_CHAN_SCC2,
- -1},
- /* SCC3 */
- {TRUE,
- {&(m8xx.scc3p),NULL},
- {&(m8xx.scc3),NULL},
- BSP_CPM_IRQ_SCC3,
- M8xx_CR_CHAN_SCC3,
- -1},
- /* SCC4 */
- {TRUE,
- {&(m8xx.scc4p),NULL},
- {&(m8xx.scc4),NULL},
- BSP_CPM_IRQ_SCC4,
- M8xx_CR_CHAN_SCC4,
- -1},
- /* SMC1 */
- {FALSE,
- {NULL,&(m8xx.smc1p)},
- {NULL,&(m8xx.smc1)},
- BSP_CPM_IRQ_SMC1,
- M8xx_CR_CHAN_SMC1,
- -1},
- /* SMC2 */
- {FALSE,
- {NULL,&(m8xx.smc2p)},
- {NULL,&(m8xx.smc2)},
- BSP_CPM_IRQ_SMC2_OR_PIP,
- M8xx_CR_CHAN_SMC2,
- -1}};
-
-#define CHN_PARAM_GET(chan,param) \
- (m8xx_console_chan_desc[chan].is_scc \
- ? m8xx_console_chan_desc[chan].parms.sccp->param \
- : m8xx_console_chan_desc[chan].parms.smcp->param)
-
-#define CHN_PARAM_SET(chan,param,value) \
- do {if (m8xx_console_chan_desc[chan].is_scc) \
- m8xx_console_chan_desc[chan].parms.sccp->param = value; \
- else \
- m8xx_console_chan_desc[chan].parms.smcp->param = value; \
- } while (0)
-
-#define CHN_EVENT_GET(chan) \
- (m8xx_console_chan_desc[chan].is_scc \
- ? m8xx_console_chan_desc[chan].regs.sccr->scce \
- : m8xx_console_chan_desc[chan].regs.smcr->smce)
-
-#define CHN_EVENT_CLR(chan,mask) \
- do { \
- if (m8xx_console_chan_desc[chan].is_scc) \
- m8xx_console_chan_desc[chan].regs.sccr->scce = (mask); \
- else \
- m8xx_console_chan_desc[chan].regs.smcr->smce = (mask); \
- }while (0)
-
-#define CHN_MASK_GET(chan) \
- (m8xx_console_chan_desc[chan].is_scc \
- ? m8xx_console_chan_desc[chan].regs.sccr->sccm \
- : m8xx_console_chan_desc[chan].regs.smcr->smcm)
-
-#define CHN_MASK_SET(chan,mask) \
- do { \
- if (m8xx_console_chan_desc[chan].is_scc) \
- m8xx_console_chan_desc[chan].regs.sccr->sccm = (mask); \
- else \
- m8xx_console_chan_desc[chan].regs.smcr->smcm = (mask); \
- }while (0)
-
-
-/*
- * I/O buffers and pointers to buffer descriptors
- */
-#define SCC_RXBD_CNT 4
-#define SCC_TXBD_CNT 4
-typedef volatile char sccRxBuf_t[SCC_RXBD_CNT][RXBUFSIZE];
-static sccRxBuf_t *rxBuf[CONS_CHN_CNT];
-
-static volatile m8xxBufferDescriptor_t *sccFrstRxBd[CONS_CHN_CNT];
-static volatile m8xxBufferDescriptor_t *sccCurrRxBd[CONS_CHN_CNT];
-static volatile m8xxBufferDescriptor_t *sccFrstTxBd[CONS_CHN_CNT];
-static volatile m8xxBufferDescriptor_t *sccPrepTxBd[CONS_CHN_CNT];
-static volatile m8xxBufferDescriptor_t *sccDequTxBd[CONS_CHN_CNT];
-
-/*
- * Compute baud-rate-generator configuration register value
- */
-static uint32_t
-sccBRGval (int baud)
-{
- int divisor;
- int div16 = 0;
-
- divisor = ((BSP_bus_frequency / 16) + (baud / 2)) / baud;
- if (divisor > 4096) {
- div16 = 1;
- divisor = (divisor + 8) / 16;
- }
- return M8xx_BRG_EN | M8xx_BRG_EXTC_BRGCLK | ((divisor - 1) << 1) | div16;
-}
-
-typedef struct {
- uint32_t reg_content;
- int link_cnt;
-}brg_state_t;
-brg_state_t scc_brg_state[BRG_CNT];
-
-/*
- * initialize brg_state
- */
-static void sccBRGinit(void)
-{
- int brg_idx;
-
- for (brg_idx = 0;brg_idx < BRG_CNT;brg_idx++) {
- scc_brg_state[brg_idx].reg_content = 0;
- scc_brg_state[brg_idx].link_cnt = 0;
- }
-#ifndef MDE360
- /*
- * on ZEM40, init CLK4/5 inputs
- */
- m8xx.papar |= ((1 << 11) | (1 << 12));
- m8xx.padir &= ~((1 << 11) | (1 << 12));
-#endif
-}
-
-#if CONS_USE_EXT_CLK
-/*
- * input clock frq for CPM clock inputs
- */
-static uint32_t clkin_frq[2][4] = {
-#ifdef MDE360
- {0,0,0,0},
- {0,0,0,0}
-#else
- {0,0,0,1843000},
- {1843000,0,0,0}
-#endif
-};
-#endif
-
-/*
- * allocate, set and connect baud rate generators
- * FIXME: or clock input
- * FIXME: set pin to be clock input
- */
-
-static int sccBRGalloc(int chan,int baud)
-{
- rtems_interrupt_level level;
- m8xx_console_chan_desc_t *chan_desc = &(m8xx_console_chan_desc[chan]);
- uint32_t reg_val;
- int old_brg;
- int new_brg = -1;
- int brg_idx;
-#if CONS_USE_EXT_CLK
- int clk_group;
- int clk_sel;
-#endif
-
- old_brg = chan_desc->brg_used;
- /* compute brg register contents needed */
- reg_val = sccBRGval(baud);
-
-#if CONS_EXT_CLK
- /* search for clock input with this frq */
- clk_group = ((chan == CONS_CHN_SCC3) ||
- (chan == CONS_CHN_SCC4) ||
- (chan == CONS_CHN_SMC2)) ? 1 : 0;
-
- for (clk_sel = 0, new_brg = -1;
- (clk_sel < 4) && (new_brg < 0);
- clk_sel++) {
- if (baud == (clkin_frq[clk_group][clk_sel] / 16)) {
- new_brg = clk_sel + 4;
- }
- }
-#endif
-
- rtems_interrupt_disable(level);
-
- if (new_brg < 0) {
- /* search for brg with this settings */
- for (brg_idx = 0;
- (new_brg < 0) && (brg_idx < BRG_CNT);
- brg_idx++) {
- if (scc_brg_state[brg_idx].reg_content == reg_val) {
- new_brg = brg_idx;
- }
- }
- /*
- * if not found: check, whether brg currently in use
- * is linked only from our channel
- */
- if ((new_brg < 0) &&
- (old_brg >= 0) &&
- (scc_brg_state[old_brg].link_cnt == 1)) {
- new_brg = old_brg;
- }
- /* if not found: search for unused brg, set it */
- for (brg_idx = 0;
- (new_brg < 0) && (brg_idx < BRG_CNT);
- brg_idx++) {
- if (scc_brg_state[brg_idx].link_cnt == 0) {
- new_brg = brg_idx;
- }
- }
- }
-
- /* decrease old link count */
- if ((old_brg >= 0) &&
- (old_brg < 4)) {
- scc_brg_state[old_brg].link_cnt--;
- }
- /* increase new brg link count, set brg */
- if ((new_brg >= 0) &&
- (new_brg < 4)) {
- scc_brg_state[new_brg].link_cnt++;
- scc_brg_state[new_brg].reg_content = reg_val;
- (&m8xx.brgc1)[new_brg] = reg_val;
- }
- rtems_interrupt_enable(level);
-
- /* connect to scc/smc */
- if (new_brg >= 0) {
- m8xx_console_chan_desc[chan].brg_used = new_brg;
- /*
- * Put SCC in NMSI mode, connect SCC to BRG or CLKx
- */
- if (m8xx_console_chan_desc[chan].is_scc) {
- m8xx.sicr = ((m8xx.sicr & ~(M8xx_SICR_SCCRX_MSK(chan) |
- M8xx_SICR_SCCTX_MSK(chan))) |
- M8xx_SICR_SCCRX(chan,new_brg)|
- M8xx_SICR_SCCTX(chan,new_brg));
- }
- else {
- /* connect SMC to BRGx or CLKx... */
- m8xx.simode = ((m8xx.simode & ~(M8xx_SIMODE_SMCCS_MSK(chan - CONS_CHN_SMC1)))|
- M8xx_SIMODE_SMCCS(chan - CONS_CHN_SMC1,new_brg));
- }
- }
- return (new_brg < 0);
-}
-
-
-/*
- * Hardware-dependent portion of tcsetattr().
- */
-static int
-sccSetAttributes (int minor, const struct termios *t)
-{
- int baud;
-
- switch (t->c_ospeed) {
- default: baud = -1; break;
- 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;
- }
- return sccBRGalloc(minor,baud);
- return 0;
-}
-
-/*
- * Interrupt handler
- */
-static rtems_isr
-sccInterruptHandler (void *arg)
-{
- int chan = (int)arg;
-
- /*
- * Buffer received?
- */
- if (CHN_EVENT_GET(chan) & 0x1) {
- /*
- * clear SCC event flag
- */
- CHN_EVENT_CLR(chan,0x01);
- /*
- * process event
- */
- while ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) == 0) {
- if (sccttyp[chan] != NULL) {
- rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer,
- sccCurrRxBd[chan]->length);
- rtems_termios_enqueue_raw_characters (sccttyp[chan],
- (char *)sccCurrRxBd[chan]->buffer,
- sccCurrRxBd[chan]->length);
- }
- /*
- * clear status
- */
- sccCurrRxBd[chan]->status =
- (sccCurrRxBd[chan]->status
- & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT))
- | M8xx_BD_EMPTY;
- /*
- * advance to next BD
- */
- if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) {
- sccCurrRxBd[chan] = sccFrstRxBd[chan];
- }
- else {
- sccCurrRxBd[chan]++;
- }
- }
- }
- /*
- * Buffer transmitted?
- */
- if (CHN_EVENT_GET(chan) & 0x2) {
- /*
- * then clear interrupt event bit
- */
- CHN_EVENT_CLR(chan,0x2);
- /*
- * and signal successful transmit to termios
- */
- /*
- * FIXME: multiple dequeue calls for multiple buffers
- */
- while((sccDequTxBd[chan] != sccPrepTxBd[chan]) &&
- ((sccDequTxBd[chan]->status & M8xx_BD_READY) == 0)) {
- if (sccttyp[chan] != NULL) {
- rtems_termios_dequeue_characters (sccttyp[chan],
- sccDequTxBd[chan]->length);
- }
- /*
- * advance to next BD
- */
- if ((sccDequTxBd[chan]->status & M8xx_BD_WRAP) != 0) {
- sccDequTxBd[chan] = sccFrstTxBd[chan];
- }
- else {
- sccDequTxBd[chan]++;
- }
- }
- }
-}
-
-static void
-mpc8xx_console_irq_on(const rtems_irq_connect_data *irq)
-{
- CHN_MASK_SET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET,
- 3); /* Enable TX and RX interrupts */
-}
-
-static void
-mpc8xx_console_irq_off(const rtems_irq_connect_data *irq)
-{
- CHN_MASK_SET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET,
- 0); /* Disable TX and RX interrupts */
-}
-
-static int
-mpc8xx_console_irq_isOn(const rtems_irq_connect_data *irq)
-{
- return (0 != CHN_MASK_GET(irq->name - BSP_CPM_IRQ_LOWEST_OFFSET)); /* Check TX and RX interrupts */
-}
-
-static void
-sccInitialize (int chan)
-{
- int i;
- /*
- * allocate buffers
- * FIXME: use a cache-line size boundary alloc here
- */
- rxBuf[chan] = malloc(sizeof(*rxBuf[chan]) + 2*PPC_CACHE_ALIGNMENT);
- if (rxBuf[chan] == NULL) {
- rtems_panic("Cannot allocate console rx buffer\n");
- }
- else {
- /*
- * round up rxBuf[chan] to start at a cache line size
- */
- rxBuf[chan] = (sccRxBuf_t *)
- (((uint32_t)rxBuf[chan]) +
- (PPC_CACHE_ALIGNMENT
- - ((uint32_t)rxBuf[chan]) % PPC_CACHE_ALIGNMENT));
- }
- /*
- * Allocate buffer descriptors
- */
- sccCurrRxBd[chan] =
- sccFrstRxBd[chan] = m8xx_bd_allocate(SCC_RXBD_CNT);
- sccPrepTxBd[chan] =
- sccDequTxBd[chan] =
- sccFrstTxBd[chan] = m8xx_bd_allocate(SCC_TXBD_CNT);
- switch(chan) {
- case CONS_CHN_SCC1:
- /*
- * Configure port A pins to enable TXD1 and RXD1 pins
- * FIXME: add setup for modem control lines....
- */
- m8xx.papar |= 0x03;
- m8xx.padir &= ~0x03;
-
- /*
- * Configure port C pins to enable RTS1 pins (static active low)
- */
- m8xx.pcpar &= ~0x01;
- m8xx.pcso &= ~0x01;
- m8xx.pcdir |= 0x01;
- m8xx.pcdat &= ~0x01;
- break;
- case CONS_CHN_SCC2:
- /*
- * Configure port A pins to enable TXD2 and RXD2 pins
- * FIXME: add setup for modem control lines....
- */
- m8xx.papar |= 0x0C;
- m8xx.padir &= ~0x0C;
-
- /*
- * Configure port C pins to enable RTS2 pins (static active low)
- */
- m8xx.pcpar &= ~0x02;
- m8xx.pcso &= ~0x02;
- m8xx.pcdir |= 0x02;
- m8xx.pcdat &= ~0x02;
- break;
- case CONS_CHN_SCC3:
- /*
- * Configure port A pins to enable TXD3 and RXD3 pins
- * FIXME: add setup for modem control lines....
- */
- m8xx.papar |= 0x30;
- m8xx.padir &= ~0x30;
-
- /*
- * Configure port C pins to enable RTS3 (static active low)
- */
- m8xx.pcpar &= ~0x04;
- m8xx.pcso &= ~0x04;
- m8xx.pcdir |= 0x04;
- m8xx.pcdat &= ~0x04;
- break;
- case CONS_CHN_SCC4:
- /*
- * Configure port A pins to enable TXD4 and RXD4 pins
- * FIXME: add setup for modem control lines....
- */
- m8xx.papar |= 0xC0;
- m8xx.padir &= ~0xC0;
-
- /*
- * Configure port C pins to enable RTS4 pins (static active low)
- */
- m8xx.pcpar &= ~0x08;
- m8xx.pcso &= ~0x08;
- m8xx.pcdir |= 0x08;
- m8xx.pcdat &= ~0x08;
- break;
- case CONS_CHN_SMC1:
- /*
- * Configure port B pins to enable SMTXD1 and SMRXD1 pins
- */
- m8xx.pbpar |= 0xC0;
- m8xx.pbdir &= ~0xC0;
- break;
- case CONS_CHN_SMC2:
- /*
- * Configure port B pins to enable SMTXD2 and SMRXD2 pins
- */
- m8xx.pbpar |= 0xC00;
- m8xx.pbdir &= ~0xC00;
- break;
- }
- /*
- * allocate and connect BRG
- */
- sccBRGalloc(chan,9600);
-
-
- /*
- * Set up SCCx parameter RAM common to all protocols
- */
- CHN_PARAM_SET(chan,rbase,(char *)sccFrstRxBd[chan] - (char *)&m8xx);
- CHN_PARAM_SET(chan,tbase,(char *)sccFrstTxBd[chan] - (char *)&m8xx);
- CHN_PARAM_SET(chan,rfcr ,M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0));
- CHN_PARAM_SET(chan,tfcr ,M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0));
- if (m8xx_scc_mode[chan] != TERMIOS_POLLED)
- CHN_PARAM_SET(chan,mrblr,RXBUFSIZE);
- else
- CHN_PARAM_SET(chan,mrblr,1);
-
- /*
- * Set up SCCx parameter RAM UART-specific parameters
- */
- CHN_PARAM_SET(chan,un.uart.max_idl ,MAX_IDL_DEFAULT);
- CHN_PARAM_SET(chan,un.uart.brkln ,0);
- CHN_PARAM_SET(chan,un.uart.brkec ,0);
- CHN_PARAM_SET(chan,un.uart.brkcr ,0);
- if (m8xx_console_chan_desc[chan].is_scc) {
- m8xx_console_chan_desc[chan].parms.sccp->un.uart.character[0]=0x8000; /* no char filter */
- m8xx_console_chan_desc[chan].parms.sccp->un.uart.rccm=0x80FF; /* control character mask */
- }
-
- /*
- * Set up the Receive Buffer Descriptors
- */
- for (i = 0;i < SCC_RXBD_CNT;i++) {
- sccFrstRxBd[chan][i].status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
- if (i == SCC_RXBD_CNT-1) {
- sccFrstRxBd[chan][i].status |= M8xx_BD_WRAP;
- }
- sccFrstRxBd[chan][i].length = 0;
- sccFrstRxBd[chan][i].buffer = (*rxBuf[chan])[i];
- }
- /*
- * Setup the Transmit Buffer Descriptor
- */
- for (i = 0;i < SCC_TXBD_CNT;i++) {
- sccFrstTxBd[chan][i].status = M8xx_BD_INTERRUPT;
- if (i == SCC_TXBD_CNT-1) {
- sccFrstTxBd[chan][i].status |= M8xx_BD_WRAP;
- }
- sccFrstTxBd[chan][i].length = 0;
- sccFrstTxBd[chan][i].buffer = NULL;
- }
-
- /*
- * Set up SCC general and protocol-specific mode registers
- */
- CHN_EVENT_CLR(chan,~0); /* Clear any pending events */
- CHN_MASK_SET(chan,0); /* Mask all interrupt/event sources */
-
- if (m8xx_console_chan_desc[chan].is_scc) {
- m8xx_console_chan_desc[chan].regs.sccr->psmr = 0xb000; /* 8N1, CTS flow control */
- m8xx_console_chan_desc[chan].regs.sccr->gsmr_h = 0x00000000;
- m8xx_console_chan_desc[chan].regs.sccr->gsmr_l = 0x00028004; /* UART mode */
- }
- else {
- m8xx_console_chan_desc[chan].regs.smcr->smcmr = 0x4820;
- }
- /*
- * Send "Init parameters" command
- */
- m8xx_cp_execute_cmd(M8xx_CR_OP_INIT_RX_TX
- | m8xx_console_chan_desc[chan].cr_chan_code);
-
- /*
- * Enable receiver and transmitter
- */
- if (m8xx_console_chan_desc[chan].is_scc) {
- m8xx_console_chan_desc[chan].regs.sccr->gsmr_l |= 0x00000030;
- }
- else {
- m8xx_console_chan_desc[chan].regs.smcr->smcmr |= 0x0003;
- }
-
- if (m8xx_scc_mode[chan] != TERMIOS_POLLED) {
-
- rtems_irq_connect_data irq_conn_data = {
- m8xx_console_chan_desc[chan].ivec_src,
- sccInterruptHandler, /* rtems_irq_hdl */
- (rtems_irq_hdl_param)chan, /* (rtems_irq_hdl_param) */
- mpc8xx_console_irq_on, /* (rtems_irq_enable) */
- mpc8xx_console_irq_off, /* (rtems_irq_disable) */
- mpc8xx_console_irq_isOn /* (rtems_irq_is_enabled) */
- };
- if (!BSP_install_rtems_irq_handler (&irq_conn_data)) {
- rtems_panic("console: cannot install IRQ handler");
- }
- }
-}
-
-/*
- * polled scc read function
- */
-static int
-sccPollRead (int minor)
-{
- int c = -1;
- int chan = minor;
-
- while(1) {
- if ((sccCurrRxBd[chan]->status & M8xx_BD_EMPTY) != 0) {
- return -1;
- }
-
- if (0 == (sccCurrRxBd[chan]->status & (M8xx_BD_OVERRUN
- | M8xx_BD_PARITY_ERROR
- | M8xx_BD_FRAMING_ERROR
- | M8xx_BD_BREAK
- | M8xx_BD_IDLE))) {
- /* character received and no error detected */
- rtems_cache_invalidate_multiple_data_lines((void *)sccCurrRxBd[chan]->buffer,
- sccCurrRxBd[chan]->length);
- c = (unsigned)*((char *)sccCurrRxBd[chan]->buffer);
- /*
- * clear status
- */
- }
- sccCurrRxBd[chan]->status =
- (sccCurrRxBd[chan]->status
- & (M8xx_BD_WRAP | M8xx_BD_INTERRUPT))
- | M8xx_BD_EMPTY;
- /*
- * advance to next BD
- */
- if ((sccCurrRxBd[chan]->status & M8xx_BD_WRAP) != 0) {
- sccCurrRxBd[chan] = sccFrstRxBd[chan];
- }
- else {
- sccCurrRxBd[chan]++;
- }
- if (c >= 0) {
- return c;
- }
- }
-}
-
-
-/*
- * Device-dependent write routine
- * Interrupt-driven devices:
- * Begin transmission of as many characters as possible (minimum is 1).
- * Polling devices:
- * Transmit all characters.
- */
-static ssize_t
-sccInterruptWrite (int minor, const char *buf, size_t len)
-{
- if (len > 0) {
- int chan = minor;
-
- if ((sccPrepTxBd[chan]->status & M8xx_BD_READY) == 0) {
- sccPrepTxBd[chan]->buffer = (char *)buf;
- sccPrepTxBd[chan]->length = len;
- rtems_cache_flush_multiple_data_lines((const void *)buf,len);
- /*
- * clear status, set ready bit
- */
- sccPrepTxBd[chan]->status =
- (sccPrepTxBd[chan]->status
- & M8xx_BD_WRAP)
- | M8xx_BD_READY | M8xx_BD_INTERRUPT;
- if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) {
- sccPrepTxBd[chan] = sccFrstTxBd[chan];
- }
- else {
- sccPrepTxBd[chan]++;
- }
- }
- }
-
- return 0;
-}
-
-static ssize_t
-sccPollWrite (int minor, const char *buf, size_t len)
-{
- static char txBuf[CONS_CHN_CNT][SCC_TXBD_CNT];
- int chan = minor;
- int bd_used;
- size_t retval = len;
-
- while (len--) {
- while (sccPrepTxBd[chan]->status & M8xx_BD_READY)
- continue;
- bd_used = sccPrepTxBd[chan]-sccFrstTxBd[chan];
- txBuf[chan][bd_used] = *buf++;
- rtems_cache_flush_multiple_data_lines((const void *)&txBuf[chan][bd_used],
- sizeof(txBuf[chan][bd_used]));
- sccPrepTxBd[chan]->buffer = &(txBuf[chan][bd_used]);
- sccPrepTxBd[chan]->length = 1;
- sccPrepTxBd[chan]->status =
- (sccPrepTxBd[chan]->status
- & M8xx_BD_WRAP)
- | M8xx_BD_READY;
- if ((sccPrepTxBd[chan]->status & M8xx_BD_WRAP) != 0) {
- sccPrepTxBd[chan] = sccFrstTxBd[chan];
- }
- else {
- sccPrepTxBd[chan]++;
- }
- }
- return retval;
-}
-
-/*
- * printk basic support
- */
-int BSP_output_chan = CONS_CHN_NONE; /* channel used for printk operation */
-
-static void console_debug_putc_onlcr(const char c)
-{
- rtems_interrupt_level irq_level;
-
- if (BSP_output_chan != CONS_CHN_NONE) {
- rtems_interrupt_disable(irq_level);
-
- sccPollWrite (BSP_output_chan,&c,1);
- rtems_interrupt_enable(irq_level);
- }
-}
-
-BSP_output_char_function_type BSP_output_char = console_debug_putc_onlcr;
-BSP_polling_getchar_function_type BSP_poll_char = NULL;
-
-
-/*
-***************
-* BOILERPLATE *
-***************
-*/
-
-struct {
- rtems_device_minor_number minor;
- int driver_mode;
-} channel_list[] = {
- {CONS_CHN_SMC1,CONS_SMC1_MODE},
- {CONS_CHN_SMC2,CONS_SMC2_MODE},
- {CONS_CHN_SCC1,CONS_SCC1_MODE},
- {CONS_CHN_SCC2,CONS_SCC2_MODE},
- {CONS_CHN_SCC3,CONS_SCC3_MODE},
- {CONS_CHN_SCC4,CONS_SCC4_MODE}
-};
-
-
-/*
- * Initialize and register the device
- */
-rtems_device_driver console_initialize(rtems_device_major_number major,
- rtems_device_minor_number minor,/* ignored */
- void *arg
- )
-{
- rtems_status_code status = RTEMS_SUCCESSFUL;
- int chan,entry,ttynum;
- char tty_name[] = "/dev/tty00";
-
- /*
- * Set up TERMIOS
- */
- rtems_termios_initialize ();
- /*
- * init BRG allocataion
- */
- sccBRGinit();
- ttynum = 0;
- for (entry = 0;
- (entry < sizeof(channel_list)/sizeof(channel_list[0]))
- && (status == RTEMS_SUCCESSFUL);
- entry++) {
- if (channel_list[entry].driver_mode != CONS_MODE_UNUSED) {
- /*
- * Do device-specific initialization
- */
- chan = channel_list[entry].minor;
- m8xx_scc_mode[chan] = channel_list[entry].driver_mode;
- sccInitialize (chan);
-
- /*
- * build device name
- */
- tty_name[sizeof(tty_name)-2] = '0'+ttynum;
- ttynum++;
- /*
- * Register the device
- */
- status = rtems_io_register_name (tty_name,
- major,
- channel_list[entry].minor);
- if (status != RTEMS_SUCCESSFUL) {
- rtems_fatal_error_occurred (status);
- }
- }
- }
- /*
- * register /dev/console
- */
- status = rtems_io_register_name ("/dev/console",
- major,
- CONSOLE_CHN);
- if (status != RTEMS_SUCCESSFUL) {
- rtems_fatal_error_occurred (status);
- }
- /*
- * enable printk support
- */
- BSP_output_chan = PRINTK_CHN;
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * Open the device
- */
-rtems_device_driver console_open(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
- )
-{
- rtems_status_code status;
- int chan = minor;
- rtems_libio_open_close_args_t *args = (rtems_libio_open_close_args_t *)arg;
- static const rtems_termios_callbacks interruptCallbacks = {
- NULL, /* firstOpen */
- NULL, /* lastClose */
- NULL, /* pollRead */
- sccInterruptWrite, /* write */
- sccSetAttributes, /* setAttributes */
- NULL, /* stopRemoteTx */
- NULL, /* startRemoteTx */
- TERMIOS_IRQ_DRIVEN /* outputUsesInterrupts */
- };
- static const rtems_termios_callbacks pollCallbacks = {
- NULL, /* firstOpen */
- NULL, /* lastClose */
- sccPollRead, /* pollRead */
- sccPollWrite, /* write */
- sccSetAttributes, /* setAttributes */
- NULL, /* stopRemoteTx */
- NULL, /* startRemoteTx */
- 0 /* outputUsesInterrupts */
- };
-
- if (m8xx_scc_mode[chan] == TERMIOS_IRQ_DRIVEN) {
- status = rtems_termios_open (major, minor, arg, &interruptCallbacks);
- sccttyp[chan] = args->iop->data1;
- }
- else {
- status = rtems_termios_open (major, minor, arg, &pollCallbacks);
- sccttyp[chan] = args->iop->data1;
- }
- return status;
-}
-
-/*
- * Close the device
- */
-rtems_device_driver console_close(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
- )
-{
- rtems_status_code rc;
-
- rc = rtems_termios_close (arg);
- sccttyp[minor] = NULL;
-
- return rc;
-
-}
-
-/*
- * Read from the device
- */
-rtems_device_driver console_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
- )
-{
- return rtems_termios_read (arg);
-}
-
-/*
- * Write to the device
- */
-rtems_device_driver console_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
- )
-{
- return rtems_termios_write (arg);
-}
-
-#if 0
-static int scc_io_set_trm_char(rtems_device_minor_number minor,
- rtems_libio_ioctl_args_t *ioa)
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- con360_io_trm_char_t *trm_char_info = ioa->buffer;
-
- /*
- * check, that parameter is non-NULL
- */
- if ((rc == RTEMS_SUCCESSFUL) &&
- (trm_char_info == NULL)) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- /*
- * transfer max_idl
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if (trm_char_info->max_idl >= 0x10000) {
- rc = RTEMS_INVALID_NUMBER;
- }
- else if (trm_char_info->max_idl > 0) {
- CHN_PARAM_SET(minor,un.uart.max_idl ,trm_char_info->max_idl);
- }
- else if (trm_char_info->max_idl == 0) {
- CHN_PARAM_SET(minor,un.uart.max_idl ,MAX_IDL_DEFAULT);
- }
- }
- /*
- * transfer characters
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if (trm_char_info->char_cnt > CON8XX_TRM_CHAR_CNT) {
- rc = RTEMS_TOO_MANY;
- }
- else if (trm_char_info->char_cnt >= 0) {
- /*
- * check, whether device is a SCC
- */
- if ((rc == RTEMS_SUCCESSFUL) &&
- !m8xx_console_chan_desc[minor].is_scc) {
- rc = RTEMS_UNSATISFIED;
- }
- else {
- int idx = 0;
- for(idx = 0;idx < trm_char_info->char_cnt;idx++) {
- m8xx_console_chan_desc[minor].parms.sccp->un.uart.character[idx] =
- trm_char_info->character[idx] & 0x00ff;
- }
- if (trm_char_info->char_cnt < CON8XX_TRM_CHAR_CNT) {
- m8xx_console_chan_desc[minor].parms.sccp
- ->un.uart.character[trm_char_info->char_cnt] = 0x8000;
- }
- }
- }
- }
-
- return rc;
-}
-#endif
-
-/*
- * Handle ioctl request.
- */
-rtems_device_driver console_control(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void * arg
- )
-{
- rtems_libio_ioctl_args_t *ioa=arg;
-
- switch (ioa->command) {
-#if 0
- case CON8XX_IO_SET_TRM_CHAR:
- return scc_io_set_trm_char(minor, ioa);
-#endif
- default:
- return rtems_termios_ioctl (arg);
- break;
- }
-}
-