示例#1
0
/*
 * Soak up buffer descriptors that have been sent
 * Note that a buffer descriptor can't be retired as soon as it becomes
 * ready.  The MC68360 Errata (May 96) says that, "If an Ethernet frame is
 *  made up of multiple buffers, the user should not reuse the first buffer
 * descriptor until the last buffer descriptor of the frame has had its
 * ready bit cleared by the CPM".
 */
static void
m8260Enet_retire_tx_bd (struct m8260_hdlc_struct *sc)
{
  uint16_t         status;
  int i;
  int nRetired;
  struct mbuf *m, *n;

  i = sc->txBdTail;
  nRetired = 0;
  while ((sc->txBdActiveCount != 0)
         &&  (((status = (sc->txBdBase + i)->status) & M8260_BD_READY) == 0)) {
    /*
     * See if anything went wrong
     */
    if (status & (M8260_BD_UNDERRUN |
                  M8260_BD_CTS_LOST)) {
      /*
       * Check for errors which stop the transmitter.
       */
      if( status & M8260_BD_UNDERRUN ) {
          hdlc_driver[0].txUnderrun++;

        /*
         * Restart the transmitter
         */
        /* FIXME: this should get executed only if using the SCC */
        m8xx_cp_execute_cmd (M8260_CR_OP_RESTART_TX | M8260_CR_SCC3);
      }
      if (status & M8260_BD_CTS_LOST)
        hdlc_driver[0].txLostCarrier++;
    }
    nRetired++;
    if (status & M8260_BD_LAST) {
      /*
       * A full frame has been transmitted.
       * Free all the associated buffer descriptors.
       */
      sc->txBdActiveCount -= nRetired;
      while (nRetired) {
        nRetired--;
        m = sc->txMbuf[sc->txBdTail];
        MFREE (m, n);
        if (++sc->txBdTail == sc->txBdCount)
          sc->txBdTail = 0;
      }
    }
    if (++i == sc->txBdCount)
      i = 0;
  }
}
void
m8xx_uart_smc_initialize (int minor)
{
    unsigned char brg;
    volatile m8xxSMCparms_t *smcparms = 0;
    volatile m8xxSMCRegisters_t *smcregs = 0;

    /*
     * Check that minor number is valid
     */
    if ( (minor < SMC1_MINOR) || (minor > SMC2_MINOR) )
        return;

    m8xx.sdcr = 0x01;                 /* as per section 16.10.2.1 MPC821UM/AD */
    /* Get the simode clock source bit values for 9600 bps */
    brg = m8xx_get_brg_clk(9600);

    /*
     * Allocate buffer descriptors
     */
    RxBd[minor] = m8xx_bd_allocate (1);
    TxBd[minor] = m8xx_bd_allocate (1);

    /*
     *  Get the address of the parameter RAM for the specified port,
     *  configure I/O port B and put SMC in NMSI mode, connect the
     *  SMC to the appropriate BRG.
     *
     *  SMC2 RxD is shared with port B bit 20
     *  SMC2 TxD is shared with port B bit 21
     *  SMC1 RxD is shared with port B bit 24
     *  SMC1 TxD is shared with port B bit 25
     */
    switch (minor) {
    case SMC1_MINOR:
        smcparms = &m8xx.smc1p;
        smcregs = &m8xx.smc1;

        m8xx.pbpar |=  0x000000C0;    /* PB24 & PB25 are dedicated peripheral pins */
        m8xx.pbdir &= ~0x000000C0;    /* PB24 & PB25 must not drive UART lines */
        m8xx.pbodr &= ~0x000000C0;    /* PB24 & PB25 are not open drain */

        m8xx.simode &= 0xFFFF0FFF;    /* Clear SMC1CS & SMC1 for NMSI mode */
        m8xx.simode |= brg << 12;     /* SMC1CS = brg */
        break;

    case SMC2_MINOR:
        smcparms = &m8xx.smc2p;
        smcregs = &m8xx.smc2;

        m8xx.pbpar |=  0x00000C00;    /* PB20 & PB21 are dedicated peripheral pins */
        m8xx.pbdir &= ~0x00000C00;    /* PB20 & PB21 must not drive the UART lines */
        m8xx.pbodr &= ~0x00000C00;    /* PB20 & PB21 are not open drain */

        m8xx.simode &= 0x0FFFFFFF;    /* Clear SMC2CS & SMC2 for NMSI mode */
        m8xx.simode |= brg << 28;     /* SMC2CS = brg */
        break;
    }

    /*
     * Set up SMC1 parameter RAM common to all protocols
     */
    smcparms->rbase = (char *)RxBd[minor] - (char *)&m8xx;
    smcparms->tbase = (char *)TxBd[minor] - (char *)&m8xx;
    smcparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
    smcparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 )
        smcparms->mrblr = RXBUFSIZE;    /* Maximum Rx buffer size */
    else
        smcparms->mrblr = 1;            /* Maximum Rx buffer size */

    /*
     * Set up SMC1 parameter RAM UART-specific parameters
     */
    smcparms->un.uart.max_idl = 10;   /* Set nb of idle chars to close buffer */
    smcparms->un.uart.brkcr = 0;      /* Set nb of breaks to send for STOP Tx */
    smcparms->un.uart.brkec = 0;      /* Clear break counter */

    /*
     * Set up the Receive Buffer Descriptor
     */
    RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
    RxBd[minor]->length = 0;
    RxBd[minor]->buffer = rxBuf[minor];

    /*
     * Setup the Transmit Buffer Descriptor
     */
    TxBd[minor]->status = M8xx_BD_WRAP;

    /*
     * Set up SMCx general and protocol-specific mode registers
     */
    smcregs->smce = ~0;               /* Clear any pending events */
    smcregs->smcm = 0;                /* Enable SMC Rx & Tx interrupts */
    smcregs->smcmr = M8xx_SMCMR_CLEN(9) | M8xx_SMCMR_SM_UART;

    /*
     * Send "Init parameters" command
     */
    switch (minor) {
    case SMC1_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC1);
        break;

    case SMC2_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC2);
        break;
    }

    /*
     * Enable receiver and transmitter
     */
    smcregs->smcmr |= M8xx_SMCMR_TEN | M8xx_SMCMR_REN;
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
        consoleIrqData.on = m8xx_smc_enable;
        consoleIrqData.off = m8xx_smc_disable;
        consoleIrqData.isOn = m8xx_smc_isOn;
        switch (minor) {
        case SMC1_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SMC1;
            consoleIrqData.hdl  = m8xx_smc1_interrupt_handler;
            break;

        case SMC2_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SMC2_OR_PIP;
            consoleIrqData.hdl  = m8xx_smc2_interrupt_handler;
            break;
        }
        if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
            printk("Unable to connect SMC Irq handler\n");
            rtems_fatal_error_occurred(1);
        }
    }
}
void
m8xx_uart_scc_initialize (int minor)
{
    unsigned char brg;
    volatile m8xxSCCparms_t *sccparms = 0;
    volatile m8xxSCCRegisters_t *sccregs = 0;

    /*
     * Check that minor number is valid
     */
    if ( (minor < SCC2_MINOR) || (minor > NUM_PORTS-1) )
        return;

    /* Get the sicr clock source bit values for 9600 bps */
    brg = m8xx_get_brg_clk(9600);

    /*
     * Allocate buffer descriptors
     */
    RxBd[minor] = m8xx_bd_allocate(1);
    TxBd[minor] = m8xx_bd_allocate(1);

    /*
     *  Get the address of the parameter RAM for the specified port,
     *  configure I/O port A,C & D and put SMC in NMSI mode, connect
     *  the SCC to the appropriate BRG.
     *
     *  SCC2 TxD is shared with port A bit 12
     *  SCC2 RxD is shared with port A bit 13
     *  SCC1 TxD is shared with port A bit 14
     *  SCC1 RxD is shared with port A bit 15
     *  SCC4 DCD is shared with port C bit 4
     *  SCC4 CTS is shared with port C bit 5
     *  SCC3 DCD is shared with port C bit 6
     *  SCC3 CTS is shared with port C bit 7
     *  SCC2 DCD is shared with port C bit 8
     *  SCC2 CTS is shared with port C bit 9
     *  SCC1 DCD is shared with port C bit 10
     *  SCC1 CTS is shared with port C bit 11
     *  SCC2 RTS is shared with port C bit 14
     *  SCC1 RTS is shared with port C bit 15
     *  SCC4 RTS is shared with port D bit 6
     *  SCC3 RTS is shared with port D bit 7
     *  SCC4 TxD is shared with port D bit 8
     *  SCC4 RxD is shared with port D bit 9
     *  SCC3 TxD is shared with port D bit 10
     *  SCC3 RxD is shared with port D bit 11
     */
    switch (minor) {
    case SCC2_MINOR:
        sccparms = &m8xx.scc2p;
        sccregs = &m8xx.scc2;

        m8xx.papar |=  0x000C;        /* PA12 & PA13 are dedicated peripheral pins */
        m8xx.padir &= ~0x000C;        /* PA13 & PA12 must not drive the UART lines */
        m8xx.paodr &= ~0x000C;        /* PA12 & PA13 are not open drain */
        m8xx.pcpar |=  0x0002;        /* PC14 is SCC2 RTS */
        m8xx.pcpar &= ~0x00C0;        /* PC8 & PC9 are SCC2 DCD and CTS */
        m8xx.pcdir &= ~0x00C2;        /* PC8, PC9 & PC14 must not drive the UART lines */
        m8xx.pcso  |=  0x00C0;        /* Enable DCD and CTS inputs */

        m8xx.sicr &= 0xFFFF00FF;      /* Clear TCS2 & RCS2, GR2=no grant, SC2=NMSI mode */
        m8xx.sicr |= (brg<<11) | (brg<<8); /* TCS2 = RCS2 = brg */
        break;

#ifdef mpc860
    case SCC3_MINOR:
        sccparms = &m8xx.scc3p;
        sccregs = &m8xx.scc3;

        m8xx.pcpar &= ~0x0300;        /* PC6 & PC7 are SCC3 DCD and CTS */
        m8xx.pcdir &= ~0x0300;        /* PC6 & PC7 must not drive the UART lines */
        m8xx.pcso  |=  0x0300;        /* Enable DCD and CTS inputs */
        m8xx.pdpar |=  0x0130;        /* PD7, PD10 & PD11 are dedicated peripheral pins */

        m8xx.sicr &= 0xFF00FFFF;      /* Clear TCS3 & RCS3, GR3=no grant, SC3=NMSI mode */
        m8xx.sicr |= (brg<<19) | (brg<<16); /* TCS3 = RCS3 = brg */
        break;

    case SCC4_MINOR:
        sccparms = &m8xx.scc4p;
        sccregs = &m8xx.scc4;

        m8xx.pcpar &= ~0x0C00;        /* PC4 & PC5 are SCC4 DCD and CTS */
        m8xx.pcdir &= ~0x0C00;        /* PC4 & PC5 must not drive the UART lines */
        m8xx.pcso  |=  0x0C00;        /* Enable DCD and CTS inputs */
        m8xx.pdpar |=  0x02C0;        /* PD6, PD8 & PD9 are dedicated peripheral pins */

        m8xx.sicr &= 0x00FFFFFF;      /* Clear TCS4 & RCS4, GR4=no grant, SC4=NMSI mode */
        m8xx.sicr |= (brg<<27) | (brg<<24); /* TCS4 = RCS4 = brg */
        break;
#endif
    }

    /*
     *  Set up SDMA
     */
    m8xx.sdcr = 0x01;                 /* as per section 16.10.2.1 MPC821UM/AD */

    /*
     *  Set up the SCC parameter RAM.
     */
    sccparms->rbase = (char *)RxBd[minor] - (char *)&m8xx;
    sccparms->tbase = (char *)TxBd[minor] - (char *)&m8xx;

    sccparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
    sccparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 )
        sccparms->mrblr = RXBUFSIZE;    /* Maximum Rx buffer size */
    else
        sccparms->mrblr = 1;            /* Maximum Rx buffer size */
    sccparms->un.uart.max_idl = 10;   /* Set nb of idle chars to close buffer */
    sccparms->un.uart.brkcr = 0;      /* Set nb of breaks to send for STOP Tx */

    sccparms->un.uart.parec = 0;      /* Clear parity error counter */
    sccparms->un.uart.frmec = 0;      /* Clear framing error counter */
    sccparms->un.uart.nosec = 0;      /* Clear noise counter */
    sccparms->un.uart.brkec = 0;      /* Clear break counter */

    sccparms->un.uart.uaddr[0] = 0;   /* Not in multidrop mode, so clear */
    sccparms->un.uart.uaddr[1] = 0;   /* Not in multidrop mode, so clear */
    sccparms->un.uart.toseq  = 0;     /* Tx Out-Of-SEQuence--no XON/XOFF now */

    sccparms->un.uart.character[0] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[1] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[2] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[3] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[4] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[5] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[6] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[7] = 0x8000; /* Entry is invalid */


    sccparms->un.uart.rccm = 0xc0ff;  /* No masking */

    /*
     * Set up the Receive Buffer Descriptor
     */
    RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
    RxBd[minor]->length = 0;
    RxBd[minor]->buffer = rxBuf[minor];

    /*
     * Setup the Transmit Buffer Descriptor
     */
    TxBd[minor]->status = M8xx_BD_WRAP;

    /*
      * Set up SCCx general and protocol-specific mode registers
      */
    sccregs->gsmr_h = 0x00000020;     /* RFW=low latency operation */
    sccregs->gsmr_l = 0x00028004;     /* TDCR=RDCR=16x clock mode, MODE=uart*/
    sccregs->scce = ~0;               /* Clear any pending event */
    sccregs->sccm = 0;                /* Mask all interrupt/event sources */
    sccregs->psmr = 0x3000;           /* Normal operation & mode, 1 stop bit,
                                       8 data bits, no parity */
    sccregs->dsr = 0x7E7E;            /* No fractional stop bits */
    sccregs->gsmr_l = 0x00028034;     /* ENT=enable Tx, ENR=enable Rx */

    /*
     *  Initialize the Rx and Tx with the new parameters.
     */
    switch (minor) {
    case SCC2_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC2);
        break;

#ifdef mpc860
    case SCC3_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC3);
        break;
    case SCC4_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC4);
        break;
#endif
    }
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
        consoleIrqData.on = m8xx_scc_enable;
        consoleIrqData.off = m8xx_scc_disable;
        consoleIrqData.isOn = m8xx_scc_isOn;

        switch (minor) {
        case SCC2_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SCC2;
            consoleIrqData.hdl = m8xx_scc2_interrupt_handler;
            break;

#ifdef mpc860
        case SCC3_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SCC3;
            consoleIrqData.hdl = m8xx_scc3_interrupt_handler;
            break;

        case SCC4_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SCC4;
            consoleIrqData.hdl = m8xx_scc4_interrupt_handler;
            break;
#endif /* mpc860 */
        }
        if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
            printk("Unable to connect SCC Irq handler\n");
            rtems_fatal_error_occurred(1);
        }
    }
}
示例#4
0
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) {
    BSP_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");
    }
  }
}
示例#5
0
/*
 *  bsp_start()
 *
 *  Board-specific initialization code. Called from the generic boot_card()
 *  function defined in rtems/c/src/lib/libbsp/shared/main.c. That function
 *  does some of the board independent initialization. It is called from the
 *  MBX8xx entry point _start() defined in
 *  rtems/c/src/lib/libbsp/powerpc/mbx8xx/startup/start.S
 *
 *  _start() has set up a stack, has zeroed the .bss section, has turned off
 *  interrupts, and placed the processor in the supervisor mode. boot_card()
 *  has left the processor in that state when bsp_start() was called.
 *
 *  RUNS WITH ADDRESS TRANSLATION AND CACHING TURNED OFF!
 *  ASSUMES THAT THE VIRTUAL ADDRESSES WILL BE IDENTICAL TO THE PHYSICAL
 *  ADDRESSES. Software-controlled address translation would be required
 *  otherwise.
 *
 *  Input parameters: NONE
 *
 *  Output parameters: NONE
 *
 *  Return values: NONE
 */
void bsp_start(void)
{
  ppc_cpu_id_t myCpu;
  ppc_cpu_revision_t myCpuRevision;

  /*
   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
   * store the result in global variables so that it can be used latter...
   */
  myCpu 	= get_ppc_cpu_type();
  myCpuRevision = get_ppc_cpu_revision();

  mmu_init();

  /*
   * Enable instruction and data caches. Do not force writethrough mode.
   */
#if NVRAM_CONFIGURE == 1
  if ( nvram->cache_mode & 0x02 )
    rtems_cache_enable_instruction();
  if ( nvram->cache_mode & 0x01 )
    rtems_cache_enable_data();
#else
#if BSP_INSTRUCTION_CACHE_ENABLED
  rtems_cache_enable_instruction();
#endif
#if BSP_DATA_CACHE_ENABLED
  rtems_cache_enable_data();
#endif
#endif

  /* Initialize exception handler */
  ppc_exc_initialize(
    PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
    (uintptr_t) IntrStack_start,
    (uintptr_t) intrStack - (uintptr_t) IntrStack_start
  );

  /* Initalize interrupt support */
  bsp_interrupt_initialize();

  /*
   *  initialize the device driver parameters
   */

#if    ( defined(mbx860_001b) || \
         defined(mbx860_002b) || \
         defined(mbx860_003b) || \
         defined(mbx860_003b) || \
         defined(mbx860_004b) || \
         defined(mbx860_005b) || \
         defined(mbx860_006b) || \
         defined(mbx821_001b) || \
         defined(mbx821_002b) || \
         defined(mbx821_003b) || \
         defined(mbx821_004b) || \
         defined(mbx821_005b) || \
         defined(mbx821_006b))
  bsp_clicks_per_usec = 0;  /* for 32768Hz extclk */
#else
  bsp_clicks_per_usec = 1;  /* for 4MHz extclk */
#endif

  bsp_serial_per_sec = 10000000;
  bsp_serial_external_clock = true;
  bsp_serial_xon_xoff = false;
  bsp_serial_cts_rts = true;
  bsp_serial_rate = 9600;
#if ( defined(mbx821_001) || defined(mbx821_001b) || defined(mbx860_001b) )
  bsp_clock_speed = 50000000;
  bsp_timer_average_overhead = 3;
  bsp_timer_least_valid = 3;
#else
  bsp_clock_speed = 40000000;
  bsp_timer_average_overhead = 3;
  bsp_timer_least_valid = 3;
#endif

  m8xx.scc2.sccm=0;
  m8xx.scc2p.rbase=0;
  m8xx.scc2p.tbase=0;
  m8xx_cp_execute_cmd( M8xx_CR_OP_STOP_TX | M8xx_CR_CHAN_SCC2 );

#ifdef SHOW_MORE_INIT_SETTINGS
  printk("Exit from bspstart\n");
#endif

}
示例#6
0
/*
 * Initialize the SCC hardware
 * Configure I/O ports for SCC3
 * Internal Tx clock, External Rx clock
 */
static void
m8260_scc_initialize_hardware (struct m8260_hdlc_struct *sc)
{
  int i;
  int brg;

  rtems_status_code status;

  /* RxD PB14 */
  m8260.pparb |=  0x00020000;
  m8260.psorb &= ~0x00020000;
  m8260.pdirb &= ~0x00020000;

  /* RxC (CLK5) PC27 */
  m8260.pparc |=  0x00000010;
  m8260.psorc &= ~0x00000010;
  m8260.pdirc &= ~0x00000010;

  /* TxD PD24 and TxC PD10 (BRG4) */
  m8260.ppard |=  0x00200080;
  m8260.psord |=  0x00200000;
  m8260.psord &= ~0x00000080;
  m8260.pdird |=  0x00200080;

  /* External Rx Clock from CLK5 */
  if( m8xx_get_clk( M8xx_CLK_5 ) == -1 )
    printk( "Error allocating CLK5 for network device.\n" );
  else
    m8260.cmxscr |= 0x00002000;

  /* Internal Tx Clock from BRG4 */
  if( (brg = m8xx_get_brg(M8xx_BRG_4, 8000000 )) == -1 )
    printk( "Error allocating BRG for network device\n" );
  else
    m8260.cmxscr |= ((unsigned)brg << 8);

  /*
   * Allocate mbuf pointers
   */
  sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
		       M_MBUF, M_NOWAIT);
  sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
		       M_MBUF, M_NOWAIT);
  if (!sc->rxMbuf || !sc->txMbuf)
    rtems_panic ("No memory for mbuf pointers");

  /*
   * Set receiver and transmitter buffer descriptor bases
   */
  sc->rxBdBase = m8xx_bd_allocate (sc->rxBdCount);
  sc->txBdBase = m8xx_bd_allocate (sc->txBdCount);

  m8260.scc3p.rbase = (char *)sc->rxBdBase - (char *)&m8260;
  m8260.scc3p.tbase = (char *)sc->txBdBase - (char *)&m8260;

  /*
   * Send "Init parameters" command
   */

  m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC3 );

  /*
   * Set receive and transmit function codes
   */
  m8260.scc3p.rfcr = M8260_RFCR_MOT | M8260_RFCR_60X_BUS;
  m8260.scc3p.tfcr = M8260_TFCR_MOT | M8260_TFCR_60X_BUS;

  /*
   * Set maximum receive buffer length
   */
  m8260.scc3p.mrblr = RBUF_SIZE;

  m8260.scc3p.un.hdlc.c_mask = 0xF0B8;
  m8260.scc3p.un.hdlc.c_pres = 0xFFFF;
  m8260.scc3p.un.hdlc.disfc  = 0;
  m8260.scc3p.un.hdlc.crcec  = 0;
  m8260.scc3p.un.hdlc.abtsc  = 0;
  m8260.scc3p.un.hdlc.nmarc  = 0;
  m8260.scc3p.un.hdlc.retrc  = 0;
  m8260.scc3p.un.hdlc.rfthr  = 1;
  m8260.scc3p.un.hdlc.mflr   = RBUF_SIZE;

  m8260.scc3p.un.hdlc.hmask  = 0x0000;	/* promiscuous */

  m8260.scc3p.un.hdlc.haddr1 = 0xFFFF;	/* Broadcast address */
  m8260.scc3p.un.hdlc.haddr2 = 0xFFFF;	/* Station address */
  m8260.scc3p.un.hdlc.haddr3 = 0xFFFF;	/* Dummy */
  m8260.scc3p.un.hdlc.haddr4 = 0xFFFF;	/* Dummy */

  /*
   * Send "Init parameters" command
   */
/*
  m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC3 );
*/

  /*
   * Set up receive buffer descriptors
   */
  for (i = 0 ; i < sc->rxBdCount ; i++) {
    (sc->rxBdBase + i)->status = 0;
  }

  /*
   * Set up transmit buffer descriptors
   */
  for (i = 0 ; i < sc->txBdCount ; i++) {
    (sc->txBdBase + i)->status = 0;
    sc->txMbuf[i] = NULL;
  }
  sc->txBdHead = sc->txBdTail = 0;
  sc->txBdActiveCount = 0;

  m8260.scc3.sccm = 0;     /* No interrupts unmasked till necessary */

  /*
   * Clear any outstanding events
   */
  m8260.scc3.scce = 0xFFFF;

  /*
   * Set up interrupts
   */
  status = BSP_install_rtems_irq_handler (&hdlcSCC3IrqData);
/*
  printk( "status = %d, Success = %d\n", status, RTEMS_SUCCESSFUL );
*/
  if (status != 1 /*RTEMS_SUCCESSFUL*/ ) {
    rtems_panic ("Can't attach M8260 SCC3 interrupt handler: %s\n",
		 rtems_status_text (status));
  }
  m8260.scc3.sccm = 0;     /* No interrupts unmasked till necessary */

  m8260.scc3.gsmr_h  = 0;
  m8260.scc3.gsmr_l  = 0x10000000;
  m8260.scc3.dsr     = 0x7E7E;	/* flag character */
  m8260.scc3.psmr    = 0x2000;	/* 2 flags between Tx'd frames */

/*  printk("scc3 init\n" ); */

  m8260.scc3.gsmr_l |=  0x00000030;  /* Set ENR and ENT to enable Rx and Tx */

}
示例#7
0
文件: network_scc.c 项目: AoLaD/rtems
/*
 * Soak up buffer descriptors that have been sent.
 * Note that a buffer descriptor can't be retired as soon as it becomes
 * ready. The MPC860 manual (MPC860UM/AD 07/98 Rev.1) and the MPC821
 * manual state that, "If an Ethernet frame is made up of multiple
 * buffers, the user should not reuse the first buffer descriptor until
 * the last buffer descriptor of the frame has had its ready bit cleared
 * by the CPM".
 */
static void
m8xx_Enet_retire_tx_bd (struct m8xx_enet_struct *sc)
{
  uint16_t   status;
  int i;
  int nRetired;
  struct mbuf *m, *n;

  i = sc->txBdTail;
  nRetired = 0;
  while ((sc->txBdActiveCount != 0)
	 &&  (((status = (sc->txBdBase + i)->status) & M8xx_BD_READY) == 0)) {
    /*
     * See if anything went wrong
     */
    if (status & (M8xx_BD_DEFER |
                  M8xx_BD_HEARTBEAT |
                  M8xx_BD_LATE_COLLISION |
                  M8xx_BD_RETRY_LIMIT |
                  M8xx_BD_UNDERRUN |
                  M8xx_BD_CARRIER_LOST)) {
      /*
       * Check for errors which stop the transmitter.
       */
      if (status & (M8xx_BD_LATE_COLLISION |
                    M8xx_BD_RETRY_LIMIT |
                    M8xx_BD_UNDERRUN)) {
        if (status & M8xx_BD_LATE_COLLISION)
          enet_driver[0].txLateCollision++;
        if (status & M8xx_BD_RETRY_LIMIT)
          enet_driver[0].txRetryLimit++;
        if (status & M8xx_BD_UNDERRUN)
          enet_driver[0].txUnderrun++;

        /*
         * Restart the transmitter
         */
        m8xx_cp_execute_cmd (M8xx_CR_OP_RESTART_TX | M8xx_CR_CHAN_SCC1);
      }
      if (status & M8xx_BD_DEFER)
        enet_driver[0].txDeferred++;
      if (status & M8xx_BD_HEARTBEAT)
        enet_driver[0].txHeartbeat++;
      if (status & M8xx_BD_CARRIER_LOST)
        enet_driver[0].txLostCarrier++;
    }
    nRetired++;
    if (status & M8xx_BD_LAST) {
      /*
       * A full frame has been transmitted.
       * Free all the associated buffer descriptors.
       */
      sc->txBdActiveCount -= nRetired;
      while (nRetired) {
        nRetired--;
        m = sc->txMbuf[sc->txBdTail];
        MFREE (m, n);
        if (++sc->txBdTail == sc->txBdCount)
          sc->txBdTail = 0;
      }
    }
    if (++i == sc->txBdCount)
      i = 0;
  }
}
示例#8
0
文件: network_scc.c 项目: AoLaD/rtems
/*
 * Initialize the ethernet hardware
 */
static void
m8xx_enet_initialize (struct m8xx_enet_struct *sc)
{
  int i;
  unsigned char *hwaddr;

  /*
   * Configure port A
   * PA15 is enet RxD. Set PAPAR(15) to 1, PADIR(15) to 0.
   * PA14 is enet TxD. Set PAPAR(14) to 1, PADIR(14) to 0, PAODR(14) to 0.
   * PA7 is input CLK1. Set PAPAR(7) to 1, PADIR(7) to 0.
   * PA6 is input CLK2. Set PAPAR(6) to 1, PADIR(6) to 0.
   */
  m8xx.papar |=  0x303;
  m8xx.padir &= ~0x303;
  m8xx.paodr &= ~0x2;

  /*
   * Configure port C
   * PC11 is CTS1*. Set PCPAR(11) to 0, PCDIR(11) to 0, and PCSO(11) to 1.
   * PC10 is CD1*. Set PCPAR(10) to 0, PCDIR(10) to 0, and PCSO(10) to 1.
   */
  m8xx.pcpar &= ~0x30;
  m8xx.pcdir &= ~0x30;
  m8xx.pcso  |=  0x30;

  /*
   * Connect CLK1 and CLK2 to SCC1 in the SICR.
   * CLK1 is TxClk, CLK2 is RxClk. No grant mechanism, SCC1 is directly
   * connected to the NMSI pins.
   * R1CS = 0b101 (CLK2)
   * T1CS = 0b100 (CLK1)
   */
  m8xx.sicr |= 0x2C;

  /*
   * Initialize SDMA configuration register
   */
  m8xx.sdcr = 1;

  /*
   * Allocate mbuf pointers
   */
  sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
		       M_MBUF, M_NOWAIT);
  sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
		       M_MBUF, M_NOWAIT);
  if (!sc->rxMbuf || !sc->txMbuf)
    rtems_panic ("No memory for mbuf pointers");

  /*
   * Set receiver and transmitter buffer descriptor bases
   */
  sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
  sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
  m8xx.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m8xx;
  m8xx.scc1p.tbase = (char *)sc->txBdBase - (char *)&m8xx;

  /*
   * Send "Init parameters" command
   */
  m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC1);

  /*
   * Set receive and transmit function codes
   */
  m8xx.scc1p.rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
  m8xx.scc1p.tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);

  /*
   * Set maximum receive buffer length
   */
  m8xx.scc1p.mrblr = RBUF_SIZE;

  /*
   * Set CRC parameters
   */
  m8xx.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
  m8xx.scc1p.un.ethernet.c_mask = 0xDEBB20E3;

  /*
   * Clear diagnostic counters
   */
  m8xx.scc1p.un.ethernet.crcec = 0;
  m8xx.scc1p.un.ethernet.alec = 0;
  m8xx.scc1p.un.ethernet.disfc = 0;

  /*
   * Set pad value
   */
  m8xx.scc1p.un.ethernet.pads = 0x8888;

  /*
   * Set retry limit
   */
  m8xx.scc1p.un.ethernet.ret_lim = 15;

  /*
   * Set maximum and minimum frame length
   */
  m8xx.scc1p.un.ethernet.mflr = 1518;
  m8xx.scc1p.un.ethernet.minflr = 64;
  m8xx.scc1p.un.ethernet.maxd1 = MAX_MTU_SIZE;
  m8xx.scc1p.un.ethernet.maxd2 = MAX_MTU_SIZE;

  /*
   * Clear group address hash table
   */
  m8xx.scc1p.un.ethernet.gaddr1 = 0;
  m8xx.scc1p.un.ethernet.gaddr2 = 0;
  m8xx.scc1p.un.ethernet.gaddr3 = 0;
  m8xx.scc1p.un.ethernet.gaddr4 = 0;

  /*
   * Set our physical address
   */
  hwaddr = sc->arpcom.ac_enaddr;

  m8xx.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
  m8xx.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
  m8xx.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];

  /*
   * Aggressive retry
   */
  m8xx.scc1p.un.ethernet.p_per = 0;

  /*
   * Clear individual address hash table
   */
  m8xx.scc1p.un.ethernet.iaddr1 = 0;
  m8xx.scc1p.un.ethernet.iaddr2 = 0;
  m8xx.scc1p.un.ethernet.iaddr3 = 0;
  m8xx.scc1p.un.ethernet.iaddr4 = 0;

  /*
   * Clear temp address
   */
  m8xx.scc1p.un.ethernet.taddr_l = 0;
  m8xx.scc1p.un.ethernet.taddr_m = 0;
  m8xx.scc1p.un.ethernet.taddr_h = 0;

  /*
   * Set up receive buffer descriptors
   */
  for (i = 0 ; i < sc->rxBdCount ; i++) {
    (sc->rxBdBase + i)->status = 0;
  }

  /*
   * Set up transmit buffer descriptors
   */
  for (i = 0 ; i < sc->txBdCount ; i++) {
    (sc->txBdBase + i)->status = 0;
    sc->txMbuf[i] = NULL;
  }
  sc->txBdHead = sc->txBdTail = 0;
  sc->txBdActiveCount = 0;

  /*
   * Clear any outstanding events
   */
  m8xx.scc1.scce = 0xFFFF;

  /*
   * Set up interrupts
   */
  if (!BSP_install_rtems_irq_handler (&ethernetSCC1IrqData)) {
    rtems_panic ("Can't attach M8xx SCC1 interrupt handler\n");
  }
  m8xx.scc1.sccm = 0;     /* No interrupts unmasked till necessary */

  /*
   * Set up General SCC Mode Register
   * Ethernet configuration
   */
  m8xx.scc1.gsmr_h = 0x0;
  m8xx.scc1.gsmr_l = 0x1088000c;

  /*
   * Set up data synchronization register
   * Ethernet synchronization pattern
   */
  m8xx.scc1.dsr = 0xd555;

  /*
   * Set up protocol-specific mode register
   *      No Heartbeat check
   *      No force collision
   *      Discard short frames
   *      Individual address mode
   *      Ethernet CRC
   *      Not promisuous
   *      Ignore/accept broadcast packets as specified
   *      Normal backoff timer
   *      No loopback
   *      No input sample at end of frame
   *      64-byte limit for late collision
   *      Wait 22 bits before looking for start of frame delimiter
   *      Disable full-duplex operation
   */
  m8xx.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);

  /*
   * Enable the TENA (RTS1*) pin
   */
  m8xx.pcpar |=  0x1;
  m8xx.pcdir &= ~0x1;

  /*
   * Enable receiver and transmitter
   */
  m8xx.scc1.gsmr_l = 0x1088003c;
}
示例#9
0
文件: spi.c 项目: AlexShiLucky/rtems
/*=========================================================================*\
| Function:                                                                 |
\*-------------------------------------------------------------------------*/
rtems_status_code m8xx_spi_init
(
/*-------------------------------------------------------------------------*\
| Purpose:                                                                  |
|   initialize the driver                                                   |
+---------------------------------------------------------------------------+
| Input Parameters:                                                         |
\*-------------------------------------------------------------------------*/
 rtems_libi2c_bus_t *bh                  /* bus specifier structure        */
)
/*-------------------------------------------------------------------------*\
| Return Value:                                                             |
|    o = ok or error code                                                   |
\*=========================================================================*/
{
  m8xx_spi_softc_t *softc_ptr = &(((m8xx_spi_desc_t *)(bh))->softc);
  rtems_status_code rc = RTEMS_SUCCESSFUL;

#if defined(DEBUG)
  printk("m8xx_spi_init called... ");
#endif
  /*
   * init HW registers:
   */
  /*
   * FIXME: set default mode in SPMODE
   */

  /*
   * allocate BDs (1x RX, 1x TX)
   */
  if (rc == RTEMS_SUCCESSFUL) {
    softc_ptr->rx_bd = m8xx_bd_allocate (1);
    softc_ptr->tx_bd = m8xx_bd_allocate (1);
    if ((softc_ptr->rx_bd == NULL) ||
	(softc_ptr->tx_bd == NULL)) {
      rc = RTEMS_NO_MEMORY;
    }
  }
  /*
   * set parameter RAM
   */
  m8xx.spip.rbase = (char *)softc_ptr->rx_bd - (char *)&m8xx;
  m8xx.spip.tbase = (char *)softc_ptr->tx_bd - (char *)&m8xx;
  m8xx.spip.rfcr  = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
  m8xx.spip.tfcr  = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
  m8xx.spip.mrblr = 2;

  /*
   * issue "InitRxTx" Command to CP
   */
  m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SPI);

  /*
   * init interrupt stuff
   */
  if (rc == RTEMS_SUCCESSFUL) {
    m8xx_spi_install_irq_handler(softc_ptr,TRUE);
  }
  if (rc == RTEMS_SUCCESSFUL) {
    /*
     * set up ports
     * LINE      PAR  DIR  DAT
     * -----------------------
     * MOSI       1    1    x
     * MISO       1    1    x
     * CLK        1    1    x
     */

    /* set Port B Pin Assignment Register... */
    m8xx.pbpar =
      m8xx.pbpar
      | M8xx_PB_SPI_MISO_MSK
      | M8xx_PB_SPI_MOSI_MSK
      | M8xx_PB_SPI_CLK_MSK;

    /* set Port B Data Direction Register... */
    m8xx.pbdir =
      m8xx.pbdir
      | M8xx_PB_SPI_MISO_MSK
      | M8xx_PB_SPI_MOSI_MSK
      | M8xx_PB_SPI_CLK_MSK;
  }
  /*
   * mark, that we have initialized
   */
  if (rc == RTEMS_SUCCESSFUL) {
    softc_ptr->initialized = TRUE;
  }
#if defined(DEBUG)
  printk("... exit OK\r\n");
#endif
  return rc;
}