Index: c/src/exec/score/cpu/powerpc/mpc860.h
===================================================================
--- c/src/exec/score/cpu/powerpc/mpc860.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/exec/score/cpu/powerpc/mpc860.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,1300 @@
+/*
+**************************************************************************
+**************************************************************************
+**                                                                      **
+**  MOTOROLA MPC860 POWER QUAD INTEGRATED COMMUNICATIONS CONTROLLER     **
+**                             POWERQUICC                               **
+**                                                                      **
+**                        HARDWARE DECLARATIONS                         **
+**                                                                      **
+**                                                                      **
+**  Submitted By:                                                       **
+**                                                                      **
+**      W. Eric Norum                                                   **
+**      Saskatchewan Accelerator Laboratory                             **
+**      University of Saskatchewan                                      **
+**      107 North Road                                                  **
+**      Saskatoon, Saskatchewan, CANADA                                 **
+**      S7N 5C6                                                         **
+**                                                                      **
+**      eric@skatter.usask.ca                                           **
+**                                                                      **
+**  Modified for use with the MPC860 (original code was for MC68360)    **
+**  by                                                                  **
+**      Jay Monkman                                                     **
+**      Frasca International, Inc.                                      **
+**      906 E. Airport Rd.                                              **
+**      Urbana, IL, 61801                                               **
+**                                                                      **
+**      jmonkman@frasca.com                                             **
+**                                                                      **
+**************************************************************************
+**************************************************************************
+*/
+
+#ifndef __MPC860_h
+#define __MPC860_h
+
+#ifndef ASM
+/*
+  Macros for SPRs
+*/
+
+#define M860_MI_CTR_GPM       (1<<31)
+#define M860_MI_CTR_PPM       (1<<30)
+#define M860_MI_CTR_CIDEF     (1<<29)
+#define M860_MI_CTR_RSV4I     (1<<27)
+#define M860_MI_CTR_PPCS      (1<<25)
+
+#define M860_MD_CTR_GPM       (1<<31)
+#define M860_MD_CTR_PPM       (1<<30)
+#define M860_MD_CTR_CIDEF     (1<<29)
+#define M860_MD_CTR_WTDEF     (1<<28)
+#define M860_MD_CTR_RSV4D     (1<<27)
+#define M860_MD_CTR_TWAM      (1<<26)
+#define M860_MD_CTR_PPCS      (1<<25)
+
+#define M860_MI_EPN_VALID     (1<<9)
+
+#define M860_MD_EPN_VALID     (1<<9)
+
+#define M860_MI_TWC_G         (1<<4)
+#define M860_MI_TWC_PSS       (0<<2)
+#define M860_MI_TWC_PS512     (1<<2)
+#define M860_MI_TWC_PS8       (3<<2)
+#define M860_MI_TWC_VALID     (1)
+
+#define M860_MD_TWC_G         (1<<4)
+#define M860_MD_TWC_PSS       (0<<2)
+#define M860_MD_TWC_PS512     (1<<2)
+#define M860_MD_TWC_PS8       (3<<2)
+#define M860_MD_TWC_WT        (1<<1)
+#define M860_MD_TWC_VALID     (1)
+
+#define M860_MI_RPN_F         (0xf<<4)
+#define M860_MI_RPN_16K       (1<<3)
+#define M860_MI_RPN_SHARED    (1<<2)
+#define M860_MI_RPN_CI        (1<<1)
+#define M860_MI_RPN_VALID     (1)
+
+#define M860_MD_RPN_CHANGE    (1<<8)
+#define M860_MD_RPN_F         (0xf<<4)
+#define M860_MD_RPN_16K       (1<<3)
+#define M860_MD_RPN_SHARED    (1<<2)
+#define M860_MD_RPN_CI        (1<<1)
+#define M860_MD_RPN_VALID     (1)
+
+#define M860_MI_AP_Kp         (1)
+
+#define M860_MD_AP_Kp         (1)
+
+#define M860_CACHE_CMD_SFWT          (0x1<<24)
+#define M860_CACHE_CMD_ENABLE        (0x2<<24)
+#define M860_CACHE_CMD_CFWT          (0x3<<24)
+#define M860_CACHE_CMD_DISABLE       (0x4<<24)
+#define M860_CACHE_CMD_STLES         (0x5<<24)
+#define M860_CACHE_CMD_LLCB          (0x6<<24)
+#define M860_CACHE_CMD_CLES          (0x7<<24)
+#define M860_CACHE_CMD_UNLOCK        (0x8<<24)
+#define M860_CACHE_CMD_UNLOCKALL     (0xa<<24)
+#define M860_CACHE_CMD_INVALIDATE    (0xc<<24)
+#define M860_CACHE_CMD_FLUSH         (0xe<<24)
+
+
+
+/*
+*************************************************************************
+*                         REGISTER SUBBLOCKS                            *
+*************************************************************************
+*/
+
+/*
+ * Memory controller registers
+ */
+typedef struct m860MEMCRegisters_ {
+  rtems_unsigned32        br;
+  rtems_unsigned32        or;
+} m860MEMCRegisters_t;
+
+/*
+ * Serial Communications Controller registers
+ */
+typedef struct m860SCCRegisters_ {
+  rtems_unsigned32        gsmr_l;
+  rtems_unsigned32        gsmr_h;
+  rtems_unsigned16        psmr;
+  rtems_unsigned16        _pad0;
+  rtems_unsigned16        todr;
+  rtems_unsigned16        dsr;
+  rtems_unsigned16        scce;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned16        sccm;
+  rtems_unsigned8         _pad2;
+  rtems_unsigned8         sccs;
+  rtems_unsigned32        _pad3[2];
+} m860SCCRegisters_t;
+
+/*
+ * Serial Management Controller registers
+ */
+typedef struct m860SMCRegisters_ {
+  rtems_unsigned16        _pad0;
+  rtems_unsigned16        smcmr;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned8         smce;
+  rtems_unsigned8         _pad2;
+  rtems_unsigned16        _pad3;
+  rtems_unsigned8         smcm;
+  rtems_unsigned8         _pad4;
+  rtems_unsigned32        _pad5;
+} m860SMCRegisters_t;
+
+/*
+ * Fast Ethernet Controller registers (Only on MPC860T)
+ */
+typedef struct m860FECRegisters_ {
+  rtems_unsigned32    addr_low;
+  rtems_unsigned32    addr_high;
+  rtems_unsigned32    hash_table_high;
+  rtems_unsigned32    hash_table_low;
+  rtems_unsigned32    r_des_start;
+  rtems_unsigned32    x_des_start;
+  rtems_unsigned32    r_buf_size;
+  rtems_unsigned32    _pad0[9];
+  rtems_unsigned32    ecntrl;
+  rtems_unsigned32    ievent;
+  rtems_unsigned32    imask;
+  rtems_unsigned32    ivec;
+  rtems_unsigned32    r_des_active;
+  rtems_unsigned32    x_des_active;
+  rtems_unsigned32    _pad1[10];
+  rtems_unsigned32    mii_data;
+  rtems_unsigned32    mii_speed;
+  rtems_unsigned32    _pad2[17];
+  rtems_unsigned32    r_bound;
+  rtems_unsigned32    r_fstart;
+  rtems_unsigned32    _pad3[6];
+  rtems_unsigned32    x_fstart;
+  rtems_unsigned32    _pad4[17];
+  rtems_unsigned32    fun_code;
+  rtems_unsigned32    _pad5[3];
+  rtems_unsigned32    r_cntrl;
+  rtems_unsigned32    r_hash;
+  rtems_unsigned32    _pad6[14];
+  rtems_unsigned32    x_cntrl;
+  rtems_unsigned32    _pad7[30];
+
+} m860FECRegisters_t;
+
+#define M860_FEC_IEVENT_HBERR  (1 << 31)
+#define M860_FEC_IEVENT_BABR   (1 << 30)
+#define M860_FEC_IEVENT_BABT   (1 << 29)
+#define M860_FEC_IEVENT_GRA    (1 << 28)
+#define M860_FEC_IEVENT_TFINT  (1 << 27)
+#define M860_FEC_IEVENT_TXB    (1 << 26)
+#define M860_FEC_IEVENT_RFINT  (1 << 25)
+#define M860_FEC_IEVENT_RXB    (1 << 24)
+#define M860_FEC_IEVENT_MII    (1 << 23)
+#define M860_FEC_IEVENT_EBERR  (1 << 22)
+#define M860_FEC_IMASK_HBEEN   (1 << 31)
+#define M860_FEC_IMASK_BREEN   (1 << 30)
+#define M860_FEC_IMASK_BTEN    (1 << 29)
+#define M860_FEC_IMASK_GRAEN   (1 << 28)
+#define M860_FEC_IMASK_TFIEN   (1 << 27)
+#define M860_FEC_IMASK_TBIEN   (1 << 26)
+#define M860_FEC_IMASK_RFIEN   (1 << 25)
+#define M860_FEC_IMASK_RBIEN   (1 << 24)
+#define M860_FEC_IMASK_MIIEN   (1 << 23)
+#define M860_FEC_IMASK_EBERREN (1 << 22)
+
+
+/*
+*************************************************************************
+*                         Miscellaneous Parameters                      *
+*************************************************************************
+*/
+typedef struct m860MiscParms_ {
+  rtems_unsigned16        rev_num;
+  rtems_unsigned16        _res1;
+  rtems_unsigned32        _res2;
+  rtems_unsigned32        _res3;
+} m860MiscParms_t;
+
+/*
+*************************************************************************
+*                              RISC Timers                              *
+*************************************************************************
+*/
+typedef struct m860TimerParms_ {
+  rtems_unsigned16        tm_base;
+  rtems_unsigned16        _tm_ptr;
+  rtems_unsigned16        _r_tmr;
+  rtems_unsigned16        _r_tmv;
+  rtems_unsigned32        tm_cmd;
+  rtems_unsigned32        tm_cnt;
+} m860TimerParms_t;
+
+/*
+ * RISC Controller Configuration Register (RCCR)
+ * All other bits in this register are reserved.
+ */
+#define M860_RCCR_TIME          (1<<15)    /* Enable timer */
+#define M860_RCCR_TIMEP(x)      ((x)<<8)   /* Timer period */
+#define M860_RCCR_DR1M          (1<<7)     /* IDMA Rqst 1 Mode */
+#define M860_RCCR_DR0M          (1<<6)     /* IDMA Rqst 0 Mode */
+#define M860_RCCR_DRQP(x)       ((x)<<4)   /* IDMA Rqst Priority */
+#define M860_RCCR_EIE           (1<<3)     /* External Interrupt Enable */
+#define M860_RCCR_SCD           (1<<2)     /* Scheduler Configuration */
+#define M860_RCCR_ERAM(x)       (x)        /* Enable RAM Microcode */
+
+/*
+ * Command register
+ * Set up this register before issuing a M860_CR_OP_SET_TIMER command.
+ */
+#define M860_TM_CMD_V           (1<<31)         /* Set to enable timer */
+#define M860_TM_CMD_R           (1<<30)         /* Set for automatic restart */
+#define M860_TM_CMD_PWM         (1<<29)         /* Set for PWM operation */
+#define M860_TM_CMD_TIMER(x)    ((x)<<16)       /* Select timer */
+#define M860_TM_CMD_PERIOD(x)   (x)             /* Timer period (16 bits) */
+
+/*
+*************************************************************************
+*                               DMA Controllers                         *
+*************************************************************************
+*/
+typedef struct m860IDMAparms_ {
+  rtems_unsigned16        ibase;
+  rtems_unsigned16        dcmr;
+  rtems_unsigned32        _sapr;
+  rtems_unsigned32        _dapr;
+  rtems_unsigned16        ibptr;
+  rtems_unsigned16        _write_sp;
+  rtems_unsigned32        _s_byte_c;
+  rtems_unsigned32        _d_byte_c;
+  rtems_unsigned32        _s_state;
+  rtems_unsigned32        _itemp[4];
+  rtems_unsigned32        _sr_mem;
+  rtems_unsigned16        _read_sp;
+  rtems_unsigned16        _res0;
+  rtems_unsigned16        _res1;
+  rtems_unsigned16        _res2;
+  rtems_unsigned32        _d_state;
+} m860IDMAparms_t;
+
+
+/*
+*************************************************************************
+*                               DSP                                     *
+*************************************************************************
+*/
+typedef struct m860DSPparms_ {
+  rtems_unsigned32        fdbase;
+  rtems_unsigned32        _fd_ptr;
+  rtems_unsigned32        _dstate;
+  rtems_unsigned32        _pad0;
+  rtems_unsigned16        _dstatus;
+  rtems_unsigned16        _i;
+  rtems_unsigned16        _tap;
+  rtems_unsigned16        _cbase;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned16        _xptr;
+  rtems_unsigned16        _pad2;
+  rtems_unsigned16        _yptr;
+  rtems_unsigned16        _m;
+  rtems_unsigned16        _pad3;
+  rtems_unsigned16        _n;
+  rtems_unsigned16        _pad4;
+  rtems_unsigned16        _k;
+  rtems_unsigned16        _pad5;
+} m860DSPparms_t;
+
+/*
+*************************************************************************
+*                   Serial Communication Controllers                    *
+*************************************************************************
+*/
+typedef struct m860SCCparms_ {
+  rtems_unsigned16        rbase;
+  rtems_unsigned16        tbase;
+  rtems_unsigned8         rfcr;
+  rtems_unsigned8         tfcr;
+  rtems_unsigned16        mrblr;
+  rtems_unsigned32        _rstate;
+  rtems_unsigned32        _pad0;
+  rtems_unsigned16        _rbptr;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned32        _pad2;
+  rtems_unsigned32        _tstate;
+  rtems_unsigned32        _pad3;
+  rtems_unsigned16        _tbptr;
+  rtems_unsigned16        _pad4;
+  rtems_unsigned32        _pad5;
+  rtems_unsigned32        _rcrc;
+  rtems_unsigned32        _tcrc;
+  union {
+    struct {
+      rtems_unsigned32        _res0;
+      rtems_unsigned32        _res1;
+      rtems_unsigned16        max_idl;
+      rtems_unsigned16        _idlc;
+      rtems_unsigned16        brkcr;
+      rtems_unsigned16        parec;
+      rtems_unsigned16        frmec;
+      rtems_unsigned16        nosec;
+      rtems_unsigned16        brkec;
+      rtems_unsigned16        brklen;
+      rtems_unsigned16        uaddr[2];
+      rtems_unsigned16        _rtemp;
+      rtems_unsigned16        toseq;
+      rtems_unsigned16        character[8];
+      rtems_unsigned16        rccm;
+      rtems_unsigned16        rccr;
+      rtems_unsigned16        rlbc;
+    } uart;
+  } un;
+} m860SCCparms_t;
+
+typedef struct m860SCCENparms_ {
+  rtems_unsigned16        rbase;
+  rtems_unsigned16        tbase;
+  rtems_unsigned8         rfcr;
+  rtems_unsigned8         tfcr;
+  rtems_unsigned16        mrblr;
+  rtems_unsigned32        _rstate;
+  rtems_unsigned32        _pad0;
+  rtems_unsigned16        _rbptr;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned32        _pad2;
+  rtems_unsigned32        _tstate;
+  rtems_unsigned32        _pad3;
+  rtems_unsigned16        _tbptr;
+  rtems_unsigned16        _pad4;
+  rtems_unsigned32        _pad5;
+  rtems_unsigned32        _rcrc;
+  rtems_unsigned32        _tcrc;
+  union {
+    struct {
+      rtems_unsigned32        _res0;
+      rtems_unsigned32        _res1;
+      rtems_unsigned16        max_idl;
+      rtems_unsigned16        _idlc;
+      rtems_unsigned16        brkcr;
+      rtems_unsigned16        parec;
+      rtems_unsigned16        frmec;
+      rtems_unsigned16        nosec;
+      rtems_unsigned16        brkec;
+      rtems_unsigned16        brklen;
+      rtems_unsigned16        uaddr[2];
+      rtems_unsigned16        _rtemp;
+      rtems_unsigned16        toseq;
+      rtems_unsigned16        character[8];
+      rtems_unsigned16        rccm;
+      rtems_unsigned16        rccr;
+      rtems_unsigned16        rlbc;
+    } uart;
+    struct {
+      rtems_unsigned32        c_pres;
+      rtems_unsigned32        c_mask;
+      rtems_unsigned32        crcec;
+      rtems_unsigned32        alec;
+      rtems_unsigned32        disfc;
+      rtems_unsigned16        pads;
+      rtems_unsigned16        ret_lim;
+      rtems_unsigned16        _ret_cnt;
+      rtems_unsigned16        mflr;
+      rtems_unsigned16        minflr;
+      rtems_unsigned16        maxd1;
+      rtems_unsigned16        maxd2;
+      rtems_unsigned16        _maxd;
+      rtems_unsigned16        dma_cnt;
+      rtems_unsigned16        _max_b;
+      rtems_unsigned16        gaddr1;
+      rtems_unsigned16        gaddr2;
+      rtems_unsigned16        gaddr3;
+      rtems_unsigned16        gaddr4;
+      rtems_unsigned32        _tbuf0data0;
+      rtems_unsigned32        _tbuf0data1;
+      rtems_unsigned32        _tbuf0rba0;
+      rtems_unsigned32        _tbuf0crc;
+      rtems_unsigned16        _tbuf0bcnt;
+      rtems_unsigned16        paddr_h;
+      rtems_unsigned16        paddr_m;
+      rtems_unsigned16        paddr_l;
+      rtems_unsigned16        p_per;
+      rtems_unsigned16        _rfbd_ptr;
+      rtems_unsigned16        _tfbd_ptr;
+      rtems_unsigned16        _tlbd_ptr;
+      rtems_unsigned32        _tbuf1data0;
+      rtems_unsigned32        _tbuf1data1;
+      rtems_unsigned32        _tbuf1rba0;
+      rtems_unsigned32        _tbuf1crc;
+      rtems_unsigned16        _tbuf1bcnt;
+      rtems_unsigned16        _tx_len;
+      rtems_unsigned16        iaddr1;
+      rtems_unsigned16        iaddr2;
+      rtems_unsigned16        iaddr3;
+      rtems_unsigned16        iaddr4;
+      rtems_unsigned16        _boff_cnt;
+      rtems_unsigned16        taddr_l;
+      rtems_unsigned16        taddr_m;
+      rtems_unsigned16        taddr_h;
+    } ethernet;
+  } un;
+} m860SCCENparms_t;
+
+/*
+ * Receive and transmit function code register bits
+ * These apply to the function code registers of all devices, not just SCC.
+ */
+#define M860_RFCR_BO(x)         ((x)<<3)
+#define M860_RFCR_MOT           (2<<3)
+#define M860_RFCR_DMA_SPACE(x)  (x)
+#define M860_TFCR_BO(x)         ((x)<<3)
+#define M860_TFCR_MOT           (2<<3)
+#define M860_TFCR_DMA_SPACE(x)  (x)
+
+/*
+*************************************************************************
+*                     Serial Management Controllers                     *
+*************************************************************************
+*/
+typedef struct m860SMCparms_ {
+  rtems_unsigned16        rbase;
+  rtems_unsigned16        tbase;
+  rtems_unsigned8         rfcr;
+  rtems_unsigned8         tfcr;
+  rtems_unsigned16        mrblr;
+  rtems_unsigned32        _rstate;
+  rtems_unsigned32        _pad0;
+  rtems_unsigned16        _rbptr;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned32        _pad2;
+  rtems_unsigned32        _tstate;
+  rtems_unsigned32        _pad3;
+  rtems_unsigned16        _tbptr;
+  rtems_unsigned16        _pad4;
+  rtems_unsigned32        _pad5;
+  union {
+    struct {
+      rtems_unsigned16        max_idl;
+      rtems_unsigned16        _idlc;
+      rtems_unsigned16        brklen;
+      rtems_unsigned16        brkec;
+      rtems_unsigned16        brkcr;
+      rtems_unsigned16        _r_mask;
+    } uart;
+    struct {
+      rtems_unsigned16        _pad0[5];
+    } transparent;
+  } un;
+} m860SMCparms_t;
+
+/*
+ * Mode register
+ */
+#define M860_SMCMR_CLEN(x)              ((x)<<11)    /* Character length */
+#define M860_SMCMR_2STOP                (1<<10)      /* 2 stop bits */
+#define M860_SMCMR_PARITY               (1<<9)       /* Enable parity */
+#define M860_SMCMR_EVEN                 (1<<8)       /* Even parity */
+#define M860_SMCMR_SM_GCI               (0<<4)       /* GCI Mode */
+#define M860_SMCMR_SM_UART              (2<<4)       /* UART Mode */
+#define M860_SMCMR_SM_TRANSPARENT       (3<<4)       /* Transparent Mode */
+#define M860_SMCMR_DM_LOOPBACK          (1<<2)       /* Local loopback mode */
+#define M860_SMCMR_DM_ECHO              (2<<2)       /* Echo mode */
+#define M860_SMCMR_TEN                  (1<<1)       /* Enable transmitter */
+#define M860_SMCMR_REN                  (1<<0)       /* Enable receiver */
+
+/*
+ * Event and mask registers (SMCE, SMCM)
+ */
+#define M860_SMCE_BRKE  (1<<6)
+#define M860_SMCE_BRK   (1<<4)
+#define M860_SMCE_BSY   (1<<2)
+#define M860_SMCE_TX    (1<<1)
+#define M860_SMCE_RX    (1<<0)
+
+/*
+*************************************************************************
+*                      Serial Peripheral Interface                      *
+*************************************************************************
+*/
+typedef struct m860SPIparms_ {
+  rtems_unsigned16        rbase;
+  rtems_unsigned16        tbase;
+  rtems_unsigned8         rfcr;
+  rtems_unsigned8         tfcr;
+  rtems_unsigned16        mrblr;
+  rtems_unsigned32        _rstate;
+  rtems_unsigned32        _pad0;
+  rtems_unsigned16        _rbptr;
+  rtems_unsigned16        _pad1;
+  rtems_unsigned32        _pad2;
+  rtems_unsigned32        _tstate;
+  rtems_unsigned32        _pad3;
+  rtems_unsigned16        _tbptr;
+  rtems_unsigned16        _pad4;
+  rtems_unsigned32        _pad5;
+} m860SPIparms_t;
+
+/*
+ * Mode register (SPMODE)
+ */
+#define M860_SPMODE_LOOP                (1<<14) /* Local loopback mode */
+#define M860_SPMODE_CI                  (1<<13) /* Clock invert */
+#define M860_SPMODE_CP                  (1<<12) /* Clock phase */
+#define M860_SPMODE_DIV16               (1<<11) /* Divide BRGCLK by 16 */
+#define M860_SPMODE_REV                 (1<<10) /* Reverse data */
+#define M860_SPMODE_MASTER              (1<<9)  /* SPI is master */
+#define M860_SPMODE_EN                  (1<<8)  /* Enable SPI */
+#define M860_SPMODE_CLEN(x)             ((x)<<4)        /* Character length */
+#define M860_SPMODE_PM(x)               (x)     /* Prescaler modulus */
+
+/*
+ * Mode register (SPCOM)
+ */
+#define M860_SPCOM_STR                  (1<<7)  /* Start transmit */
+
+/*
+ * Event and mask registers (SPIE, SPIM)
+ */
+#define M860_SPIE_MME   (1<<5)          /* Multi-master error */
+#define M860_SPIE_TXE   (1<<4)          /* Tx error */
+#define M860_SPIE_BSY   (1<<2)          /* Busy condition*/
+#define M860_SPIE_TXB   (1<<1)          /* Tx buffer */
+#define M860_SPIE_RXB   (1<<0)          /* Rx buffer */
+
+/*
+*************************************************************************
+*                 SDMA (SCC, SMC, SPI) Buffer Descriptors               *
+*************************************************************************
+*/
+typedef struct m860BufferDescriptor_ {
+  rtems_unsigned16        status;
+  rtems_unsigned16        length;
+  volatile void           *buffer;
+} m860BufferDescriptor_t;
+
+/*
+ * Bits in receive buffer descriptor status word
+ */
+#define M860_BD_EMPTY           (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M860_BD_WRAP            (1<<13) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M860_BD_INTERRUPT       (1<<12) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M860_BD_LAST            (1<<11) /* Ethernet, SPI */
+#define M860_BD_CONTROL_CHAR    (1<<11) /* SCC UART */
+#define M860_BD_FIRST_IN_FRAME  (1<<10) /* Ethernet */
+#define M860_BD_ADDRESS         (1<<10) /* SCC UART */
+#define M860_BD_CONTINUOUS      (1<<9)  /* SCC UART, SMC UART, SPI */
+#define M860_BD_MISS            (1<<8)  /* Ethernet */
+#define M860_BD_IDLE            (1<<8)  /* SCC UART, SMC UART */
+#define M860_BD_ADDRSS_MATCH    (1<<7)  /* SCC UART */
+#define M860_BD_LONG            (1<<5)  /* Ethernet */
+#define M860_BD_BREAK           (1<<5)  /* SCC UART, SMC UART */
+#define M860_BD_NONALIGNED      (1<<4)  /* Ethernet */
+#define M860_BD_FRAMING_ERROR   (1<<4)  /* SCC UART, SMC UART */
+#define M860_BD_SHORT           (1<<3)  /* Ethernet */
+#define M860_BD_PARITY_ERROR    (1<<3)  /* SCC UART, SMC UART */
+#define M860_BD_CRC_ERROR       (1<<2)  /* Ethernet */
+#define M860_BD_OVERRUN         (1<<1)  /* Ethernet, SCC UART, SMC UART, SPI */
+#define M860_BD_COLLISION       (1<<0)  /* Ethernet */
+#define M860_BD_CARRIER_LOST    (1<<0)  /* SCC UART, SMC UART */
+#define M860_BD_MASTER_ERROR    (1<<0)  /* SPI */
+
+/*
+ * Bits in transmit buffer descriptor status word
+ * Many bits have the same meaning as those in receiver buffer descriptors.
+ */
+#define M860_BD_READY           (1<<15) /* Ethernet, SCC UART, SMC UART, SPI */
+#define M860_BD_PAD             (1<<14) /* Ethernet */
+#define M860_BD_CTS_REPORT      (1<<11) /* SCC UART */
+#define M860_BD_TX_CRC          (1<<10) /* Ethernet */
+#define M860_BD_DEFER           (1<<9)  /* Ethernet */
+#define M860_BD_HEARTBEAT       (1<<8)  /* Ethernet */
+#define M860_BD_PREAMBLE        (1<<8)  /* SCC UART, SMC UART */
+#define M860_BD_LATE_COLLISION  (1<<7)  /* Ethernet */
+#define M860_BD_NO_STOP_BIT     (1<<7)  /* SCC UART */
+#define M860_BD_RETRY_LIMIT     (1<<6)  /* Ethernet */
+#define M860_BD_RETRY_COUNT(x)  (((x)&0x3C)>>2) /* Ethernet */
+#define M860_BD_UNDERRUN        (1<<1)  /* Ethernet, SPI */
+#define M860_BD_CARRIER_LOST    (1<<0)  /* Ethernet */
+#define M860_BD_CTS_LOST        (1<<0)  /* SCC UART */
+
+/*
+*************************************************************************
+*                           IDMA Buffer Descriptors                     *
+*************************************************************************
+*/
+typedef struct m860IDMABufferDescriptor_ {
+  rtems_unsigned16        status;
+  rtems_unsigned8         dfcr;       
+  rtems_unsigned8         sfcr;       
+  rtems_unsigned32        length;
+  void                    *source;
+  void                    *destination;
+} m860IDMABufferDescriptor_t;
+
+/*
+*************************************************************************
+*       RISC Communication Processor Module Command Register (CR)       *
+*************************************************************************
+*/
+#define M860_CR_RST             (1<<15) /* Reset communication processor */
+#define M860_CR_OP_INIT_RX_TX   (0<<8)  /* SCC, SMC UART, SMC GCI, SPI */
+#define M860_CR_OP_INIT_RX      (1<<8)  /* SCC, SMC UART, SPI */
+#define M860_CR_OP_INIT_TX      (2<<8)  /* SCC, SMC UART, SPI */
+#define M860_CR_OP_INIT_HUNT    (3<<8)  /* SCC, SMC UART */
+#define M860_CR_OP_STOP_TX      (4<<8)  /* SCC, SMC UART */
+#define M860_CR_OP_GR_STOP_TX   (5<<8)  /* SCC */
+#define M860_CR_OP_INIT_IDMA    (5<<8)  /* IDMA */
+#define M860_CR_OP_RESTART_TX   (6<<8)  /* SCC, SMC UART */
+#define M860_CR_OP_CLOSE_RX_BD  (7<<8)  /* SCC, SMC UART, SPI */
+#define M860_CR_OP_SET_GRP_ADDR (8<<8)  /* SCC */
+#define M860_CR_OP_SET_TIMER    (8<<8)  /* Timer */
+#define M860_CR_OP_GCI_TIMEOUT  (9<<8)  /* SMC GCI */
+#define M860_CR_OP_RESERT_BCS   (10<<8) /* SCC */
+#define M860_CR_OP_GCI_ABORT    (10<<8) /* SMC GCI */
+#define M860_CR_OP_STOP_IDMA    (11<<8) /* IDMA */
+#define M860_CR_OP_START_DSP    (12<<8) /* DSP */
+#define M860_CR_OP_INIT_DSP     (13<<8) /* DSP */
+
+#define M860_CR_CHAN_SCC1       (0<<4)  /* Channel selection */
+#define M860_CR_CHAN_I2C        (1<<4)
+#define M860_CR_CHAN_IDMA1      (1<<4)
+#define M860_CR_CHAN_SCC2       (4<<4)
+#define M860_CR_CHAN_SPI        (5<<4)
+#define M860_CR_CHAN_IDMA2      (5<<4)
+#define M860_CR_CHAN_TIMER      (5<<4)
+#define M860_CR_CHAN_SCC3       (8<<4)
+#define M860_CR_CHAN_SMC1       (9<<4)
+#define M860_CR_CHAN_DSP1       (9<<4)
+#define M860_CR_CHAN_SCC4       (12<<4)
+#define M860_CR_CHAN_SMC2       (13<<4)
+#define M860_CR_CHAN_DSP2       (13<<4)
+#define M860_CR_FLG             (1<<0)  /* Command flag */
+
+/*
+*************************************************************************
+*                 System Protection Control Register (SYPCR)            *
+*************************************************************************
+*/
+#define M860_SYPCR_SWTC(x)      ((x)<<16)   /* Software watchdog timer count */
+#define M860_SYPCR_BMT(x)       ((x)<<8)    /* Bus monitor timing */
+#define M860_SYPCR_BME          (1<<7)      /* Bus monitor enable */
+#define M860_SYPCR_SWF          (1<<3)      /* Software watchdog freeze */
+#define M860_SYPCR_SWE          (1<<2)      /* Software watchdog enable */
+#define M860_SYPCR_SWRI         (1<<1)      /* Watchdog reset/interrupt sel. */
+#define M860_SYPCR_SWP          (1<<0)      /* Software watchdog prescale */
+
+/*
+*************************************************************************
+*                        Memory Control Registers                       *
+*************************************************************************
+*/
+#define M860_UPM_AMX_8col       (0<<20) /* 8 column DRAM */
+#define M860_UPM_AMX_9col       (1<<20) /* 9 column DRAM */
+#define M860_UPM_AMX_10col      (2<<20) /* 10 column DRAM */
+#define M860_UPM_AMX_11col      (3<<20) /* 11 column DRAM */
+#define M860_UPM_AMX_12col      (4<<20) /* 12 column DRAM */
+#define M860_UPM_AMX_13col      (5<<20) /* 13 column DRAM */
+#define M860_MSR_PER(x)         (0x100<<(7-x)) /* Perity error bank (x) */
+#define M860_MSR_WPER           (1<<7)  /* Write protection error */
+#define M860_MPTPR_PTP(x)       ((x)<<8) /* Periodic timer prescaler */
+#define M860_BR_BA(x)           ((x)&0xffff8000) /* Base address */
+#define M860_BR_AT(x)           ((x)<<12) /* Address type */
+#define M860_BR_PS8             (1<<10)  /* 8 bit port */
+#define M860_BR_PS16            (2<<10)  /* 16 bit port */
+#define M860_BR_PS32            (0<<10)  /* 32 bit port */
+#define M860_BR_PARE            (1<<9)   /* Parity checking enable */
+#define M860_BR_WP              (1<<8)   /* Write protect */
+#define M860_BR_MS_GPCM         (0<<6)   /* GPCM */
+#define M860_BR_MS_UPMA         (2<<6)   /* UPM A */
+#define M860_BR_MS_UPMB         (3<<6)   /* UPM B */
+#define M860_MEMC_BR_V          (1<<0)  /* Base/Option register are valid */
+
+#define M860_MEMC_OR_32K        0xffff8000      /* Address range */
+#define M860_MEMC_OR_64K        0xffff0000
+#define M860_MEMC_OR_128K       0xfffe0000
+#define M860_MEMC_OR_256K       0xfffc0000
+#define M860_MEMC_OR_512K       0xfff80000
+#define M860_MEMC_OR_1M         0xfff00000
+#define M860_MEMC_OR_2M         0xffe00000
+#define M860_MEMC_OR_4M         0xffc00000
+#define M860_MEMC_OR_8M         0xff800000
+#define M860_MEMC_OR_16M        0xff000000
+#define M860_MEMC_OR_32M        0xfe000000
+#define M860_MEMC_OR_64M        0xfc000000
+#define M860_MEMC_OR_128        0xf8000000
+#define M860_MEMC_OR_256M       0xf0000000
+#define M860_MEMC_OR_512M       0xe0000000
+#define M860_MEMC_OR_1G         0xc0000000
+#define M860_MEMC_OR_2G         0x80000000
+#define M860_MEMC_OR_4G         0x00000000
+#define M860_MEMC_OR_ATM(x)     ((x)<<12)   /* Address type mask */
+#define M860_MEMC_OR_CSNT       (1<<11)     /* Chip select is negated early */
+#define M860_MEMC_OR_SAM        (1<<11)     /* Address lines are multiplexed */
+#define M860_MEMC_OR_ACS_NORM   (0<<9)      /* *CS asserted with addr lines */
+#define M860_MEMC_OR_ACS_QRTR   (2<<9)      /* *CS asserted 1/4 after addr */
+#define M860_MEMC_OR_ACS_HALF   (3<<9)      /* *CS asserted 1/2 after addr */
+#define M860_MEMC_OR_BI         (1<8)       /* Burst inhibit */
+#define M860_MEMC_OR_SCY(x)     ((x)<<4)    /* Cycle length in clocks */
+#define M860_MEMC_OR_SETA       (1<<3)      /* *TA generated externally */
+#define M860_MEMC_OR_TRLX       (1<<2)      /* Relaxed timing in GPCM */
+#define M860_MEMC_OR_EHTR       (1<<1)      /* Extended hold time on reads */
+
+/*
+*************************************************************************
+*                         UPM Registers (MxMR)                          *
+*************************************************************************
+*/
+#define M860_MEMC_MMR_PTP(x)   ((x)<<24)    /* Periodic timer period */
+#define M860_MEMC_MMR_PTE      (1<<23)      /* Periodic timer enable */
+#define M860_MEMC_MMR_DSP(x)   ((x)<<17)    /* Disable timer period */
+#define M860_MEMC_MMR_G0CL(x)  ((x)<<13)    /* General line 0 control */
+#define M860_MEMC_MMR_UPWAIT   (1<<12)      /* GPL_x4 is UPWAITx */
+#define M860_MEMC_MMR_RLF(x)   ((x)<<8)     /* Read loop field */
+#define M860_MEMC_MMR_WLF(x)   ((x)<<4)     /* Write loop field */
+#define M860_MEMC_MMR_TLF(x)   ((x)<<0)     /* Timer loop field */
+/*
+*************************************************************************
+*                         Memory Command Register (MCR)                 *
+*************************************************************************
+*/
+#define M860_MEMC_MCR_WRITE     (0<<30)     /* WRITE command */
+#define M860_MEMC_MCR_READ      (1<<30)     /* READ command */
+#define M860_MEMC_MCR_RUN       (2<<30)     /* RUN command */
+#define M860_MEMC_MCR_UPMA      (0<<23)     /* Cmd is for UPMA */
+#define M860_MEMC_MCR_UPMB      (1<<23)     /* Cmd is for UPMB */
+#define M860_MEMC_MCR_MB(x)     ((x)<<13)   /* Memory bank when RUN cmd */
+#define M860_MEMC_MCR_MCLF(x)   ((x)<<8)    /* Memory command loop field */
+#define M860_MEMC_MCR_MAD(x)    (x)         /* Machine address */
+
+
+
+/*
+*************************************************************************
+*                         SI Mode Register (SIMODE)                     *
+*************************************************************************
+*/
+#define M860_SI_SMC2_BITS       0xFFFF0000      /* All SMC2 bits */
+#define M860_SI_SMC2_TDM        (1<<31) /* Multiplexed SMC2 */
+#define M860_SI_SMC2_BRG1       (0<<28) /* SMC2 clock souce */
+#define M860_SI_SMC2_BRG2       (1<<28)
+#define M860_SI_SMC2_BRG3       (2<<28)
+#define M860_SI_SMC2_BRG4       (3<<28)
+#define M860_SI_SMC2_CLK5       (0<<28)
+#define M860_SI_SMC2_CLK6       (1<<28)
+#define M860_SI_SMC2_CLK7       (2<<28)
+#define M860_SI_SMC2_CLK8       (3<<28)
+#define M860_SI_SMC1_BITS       0x0000FFFF      /* All SMC1 bits */
+#define M860_SI_SMC1_TDM        (1<<15) /* Multiplexed SMC1 */
+#define M860_SI_SMC1_BRG1       (0<<12) /* SMC1 clock souce */
+#define M860_SI_SMC1_BRG2       (1<<12)
+#define M860_SI_SMC1_BRG3       (2<<12)
+#define M860_SI_SMC1_BRG4       (3<<12)
+#define M860_SI_SMC1_CLK1       (0<<12)
+#define M860_SI_SMC1_CLK2       (1<<12)
+#define M860_SI_SMC1_CLK3       (2<<12)
+#define M860_SI_SMC1_CLK4       (3<<12)
+
+/*
+*************************************************************************
+*                  SDMA Configuration Register (SDCR)                   *
+*************************************************************************
+*/
+#define M860_SDCR_FREEZE        (2<<13) /* Freeze on next bus cycle */
+#define M860_SDCR_RAID_5        (1<<0)  /* Normal arbitration ID */
+
+/*
+*************************************************************************
+*                  SDMA Status Register (SDSR)                          *
+*************************************************************************
+*/
+#define M860_SDSR_SBER          (1<<7)  /* SDMA Channel bus error */
+#define M860_SDSR_DSP2          (1<<1)  /* DSP Chain 2 interrupt */
+#define M860_SDSR_DSP1          (1<<0)  /* DSP Chain 1 interrupt */
+
+/*
+*************************************************************************
+*                      Baud (sic) Rate Generators                       *
+*************************************************************************
+*/
+#define M860_BRG_RST            (1<<17)         /* Reset generator */
+#define M860_BRG_EN             (1<<16)         /* Enable generator */
+#define M860_BRG_EXTC_BRGCLK    (0<<14)         /* Source is BRGCLK */
+#define M860_BRG_EXTC_CLK2      (1<<14)         /* Source is CLK2 pin */
+#define M860_BRG_EXTC_CLK6      (2<<14)         /* Source is CLK6 pin */
+#define M860_BRG_ATB            (1<<13)         /* Autobaud */
+#define M860_BRG_115200         (21<<1)         /* Assume 40 MHz clock */
+#define M860_BRG_57600          (32<<1)
+#define M860_BRG_38400          (64<<1)
+#define M860_BRG_19200          (129<<1)
+#define M860_BRG_9600           (259<<1)
+#define M860_BRG_4800           (520<<1)
+#define M860_BRG_2400           (1040<<1)
+#define M860_BRG_1200           (2082<<1)
+#define M860_BRG_600            ((259<<1) | 1)
+#define M860_BRG_300            ((520<<1) | 1)
+#define M860_BRG_150            ((1040<<1) | 1)
+#define M860_BRG_75             ((2080<<1) | 1)
+
+#define M860_TGCR_CAS4          (1<<15)   /* Cascade timers 3 and 4 */
+#define M860_TGCR_CAS2          (1<<7)    /* Cascade timers 1 and 2 */
+#define M860_TGCR_FRZ1          (1<<2)    /* Halt timer if FREEZE asserted */
+#define M860_TGCR_FRZ2          (1<<6)    /* Halt timer if FREEZE asserted */
+#define M860_TGCR_FRZ3          (1<<10)   /* Halt timer if FREEZE asserted */
+#define M860_TGCR_FRZ4          (1<<14)   /* Halt timer if FREEZE asserted */
+#define M860_TGCR_STP1          (1<<1)    /* Stop timer */
+#define M860_TGCR_STP2          (1<<5)    /* Stop timer */
+#define M860_TGCR_STP3          (1<<9)    /* Stop timer */
+#define M860_TGCR_STP4          (1<<13)   /* Stop timer */
+#define M860_TGCR_RST1          (1<<0)    /* Enable timer */
+#define M860_TGCR_RST2          (1<<4)    /* Enable timer */
+#define M860_TGCR_RST3          (1<<8)    /* Enable timer */
+#define M860_TGCR_RST4          (1<<12)   /* Enable timer */
+#define M860_TGCR_GM1           (1<<3)    /* Gate Mode 1 for TMR1 or TMR2 */
+#define M860_TGCR_GM2           (1<<11)   /* Gate Mode 2 for TMR3 or TMR4 */
+
+#define M860_TMR_PS(x)          ((x)<<8)  /* Timer prescaler */
+#define M860_TMR_CE_RISE        (1<<6)    /* Capture on rising edge */
+#define M860_TMR_CE_FALL        (2<<6)    /* Capture on falling edge */
+#define M860_TMR_CE_ANY         (3<<6)    /* Capture on any edge */
+#define M860_TMR_OM_TOGGLE      (1<<5)    /* Toggle TOUTx pin */
+#define M860_TMR_ORI            (1<<4)    /* Interrupt on reaching reference */
+#define M860_TMR_RESTART        (1<<3)    /* Restart timer after reference */
+#define M860_TMR_ICLK_INT       (1<<1)    /* Internal clock is timer source */
+#define M860_TMR_ICLK_INT16     (2<<1)    /* Internal clock/16 is tmr src */
+#define M860_TMR_ICLK_TIN       (3<<1)    /* TIN pin is timer source */
+#define M860_TMR_TGATE          (1<<0)    /* TGATE controls timer */
+
+#define M860_PISCR_PIRQ(x)      (1<<(15-x))  /* PIT interrupt level */
+#define M860_PISCR_PS           (1<<7)    /* PIT Interrupt state */
+#define M860_PISCR_PIE          (1<<2)    /* PIT interrupt enable */
+#define M860_PISCR_PITF         (1<<1)    /* Stop timer when freeze asserted */
+#define M860_PISCR_PTE          (1<<0)    /* PIT enable */
+
+#define M860_TBSCR_TBIRQ(x)     (1<<(15-x))  /* TB interrupt level */
+#define M860_TBSCR_REFA         (1<<7)    /* TB matches TBREFF0 */
+#define M860_TBSCR_REFB         (1<<6)    /* TB matches TBREFF1 */
+#define M860_TBSCR_REFAE        (1<<3)    /* Enable ints for REFA */
+#define M860_TBSCR_REFBE        (1<<2)    /* Enable ints for REFB */
+#define M860_TBSCR_TBF          (1<<1)    /* TB stops on FREEZE */
+#define M860_TBSCR_TBE          (1<<0)    /* enable TB and decrementer */
+
+#define M860_SIMASK_IRM0        (1<<31)
+#define M860_SIMASK_LVM0        (1<<30)
+#define M860_SIMASK_IRM1        (1<<29)
+#define M860_SIMASK_LVM1        (1<<28)
+#define M860_SIMASK_IRM2        (1<<27)
+#define M860_SIMASK_LVM2        (1<<26)
+#define M860_SIMASK_IRM3        (1<<25)
+#define M860_SIMASK_LVM3        (1<<24)
+#define M860_SIMASK_IRM4        (1<<23)
+#define M860_SIMASK_LVM4        (1<<22)
+#define M860_SIMASK_IRM5        (1<<21)
+#define M860_SIMASK_LVM5        (1<<20)
+#define M860_SIMASK_IRM6        (1<<19)
+#define M860_SIMASK_LVM6        (1<<18)
+#define M860_SIMASK_IRM7        (1<<17)
+#define M860_SIMASK_LVM7        (1<<16)
+
+#define M860_SIUMCR_EARB        (1<<31)
+#define M860_SIUMCR_EARP0       (0<<28)
+#define M860_SIUMCR_EARP1       (1<<28)
+#define M860_SIUMCR_EARP2       (2<<28)
+#define M860_SIUMCR_EARP3       (3<<28)
+#define M860_SIUMCR_EARP4       (4<<28)
+#define M860_SIUMCR_EARP5       (5<<28)
+#define M860_SIUMCR_EARP6       (6<<28)
+#define M860_SIUMCR_EARP7       (7<<28)
+#define M860_SIUMCR_DSHW        (1<<23)
+#define M860_SIUMCR_DBGC0       (0<<21)
+#define M860_SIUMCR_DBGC1       (1<<21)
+#define M860_SIUMCR_DBGC2       (2<<21)
+#define M860_SIUMCR_DBGC3       (3<<21)
+#define M860_SIUMCR_DBPC0       (0<<19)
+#define M860_SIUMCR_DBPC1       (1<<19)
+#define M860_SIUMCR_DBPC2       (2<<19)
+#define M860_SIUMCR_DBPC3       (3<<19)
+#define M860_SIUMCR_FRC         (1<<17)
+#define M860_SIUMCR_DLK         (1<<16)
+#define M860_SIUMCR_PNCS        (1<<15)
+#define M860_SIUMCR_OPAR        (1<<14)
+#define M860_SIUMCR_DPC         (1<<13)
+#define M860_SIUMCR_MPRE        (1<<12)
+#define M860_SIUMCR_MLRC0       (0<<10)
+#define M860_SIUMCR_MLRC1       (1<<10)
+#define M860_SIUMCR_MLRC2       (2<<10)
+#define M860_SIUMCR_MLRC3       (3<<10)
+#define M860_SIUMCR_AEME        (1<<9)
+#define M860_SIUMCR_SEME        (1<<8)
+#define M860_SIUMCR_BSC         (1<<7)
+#define M860_SIUMCR_GB5E        (1<<6)
+#define M860_SIUMCR_B2DD        (1<<5)
+#define M860_SIUMCR_B3DD        (1<<4)
+/*
+*************************************************************************
+*                 MPC860 DUAL-PORT RAM AND REGISTERS                    *
+*************************************************************************
+*/
+typedef struct m860_ {
+        
+  /*
+   * SIU Block
+   */
+  rtems_unsigned32      siumcr;
+  rtems_unsigned32      sypcr;
+  rtems_unsigned32      swt;
+  rtems_unsigned16      _pad0;
+  rtems_unsigned16      swsr;
+  rtems_unsigned32      sipend;
+  rtems_unsigned32      simask;
+  rtems_unsigned32      siel;
+  rtems_unsigned32      sivec;
+  rtems_unsigned32      tesr;
+  rtems_unsigned32      _pad1[3];
+  rtems_unsigned32      sdcr;
+  rtems_unsigned8       _pad2[0x80-0x34];
+  
+  /*
+   * PCMCIA Block
+   */
+  rtems_unsigned32      pbr0;
+  rtems_unsigned32      por0;
+  rtems_unsigned32      pbr1;
+  rtems_unsigned32      por1;
+  rtems_unsigned32      pbr2;
+  rtems_unsigned32      por2;
+  rtems_unsigned32      pbr3;
+  rtems_unsigned32      por3;
+  rtems_unsigned32      pbr4;
+  rtems_unsigned32      por4;
+  rtems_unsigned32      pbr5;
+  rtems_unsigned32      por5;
+  rtems_unsigned32      pbr6;
+  rtems_unsigned32      por6;
+  rtems_unsigned32      pbr7;
+  rtems_unsigned32      por7;
+  rtems_unsigned8       _pad3[0xe0-0xc0];
+  rtems_unsigned32      pgcra;
+  rtems_unsigned32      pgcrb;
+  rtems_unsigned32      pscr;
+  rtems_unsigned32      _pad4;
+  rtems_unsigned32      pipr;
+  rtems_unsigned32      _pad5;
+  rtems_unsigned32      per;
+  rtems_unsigned32      _pad6;
+  
+  /*
+   * MEMC Block
+   */
+  m860MEMCRegisters_t   memc[8];
+  rtems_unsigned8       _pad7[0x164-0x140];
+  rtems_unsigned32      mar;
+  rtems_unsigned32      mcr;
+  rtems_unsigned32      _pad8;
+  rtems_unsigned32      mamr;
+  rtems_unsigned32      mbmr;
+  rtems_unsigned16      mstat;
+  rtems_unsigned16      mptpr;
+  rtems_unsigned32      mdr;
+  rtems_unsigned8       _pad9[0x200-0x180];
+  
+  /*
+   * System integration timers
+   */
+  rtems_unsigned16      tbscr;
+  rtems_unsigned16      _pad10;
+  rtems_unsigned32      tbreff0;
+  rtems_unsigned32      tbreff1;
+  rtems_unsigned8       _pad11[0x220-0x20c];
+  rtems_unsigned16      rtcsc;
+  rtems_unsigned16      _pad12;
+  rtems_unsigned32      rtc;
+  rtems_unsigned32      rtsec;
+  rtems_unsigned32      rtcal;
+  rtems_unsigned32      _pad13[4];
+  rtems_unsigned16      piscr;
+  rtems_unsigned16      _pad14;
+  rtems_unsigned16      pitc;
+  rtems_unsigned16      _pad_14_1;
+  rtems_unsigned16      pitr;
+  rtems_unsigned16      _pad_14_2;
+  rtems_unsigned8       _pad15[0x280-0x24c];
+  
+  
+  /*
+   * Clocks and Reset
+   */
+  rtems_unsigned32      sccr;
+  rtems_unsigned32      plprcr;
+  rtems_unsigned32      rsr;
+  rtems_unsigned8       _pad16[0x300-0x28c];
+  
+  
+  /*
+   * System integration timers keys
+   */
+  rtems_unsigned32      tbscrk;
+  rtems_unsigned32      tbreff0k;
+  rtems_unsigned32      tbreff1k;
+  rtems_unsigned32      tbk;
+  rtems_unsigned32      _pad17[4];
+  rtems_unsigned32      rtcsk;
+  rtems_unsigned32      rtck;
+  rtems_unsigned32      rtseck;
+  rtems_unsigned32      rtcalk;
+  rtems_unsigned32      _pad18[4];
+  rtems_unsigned32      piscrk;
+  rtems_unsigned32      pitck;
+  rtems_unsigned8       _pad19[0x380-0x348];
+  
+  /*
+   * Clocks and Reset Keys
+   */
+  rtems_unsigned32      sccrk;
+  rtems_unsigned32      plprck;
+  rtems_unsigned32      rsrk;
+  rtems_unsigned8       _pad20[0x400-0x38c];
+  rtems_unsigned8       _pad21[0x800-0x400];
+  rtems_unsigned8       _pad22[0x860-0x800];
+  
+  
+  /*
+   * I2C
+   */
+  rtems_unsigned8       i2mod;
+  rtems_unsigned8       _pad23[3];
+  rtems_unsigned8       i2add;
+  rtems_unsigned8       _pad24[3];
+  rtems_unsigned8       i2brg;
+  rtems_unsigned8       _pad25[3];
+  rtems_unsigned8       i2com;
+  rtems_unsigned8       _pad26[3];
+  rtems_unsigned8       i2cer;
+  rtems_unsigned8       _pad27[3];
+  rtems_unsigned8       i2cmr;
+  rtems_unsigned8       _pad28[0x900-0x875];
+  
+  /*
+   * DMA Block
+   */
+  rtems_unsigned32      _pad29;
+  rtems_unsigned32      sdar;
+  rtems_unsigned8       sdsr;
+  rtems_unsigned8       _pad30[3];
+  rtems_unsigned8       sdmr;
+  rtems_unsigned8       _pad31[3];
+  rtems_unsigned8       idsr1;
+  rtems_unsigned8       _pad32[3];
+  rtems_unsigned8       idmr1;
+  rtems_unsigned8       _pad33[3];
+  rtems_unsigned8       idsr2;
+  rtems_unsigned8       _pad34[3];
+  rtems_unsigned8       idmr2;
+  rtems_unsigned8       _pad35[0x930-0x91d];
+  
+  
+  
+  /*
+   * CPM Interrupt Control Block
+   */
+  rtems_unsigned16      civr;
+  rtems_unsigned8       _pad36[14];
+  rtems_unsigned32      cicr;
+  rtems_unsigned32      cipr;
+  rtems_unsigned32      cimr;
+  rtems_unsigned32      cisr;
+  
+  /*
+   * I/O Port Block
+   */
+  rtems_unsigned16      padir;
+  rtems_unsigned16      papar;
+  rtems_unsigned16      paodr;
+  rtems_unsigned16      padat;
+  rtems_unsigned8       _pad37[8];
+  rtems_unsigned16      pcdir;
+  rtems_unsigned16      pcpar;
+  rtems_unsigned16      pcso;
+  rtems_unsigned16      pcdat;
+  rtems_unsigned16      pcint;
+  rtems_unsigned8       _pad39[6];
+  rtems_unsigned16      pddir;
+  rtems_unsigned16      pdpar;
+  rtems_unsigned16      _pad40;
+  rtems_unsigned16      pddat;
+  rtems_unsigned8       _pad41[8];
+  
+  /*
+   * CPM Timers Block
+   */
+  rtems_unsigned16      tgcr;
+  rtems_unsigned8       _pad42[14];
+  rtems_unsigned16      tmr1;
+  rtems_unsigned16      tmr2;
+  rtems_unsigned16      trr1;
+  rtems_unsigned16      trr2;
+  rtems_unsigned16      tcr1;
+  rtems_unsigned16      tcr2;
+  rtems_unsigned16      tcn1;
+  rtems_unsigned16      tcn2;
+  rtems_unsigned16      tmr3;
+  rtems_unsigned16      tmr4;
+  rtems_unsigned16      trr3;
+  rtems_unsigned16      trr4;
+  rtems_unsigned16      tcr3;
+  rtems_unsigned16      tcr4;
+  rtems_unsigned16      tcn3;
+  rtems_unsigned16      tcn4;
+  rtems_unsigned16      ter1;
+  rtems_unsigned16      ter2;
+  rtems_unsigned16      ter3;
+  rtems_unsigned16      ter4;
+  rtems_unsigned8       _pad43[8];
+  
+  
+  
+  /*
+   * CPM Block
+   */
+  rtems_unsigned16      cpcr;
+  rtems_unsigned16      _pad44;
+  rtems_unsigned16      rccr;
+  rtems_unsigned8       _pad45;
+  rtems_unsigned8       rmds;
+  rtems_unsigned32      rmdr;
+  rtems_unsigned16      rctr1;
+  rtems_unsigned16      rctr2;
+  rtems_unsigned16      rctr3;
+  rtems_unsigned16      rctr4;
+  rtems_unsigned16      _pad46;
+  rtems_unsigned16      rter;
+  rtems_unsigned16      _pad47;
+  rtems_unsigned16      rtmr;
+  rtems_unsigned8       _pad48[0x9f0-0x9dc];
+  
+  /*
+   * BRG Block
+   */
+  rtems_unsigned32      brgc1;
+  rtems_unsigned32      brgc2;
+  rtems_unsigned32      brgc3;
+  rtems_unsigned32      brgc4;
+  
+  /*
+   * SCC Block
+   */
+  m860SCCRegisters_t    scc1;
+  m860SCCRegisters_t    scc2;
+  m860SCCRegisters_t    scc3;
+  m860SCCRegisters_t    scc4;
+  
+  /*
+   * SMC Block
+   */
+  m860SMCRegisters_t    smc1;
+  m860SMCRegisters_t    smc2;
+  
+  /*
+   * SPI Block
+   */
+  rtems_unsigned16      spmode;
+  rtems_unsigned16      _pad49[2];
+  rtems_unsigned8       spie;
+  rtems_unsigned8       _pad50;
+  rtems_unsigned16      _pad51;
+  rtems_unsigned8       spim;
+  rtems_unsigned8       _pad52[2];
+  rtems_unsigned8       spcom;
+  rtems_unsigned16      _pad53[2];
+  
+  /*
+   * PIP Block
+   */
+  rtems_unsigned16      pipc;
+  rtems_unsigned16      _pad54;
+  rtems_unsigned16      ptpr;
+  rtems_unsigned32      pbdir;
+  rtems_unsigned32      pbpar;
+  rtems_unsigned16      _pad55;
+  rtems_unsigned16      pbodr;
+  rtems_unsigned32      pbdat;
+  rtems_unsigned32      _pad56[6];
+  
+  /*
+   * SI Block
+   */
+  rtems_unsigned32      simode;
+  rtems_unsigned8       sigmr;
+  rtems_unsigned8       _pad57;
+  rtems_unsigned8       sistr;
+  rtems_unsigned8       sicmr;
+  rtems_unsigned32      _pad58;
+  rtems_unsigned32      sicr;
+  rtems_unsigned16      sirp[2];
+  rtems_unsigned32      _pad59[3];
+  rtems_unsigned8       _pad60[0xc00-0xb00];
+  rtems_unsigned8       siram[512];
+
+  /*
+   * This is only used on the MPC860T - for the Fast Ethernet Controller (FEC)
+   */
+  m860FECRegisters_t         fec;
+
+  rtems_unsigned8       _pad62[0x2000-0x1000];
+  /*
+   * Dual-port RAM
+   */
+  rtems_unsigned8       dpram0[0x200];  /* BD/DATA/UCODE */
+  rtems_unsigned8       dpram1[0x200];  /* BD/DATA/UCODE */
+  rtems_unsigned8       dpram2[0x400];  /* BD/DATA/UCODE */
+  rtems_unsigned8       dpram3[0x600];  /* BD/DATA*/
+  rtems_unsigned8       dpram4[0x200];  /* BD/DATA/UCODE */
+  rtems_unsigned8       _pad63[0x3c00-0x3000];
+  
+  /* When using SCC1 for ethernet, we lose the use of I2C since
+   *  their parameters would overlap. Motorola has a microcode
+   *  patch to move parameters around so that both can be used
+   *  together. It is available on their web site somewhere 
+   *  under http://www.mot.com/mpc860. If ethernet is used on
+   *  one (or more) of the other SCCs, then other CPM features
+   *  will be unavailable:
+   *    SCC2    -> lose SPI
+   *    SCC3    -> lose SMC1
+   *    SCC4    -> lose SMC2
+   */
+  m860SCCENparms_t      scc1p;
+  rtems_unsigned8       _rsv1[0xCB0-0xC00-sizeof(m860SCCENparms_t)];
+  m860MiscParms_t       miscp;
+  rtems_unsigned8       _rsv2[0xcc0-0xCB0-sizeof(m860MiscParms_t)];
+  m860IDMAparms_t       idma1p;
+  rtems_unsigned8       _rsv3[0xd00-0xcc0-sizeof(m860IDMAparms_t)];
+  
+  m860SCCparms_t        scc2p;
+  rtems_unsigned8       _rsv4[0xD80-0xD00-sizeof(m860SCCparms_t)];
+  m860SPIparms_t        spip;
+  rtems_unsigned8       _rsv5[0xDB0-0xD80-sizeof(m860SPIparms_t)];
+  m860TimerParms_t      tmp;
+  rtems_unsigned8       _rsv6[0xDC0-0xDB0-sizeof(m860TimerParms_t)];
+  m860IDMAparms_t       idma2p;
+  rtems_unsigned8       _rsv7[0xE00-0xDC0-sizeof(m860IDMAparms_t)];
+  
+  m860SCCparms_t        scc3p;
+  rtems_unsigned8       _rsv8[0xE80-0xE00-sizeof(m860SCCparms_t)];
+  m860SMCparms_t        smc1p;
+  rtems_unsigned8       _rsv9[0xEC0-0xE80-sizeof(m860SMCparms_t)];
+  m860DSPparms_t        dsp1p;
+  rtems_unsigned8       _rsv10[0xF00-0xEC0-sizeof(m860DSPparms_t)];
+  
+  m860SCCparms_t        scc4p;
+  rtems_unsigned8       _rsv11[0xF80-0xF00-sizeof(m860SCCparms_t)];
+  m860SMCparms_t        smc2p;
+  rtems_unsigned8       _rsv12[0xFC0-0xF80-sizeof(m860SMCparms_t)];
+  m860DSPparms_t        dsp2p;
+  rtems_unsigned8       _rsv13[0x1000-0xFC0-sizeof(m860DSPparms_t)];
+} m860_t;
+
+extern volatile m860_t m860;
+#endif /* ASM */
+
+#endif /* __MPC860_h */
Index: c/src/lib/libbsp/powerpc/eth_comm/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,25 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/directory.cfg
+
+SRCS=README
+
+# We only build the networking device driver if HAS_NETWORKING was defined
+NETWORKING_DRIVER_yes_V = network
+NETWORKING_DRIVER = $(NETWORKING_DRIVER_$(HAS_NETWORKING)_V)
+
+all: $(SRCS)
+
+# wrapup is the one that actually builds and installs the library
+#  from the individual .rel files built in other directories
+SUB_DIRS=include startup start canbus console $(NETWORKING_DRIVER) wrapup
+
Index: c/src/lib/libbsp/powerpc/eth_comm/README
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,100 @@
+#
+#  $Id$
+#
+
+BSP NAME:           eth_comm
+BOARD:              Frasca International, Inc Ethernet Comm board
+BUS:                N/A
+CPU FAMILY:         ppc
+CPU:                PowerPC MPC860/MPC860T
+COPROCESSORS:       N/A
+MODE:               32 bit mode
+
+DEBUG MONITOR:      None
+
+PERIPHERALS
+===========
+TIMERS:             PIT 
+  RESOLUTION:         1 microsecond
+SERIAL PORTS:       4 SCCs (one is used for ethernet on MPC860, and unused
+			on MPC860T), 2 SMC, 4 on external FPGA, 3 CANBUS
+REAL-TIME CLOCK:    
+DMA:                Each serial port
+VIDEO:              none
+SCSI:               none
+NETWORKING:         Ethernet (10 Mbps) on SCC1 (MPC860)
+		    Fast ethernet (100/10 Mbps) on FEC (MPC860T)
+
+DRIVER INFORMATION
+==================
+CLOCK DRIVER:       
+IOSUPP DRIVER:      
+SHMSUPP:            none
+TIMER DRIVER:       
+
+STDIO
+=====
+PORT:               SCC2
+ELECTRICAL:         RS-232
+BAUD:               9600
+BITS PER CHARACTER: 8
+PARITY:             None
+STOP BITS:          1
+
+NOTES
+=====
+On-chip resources:
+	SCC1		network or console
+	SCC2		console
+	SCC3		console
+	SCC4		console
+	CLK1		network
+	CLK2		network
+	CLK3
+	CLK4
+	CLK5
+	CLK6
+	CLK7
+	CLK8
+	BRG1		console
+	BRG2		console
+	BRG3		console
+	BRG4		console
+	RTC
+	PIT		clock
+	TB
+	DEC
+	SWT	
+	*CS0		FLASH
+	*CS1		DRAM bank 1
+	*CS2		CAN0
+	*CS3		CAN1
+	*CS4		CAN2
+	*CS5		MB1
+	*CS6		ARINC
+	*CS7		DRAM bank 0
+	UPMA
+	UPMB
+	IRQ0
+	IRQ1
+	IRQ2		CAN2
+	IRQ3		CAN0
+	IRQ4		CAN1
+	IRQ5	
+	IRQ6
+	IRQ7
+	IRQ_LVL0	clock - PIT
+	IRQ_LVL1
+	IRQ_LVL2
+	IRQ_LVL3
+	IRQ_LVL4
+	IRQ_LVL5
+	IRQ_LVL6
+	IRQ_LVL7
+Board description
+-----------------
+Clock rate:	40 - 66 MHz, depending on CPU
+Bus width:	16 bit Flash, 32 bit DRAM
+FLASH:		128K - 1024K, 120ns
+RAM:		2 - 32M DRAM SIMM, autodetects size and speed
+
Index: c/src/lib/libbsp/powerpc/eth_comm/bsp_specs
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/bsp_specs	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/bsp_specs	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,23 @@
+%rename cpp old_cpp
+%rename lib old_lib
+%rename endfile old_endfile
+%rename startfile old_startfile
+%rename link old_link
+
+*cpp:
+%(old_cpp) %{qrtems: -D__embedded__} -Asystem(embedded)
+
+*lib:
+%{!qrtems: %(old_lib)} %{qrtems: ecrti%O%s --start-group \
+%{!qrtems_debug: -lrtemsall} %{qrtems_debug: -lrtemsall_g} \
+-lc -lgcc --end-group \
+%{!qnolinkcmds: -T linkcmds%s}}
+
+*startfile:
+%{!qrtems: %(old_startfile)} %{qrtems: \
+%{!qrtems_debug: } \
+%{qrtems_debug: }}
+
+*link:
+%{!qrtems: %(old_link)} %{qrtems: -dc -dp -u __vectors -N -u start -e start}
+
Index: c/src/lib/libbsp/powerpc/eth_comm/canbus/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/canbus/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/canbus/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,54 @@
+#
+#  $Id: 
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/canbus.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=canbus
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
Index: c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/canbus/canbus.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,479 @@
+/*
+ * RTEMS CANBUS driver for eth-comm BSP
+ *
+ * Written by Jay Monkman (jmonkman@frasca.com)
+ *
+ *  COPYRIGHT (c) 1998
+ *  Frasca International, Inc.
+ *
+ *  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.
+ *
+ *  Note: All of this code assumes a 10Mhz clock input to the 82527
+ *
+ *  $Id: 
+ */
+#include <stdio.h>
+#include <bsp.h>
+#include <mpc860.h>
+#include <rtems/error.h>
+#include <canbus.h>
+/* How many CAN interfaces are there? */
+#define NUM_CAN_DEVS 3
+
+/* How many received messages should be buffered for each channel */
+#define RX_CAN_BUF_SIZE 16
+
+int rxMsgBufHead[NUM_CAN_DEVS];
+int rxMsgBufTail[NUM_CAN_DEVS];
+i82527_msg_t rxMsgBuf[NUM_CAN_DEVS][RX_CAN_BUF_SIZE];
+
+volatile i82527_t *candev[NUM_CAN_DEVS];
+
+
+static rtems_isr
+canInterruptHandler (rtems_vector_number v)
+{
+  int dev;
+  int tmpTail;
+
+  switch (v) {
+  case PPC_IRQ_IRQ3: dev = 0; break;
+  case PPC_IRQ_IRQ4: dev = 1; break;
+  case PPC_IRQ_IRQ2: dev = 2; break;
+  default:           return;    /* something screwed up */
+  }
+
+  /* we only do rx interrupts right now */
+  if (!(candev[dev]->msg15.ctrl1 & I82527_MSG_CTRL_NEWDAT)) {
+    /* Hmmm, that's odd. Why were we triggered? */
+    candev[dev]->msg15.ctrl0 = 0xff & (I82527_MSG_CTRL_INTPND_CLR |
+                                       I82527_MSG_CTRL_MSGVAL_SET);
+    candev[dev]->msg15.ctrl1 = 0xff & (I82527_MSG_CTRL_RMTPND_CLR |
+                                       I82527_MSG_CTRL_MSGLST_CLR |
+                                       I82527_MSG_CTRL_NEWDAT_CLR);
+    return;
+  }
+  tmpTail = rxMsgBufTail[dev];
+  while (1) {
+    if ((tmpTail == rxMsgBufHead[dev]) && 
+        (rxMsgBuf[dev][tmpTail].ctrl1 & I82527_MSG_CTRL_NEWDAT)) {
+      break;  /* Buf is full */
+    }
+
+    if (!(rxMsgBuf[dev][tmpTail].ctrl1 & I82527_MSG_CTRL_NEWDAT)) {
+      int pkt_len;
+      int i;
+
+      rxMsgBuf[dev][tmpTail].ctrl0 = candev[dev]->msg15.ctrl0;
+      rxMsgBuf[dev][tmpTail].ctrl1 = candev[dev]->msg15.ctrl1;
+      rxMsgBuf[dev][tmpTail].arb = candev[dev]->msg15.arb;
+      rxMsgBuf[dev][tmpTail].cfg = candev[dev]->msg15.cfg;
+      
+      pkt_len = (rxMsgBuf[dev][tmpTail].cfg >> 4) & 0xf;
+      for (i=0; i<pkt_len; i++) {
+        rxMsgBuf[dev][tmpTail].data[i] = candev[dev]->msg15.data[i];
+      }
+
+      tmpTail++;
+      if (tmpTail == RX_CAN_BUF_SIZE) {
+        tmpTail = 0;
+      }
+
+      rxMsgBufTail[dev] = tmpTail;
+
+      break;
+    }
+
+    tmpTail++;
+    if (tmpTail == RX_CAN_BUF_SIZE) {
+      tmpTail = 0;
+    }
+    if (tmpTail == rxMsgBufTail[dev]) {
+      break;
+    }
+  }
+
+
+  candev[dev]->msg15.ctrl0  = 0xff & (I82527_MSG_CTRL_MSGVAL_SET |
+                                      I82527_MSG_CTRL_INTPND_CLR);
+  candev[dev]->msg15.ctrl1  = 0xff & (I82527_MSG_CTRL_NEWDAT_CLR | 
+                                      I82527_MSG_CTRL_RMTPND_CLR);
+  candev[dev]->status = 0x0;
+}
+
+rtems_device_driver canbus_initialize(
+  rtems_device_major_number  major,
+  rtems_device_minor_number  minor,
+  void                      *arg
+)
+{
+  int i,j;
+  char dev_str[16]; /* This allows us to have a device name up to */
+                    /* 15 chars long. If we only use names like   */
+                    /* /dev/can0 (9 chars) we will be fine up to  */
+                    /* /dev/can9999999 */
+  rtems_status_code status;
+  rtems_isr_entry old_handler;
+  
+#if (NUM_CAN_DEVS > 0)
+  candev[0]=&canbus0;
+  rtems_interrupt_catch (canInterruptHandler,
+                         PPC_IRQ_IRQ3,
+                         &old_handler);
+
+#if (NUM_CAN_DEVS > 1)
+  candev[1]=&canbus1;
+  rtems_interrupt_catch (canInterruptHandler,
+                         PPC_IRQ_IRQ4,
+                         &old_handler);
+
+#if (NUM_CAN_DEVS > 2)
+  candev[2]=&canbus2;
+  rtems_interrupt_catch (canInterruptHandler,
+                         PPC_IRQ_IRQ2,
+                         &old_handler);
+  
+  /* Right now, we only support 3 CAN interfaces */
+#else
+#error NUM_CAN_DEVS is too big. Fix it, damnit!
+#endif /* NUM_CAN_DEVS > 2 */
+#endif /* NUM_CAN_DEVS > 1 */
+#else
+#error NUM_CAN_DEVS is 0. It needs to be at least 1
+#endif /* NUM_CAN_DEVS > 0 */
+
+
+  for (i=0; i < NUM_CAN_DEVS; i++) {
+    
+    /* clear rx buffers */
+    rxMsgBufHead[i] = 0;
+    rxMsgBufTail[i] = 0;
+    for (j=0; j < RX_CAN_BUF_SIZE; j++) {
+      rxMsgBuf[i][j].ctrl0 = 0x55; /* all flags are cleared */
+      rxMsgBuf[i][j].ctrl1 = 0x55; /* all flags are cleared */
+    }
+
+    candev[i]->ctrl = I82527_CTRL_CCE | /* Enable cfg reg writes */
+                      I82527_CTRL_INIT; /* Disable external xfers */
+  
+    candev[i]->cir = I82527_CIR_DMC;    /* Divide memory clock by 2 */
+
+    
+    /* We want 250 kbps so assuming an input clock rate of 10 MHz:
+     *   DSC = 0  =>  SCLK = 10 MHz, tSCLK = 100ns
+     *   BRP = 1  =>  tq = 200ns
+     *   tSYNC_SEG = 1 tq
+     *   tSEG1 = TSEG1+1 = 14+1 = 15
+     *   tSEG2 = TSEG2+1 = 3+1  = 4
+     *
+     *  bittime = tSYNC_SEG + tSEG1 + tSEG2
+     *          = 1 + 15 + 4 = 20
+     *  baudrate = 1/(bittime * tq) = 1/(20 * 200ns) = 1/(4000ns) = 250 kbps
+     */
+    candev[i]->btr0 = 0xc1;  /* Baud rate prescaler=0, Sync jump width=3 */
+
+    candev[i]->btr1 = I82527_BTR1_SPL | /* go for noise immunity */
+                      (0x3 << 4) |      /* TSEG2 = 3 */
+                      (0xe);            /* TSEG1 = 14 */
+
+    candev[i]->gms = 0xffff;            /* addresses must match exactly */
+    candev[i]->gml = 0xffffffff;        /* addresses must match exactly */
+    
+    candev[i]->mlm = 0x0;               /* all addresses accepted */
+
+    candev[i]->p2conf = 0xff;           /* make all outputs */
+
+    candev[i]->msg1.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg1.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg2.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg2.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg3.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg3.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg4.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg4.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR  | /* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg5.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg5.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg6.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg6.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg7.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg7.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg8.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg8.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg9.cfg    = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg9.ctrl0  = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg10.cfg   = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg10.ctrl0 = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR  | /* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg11.cfg   = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg11.ctrl0 = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg12.cfg   = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg12.ctrl0 = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg13.cfg   = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg13.ctrl0 = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg14.cfg   = I82527_MSG_CFG_DIR ;        /* dir is xmit */
+    candev[i]->msg14.ctrl0 = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR; 
+
+    candev[i]->msg15.cfg   = 0 ;        /* dir is rcv */
+    candev[i]->msg15.ctrl0 = I82527_MSG_CTRL_MSGVAL_CLR |/* this msg invalid */
+                             I82527_MSG_CTRL_TXIE_CLR   |/* no tx interrupts */
+                             I82527_MSG_CTRL_RXIE_CLR   |/* no rx interrupts */
+                             I82527_MSG_CTRL_INTPND_CLR;
+    candev[i]->msg15.ctrl1 = I82527_MSG_CTRL_RMTPND_CLR |
+                             I82527_MSG_CTRL_TXRQ_CLR   |
+                             I82527_MSG_CTRL_MSGLST_CLR |
+                             I82527_MSG_CTRL_NEWDAT_CLR;
+
+  }
+
+  if ((status=rtems_io_register_name ("/dev/can0", major, 0)) !=
+      RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred (status);
+  }
+  if ((status=rtems_io_register_name ("/dev/can1", major, 1)) !=
+      RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred (status);
+  }
+  if ((status=rtems_io_register_name ("/dev/can2", major, 2)) !=
+      RTEMS_SUCCESSFUL) {
+    rtems_fatal_error_occurred (status);
+  }
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver canbus_open(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+    /* msg is in use, rx interrupts are enabled */
+  candev[minor]->msg15.ctrl0 = 0xff & (I82527_MSG_CTRL_MSGVAL_SET |
+                                       I82527_MSG_CTRL_RXIE_SET);
+    
+  candev[minor]->ctrl |= I82527_CTRL_IE;
+  candev[minor]->ctrl &= ~(I82527_CTRL_CCE | I82527_CTRL_INIT);
+  switch (minor) {
+  case 0: m860.simask |= M860_SIMASK_IRM3; break;
+  case 1: m860.simask |= M860_SIMASK_IRM4; break;
+  case 2: m860.simask |= M860_SIMASK_IRM2; break;
+  default: return;
+  }
+
+  return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver canbus_close(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  /* msg is not in use, rx & txinterrupts are disbled */
+  candev[minor]->msg15.ctrl0 = 0xff & (I82527_MSG_CTRL_MSGVAL_CLR |
+                                       I82527_MSG_CTRL_RXIE_CLR |
+                                       I82527_MSG_CTRL_TXIE_CLR);
+    
+  /* Take transceiver off the bus, enable cfg. reg. writes */
+  candev[minor]->ctrl |= (I82527_CTRL_CCE | I82527_CTRL_INIT);
+    
+  return RTEMS_SUCCESSFUL;
+}
+
+
+rtems_device_driver canbus_read(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  i82527_msg_t *msg;
+  int i;
+  int tmpHead;
+
+  msg = arg;
+  tmpHead = rxMsgBufHead[minor];
+
+  while (1){
+    if ((tmpHead == rxMsgBufTail[minor]) && 
+        !(rxMsgBuf[minor][tmpHead].ctrl1 & I82527_MSG_CTRL_NEWDAT)) {
+      break;
+    }
+    if (rxMsgBuf[minor][tmpHead].ctrl1 & I82527_MSG_CTRL_NEWDAT) {
+      int pkt_len;
+      msg->ctrl0 = rxMsgBuf[minor][tmpHead].ctrl0;
+      msg->ctrl1 = rxMsgBuf[minor][tmpHead].ctrl1;
+      msg->arb = rxMsgBuf[minor][tmpHead].arb;
+      msg->cfg = rxMsgBuf[minor][tmpHead].cfg;
+      
+      pkt_len = (msg->cfg >> 4) & 0xf;
+      for (i=0; i<pkt_len; i++) {
+        msg->data[i] = rxMsgBuf[minor][tmpHead].data[i];
+      }
+      rxMsgBuf[minor][tmpHead].ctrl1 = 0xff & I82527_MSG_CTRL_NEWDAT_CLR;
+
+      tmpHead++;
+      if (tmpHead == RX_CAN_BUF_SIZE) {
+        tmpHead = 0;
+      }
+      rxMsgBufHead[minor] = tmpHead;
+
+      return RTEMS_SUCCESSFUL;
+
+    }
+
+    tmpHead++;
+    if (tmpHead == RX_CAN_BUF_SIZE) {
+      tmpHead = 0;
+    }
+    if (tmpHead == rxMsgBufHead[minor]) {
+      break;
+    }
+  }
+
+  return RTEMS_UNSATISFIED;
+
+}
+    
+rtems_device_driver canbus_write(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  i82527_msg_t *msg;
+  int i;
+
+  msg = arg;
+  while(candev[minor]->msg1.ctrl1 & I82527_MSG_CTRL_TXRQ){
+    continue;
+  }
+  candev[minor]->msg1.ctrl1  = 0xff & I82527_MSG_CTRL_CPUUPD_SET;
+
+  candev[minor]->msg1.cfg = msg->cfg;
+  candev[minor]->msg1.arb = msg->arb;
+
+  for (i=0; i < ((msg->cfg >> 4) & 0xff);  i++) {
+    candev[minor]->msg1.data[i] = msg->data[i];
+  }
+
+  candev[minor]->msg1.ctrl0  = 0xff & (I82527_MSG_CTRL_INTPND_CLR |
+                                       I82527_MSG_CTRL_MSGVAL_SET |
+                                       I82527_MSG_CTRL_TXIE_CLR);
+  candev[minor]->msg1.cfg    |= I82527_MSG_CFG_DIR;
+  candev[minor]->msg1.ctrl1  = 0xff & (I82527_MSG_CTRL_NEWDAT_SET |
+                                       I82527_MSG_CTRL_CPUUPD_CLR |
+                                       I82527_MSG_CTRL_TXRQ_SET);
+
+
+
+  return RTEMS_SUCCESSFUL;
+}
+rtems_device_driver canbus_control(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void                    * arg
+)
+{
+  return RTEMS_SUCCESSFUL;
+}
+
+
+/* part of old canbus_read */
+#if 0 
+  for (i=0; i < RX_CAN_BUF_SIZE) {
+    if (rxMsgBuf[minor][i].ctrl1 & I82527_MSG_CTRL_NEWDAT)
+      break;
+  }
+
+  if (i < RX_CAN_BUF_SIZE) {
+    int pkt_len;
+    int j;
+    msg.arb = rxMsgBuf[minor][i].arb;
+    msg.cfg = rxMsgBuf[minor][i].cfg;
+    
+    pkt_len = (msg.cfg >> 4) & 0xf;
+
+    for (j=0; j < pkt_len; j++) 
+      msg.data[j] = rxMsgBuf[minor][i].data[j];
+  
+  
+  /* wait until there is a msg */
+  while (!(candev->msg15.ctrl1 & I82527_MSG_CTRL_NEWDAT))
+     continue;
+ 
+  msg->ctrl1 = candev->msg15.ctrl1;
+  msg->cfg = candev->msg15.cfg;
+  msg->arb = candev->msg15.arb;
+
+  for (i=0; i < ((candev->msg15.cfg >> 4) & 0xff);  i++) {
+    msg->data[i] = candev->msg15.data[i];
+  }
+
+  candev->msg15.ctrl0  = 0xff & (I82527_MSG_CTRL_MSGVAL_SET |
+                                 I82527_MSG_CTRL_INTPND_CLR);
+  candev->msg15.ctrl1  = 0xff & (I82527_MSG_CTRL_NEWDAT_CLR | 
+                                 I82527_MSG_CTRL_RMTPND_CLR);
+
+  candev->status = 0x0;
+
+
+  return RTEMS_SUCCESSFUL;
+#endif
+
+
Index: c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/console/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,54 @@
+#
+#  $Id: 
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/console.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=console
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
Index: c/src/lib/libbsp/powerpc/eth_comm/console/console.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/console/console.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/console/console.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,233 @@
+#define I_WANT_TERMIOS 
+/*
+ *  BSP specific Serial I/O Functions for the eth-comm BSP
+ *
+ * This file contains the BSP specific functions for 
+ * performing serial I/O. These are the functions
+ * RTEMS uses (the 6 listed in the device driver 
+ * structure)
+ *
+ * The SCCs and SMCs are assigned as follows
+ *
+ *   Channel     Device      Minor   Termios
+ *    SMC1      /dev/tty0      0       no
+ *    SMC2      /dev/tty1      1       no
+ *    SCC1      ethernet
+ *    SCC2      /dev/console   3       yes
+ *    SCC3      /dev/tty3      4       no
+ *    SCC4      /dev/tty4      5       no
+ *
+ * FIXME: This should use termios for /dev/console, but it doesn't
+ *  appear to work correctly yet. On startup, with termios enabled,
+ *  the board hangs for a few seconds before running correctly
+ *
+ * Author: Jay Monkman (jmonkman@frasca.com) 
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ */
+#include <rtems/libio.h>
+#include <mpc860.h>
+#include <mpc860/console.h>
+#include <termios.h>
+
+rtems_device_driver console_initialize(rtems_device_major_number major,
+                                       rtems_device_minor_number minor,
+                                       void *arg)
+{
+  rtems_status_code status;
+  rtems_isr_entry old_handler;
+  rtems_status_code sc;
+  
+#ifdef I_WANT_TERMIOS
+  /*
+   * Set up TERMIOS (for /dev/console)
+   */
+  rtems_termios_initialize();
+#endif
+
+  /*
+   * Set up Buffer Descriptors
+   */
+  m860_console_initialize();
+
+  /*
+   * Do device-specific initialization
+   */
+  m860_scc_initialize(2);  /* /dev/console */
+  m860_scc_initialize(3);  /* /dev/tty3   */
+  m860_scc_initialize(4);  /* /dev/tty4   */
+  m860_smc_initialize(1);  /* /dev/tty0   */
+  m860_smc_initialize(2);  /* /dev/tty1   */
+  
+  sc = rtems_interrupt_catch (m860_scc2_console_interrupt_handler,
+                              PPC_IRQ_CPM_SCC2,
+                              &old_handler);
+  sc = rtems_interrupt_catch (m860_scc3_console_interrupt_handler,
+                              PPC_IRQ_CPM_SCC3,
+                              &old_handler);
+  sc = rtems_interrupt_catch (m860_scc4_console_interrupt_handler,
+                              PPC_IRQ_CPM_SCC4,
+                              &old_handler);
+  sc = rtems_interrupt_catch (m860_smc1_console_interrupt_handler,
+                              PPC_IRQ_CPM_SMC1,
+                              &old_handler);
+  sc = rtems_interrupt_catch (m860_smc2_console_interrupt_handler,
+                              PPC_IRQ_CPM_SMC2,
+                              &old_handler);
+
+  /*
+   * Register the devices
+   */
+  status = rtems_io_register_name ("/dev/console", major, SCC2_MINOR);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+  status = rtems_io_register_name ("/dev/tty0", major, SMC1_MINOR);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+  status = rtems_io_register_name ("/dev/tty1", major, SMC2_MINOR);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+  status = rtems_io_register_name ("/dev/tty3", major, SCC3_MINOR);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+  status = rtems_io_register_name ("/dev/tty4", major, SCC4_MINOR);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_fatal_error_occurred (status);
+  return RTEMS_SUCCESSFUL;
+}
+ 
+rtems_device_driver console_open(rtems_device_major_number major,
+                                 rtems_device_minor_number minor,
+                                 void *arg)
+{
+  volatile m860SCCRegisters_t *sccregs;
+
+#ifdef I_WANT_TERMIOS
+  static const rtems_termios_callbacks sccPollCallbacks = {
+    NULL,                       /* firstOpen */
+    NULL,                       /* lastClose */
+    m860_char_poll_read,        /* pollRead */
+    m860_char_poll_write,       /* write */
+    m860_scc_set_attributes,    /* setAttributes */
+    NULL,                       /* stopRemoteTx */
+    NULL,                       /* startRemoteTx */
+    0                           /* outputUsesInterrupts */
+  };
+#endif /* I_WANT_TERMIOS */
+
+  sccregs = 0;
+
+  switch (minor) {
+  case 0:
+    m860.smc1.smcm = 1;           /* Enable SMC1 RX interrupts */
+    m860.cimr |= 1UL <<  4;       /* Enable SMC1 interrupts */
+    break;
+  case 1:
+    m860.smc2.smcm = 1;           /* Enable SMC2 RX interrupts */
+    m860.cimr |= 1UL <<  3;       /* Enable SMC2 interrupts */
+    break;
+  case 2:
+    m860.cimr |= 1UL << 30;      /* Enable SCC1 interrupts */
+    sccregs = &m860.scc1;
+    break;
+  case 3: 
+#ifndef I_WANT_TERMIOS
+    m860.cimr |= 1UL << 29;      /* Enable SCC2 interrupts */
+#endif /* I_WANT_TERMIOS */
+    sccregs = &m860.scc2;
+    break;
+  case 4:
+    m860.cimr |= 1UL << 28;      /* Enable SCC3 interrupts */
+    sccregs = &m860.scc3;
+    break;
+  case 5:
+    m860.cimr |= 1UL << 27;      /* Enable SCC4 interrupts */
+    sccregs = &m860.scc4;
+    break;
+  default:
+    rtems_panic ("CONSOLE: bad minor number");
+  }
+
+  if (sccregs)
+    sccregs->sccm=0x3;
+
+#ifdef I_WANT_TERMIOS
+  if (minor == SCC2_MINOR) {
+    return rtems_termios_open (major, minor, arg, &sccPollCallbacks);
+  }
+  else { 
+    return RTEMS_SUCCESSFUL;
+  }
+#else
+  return RTEMS_SUCCESSFUL;
+#endif
+}
+
+rtems_device_driver console_close(rtems_device_major_number major,
+                                  rtems_device_minor_number minor,
+                                  void *arg)
+{
+#ifdef I_WANT_TERMIOS
+  if (minor == SCC2_MINOR) {
+    return rtems_termios_close (arg);
+  }
+  else {
+    return RTEMS_SUCCESSFUL;
+  }
+#else
+  return RTEMS_SUCCESSFUL;
+#endif
+}
+
+rtems_device_driver console_read(rtems_device_major_number major,
+                                 rtems_device_minor_number minor,
+                                 void *arg)
+{
+#ifdef I_WANT_TERMIOS
+  if (minor == SCC2_MINOR) {
+    return rtems_termios_read(arg);
+  }
+  else {
+    return m860_console_read(major, minor, arg);
+  }
+#else
+  return m860_console_read(major, minor, arg);
+#endif
+}
+
+rtems_device_driver console_write(rtems_device_major_number major,
+                                  rtems_device_minor_number minor,
+                                  void *arg)
+{
+#ifdef I_WANT_TERMIOS
+  if (minor == SCC2_MINOR) {
+    return rtems_termios_write(arg);
+  }
+  else {
+    return m860_console_write(major, minor, arg);
+  }
+#else
+  return m860_console_write(major, minor, arg);
+#endif
+}
+
+/*
+ * Handle ioctl request.
+ * Should set hardware line speed, bits/char, etc.
+ */
+rtems_device_driver console_control(rtems_device_major_number major,
+                                    rtems_device_minor_number minor,
+                                    void *arg)
+{ 
+#ifdef I_WANT_TERMIOS
+  if (minor == SCC2_MINOR) {
+    return rtems_termios_ioctl (arg);
+  }
+  else {
+    return RTEMS_SUCCESSFUL;
+  }
+#else
+  return RTEMS_SUCCESSFUL;
+#endif
+}
+
Index: c/src/lib/libbsp/powerpc/eth_comm/include/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/include/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/include/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,33 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+H_FILES = $(srcdir)/bsp.h $(srcdir)/coverhd.h $(srcdir)/canbus.h $(srcdir)/info.h
+
+#
+#  Equate files are for including from assembly preprocessed by
+#  gm4 or gasp.  No examples are provided except for those for
+#  other CPUs.  The best way to generate them would be to
+#  provide a program which generates the constants used based
+#  on the C equivalents.
+#
+
+EQ_FILES =
+
+SRCS=$(H_FILES) $(EQ_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+all:	$(SRCS)
+	$(INSTALL) -m 444 $(H_FILES) $(PROJECT_INCLUDE)
+	$(INSTALL) -m 444 $(EQ_FILES) $(PROJECT_INCLUDE)
Index: c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/include/bsp.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,116 @@
+/*  bsp.h
+ *
+ *  This include file contains all board IO definitions.
+ *
+ *  XXX : put yours in here
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#ifndef __NO_BSP_h
+#define __NO_BSP_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+#include <console.h>
+#include <clockdrv.h>
+
+/*
+ * Network driver configuration
+ */
+struct rtems_bsdnet_ifconfig;
+extern int rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config);
+#define RTEMS_BSP_NETWORK_DRIVER_NAME	"eth1"
+#define RTEMS_BSP_NETWORK_DRIVER_ATTACH	rtems_enet_driver_attach
+
+/*
+ * We need to decide how much memory will be non-cacheable. This
+ * will mainly be memory that will be used in DMA (network and serial
+ * buffers).
+ */
+#define NOCACHE_MEM_SIZE 512*1024
+
+/*
+ *  Define the time limits for RTEMS Test Suite test durations.
+ *  Long test and short test duration limits are provided.  These
+ *  values are in seconds and need to be converted to ticks for the
+ *  application.
+ *
+ */
+
+#define MAX_LONG_TEST_DURATION       300 /* 5 minutes = 300 seconds */
+#define MAX_SHORT_TEST_DURATION      3   /* 3 seconds */
+
+/*
+ *  Stuff for Time Test 27
+ */
+
+#define MUST_WAIT_FOR_INTERRUPT 0
+
+#define Install_tm27_vector( handler ) set_vector( (handler), PPC_IRQ_SCALL, 1 )
+
+#define Cause_tm27_intr() asm volatile ("sc")
+
+#define Clear_tm27_intr()
+
+#define Lower_tm27_intr()
+
+/* Constants */
+
+#define RAM_START 0
+#define RAM_END   0x100000
+
+/* miscellaneous stuff assumed to exist */
+
+extern rtems_configuration_table BSP_Configuration;
+
+/*
+ *  Device Driver Table Entries
+ */
+
+/*
+ * NOTE: Use the standard Console driver entry
+ */
+ 
+/*
+ * NOTE: Use the standard Clock driver entry
+ */
+
+/*
+ * How many libio files we want
+ */
+
+#define BSP_LIBIO_MAX_FDS       20
+
+/* functions */
+
+void bsp_cleanup( void );
+
+void M860ExecuteRISC( rtems_unsigned16 command );
+void *M860AllocateBufferDescriptors( int count );
+void *M860AllocateRiscTimers( int count );
+extern char M860DefaultWatchdogFeeder;
+
+rtems_isr_entry set_vector(                    /* returns old vector */
+  rtems_isr_entry     handler,                  /* isr routine        */
+  rtems_vector_number vector,                   /* vector number      */
+  int                 type                      /* RTEMS or RAW intr  */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
Index: c/src/lib/libbsp/powerpc/eth_comm/include/canbus.h
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/include/canbus.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/include/canbus.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,172 @@
+/*  canbus.h
+ *
+ *  This include file contains all canbus IO definitions
+ *
+ *  Written by Jay Monkman (jmonkman@frasca.com)
+ *
+ *  COPYRIGHT (c) 1998
+ *  Frasca International, Inc.
+ *
+ *  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.
+ *
+ *  $Id: 
+ */
+
+#ifndef __CANBUS_H_
+#define __CANBUS_H_
+
+#include <rtems.h>
+
+typedef struct i82527_msg_t_ {
+  rtems_unsigned8  ctrl0 __attribute__ ((packed));    /* Control 0 register */
+  rtems_unsigned8  ctrl1 __attribute__ ((packed));    /* Control 1 register */
+  rtems_unsigned32 arb __attribute__ ((packed));      /* Arbitration reg */
+  rtems_unsigned8  cfg __attribute__ ((packed));      /* Message config reg */
+  rtems_unsigned8  data[8] __attribute__ ((packed));  /* Actual message */
+} i82527_msg_t;
+
+typedef struct i82527_t_ {
+  rtems_unsigned8  ctrl __attribute__ ((packed));    /* Control register */
+  rtems_unsigned8  status __attribute__ ((packed));  /* Status register */
+  rtems_unsigned8  cir __attribute__ ((packed));     /* CPU interface reg */
+  rtems_unsigned8  _res0 __attribute__ ((packed));
+  rtems_unsigned16 hsr __attribute__ ((packed));     /* High speed read */
+  rtems_unsigned16 gms __attribute__ ((packed));     /* Global Mask - std */
+  rtems_unsigned32 gml __attribute__ ((packed));     /* Global Mask - long */
+  rtems_unsigned32 mlm __attribute__ ((packed));     /* Mask last message  */
+  i82527_msg_t     msg1 __attribute__ ((packed));    /* Message 1 */
+  rtems_unsigned8  clkout __attribute__ ((packed));  /* CLKOUT register */
+  i82527_msg_t     msg2 __attribute__ ((packed));    /* Message 2 */
+  rtems_unsigned8  bcr __attribute__ ((packed));     /* Bus config register */
+  i82527_msg_t     msg3 __attribute__ ((packed));    /* Message 3 */
+  rtems_unsigned8  btr0 __attribute__ ((packed));    /* Bit timing reg 0 */
+  i82527_msg_t     msg4 __attribute__ ((packed));    /* Message 4 */
+  rtems_unsigned8  btr1 __attribute__ ((packed));    /* Bit timing reg 1 */
+  i82527_msg_t     msg5 __attribute__ ((packed));    /* Message 5 */
+  rtems_unsigned8  intr __attribute__ ((packed));    /* Interrupt register */
+  i82527_msg_t     msg6 __attribute__ ((packed));    /* Message 6 */
+  rtems_unsigned8  _res1 __attribute__ ((packed));
+  i82527_msg_t     msg7 __attribute__ ((packed));    /* Message 7 */
+  rtems_unsigned8  _res2 __attribute__ ((packed));
+  i82527_msg_t     msg8 __attribute__ ((packed));    /* Message 8 */
+  rtems_unsigned8  _res3 __attribute__ ((packed));
+  i82527_msg_t     msg9 __attribute__ ((packed));    /* Message 9 */
+  rtems_unsigned8  p1conf __attribute__ ((packed));  /* Port 1 config */
+  i82527_msg_t     msg10 __attribute__ ((packed));   /* Message 10 */
+  rtems_unsigned8  p2conf __attribute__ ((packed));  /* Port 2 config */
+  i82527_msg_t     msg11 __attribute__ ((packed));   /* Message 11 */
+  rtems_unsigned8  p1in __attribute__ ((packed));    /* Port 1 in */
+  i82527_msg_t     msg12 __attribute__ ((packed));   /* Message 12 */
+  rtems_unsigned8  p2in __attribute__ ((packed));    /* Port 2 in */
+  i82527_msg_t     msg13 __attribute__ ((packed));   /* Message 13 */
+  rtems_unsigned8  p1out __attribute__ ((packed));   /* Port 1 out */
+  i82527_msg_t     msg14 __attribute__ ((packed));   /* Message 14 */
+  rtems_unsigned8  p2out __attribute__ ((packed));   /* Port 2 out */
+  i82527_msg_t     msg15 __attribute__ ((packed));   /* Message 15 */
+  rtems_unsigned8  sra __attribute__ ((packed));     /* Serial reset address */
+} i82527_t;
+
+#define I82527_CTRL_CCE         (1<<6)
+#define I82527_CTRL_EIE         (1<<3)
+#define I82527_CTRL_SIE         (1<<2)
+#define I82527_CTRL_IE          (1<<1)
+#define I82527_CTRL_INIT        (1)
+#define I82527_STATUS_BOFF      (1<<7)
+#define I82527_STATUS_WARN      (1<<6)
+#define I82527_STATUS_WAKE      (1<<5)
+#define I82527_STATUS_RXOK      (1<<4)
+#define I82527_STATUS_TXOK      (1<<3)
+#define I82527_STATUS_LEC       (7)
+#define I82527_STATUS_LEC_NONE  0
+#define I82527_STATUS_LEC_STUFF 1
+#define I82527_STATUS_LEC_FORM  2
+#define I82527_STATUS_LEC_ACK   3
+#define I82527_STATUS_LEC_BIT1  4
+#define I82527_STATUS_LEC_BIT0  5
+#define I82527_STATUS_LEC_CRC   6
+#define I82527_CIR_RSTSTAT      (1<<7)
+#define I82527_CIR_DSC          (1<<6)
+#define I82527_CIR_DMC          (1<<5)
+#define I82527_CIR_PWD          (1<<4)
+#define I82527_CIR_SLEEP        (1<<3)
+#define I82527_CIR_MUX          (1<<2)
+#define I82527_CIR_CEN          (1)
+#define I82527_CLKOUT_SL1       (1<<5)
+#define I82527_CLKOUT_SLO       (1<<4)
+#define I82527_BCR_COBY         (1<<6)
+#define I82527_BCR_POL          (1<<5)
+#define I82527_DCT1             (1<<3)
+#define I82527_DCR1             (1<<1)
+#define I82527_DCR0             (1)
+#define I82527_BTR1_SPL         (1<<7)
+#define I82527_MSG_CTRL_MSGVAL     (2<<6)
+#define I82527_MSG_CTRL_MSGVAL_NC  (3<<6) 
+#define I82527_MSG_CTRL_MSGVAL_SET (2<<6) 
+#define I82527_MSG_CTRL_MSGVAL_CLR (1<<6)
+#define I82527_MSG_CTRL_TXIE       (2<<4)
+#define I82527_MSG_CTRL_TXIE_NC    (3<<4)
+#define I82527_MSG_CTRL_TXIE_SET   (2<<4)
+#define I82527_MSG_CTRL_TXIE_CLR   (1<<4)
+#define I82527_MSG_CTRL_RXIE       (2<<2)
+#define I82527_MSG_CTRL_RXIE_NC    (3<<2)
+#define I82527_MSG_CTRL_RXIE_SET   (2<<2)
+#define I82527_MSG_CTRL_RXIE_CLR   (1<<2)
+#define I82527_MSG_CTRL_INTPND     (2)
+#define I82527_MSG_CTRL_INTPND_NC  (3)
+#define I82527_MSG_CTRL_INTPND_SET (2)
+#define I82527_MSG_CTRL_INTPND_CLR (1)
+#define I82527_MSG_CTRL_RMTPND     (2<<6)
+#define I82527_MSG_CTRL_RMTPND_NC  (3<<6)
+#define I82527_MSG_CTRL_RMTPND_SET (2<<6)
+#define I82527_MSG_CTRL_RMTPND_CLR (1<<6)
+#define I82527_MSG_CTRL_TXRQ       (2<<4)
+#define I82527_MSG_CTRL_TXRQ_NC    (3<<4)
+#define I82527_MSG_CTRL_TXRQ_SET   (2<<4)
+#define I82527_MSG_CTRL_TXRQ_CLR   (1<<4)
+#define I82527_MSG_CTRL_MSGLST     (2<<2)
+#define I82527_MSG_CTRL_MSGLST_NC  (3<<2)
+#define I82527_MSG_CTRL_MSGLST_SET (2<<2)
+#define I82527_MSG_CTRL_MSGLST_CLR (1<<2)
+#define I82527_MSG_CTRL_CPUUPD     (2<<2)
+#define I82527_MSG_CTRL_CPUUPD_NC  (3<<2)
+#define I82527_MSG_CTRL_CPUUPD_SET (2<<2)
+#define I82527_MSG_CTRL_CPUUPD_CLR (1<<2)
+#define I82527_MSG_CTRL_NEWDAT     (2)
+#define I82527_MSG_CTRL_NEWDAT_NC  (3)
+#define I82527_MSG_CTRL_NEWDAT_SET (2)
+#define I82527_MSG_CTRL_NEWDAT_CLR (1)
+#define I82527_MSG_CFG_DIR          (1<<3)
+#define I82527_MSG_CFG_XTD          (1<<2)
+
+extern i82527_t canbus0;
+extern i82527_t canbus1;
+extern i82527_t canbus2;
+
+
+rtems_device_driver canbus_initialize(rtems_device_major_number, 
+				      rtems_device_minor_number, 
+				      void *);
+rtems_device_driver canbus_open(rtems_device_major_number, 
+				rtems_device_minor_number, 
+				void *);
+rtems_device_driver canbus_close(rtems_device_major_number, 
+				 rtems_device_minor_number, 
+				 void *);
+rtems_device_driver canbus_read(rtems_device_major_number, 
+				rtems_device_minor_number, 
+				void *);
+rtems_device_driver canbus_write(rtems_device_major_number, 
+				 rtems_device_minor_number, 
+				 void *);
+rtems_device_driver canbus_control(rtems_device_major_number, 
+				   rtems_device_minor_number, 
+				   void *);
+
+
+#define CANBUS_DRIVER_TABLE_ENTRY \
+  { canbus_initialize, canbus_open, canbus_close, \
+    canbus_read, canbus_write, canbus_control }
+
+#endif /* __CANBUS_H_ */
Index: c/src/lib/libbsp/powerpc/eth_comm/include/coverhd.h
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/include/coverhd.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/include/coverhd.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,115 @@
+/*  coverhd.h
+ *
+ *  This include file has defines to represent the overhead associated
+ *  with calling a particular directive from C.  These are used in the
+ *  Timing Test Suite to ignore the overhead required to pass arguments
+ *  to directives.  On some CPUs and/or target boards, this overhead
+ *  is significant and makes it difficult to distinguish internal
+ *  RTEMS execution time from that used to call the directive.
+ *  This file should be updated after running the C overhead timing
+ *  test.  Once this update has been performed, the RTEMS Time Test
+ *  Suite should be rebuilt to account for these overhead times in the
+ *  timing results.
+ *
+ *  NOTE:  If these are all zero, then the times reported include
+ *         all calling overhead including passing of arguments.
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#ifndef __COVERHD_h
+#define __COVERHD_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE      0
+#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE        0
+#define CALLING_OVERHEAD_TASK_CREATE               0
+#define CALLING_OVERHEAD_TASK_IDENT                0
+#define CALLING_OVERHEAD_TASK_START                0
+#define CALLING_OVERHEAD_TASK_RESTART              0
+#define CALLING_OVERHEAD_TASK_DELETE               0
+#define CALLING_OVERHEAD_TASK_SUSPEND              0
+#define CALLING_OVERHEAD_TASK_RESUME               0
+#define CALLING_OVERHEAD_TASK_SET_PRIORITY         0
+#define CALLING_OVERHEAD_TASK_MODE                 0
+#define CALLING_OVERHEAD_TASK_GET_NOTE             0
+#define CALLING_OVERHEAD_TASK_SET_NOTE             0
+#define CALLING_OVERHEAD_TASK_WAKE_WHEN            2
+#define CALLING_OVERHEAD_TASK_WAKE_AFTER           0
+#define CALLING_OVERHEAD_INTERRUPT_CATCH           0
+#define CALLING_OVERHEAD_CLOCK_GET                 2
+#define CALLING_OVERHEAD_CLOCK_SET                 2
+#define CALLING_OVERHEAD_CLOCK_TICK                0
+
+#define CALLING_OVERHEAD_TIMER_CREATE              0
+#define CALLING_OVERHEAD_TIMER_IDENT               0
+#define CALLING_OVERHEAD_TIMER_DELETE              0
+#define CALLING_OVERHEAD_TIMER_FIRE_AFTER          0
+#define CALLING_OVERHEAD_TIMER_FIRE_WHEN           2
+#define CALLING_OVERHEAD_TIMER_RESET               0
+#define CALLING_OVERHEAD_TIMER_CANCEL              0
+#define CALLING_OVERHEAD_SEMAPHORE_CREATE          0
+#define CALLING_OVERHEAD_SEMAPHORE_IDENT           0
+#define CALLING_OVERHEAD_SEMAPHORE_DELETE          0
+#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN          0
+#define CALLING_OVERHEAD_SEMAPHORE_RELEASE         0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT       0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND        0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT      0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST   0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE     0
+#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH       0
+
+#define CALLING_OVERHEAD_EVENT_SEND                0
+#define CALLING_OVERHEAD_EVENT_RECEIVE             0
+#define CALLING_OVERHEAD_SIGNAL_CATCH              0
+#define CALLING_OVERHEAD_SIGNAL_SEND               0
+#define CALLING_OVERHEAD_PARTITION_CREATE          0
+#define CALLING_OVERHEAD_PARTITION_IDENT           0
+#define CALLING_OVERHEAD_PARTITION_DELETE          0
+#define CALLING_OVERHEAD_PARTITION_GET_BUFFER      0
+#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER   0
+#define CALLING_OVERHEAD_REGION_CREATE             0
+#define CALLING_OVERHEAD_REGION_IDENT              0
+#define CALLING_OVERHEAD_REGION_DELETE             0
+#define CALLING_OVERHEAD_REGION_GET_SEGMENT        0
+#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT     0
+#define CALLING_OVERHEAD_PORT_CREATE               0
+#define CALLING_OVERHEAD_PORT_IDENT                0
+#define CALLING_OVERHEAD_PORT_DELETE               0
+#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0
+#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0
+
+#define CALLING_OVERHEAD_IO_INITIALIZE             0
+#define CALLING_OVERHEAD_IO_OPEN                   0
+#define CALLING_OVERHEAD_IO_CLOSE                  0
+#define CALLING_OVERHEAD_IO_READ                   0
+#define CALLING_OVERHEAD_IO_WRITE                  0
+#define CALLING_OVERHEAD_IO_CONTROL                0
+#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT      0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL     0
+#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD     0
+#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE  0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
Index: c/src/lib/libbsp/powerpc/eth_comm/include/info.h
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/include/info.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/include/info.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,90 @@
+/* info.h - Defines board info block structure and macros for
+ *          handling elements of struct for ethernet comm board
+ *
+ * Written by Jay Monkman 7/21/98
+ * Copyright Frasca International, Inc 1998
+ */
+
+#ifndef __info_h__
+#define __info_h__
+
+typedef struct BoardInfoBlock_ {
+  rtems_unsigned16       size;         /* size of info block in bytes */
+  rtems_unsigned8        eth_id[6];    /* ethernet id of ethernet interface */
+  rtems_unsigned32       cpu_spd;      /* cpu speed in Hz */
+  rtems_unsigned32       flash_size;   /* size of flash memory in bytes */
+  rtems_unsigned32       ram_size;     /* size of ram in bytes */
+  rtems_unsigned32       version;      /* version of firmare (x.y format) */
+  rtems_unsigned32       if429;        /* mask for arinc429 interface */
+  rtems_unsigned32       ifcsdb;       /* mask for csdb interface */
+  rtems_unsigned16       if232;        /* mask for rs232 interface */
+  rtems_unsigned8        ifcan;        /* mask for canbus interface */
+  rtems_unsigned8        if568;        /* mask for arinc568 interface */
+  rtems_unsigned8        fpn[16];      /* Frasca part number in ASCII */
+  rtems_unsigned16       rev;          /* Board revision */
+  rtems_unsigned32       ip_num;       /* Board IP number */
+  
+} boardinfo_t;
+
+#define IFACE_ARINC429_TX0 0x00000001;
+#define IFACE_ARINC429_RX0 0x00000002;
+#define IFACE_ARINC429_TX1 0x00000004;
+#define IFACE_ARINC429_RX1 0x00000008;
+#define IFACE_ARINC429_TX2 0x00000010;
+#define IFACE_ARINC429_RX2 0x00000020;
+#define IFACE_ARINC429_TX3 0x00000040;
+#define IFACE_ARINC429_RX3 0x00000080;
+#define IFACE_ARINC429_TX4 0x00000100;
+#define IFACE_ARINC429_RX4 0x00000200;
+#define IFACE_ARINC429_TX5 0x00000400;
+#define IFACE_ARINC429_RX5 0x00000800;
+#define IFACE_ARINC429_TX6 0x00001000;
+#define IFACE_ARINC429_RX6 0x00002000;
+#define IFACE_ARINC429_TX7 0x00004000;
+#define IFACE_ARINC429_RX7 0x00008000;
+
+#define IFACE_ARINC568_TX0 0x0001;
+#define IFACE_ARINC568_RX0 0x0002;
+#define IFACE_ARINC568_TX1 0x0004;
+#define IFACE_ARINC568_RX1 0x0008;
+
+#define IFACE_CSDB_TX0 0x00000001;
+#define IFACE_CSDB_RX0 0x00000002;
+#define IFACE_CSDB_TX1 0x00000004;
+#define IFACE_CSDB_RX1 0x00000008;
+#define IFACE_CSDB_TX2 0x00000010;
+#define IFACE_CSDB_RX2 0x00000020;
+#define IFACE_CSDB_TX3 0x00000040;
+#define IFACE_CSDB_RX3 0x00000080;
+#define IFACE_CSDB_TX4 0x00000100;
+#define IFACE_CSDB_RX4 0x00000200;
+#define IFACE_CSDB_TX5 0x00000400;
+#define IFACE_CSDB_RX5 0x00000800;
+#define IFACE_CSDB_TX6 0x00001000;
+#define IFACE_CSDB_RX6 0x00002000;
+#define IFACE_CSDB_TX7 0x00004000;
+#define IFACE_CSDB_RX7 0x00008000;
+#define IFACE_CSDB_TX8 0x00010000;
+#define IFACE_CSDB_RX8 0x00020000;
+
+#define IFACE_CAN_TX0 0x0001;
+#define IFACE_CAN_RX0 0x0002;
+#define IFACE_CAN_TX1 0x0004;
+#define IFACE_CAN_RX1 0x0008;
+#define IFACE_CAN_TX2 0x0010;
+#define IFACE_CAN_RX2 0x0020;
+
+#define IFACE_RS232_TX0 0x0001;
+#define IFACE_RS232_RX0 0x0002;
+#define IFACE_RS232_TX1 0x0004;
+#define IFACE_RS232_RX1 0x0008;
+#define IFACE_RS232_TX2 0x0010;
+#define IFACE_RS232_RX2 0x0020;
+#define IFACE_RS232_TX3 0x0040;
+#define IFACE_RS232_RX3 0x0080;
+#define IFACE_RS232_TX4 0x0100;
+#define IFACE_RS232_RX4 0x0200;
+
+
+
+#endif /* __info_h__*/
Index: c/src/lib/libbsp/powerpc/eth_comm/network/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/network/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/network/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,55 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/network.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=network
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS \
+     -DDIAGNOSTIC -DBOOTP_COMPAT
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
Index: c/src/lib/libbsp/powerpc/eth_comm/network/README
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/network/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/network/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,294 @@
+#
+#  $Id$
+#
+
+#
+# This package requires a version of GCC that supports the `-mcpu32' option.
+#
+
+#
+# Please send any comments, improvements, or bug reports to:
+#	W. Eric Norum
+#	Saskatchewan Accelerator Laboratory
+#	107 North Road
+#	University of Saskatchewan
+#	Saskatoon, Saskatchewan, CANADA
+#	S7N 5C6
+# eric@skatter.usask.ca
+#
+
+#
+# This board support package works with several different versions of
+# MC68360 systems.  The choice of hardware is made at the final link-edit
+# phase by setting the Makefile CLAGS_LD definition appropriately.
+#
+# Decisions made at compile time include:
+#	- If the CPU is a member of the 68040 family, the BSP is
+#	  compiled for a generic 68040/68360 system as described
+#	  in Chapter 9 of the MC68360 User's Manual.
+#	- If the preprocessor symbol M68360_ATLAS_HSB is defined,
+#	  the BSP is compiled for an Atlas HSB card.
+#	- Otherwise, the BSP is compiled for a generic 68360 system
+#	  as described in Chapter 9 of the MC68360 User's Manual.
+#
+# Decisions to be made a link-edit time are:
+#     - The size of the memory allocator heap.  The default value is
+#       64 kbytes.  If the network package is used the heap
+#       should be at least 256 kbytes.  If your network is large, or
+#       busy, the heap should be even larger.
+#       To choose a heap size of 256 kbytes,
+#	CFLAGS_LD += -Wl,--defsym -Wl,HeapSize=0x40000
+
+BSP NAME:	    gen68360 or gen68360_040
+BOARD:              Generic 68360 as described in Motorola MC68360 User's Manual
+BOARD:              Atlas Computer Equipment Inc. High Speed Bridge (HSB)
+BOARD:              Atlas Computer Equipment Inc. Advanced Communication Engine (ACE)
+BOARD:              Arnewsh SBC360 68040/68360 card
+BUS:                none
+CPU FAMILY:         Motorola CPU32+, Motorola 68040
+COPROCESSORS:       none
+MODE:               not applicable
+
+DEBUG MONITOR:      none (Hardware provides BDM)
+
+PERIPHERALS
+===========
+TIMERS:             PIT, Watchdog, 4 general purpose, 16 RISC
+  RESOLUTION:       one microsecond
+SERIAL PORTS:       4 SCC, 2 SMC, 1 SPI
+REAL-TIME CLOCK:
+DMA:                Each serial port, 2 general purpose
+VIDEO:              none
+SCSI:               none
+NETWORKING:         Ethernet on SCC1.
+
+DRIVER INFORMATION
+==================
+CLOCK DRIVER:       Programmable Interval Timer
+IOSUPP DRIVER:      Serial Management Controller 1
+SHMSUPP:            none
+TIMER DRIVER:       Timer 1
+
+STDIO
+=====
+PORT:               SMC1
+ELECTRICAL:         EIA-232 (if board supplies level shifter)
+BAUD:               9600
+BITS PER CHARACTER: 8
+PARITY:             None
+STOP BITS:          1
+
+NOTES
+=====
+
+Board description
+-----------------
+clock rate:	25 MHz
+bus width:	8-bit PROM, 32-bit DRAM
+ROM:		To 1 MByte, 180 nsec (3 wait states), chip select 0
+RAM:		1 to 16 MByte DRAM SIMM, 60 nsec (0 wait states), parity or nonparity
+
+Host System
+-----------
+OPENSTEP 4.2 (Intel and Motorola), Solaris 2.5, Linux 2.0.29
+
+Verification (Standalone 68360)
+-------------------------------
+Single processor tests:  Passed
+Multi-processort tests:  not applicable
+Timing tests:
+	Context Switch
+
+	context switch: self 10
+	context switch: to another task 11
+	context switch: no floating point contexts 40
+	fp context switch: restore 1st FP task 41
+	fp context switch: save initialized, restore initialized 14
+	fp context switch: save idle, restore initialized 14
+	fp context switch: save idle, restore idle 43
+
+	Task Manager
+
+	rtems_task_create 133
+	rtems_task_ident 351
+	rtems_task_start 77
+	rtems_task_restart: calling task 93
+	rtems_task_restart: suspended task -- returns to caller 90
+	rtems_task_restart: blocked task -- returns to caller 120
+	rtems_task_restart: ready task -- returns to caller 92
+	rtems_task_restart: suspended task -- preempts caller 121
+	rtems_task_restart: blocked task -- preempts caller 143
+	rtems_task_restart: ready task -- preempts caller 138
+	rtems_task_delete: calling task 158
+	rtems_task_delete: suspended task 129
+	rtems_task_delete: blocked task 134
+	rtems_task_delete: ready task 136
+	rtems_task_suspend: calling task 71
+	rtems_task_suspend: returns to caller 47
+	rtems_task_resume: task readied -- returns to caller 48
+	rtems_task_resume: task readied -- preempts caller 67
+	rtems_task_set_priority: obtain current priority 36
+	rtems_task_set_priority: returns to caller 65
+	rtems_task_set_priority: preempts caller 102
+	rtems_task_mode: obtain current mode 13
+	rtems_task_mode: no reschedule 15
+	rtems_task_mode: reschedule -- returns to caller 22
+	rtems_task_mode: reschedule -- preempts caller 61
+	rtems_task_get_note 38
+	rtems_task_set_note 37
+	rtems_task_wake_after: yield -- returns to caller 22
+	rtems_task_wake_after: yields -- preempts caller 56
+	rtems_task_wake_when 110
+
+	Interrupt Manager
+
+	interrupt entry overhead: returns to nested interrupt 8
+	interrupt entry overhead: returns to interrupted task 8
+	interrupt entry overhead: returns to preempting task 8
+	interrupt exit overhead: returns to nested interrupt 7
+	interrupt exit overhead: returns to interrupted task 8
+	interrupt exit overhead: returns to preempting task 52
+
+	Clock Manager
+
+	rtems_clock_set 82
+	rtems_clock_get 2
+	rtems_clock_tick 15
+
+	Timer Manager
+
+	rtems_timer_create 33
+	rtems_timer_ident 343
+	rtems_timer_delete: inactive 47
+	rtems_timer_delete: active 50
+	rtems_timer_fire_after: inactive 59
+	rtems_timer_fire_after: active 63
+	rtems_timer_fire_when: inactive 83
+	rtems_timer_fire_when: active 83
+	rtems_timer_reset: inactive 55
+	rtems_timer_reset: active 58
+	rtems_timer_cancel: inactive 35
+	rtems_timer_cancel: active 38
+
+	Semaphore Manager
+
+	rtems_semaphore_create 62
+	rtems_semaphore_ident 368
+	rtems_semaphore_delete 61
+	rtems_semaphore_obtain: available 42
+	rtems_semaphore_obtain: not available -- NO_WAIT 42
+	rtems_semaphore_obtain: not available -- caller blocks 105
+	rtems_semaphore_release: no waiting tasks 46
+	rtems_semaphore_release: task readied -- returns to caller 64
+	rtems_semaphore_release: task readied -- preempts caller 84
+
+	Message Queue Manager
+
+	rtems_message_queue_create 240
+	rtems_message_queue_ident 342
+	rtems_message_queue_delete 79
+	rtems_message_queue_send: no waiting tasks 93
+	rtems_message_queue_send: task readied -- returns to caller 96
+	rtems_message_queue_send: task readied -- preempts caller 116
+	rtems_message_queue_urgent: no waiting tasks 93
+	rtems_message_queue_urgent: task readied -- returns to caller 97
+	rtems_message_queue_urgent: task readied -- preempts caller 117
+	rtems_message_queue_broadcast: no waiting tasks 54
+	rtems_message_queue_broadcast: task readied -- returns to caller 106
+	rtems_message_queue_broadcast: task readied -- preempts caller 126
+	rtems_message_queue_receive: available 79
+	rtems_message_queue_receive: not available -- NO_WAIT 48
+	rtems_message_queue_receive: not available -- caller blocks 111
+	rtems_message_queue_flush: no messages flushed 35
+	rtems_message_queue_flush: messages flushed 44
+
+	Event Manager
+
+	rtems_event_send: no task readied 30
+	rtems_event_send: task readied -- returns to caller 59
+	rtems_event_send: task readied -- preempts caller 81
+	rtems_event_receive: obtain current events 1
+	rtems_event_receive: available 34
+	rtems_event_receive: not available -- NO_WAIT 31
+	rtems_event_receive: not available -- caller blocks 84
+
+	Signal Manager
+
+	rtems_signal_catch 24
+	rtems_signal_send: returns to caller 42
+	rtems_signal_send: signal to self 47
+	exit ASR overhead: returns to calling task 33
+	exit ASR overhead: returns to preempting task 58
+
+	Partition Manager
+
+	rtems_partition_create 78
+	rtems_partition_ident 342
+	rtems_partition_delete 46
+	rtems_partition_get_buffer: available 40
+	rtems_partition_get_buffer: not available 39
+	rtems_partition_return_buffer 47
+
+	Region Manager
+
+	rtems_region_create 65
+	rtems_region_ident 349
+	rtems_region_delete 45
+	rtems_region_get_segment: available 55
+	rtems_region_get_segment: not available -- NO_WAIT 52
+	rtems_region_get_segment: not available -- caller blocks 119
+	rtems_region_return_segment: no waiting tasks 57
+	rtems_region_return_segment: task readied -- returns to caller 106
+	rtems_region_return_segment: task readied -- preempts caller 127
+
+	Dual-Ported Memory Manager
+
+	rtems_port_create 40
+	rtems_port_ident 342
+	rtems_port_delete 44
+	rtems_port_internal_to_external 32
+	rtems_port_external_to_internal 32
+
+	IO Manager
+
+	rtems_io_initialize 4
+	rtems_io_open 1
+	rtems_io_close 1
+	rtems_io_read 1
+	rtems_io_write 1
+	rtems_io_control 1
+
+	Rate Monotonic Manager
+
+	rtems_rate_monotonic_create 39
+	rtems_rate_monotonic_ident 343
+	rtems_rate_monotonic_cancel 43
+	rtems_rate_monotonic_delete: active 54
+	rtems_rate_monotonic_delete: inactive 52
+	rtems_rate_monotonic_period: obtain status 37
+	rtems_rate_monotonic_period: initiate period -- returns to caller 58
+	rtems_rate_monotonic_period: conclude periods -- caller blocks 75
+
+Porting
+-------
+This board support package is written for a 68360 system similar to that
+described in chapter 9 of the Motorola MC68360 Quad Integrated Communication
+Processor Users' Manual.  The salient features of this hardware are:
+
+	25 MHz external clock
+	DRAM address multiplexing provided by 68360
+	8-bit 180nsec PROM to CS0*
+	4 MBytes of 60 nsec parity DRAM (1Mx36) to RAS1*/CAS1*
+	Console serial port on SMC1
+	Ethernet interface on SCC1
+
+The board support package has been tested with:
+	A home-built 68360 board
+	An ACE360A and an HSB board produced by:
+		Atlas Computer Equipment
+		703 Colina Lane
+		Santa Barbara, CA 93103
+	A 68040/68360 board (SBC360) produced by:
+		Arnewsh Inc.
+		P.O. Box 270352
+		Fort Collins, CO 80527-0352
Index: c/src/lib/libbsp/powerpc/eth_comm/network/network.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/network/network.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/network/network.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,1620 @@
+/*
+ * RTEMS/KA9Q driver for MPC860 SCC1 Ethernet
+ *
+ * Modified for MPC860 by Jay Monkman (jmonkman@frasca.com)
+ *
+ * This supports ethernet on either SCC1 or the FEC of the MPC860T.
+ *  Right now, we only do 10 Mbps, even with the FEC. The function
+ *  rtems_m860_enet_driver_attach determines which one to use. Currently,
+ *  only one may be used at a time.
+ *
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ *  $Id$
+ */
+#include <bsp.h>
+#include <mpc860.h>
+#include <stdio.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+/*
+ * Number of interfaces supported by this driver
+ */
+#define NIFACES 1
+
+/*
+ * Default number of buffer descriptors set aside for this driver.
+ * The number of transmit buffer descriptors has to be quite large
+ * since a single frame often uses four or more buffer descriptors.
+ */
+#define RX_BUF_COUNT     32
+#define TX_BUF_COUNT     8
+#define TX_BD_PER_BUF    4
+
+/*
+ * RTEMS event used by interrupt handler to signal daemons.
+ * This must *not* be the same event used by the KA9Q task synchronization.
+ */
+#define INTERRUPT_EVENT RTEMS_EVENT_1
+
+/*
+ * RTEMS event used to start transmit daemon.
+ * This must not be the same as INTERRUPT_EVENT.
+ */
+#define START_TRANSMIT_EVENT    RTEMS_EVENT_2
+
+/*
+ * Receive buffer size -- Allow for a full ethernet packet plus a pointer
+ */
+#define RBUF_SIZE       1520
+
+#if (MCLBYTES < RBUF_SIZE)
+# error "Driver must have MCLBYTES > RBUF_SIZE"
+#endif
+
+/*
+ * Per-device data
+ */
+struct m860_enet_struct {
+        struct arpcom           arpcom;
+        struct mbuf             **rxMbuf;
+        struct mbuf             **txMbuf;
+        int                     acceptBroadcast;
+        int                     rxBdCount;
+        int                     txBdCount;
+        int                     txBdHead;
+        int                     txBdTail;
+        int                     txBdActiveCount;
+        m860BufferDescriptor_t  *rxBdBase;
+        m860BufferDescriptor_t  *txBdBase;
+        rtems_id                rxDaemonTid;
+        rtems_id                txDaemonTid;
+
+        /*
+         * Statistics
+         */
+        unsigned long   rxInterrupts;
+        unsigned long   rxNotFirst;
+        unsigned long   rxNotLast;
+        unsigned long   rxGiant;
+        unsigned long   rxNonOctet;
+        unsigned long   rxRunt;
+        unsigned long   rxBadCRC;
+        unsigned long   rxOverrun;
+        unsigned long   rxCollision;
+
+        unsigned long   txInterrupts;
+        unsigned long   txDeferred;
+        unsigned long   txHeartbeat;
+        unsigned long   txLateCollision;
+        unsigned long   txRetryLimit;
+        unsigned long   txUnderrun;
+        unsigned long   txLostCarrier;
+        unsigned long   txRawWait;
+};
+static struct m860_enet_struct enet_driver[NIFACES];
+
+/*
+ * SCC1 interrupt handler
+ */
+static rtems_isr
+m860_scc1_interrupt_handler (rtems_vector_number v)
+{
+        /*
+         * Frame received?
+         */
+        if ((m860.scc1.sccm & 0x8) && (m860.scc1.scce & 0x8)) {
+                m860.scc1.scce = 0x8;
+                /* I don't think the next line is needed. It was in 
+                 * the 68360 stuff, though.
+                 *   m860.scc1.sccm &= ~0x8; 
+                 */
+                enet_driver[0].rxInterrupts++;
+                rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
+        }
+
+        /*
+         * Buffer transmitted or transmitter error?
+         */
+        if ((m860.scc1.sccm & 0x12) && (m860.scc1.scce & 0x12)) {
+                m860.scc1.scce = 0x12;
+                /* I don't think the next line is needed. It was in 
+                 * the 68360 stuff, though.
+                 *   m860.scc1.sccm &= ~0x12; 
+                 */
+                enet_driver[0].txInterrupts++;
+                rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
+        }
+        m860.cisr = 1UL << 30;  /* Clear SCC1 interrupt-in-service bit */
+}
+
+/*
+ * FEC interrupt handler
+ */
+static rtems_isr
+m860_fec_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Frame received?
+   */
+  if (m860.fec.ievent & M860_FEC_IEVENT_RFINT) {
+    m860.fec.ievent = M860_FEC_IEVENT_RFINT;
+    enet_driver[0].rxInterrupts++;
+    rtems_event_send (enet_driver[0].rxDaemonTid, INTERRUPT_EVENT);
+  }
+  
+  /*
+   * Buffer transmitted or transmitter error?
+   */
+  if (m860.fec.ievent & M860_FEC_IEVENT_TFINT) {
+    m860.fec.ievent = M860_FEC_IEVENT_TFINT;
+    enet_driver[0].txInterrupts++;
+    rtems_event_send (enet_driver[0].txDaemonTid, INTERRUPT_EVENT);
+  }
+}
+
+/*
+ * Initialize the ethernet hardware
+ */
+static void
+m860_scc_initialize_hardware (struct m860_enet_struct *sc)
+{
+  int i;
+  unsigned char *hwaddr;
+  rtems_status_code status;
+  rtems_isr_entry old_handler;
+  
+  /*
+   * Configure port A CLK1, CLK2, TXD1 and RXD1 pins
+   */
+  m860.papar |=  0x303;
+  m860.padir &= ~0x303;
+  m860.paodr &= ~0x303;
+  
+  /*
+   * Configure port C CTS1* and CD1* pins, and PC4-PC7
+   *  
+   */
+  m860.pcpar &= ~0x30;
+  m860.pcdir |= 0x0f00;
+  m860.pcdir &= ~0x30;
+  m860.pcso  |=  0x30;
+  m860.pcdat &= ~0x0f00;  /* Clear LOOP */
+  m860.pcdat |= 0x0700;   /* Set FULDL, TPSQEL, TPAPCE */
+  
+  /*
+   * Connect CLK1 and CLK2 to SCC1
+   */
+  m860.sicr &= ~0xFF;
+  m860.sicr |= (5 << 3) | 4;
+  
+  /*
+   * Initialize SDMA configuration register
+   */
+  m860.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 = M860AllocateBufferDescriptors(sc->rxBdCount);
+  sc->txBdBase = M860AllocateBufferDescriptors(sc->txBdCount);
+  m860.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m860;
+  m860.scc1p.tbase = (char *)sc->txBdBase - (char *)&m860;
+  
+  /*
+   * Send "Init parameters" command
+   */
+  M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC1);
+  
+  /*
+   * Set receive and transmit function codes
+   */
+  m860.scc1p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
+  m860.scc1p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
+  
+  /*
+   * Set maximum receive buffer length
+   */
+  m860.scc1p.mrblr = RBUF_SIZE;
+  
+  /*
+   * Set CRC parameters
+   */
+  m860.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
+  m860.scc1p.un.ethernet.c_mask = 0xDEBB20E3;
+  
+  /*
+   * Clear diagnostic counters
+   */
+  m860.scc1p.un.ethernet.crcec = 0;
+  m860.scc1p.un.ethernet.alec = 0;
+  m860.scc1p.un.ethernet.disfc = 0;
+  
+  /*
+   * Set pad value
+   */
+  m860.scc1p.un.ethernet.pads = 0x8888;
+  
+  /*
+   * Set retry limit
+   */
+  m860.scc1p.un.ethernet.ret_lim = 15;
+  
+  /*
+   * Set maximum and minimum frame length
+   */
+  m860.scc1p.un.ethernet.mflr = 1518;
+  m860.scc1p.un.ethernet.minflr = 64;
+  m860.scc1p.un.ethernet.maxd1 = RBUF_SIZE;
+  m860.scc1p.un.ethernet.maxd2 = RBUF_SIZE;
+  
+  /*
+   * Clear group address hash table
+   */
+  m860.scc1p.un.ethernet.gaddr1 = 0;
+  m860.scc1p.un.ethernet.gaddr2 = 0;
+  m860.scc1p.un.ethernet.gaddr3 = 0;
+  m860.scc1p.un.ethernet.gaddr4 = 0;
+  
+  /*
+   * Set our physical address
+   */
+  hwaddr = sc->arpcom.ac_enaddr;
+  
+  m860.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
+  m860.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
+  m860.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];
+  
+  /*
+   * Aggressive retry
+   */
+  m860.scc1p.un.ethernet.p_per = 0;
+  
+  /*
+   * Clear individual address hash table
+   */
+  m860.scc1p.un.ethernet.iaddr1 = 0;
+  m860.scc1p.un.ethernet.iaddr2 = 0;
+  m860.scc1p.un.ethernet.iaddr3 = 0;
+  m860.scc1p.un.ethernet.iaddr4 = 0;
+  
+  /*
+   * Clear temp address
+   */
+  m860.scc1p.un.ethernet.taddr_l = 0;
+  m860.scc1p.un.ethernet.taddr_m = 0;
+  m860.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
+   */
+  m860.scc1.scce = 0xFFFF;
+  
+  /*
+   * Set up interrupts
+   */
+  status = rtems_interrupt_catch (m860_scc1_interrupt_handler,
+				  PPC_IRQ_CPM_SCC1,
+				  &old_handler);
+  if (status != RTEMS_SUCCESSFUL) {
+    rtems_panic ("Can't attach M860 SCC1 interrupt handler: %s\n",
+		 rtems_status_text (status));
+  }
+  m860.scc1.sccm = 0;     /* No interrupts unmasked till necessary */
+  m860.cimr |= (1UL << 30);       /* Enable SCC1 interrupt */
+  
+  /*
+   * Set up General SCC Mode Register
+   * Ethernet configuration
+   */
+  m860.scc1.gsmr_h = 0x0;
+  m860.scc1.gsmr_l = 0x1088000c;
+  
+  /*
+   * Set up data synchronization register
+   * Ethernet synchronization pattern
+   */
+  m860.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
+   */
+  m860.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);
+  
+  /*
+   * Enable the TENA (RTS1*) pin
+   */
+  m860.pcpar |=  0x1;
+  m860.pcdir &= ~0x1;
+  
+  
+  /*
+   * Set up interrupts
+   * FIXME: DANGER: WARNING:
+   * CICR and SIMASK must be set in any module that uses
+   *   the CPM. Currently those are console-generic.c and
+   *   network.c. If the registers are not set the same
+   *   in both places, strange things may happen.
+   *   If they are only set in one place, then an application
+   *   that used the other module won't work correctly.
+   *   Put this comment in each module that sets these 2 registers
+   */
+  m860.cicr = 0x00e43e80;   /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3, 
+			       SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
+  m860.simask |= M860_SIMASK_LVM1;
+  
+  /*
+   * Enable receiver and transmitter
+   */
+  m860.scc1.gsmr_l = 0x1088003c;
+}
+
+static void
+m860_fec_initialize_hardware (struct m860_enet_struct *sc)
+{
+  int i;
+  unsigned char *hwaddr;
+  rtems_status_code status;
+  rtems_isr_entry old_handler;
+
+  /*
+   * Issue reset to FEC
+   */
+  m860.fec.ecntrl=0x1;
+
+  /* 
+   * Put ethernet transciever in reset
+   */
+  m860.pgcra |= 0x80;
+
+  /*
+   * Configure I/O ports
+   */
+  m860.pdpar = 0x1fff;
+  m860.pddir = 0x1c58;
+
+  /*
+   * Take ethernet transciever out of reset
+   */
+  m860.pgcra &= ~0x80;
+
+
+  /*
+   * Set SIU interrupt level to LVL2
+   *  
+   */
+  m860.fec.ivec = 0x02 << 29;
+  
+  /*
+   * Set the TX and RX fifo sizes. For now, we'll split it evenly
+   */
+  /* If you uncomment these, the FEC will not work right.
+  m860.fec.r_fstart = ((m860.fec.r_bound & 0x3ff) >> 2) & 0x3ff;
+  m860.fec.x_fstart = 0;
+  */
+
+  /*
+   * Set our physical address
+   */
+  hwaddr = sc->arpcom.ac_enaddr;
+  
+  m860.fec.addr_low = (hwaddr[0] << 24) | (hwaddr[1] << 16) |
+                      (hwaddr[2] << 8)  | (hwaddr[3] << 0);
+  m860.fec.addr_high = (hwaddr[4] << 24) | (hwaddr[5] << 16);
+
+  /*
+   * Clear the hash table
+   */
+  m860.fec.hash_table_high = 0;
+  m860.fec.hash_table_low  = 0;
+
+  /*
+   * Set up receive buffer size
+   */
+  m860.fec.r_buf_size = 0x5f0; /* set to 1520 */
+
+  /*
+   * 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 = M860AllocateBufferDescriptors(sc->rxBdCount);
+  sc->txBdBase = M860AllocateBufferDescriptors(sc->txBdCount);
+  m860.fec.r_des_start = (int)sc->rxBdBase;
+  m860.fec.x_des_start = (int)sc->txBdBase;
+  
+  /*
+   * Set up Receive Control Register:
+   *   Not promiscuous mode
+   *   MII mode
+   *   Half duplex
+   *   No loopback
+   */
+  m860.fec.r_cntrl = 0x00000006;
+
+  /*
+   * Set up Transmit Control Register:
+   *   Half duplex
+   *   No heartbeat
+   */
+  m860.fec.x_cntrl = 0x00000000;
+
+  /*
+   * Set up DMA function code:
+   *   Big-endian
+   *   DMA functino code = 0
+   */
+  m860.fec.fun_code = 0x78000000;
+
+  /*
+   * Initialize SDMA configuration register
+   *   SDMA ignores FRZ
+   *   FEC not aggressive
+   *   FEC arbitration ID = 0 => U-bus arbitration = 6
+   *   RISC arbitration ID = 1 => U-bus arbitration = 5
+   */
+  m860.sdcr = 1;
+
+  /*
+   * Set MII speed to 2.5 MHz for 25 Mhz system clock  
+   */
+  m860.fec.mii_speed = 0x0a;
+  m860.fec.mii_data = 0x58021000;
+  
+  /*
+   * 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;
+  
+  
+
+  /*
+   * Mask all FEC interrupts and clear events
+   */
+  m860.fec.imask = M860_FEC_IEVENT_TFINT | 
+                   M860_FEC_IEVENT_RFINT;
+  m860.fec.ievent = ~0;
+
+  /*
+   * Set up interrupts
+   */
+  status = rtems_interrupt_catch (m860_fec_interrupt_handler,
+                                  PPC_IRQ_LVL2,
+                                  &old_handler);
+  if (status != RTEMS_SUCCESSFUL)
+    rtems_panic ("Can't attach M860 FEC interrupt handler: %s\n",
+                 rtems_status_text (status));
+
+  m860.simask |= M860_SIMASK_LVM2;
+
+}
+
+
+/*
+ * 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
+m860Enet_retire_tx_bd (struct m860_enet_struct *sc)
+{
+  rtems_unsigned16 status;
+  int i;
+  int nRetired;
+  struct mbuf *m, *n;
+  
+  i = sc->txBdTail;
+  nRetired = 0;
+  while ((sc->txBdActiveCount != 0)
+         &&  (((status = (sc->txBdBase + i)->status) & M860_BD_READY) == 0)) {
+    /*
+     * See if anything went wrong
+     */
+    if (status & (M860_BD_DEFER |
+                  M860_BD_HEARTBEAT |
+                  M860_BD_LATE_COLLISION |
+                  M860_BD_RETRY_LIMIT |
+                  M860_BD_UNDERRUN |
+                  M860_BD_CARRIER_LOST)) {
+      /*
+       * Check for errors which stop the transmitter.
+       */
+      if (status & (M860_BD_LATE_COLLISION |
+                    M860_BD_RETRY_LIMIT |
+                    M860_BD_UNDERRUN)) {
+        if (status & M860_BD_LATE_COLLISION)
+          enet_driver[0].txLateCollision++;
+        if (status & M860_BD_RETRY_LIMIT)
+          enet_driver[0].txRetryLimit++;
+        if (status & M860_BD_UNDERRUN)
+          enet_driver[0].txUnderrun++;
+        
+        /*
+         * Restart the transmitter
+         */
+        /* FIXME: this should get executed only if using the SCC */
+        M860ExecuteRISC (M860_CR_OP_RESTART_TX | M860_CR_CHAN_SCC1);
+      }
+      if (status & M860_BD_DEFER)
+        enet_driver[0].txDeferred++;
+      if (status & M860_BD_HEARTBEAT)
+        enet_driver[0].txHeartbeat++;
+      if (status & M860_BD_CARRIER_LOST)
+        enet_driver[0].txLostCarrier++;
+    }
+    nRetired++;
+    if (status & M860_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;
+  }
+}
+
+/*
+ * reader task
+ */
+static void
+scc_rxDaemon (void *arg)
+{
+  struct m860_enet_struct *sc = (struct m860_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  rtems_unsigned16 status;
+  m860BufferDescriptor_t *rxBd;
+  int rxBdIndex;
+  
+  /*
+   * Allocate space for incoming packets and start reception
+   */
+  for (rxBdIndex = 0 ; ;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+    MGETHDR (m, M_WAIT, MT_DATA);
+    MCLGET (m, M_WAIT);
+    m->m_pkthdr.rcvif = ifp;
+    sc->rxMbuf[rxBdIndex] = m;
+    rxBd->buffer = mtod (m, void *);
+    rxBd->status = M860_BD_EMPTY | M860_BD_INTERRUPT;
+    if (++rxBdIndex == sc->rxBdCount) {
+      rxBd->status |= M860_BD_WRAP;
+      break;
+    }
+  }
+  
+  /*
+   * Input packet handling loop
+   */
+  rxBdIndex = 0;
+  for (;;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+    
+    /*
+     * Wait for packet if there's not one ready
+     */
+    if ((status = rxBd->status) & M860_BD_EMPTY) {
+      /*
+       * Clear old events
+       */
+      m860.scc1.scce = 0x8;
+      
+      /*
+       * Wait for packet
+       * Note that the buffer descriptor is checked
+       * *before* the event wait -- this catches the
+       * possibility that a packet arrived between the
+       * `if' above, and the clearing of the event register.
+       */
+      while ((status = rxBd->status) & M860_BD_EMPTY) {
+        rtems_event_set events;
+        
+        /*
+         * Unmask RXF (Full frame received) event
+         */
+        m860.scc1.sccm |= 0x8;
+        
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+      }
+    }
+    
+    /*
+     * Check that packet is valid
+     */
+    if ((status & (M860_BD_LAST |
+                   M860_BD_FIRST_IN_FRAME |
+                   M860_BD_LONG |
+                   M860_BD_NONALIGNED |
+                   M860_BD_SHORT |
+                   M860_BD_CRC_ERROR |
+                   M860_BD_OVERRUN |
+                   M860_BD_COLLISION)) ==
+        (M860_BD_LAST |
+         M860_BD_FIRST_IN_FRAME)) {
+      /*
+       * Pass the packet up the chain.
+       * FIXME: Packet filtering hook could be done here.
+       */
+      struct ether_header *eh;
+      
+      m = sc->rxMbuf[rxBdIndex];
+      m->m_len = m->m_pkthdr.len = rxBd->length -
+        sizeof(rtems_unsigned32) -
+        sizeof(struct ether_header);
+      eh = mtod (m, struct ether_header *);
+      m->m_data += sizeof(struct ether_header);
+      ether_input (ifp, eh, m);
+      
+      /*
+       * Allocate a new mbuf
+       */
+      MGETHDR (m, M_WAIT, MT_DATA);
+      MCLGET (m, M_WAIT);
+      m->m_pkthdr.rcvif = ifp;
+      sc->rxMbuf[rxBdIndex] = m;
+      rxBd->buffer = mtod (m, void *);
+    }
+    else {
+      /*
+       * Something went wrong with the reception
+       */
+      if (!(status & M860_BD_LAST))
+        sc->rxNotLast++;
+      if (!(status & M860_BD_FIRST_IN_FRAME))
+        sc->rxNotFirst++;
+      if (status & M860_BD_LONG)
+        sc->rxGiant++;
+      if (status & M860_BD_NONALIGNED)
+        sc->rxNonOctet++;
+      if (status & M860_BD_SHORT)
+        sc->rxRunt++;
+      if (status & M860_BD_CRC_ERROR)
+        sc->rxBadCRC++;
+      if (status & M860_BD_OVERRUN)
+        sc->rxOverrun++;
+      if (status & M860_BD_COLLISION)
+        sc->rxCollision++;
+    }
+    
+    /*
+     * Reenable the buffer descriptor
+     */
+    rxBd->status = (status & (M860_BD_WRAP | M860_BD_INTERRUPT)) |
+                    M860_BD_EMPTY;
+    
+    /*
+     * Move to next buffer descriptor
+     */
+    if (++rxBdIndex == sc->rxBdCount)
+      rxBdIndex = 0;
+  }
+}
+
+static void
+fec_rxDaemon (void *arg)
+{
+  struct m860_enet_struct *sc = (struct m860_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  rtems_unsigned16 status;
+  m860BufferDescriptor_t *rxBd;
+  int rxBdIndex;
+  
+  /*
+   * Allocate space for incoming packets and start reception
+   */
+  for (rxBdIndex = 0 ; ;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+    MGETHDR (m, M_WAIT, MT_DATA);
+    MCLGET (m, M_WAIT);
+    m->m_pkthdr.rcvif = ifp;
+    sc->rxMbuf[rxBdIndex] = m;
+    rxBd->buffer = mtod (m, void *);
+    rxBd->status = M860_BD_EMPTY;
+    m860.fec.r_des_active = 0x1000000;
+    if (++rxBdIndex == sc->rxBdCount) {
+      rxBd->status |= M860_BD_WRAP;
+      break;
+    }
+  }
+  
+  /*
+   * Input packet handling loop
+   */
+  rxBdIndex = 0;
+  for (;;) {
+    rxBd = sc->rxBdBase + rxBdIndex;
+    
+    /*
+     * Wait for packet if there's not one ready
+     */
+    if ((status = rxBd->status) & M860_BD_EMPTY) {
+      /*
+       * Clear old events
+       */
+      m860.fec.ievent = M860_FEC_IEVENT_RFINT;
+      
+      /*
+       * Wait for packet
+       * Note that the buffer descriptor is checked
+       * *before* the event wait -- this catches the
+       * possibility that a packet arrived between the
+       * `if' above, and the clearing of the event register.
+       */
+      while ((status = rxBd->status) & M860_BD_EMPTY) {
+        rtems_event_set events;
+        
+        /*
+         * Unmask RXF (Full frame received) event
+         */
+        m860.fec.ievent |= M860_FEC_IEVENT_RFINT;
+        
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+      }
+    }
+    
+    /*
+     * Check that packet is valid
+     */
+    if (status & M860_BD_LAST) {
+      /*
+       * Pass the packet up the chain.
+       * FIXME: Packet filtering hook could be done here.
+       */
+      struct ether_header *eh;
+      
+      m = sc->rxMbuf[rxBdIndex];
+      m->m_len = m->m_pkthdr.len = rxBd->length -
+        sizeof(rtems_unsigned32) -
+        sizeof(struct ether_header);
+      eh = mtod (m, struct ether_header *);
+      m->m_data += sizeof(struct ether_header);
+      ether_input (ifp, eh, m);
+      
+      /*
+       * Allocate a new mbuf
+       */
+      MGETHDR (m, M_WAIT, MT_DATA);
+      MCLGET (m, M_WAIT);
+      m->m_pkthdr.rcvif = ifp;
+      sc->rxMbuf[rxBdIndex] = m;
+      rxBd->buffer = mtod (m, void *);
+    }
+    else {
+      /*
+       * Something went wrong with the reception
+       */
+      if (!(status & M860_BD_LAST))
+        sc->rxNotLast++;
+      if (status & M860_BD_LONG)
+        sc->rxGiant++;
+      if (status & M860_BD_NONALIGNED)
+        sc->rxNonOctet++;
+      if (status & M860_BD_SHORT)
+        sc->rxRunt++;
+      if (status & M860_BD_CRC_ERROR)
+        sc->rxBadCRC++;
+      if (status & M860_BD_OVERRUN)
+        sc->rxOverrun++;
+      if (status & M860_BD_COLLISION)
+        sc->rxCollision++;
+    }
+    /*
+     * Reenable the buffer descriptor
+     */
+    rxBd->status = (status & M860_BD_WRAP) |
+                    M860_BD_EMPTY;
+    m860.fec.r_des_active = 0x1000000;
+    /*
+     * Move to next buffer descriptor
+     */
+    if (++rxBdIndex == sc->rxBdCount)
+      rxBdIndex = 0;
+  }
+}
+
+static void
+scc_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+  struct m860_enet_struct *sc = ifp->if_softc;
+  volatile m860BufferDescriptor_t *firstTxBd, *txBd;
+  struct mbuf *l = NULL;
+  rtems_unsigned16 status;
+  int nAdded;
+  
+  /*
+   * Free up buffer descriptors
+   */
+  m860Enet_retire_tx_bd (sc);
+  
+  /*
+   * Set up the transmit buffer descriptors.
+   * No need to pad out short packets since the
+   * hardware takes care of that automatically.
+   * No need to copy the packet to a contiguous buffer
+   * since the hardware is capable of scatter/gather DMA.
+   */
+  nAdded = 0;
+  txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
+  for (;;) {
+    /*
+     * Wait for buffer descriptor to become available.
+     */
+    if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+      /*
+       * Clear old events
+       */
+      m860.scc1.scce = 0x12;
+      
+      /*
+       * Wait for buffer descriptor to become available.
+       * Note that the buffer descriptors are checked
+       * *before* * entering the wait loop -- this catches
+       * the possibility that a buffer descriptor became
+       * available between the `if' above, and the clearing
+       * of the event register.
+       * This is to catch the case where the transmitter
+       * stops in the middle of a frame -- and only the
+       * last buffer descriptor in a frame can generate
+       * an interrupt.
+       */
+      m860Enet_retire_tx_bd (sc);
+      while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+        rtems_event_set events;
+        
+                                /*
+                                 * Unmask TXB (buffer transmitted) and
+                                 * TXE (transmitter error) events.
+                                 */
+        m860.scc1.sccm |= 0x12;
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+        m860Enet_retire_tx_bd (sc);
+      }
+    }
+    
+    /*
+     * Don't set the READY flag till the
+     * whole packet has been readied.
+     */
+    status = nAdded ? M860_BD_READY : 0;
+    
+    /*
+     *  FIXME: Why not deal with empty mbufs at at higher level?
+     * The IP fragmentation routine in ip_output
+     * can produce packet fragments with zero length.
+     * I think that ip_output should be changed to get
+     * rid of these zero-length mbufs, but for now,
+     * I'll deal with them here.
+     */
+    if (m->m_len) {
+      /*
+       * Fill in the buffer descriptor
+       */
+      txBd->buffer = mtod (m, void *);
+      txBd->length = m->m_len;
+      sc->txMbuf[sc->txBdHead] = m;
+      nAdded++;
+      if (++sc->txBdHead == sc->txBdCount) {
+        status |= M860_BD_WRAP;
+        sc->txBdHead = 0;
+      }
+      l = m;
+      m = m->m_next;
+    }
+    else {
+      /*
+       * Just toss empty mbufs
+       */
+      struct mbuf *n;
+      MFREE (m, n);
+      m = n;
+      if (l != NULL)
+        l->m_next = m;
+    }
+    
+    /*
+     * Set the transmit buffer status.
+     * Break out of the loop if this mbuf is the last in the frame.
+     */
+    if (m == NULL) {
+      if (nAdded) {
+        status |= M860_BD_PAD | M860_BD_LAST | M860_BD_TX_CRC | M860_BD_INTERRUPT;
+        txBd->status = status;
+        firstTxBd->status |= M860_BD_READY;
+        sc->txBdActiveCount += nAdded;
+      }
+      break;
+    }
+    txBd->status = status;
+    txBd = sc->txBdBase + sc->txBdHead;
+  }
+}
+
+static void
+fec_sendpacket (struct ifnet *ifp, struct mbuf *m)
+{
+  struct m860_enet_struct *sc = ifp->if_softc;
+  volatile m860BufferDescriptor_t *firstTxBd, *txBd;
+  /*  struct mbuf *l = NULL; */
+  rtems_unsigned16 status;
+  int nAdded;
+  
+  /*
+   * Free up buffer descriptors
+   */
+  m860Enet_retire_tx_bd (sc);
+  
+  /*
+   * Set up the transmit buffer descriptors.
+   * No need to pad out short packets since the
+   * hardware takes care of that automatically.
+   * No need to copy the packet to a contiguous buffer
+   * since the hardware is capable of scatter/gather DMA.
+   */
+  nAdded = 0;
+  txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
+  for (;;) {
+    /*
+     * Wait for buffer descriptor to become available.
+     */
+    if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+      /*
+       * Clear old events
+       */
+      m860.fec.ievent = M860_FEC_IEVENT_TFINT;
+      
+      /*
+       * Wait for buffer descriptor to become available.
+       * Note that the buffer descriptors are checked
+       * *before* * entering the wait loop -- this catches
+       * the possibility that a buffer descriptor became
+       * available between the `if' above, and the clearing
+       * of the event register.
+       * This is to catch the case where the transmitter
+       * stops in the middle of a frame -- and only the
+       * last buffer descriptor in a frame can generate
+       * an interrupt.
+       */
+      m860Enet_retire_tx_bd (sc);
+      while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
+        rtems_event_set events;
+        
+        /*
+         * Unmask TXB (buffer transmitted) and
+         * TXE (transmitter error) events.
+         */
+        m860.fec.ievent |= M860_FEC_IEVENT_TFINT;
+        rtems_bsdnet_event_receive (INTERRUPT_EVENT,
+                                    RTEMS_WAIT|RTEMS_EVENT_ANY,
+                                    RTEMS_NO_TIMEOUT,
+                                    &events);
+        m860Enet_retire_tx_bd (sc);
+      }
+    }
+    
+    /*
+     * Don't set the READY flag till the
+     * whole packet has been readied.
+     */
+    status = nAdded ? M860_BD_READY : 0;
+    
+    /*
+     *  FIXME: Why not deal with empty mbufs at at higher level?
+     * The IP fragmentation routine in ip_output
+     * can produce packet fragments with zero length.
+     * I think that ip_output should be changed to get
+     * rid of these zero-length mbufs, but for now,
+     * I'll deal with them here.
+     */
+    if (m->m_len) {
+      /*
+       * Fill in the buffer descriptor
+       */
+      txBd->buffer = mtod (m, void *);
+      txBd->length = m->m_len;
+      sc->txMbuf[sc->txBdHead] = m;
+      nAdded++;
+      if (++sc->txBdHead == sc->txBdCount) {
+        status |= M860_BD_WRAP;
+        sc->txBdHead = 0;
+      }
+      /*      l = m;*/
+      m = m->m_next;
+    }
+    else {
+      /*
+       * Just toss empty mbufs
+       */
+      struct mbuf *n;
+      MFREE (m, n);
+      m = n;
+      /*
+      if (l != NULL)
+        l->m_next = m;
+      */
+    }
+    
+    /*
+     * Set the transmit buffer status.
+     * Break out of the loop if this mbuf is the last in the frame.
+     */
+    if (m == NULL) {
+      if (nAdded) {
+        status |= M860_BD_LAST | M860_BD_TX_CRC;
+        txBd->status = status;
+        firstTxBd->status |= M860_BD_READY;
+        m860.fec.x_des_active = 0x1000000;
+        sc->txBdActiveCount += nAdded;
+      }
+      break;
+    }
+    txBd->status = status;
+    txBd = sc->txBdBase + sc->txBdHead;
+  }
+}
+
+/*
+ * Driver transmit daemon
+ */
+void
+scc_txDaemon (void *arg)
+{
+  struct m860_enet_struct *sc = (struct m860_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  rtems_event_set events;
+  
+  for (;;) {
+    /*
+     * Wait for packet
+     */
+    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
+    
+    /*
+     * Send packets till queue is empty
+     */
+    for (;;) {
+      /*
+       * Get the next mbuf chain to transmit.
+       */
+      IF_DEQUEUE(&ifp->if_snd, m);
+      if (!m)
+        break;
+      scc_sendpacket (ifp, m);
+    }
+    ifp->if_flags &= ~IFF_OACTIVE;
+  }
+}
+
+void
+fec_txDaemon (void *arg)
+{
+  struct m860_enet_struct *sc = (struct m860_enet_struct *)arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  struct mbuf *m;
+  rtems_event_set events;
+  
+  for (;;) {
+    /*
+     * Wait for packet
+     */
+    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, 
+                                RTEMS_EVENT_ANY | RTEMS_WAIT, 
+                                RTEMS_NO_TIMEOUT, 
+                                &events);
+    
+    /*
+     * Send packets till queue is empty
+     */
+    for (;;) {
+      /*
+       * Get the next mbuf chain to transmit.
+       */
+      IF_DEQUEUE(&ifp->if_snd, m);
+      if (!m)
+        break;
+      fec_sendpacket (ifp, m);
+    }
+    ifp->if_flags &= ~IFF_OACTIVE;
+  }
+}
+
+/*
+ * Send packet (caller provides header).
+ */
+static void
+m860_enet_start (struct ifnet *ifp)
+{
+  struct m860_enet_struct *sc = ifp->if_softc;
+  
+  rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
+  ifp->if_flags |= IFF_OACTIVE;
+}
+
+/*
+ * Initialize and start the device
+ */
+static void
+scc_init (void *arg)
+{
+  struct m860_enet_struct *sc = arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  
+  if (sc->txDaemonTid == 0) {
+    
+    /*
+     * Set up SCC hardware
+     */
+    m860_scc_initialize_hardware (sc);
+    
+    /*
+     * Start driver tasks
+     */
+    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, scc_txDaemon, sc);
+    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, scc_rxDaemon, sc);
+    
+  }
+  
+  /*
+   * Set flags appropriately
+   */
+  if (ifp->if_flags & IFF_PROMISC)
+    m860.scc1.psmr |= 0x200;
+  else
+    m860.scc1.psmr &= ~0x200;
+  
+  /*
+   * Tell the world that we're running.
+   */
+  ifp->if_flags |= IFF_RUNNING;
+  
+  /*
+   * Enable receiver and transmitter
+   */
+  m860.scc1.gsmr_l |= 0x30;
+}
+
+static void
+fec_init (void *arg)
+{
+  struct m860_enet_struct *sc = arg;
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  
+  if (sc->txDaemonTid == 0) {
+    
+    /*
+     * Set up SCC hardware
+     */
+    m860_fec_initialize_hardware (sc);
+    
+    /*
+     * Start driver tasks
+     */
+    sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, fec_txDaemon, sc);
+    sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, fec_rxDaemon, sc);
+    
+  }
+  
+  /*
+   * Set flags appropriately
+   */
+  if (ifp->if_flags & IFF_PROMISC)
+    m860.fec.r_cntrl |= 0x8;
+  else
+    m860.fec.r_cntrl &= ~0x8;
+
+  
+  /*
+   * Tell the world that we're running.
+   */
+  ifp->if_flags |= IFF_RUNNING;
+  
+  /*
+   * Enable receiver and transmitter
+   */
+  m860.fec.ecntrl = 0x2;
+}
+
+
+/*
+ * Stop the device
+ */
+static void
+scc_stop (struct m860_enet_struct *sc)
+{
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  
+  ifp->if_flags &= ~IFF_RUNNING;
+  
+  /*
+   * Shut down receiver and transmitter
+   */
+  m860.scc1.gsmr_l &= ~0x30;
+}
+
+static void
+fec_stop (struct m860_enet_struct *sc)
+{
+  struct ifnet *ifp = &sc->arpcom.ac_if;
+  
+  ifp->if_flags &= ~IFF_RUNNING;
+  
+  /*
+   * Shut down receiver and transmitter
+   */
+  m860.fec.ecntrl = 0x0;
+}
+
+/*
+ * Show interface statistics
+ */
+static void
+enet_stats (struct m860_enet_struct *sc)
+{
+  printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
+  printf ("       Not First:%-8lu", sc->rxNotFirst);
+  printf ("        Not Last:%-8lu\n", sc->rxNotLast);
+  printf ("              Giant:%-8lu", sc->rxGiant);
+  printf ("            Runt:%-8lu", sc->rxRunt);
+  printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
+  printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
+  printf ("         Overrun:%-8lu", sc->rxOverrun);
+  printf ("       Collision:%-8lu\n", sc->rxCollision);
+  printf ("          Discarded:%-8lu\n", (unsigned long)m860.scc1p.un.ethernet.disfc);
+  
+  printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
+  printf ("        Deferred:%-8lu", sc->txDeferred);
+  printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
+  printf ("         No Carrier:%-8lu", sc->txLostCarrier);
+  printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
+  printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
+  printf ("           Underrun:%-8lu", sc->txUnderrun);
+  printf (" Raw output wait:%-8lu\n", sc->txRawWait);
+}
+
+/*
+ * Driver ioctl handler
+ */
+static int
+scc_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+  struct m860_enet_struct *sc = ifp->if_softc;
+  int error = 0;
+  
+  switch (command) {
+  case SIOCGIFADDR:
+  case SIOCSIFADDR:
+    ether_ioctl (ifp, command, data);
+    break;
+    
+  case SIOCSIFFLAGS:
+    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+    case IFF_RUNNING:
+      scc_stop (sc);
+      break;
+      
+    case IFF_UP:
+      scc_init (sc);
+      break;
+      
+    case IFF_UP | IFF_RUNNING:
+      scc_stop (sc);
+      scc_init (sc);
+      break;
+      
+    default:
+      break;
+    }
+    break;
+    
+  case SIO_RTEMS_SHOW_STATS:
+    enet_stats (sc);
+    break;
+    
+    /*
+     * FIXME: All sorts of multicast commands need to be added here!
+     */
+  default:
+    error = EINVAL;
+    break;
+  }
+  return error;
+}
+
+static int
+fec_ioctl (struct ifnet *ifp, int command, caddr_t data)
+{
+  struct m860_enet_struct *sc = ifp->if_softc;
+  int error = 0;
+  
+  switch (command) {
+  case SIOCGIFADDR:
+  case SIOCSIFADDR:
+    ether_ioctl (ifp, command, data);
+    break;
+    
+  case SIOCSIFFLAGS:
+    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
+    case IFF_RUNNING:
+      fec_stop (sc);
+      break;
+      
+    case IFF_UP:
+      fec_init (sc);
+      break;
+      
+    case IFF_UP | IFF_RUNNING:
+      fec_stop (sc);
+      fec_init (sc);
+      break;
+      
+    default:
+      break;
+    }
+    break;
+    
+  case SIO_RTEMS_SHOW_STATS:
+    enet_stats (sc);
+    break;
+    
+    /*
+     * FIXME: All sorts of multicast commands need to be added here!
+     */
+  default:
+    error = EINVAL;
+    break;
+  }
+  return error;
+}
+
+/*
+ * Attach an SCC driver to the system
+ */
+int
+rtems_scc1_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+  struct m860_enet_struct *sc;
+  struct ifnet *ifp;
+  int mtu;
+  int i;
+  
+  /*
+   * Find a free driver
+   */
+  for (i = 0 ; i < NIFACES ; i++) {
+    sc = &enet_driver[i];
+    ifp = &sc->arpcom.ac_if;
+    if (ifp->if_softc == NULL)
+      break;
+  }
+  if (i >= NIFACES) {
+    printf ("Too many SCC drivers.\n");
+    return 0;
+  }
+  
+  /*
+   * Process options
+   */
+  if (config->hardware_address) {
+    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+  }
+  else {
+    sc->arpcom.ac_enaddr[0] = 0x44;
+    sc->arpcom.ac_enaddr[1] = 0x22;
+    sc->arpcom.ac_enaddr[2] = 0x33;
+    sc->arpcom.ac_enaddr[3] = 0x33;
+    sc->arpcom.ac_enaddr[4] = 0x22;
+    sc->arpcom.ac_enaddr[5] = 0x44;
+  }
+  if (config->mtu)
+    mtu = config->mtu;
+  else
+    mtu = ETHERMTU;
+  if (config->rbuf_count)
+    sc->rxBdCount = config->rbuf_count;
+  else
+    sc->rxBdCount = RX_BUF_COUNT;
+  if (config->xbuf_count)
+    sc->txBdCount = config->xbuf_count;
+  else
+    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+  sc->acceptBroadcast = !config->ignore_broadcast;
+  
+  /*
+   * Set up network interface values
+   */
+  ifp->if_softc = sc;
+  ifp->if_unit = i + 1;
+  ifp->if_name = "eth";
+  ifp->if_mtu = mtu;
+  ifp->if_init = scc_init;
+  ifp->if_ioctl = scc_ioctl;
+  ifp->if_start = m860_enet_start;
+  ifp->if_output = ether_output;
+  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+  if (ifp->if_snd.ifq_maxlen == 0)
+    ifp->if_snd.ifq_maxlen = ifqmaxlen;
+  
+  /*
+   * Attach the interface
+   */
+  if_attach (ifp);
+  ether_ifattach (ifp);
+  return 1;
+};
+
+int
+rtems_fec_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+  struct m860_enet_struct *sc;
+  struct ifnet *ifp;
+  int mtu;
+  
+  /*
+   * Find a free driver
+   */
+  sc = &enet_driver[0];
+  ifp = &sc->arpcom.ac_if;
+  if (ifp->if_softc != NULL)
+    return 0;
+
+  
+  /*
+   * Process options
+   */
+  if (config->hardware_address) {
+    memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
+  }
+  else {
+    sc->arpcom.ac_enaddr[0] = 0x44;
+    sc->arpcom.ac_enaddr[1] = 0x22;
+    sc->arpcom.ac_enaddr[2] = 0x33;
+    sc->arpcom.ac_enaddr[3] = 0x33;
+    sc->arpcom.ac_enaddr[4] = 0x22;
+    sc->arpcom.ac_enaddr[5] = 0x44;
+  }
+  if (config->mtu)
+    mtu = config->mtu;
+  else
+    mtu = ETHERMTU;
+  if (config->rbuf_count)
+    sc->rxBdCount = config->rbuf_count;
+  else
+    sc->rxBdCount = RX_BUF_COUNT;
+  if (config->xbuf_count)
+    sc->txBdCount = config->xbuf_count;
+  else
+    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
+  sc->acceptBroadcast = !config->ignore_broadcast;
+  
+  /*
+   * Set up network interface values
+   */
+  ifp->if_softc = sc;
+  ifp->if_unit = 1;
+  ifp->if_name = "eth";
+  ifp->if_mtu = mtu;
+  ifp->if_init = fec_init;
+  ifp->if_ioctl = fec_ioctl;
+  ifp->if_start = m860_enet_start;
+  ifp->if_output = ether_output;
+  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
+  if (ifp->if_snd.ifq_maxlen == 0)
+    ifp->if_snd.ifq_maxlen = ifqmaxlen;
+  
+  /*
+   * Attach the interface
+   */
+  if_attach (ifp);
+  ether_ifattach (ifp);
+  return 1;
+};
+
+int
+rtems_enet_driver_attach (struct rtems_bsdnet_ifconfig *config)
+{
+  int i;
+
+  if ((m860.fec.mii_data & 0xffff) == 0x2000) {
+/*    rtems_scc1_driver_attach(config);*/
+    return rtems_fec_driver_attach(config);
+  }
+  else {
+    return rtems_scc1_driver_attach(config);
+  }
+}
Index: c/src/lib/libbsp/powerpc/eth_comm/start/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/start/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/start/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,59 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/start.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .S
+S_PIECES=start
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
Index: c/src/lib/libbsp/powerpc/eth_comm/start/start.S
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/start/start.S	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/start/start.S	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,154 @@
+/*  dlentry.s
+ *
+ *  $Id$
+ *
+ *  This file contains the entry veneer for RTEMS programs
+ *  downloaded to the eth-comm board.
+ *
+ * This file was written by Jay Monkman (jmonkman@fracsa.com)
+ * It was based on the dlentry.s file for the Papyrus BSP,
+ * written by:
+ *
+ *  Author:     Andrew Bray <andy@i-cubed.co.uk>
+ *
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ */
+
+#include "asm.h"
+
+/*
+ *  The initial stack is set to run BELOW the code base address.
+ *  (between the vectors and text sections)
+ *
+ *  All the entry veneer has to do is to clear the BSS.
+ */
+
+/*
+ *  GDB likes to have debugging information for the entry veneer.
+ *  Here is some DWARF information.
+ */
+/* 
+ * There was some debugging info here, but I removed it because I
+ * couldn't get it to work. It isn't really necessary as far as I
+ * can tell. It should still be in the papyrus BSP. -Jay
+ */
+
+
+
+/* 
+ * On entry to download_entry, R3 will hold a pointer to a Board Info
+ *  Block (boardinfo_t). This should be copied as soon as possible
+ *  to the global M860_binfo. (The block should be copied, _NOT_
+ *  the pointer)
+ */
+
+        .section ".entry"  /* This might have to be the first thing in the 
+                            * text section. At one time, it had to be
+                            * first, but I don't believe it is true
+                            * andy more. */
+        PUBLIC_VAR (start)
+SYM(start):
+        bl      .startup
+base_addr:      
+
+/*
+ * Parameters from linker
+ */
+toc_pointer:    
+        .long   s.got
+bss_length:     
+        .long   bss.size
+bss_addr:       
+        .long   bss.start
+
+PUBLIC_VAR (text_addr)
+text_addr:
+        .long   text.start
+
+PUBLIC_VAR (text_length)
+text_length:
+        .long   text.size
+
+
+/*
+ * Initialization code 
+ */
+.startup:
+        /* Get start address */
+        mflr    r1
+        
+        /* clear the bss section */
+        bl      bssclr
+
+/* 
+ * Copy the Board Info Block
+ */
+        .extern SYM(M860_binfo)
+        lis     r6, SYM(M860_binfo)@ha
+        addi    r6, r6, SYM(M860_binfo)@l
+
+        lhz     r4, 0(r3)                /* Load the size of the block */
+        rlwinm. r4, r4, 30, 0x3fffffff   /* get number of words */
+
+        mtctr   r4
+
+cpy_b:  lwz     r5, 0(r3)                /* In with the old ...  */
+        stw     r5, 0(r6)                /* ... Out with the new */
+        addi    r6, r6, 0x4              /* Go to the next word */
+        addi    r3, r3, 0x4
+        bdnz    cpy_b                    /* decrement counter and loop */
+
+/*
+ * C_setup.
+ */
+
+        /* set toc */
+        lwz r2, toc_pointer-base_addr(r1)
+
+        /* Set up stack pointer = beginning of text section - 56 */
+        addi    r1, r1, -56-4
+
+        lis     r9, 0xff00
+        addi    r10, 0, -16384
+        sth     r10, 0x950(r9)
+
+        lis     r9, 0x0000
+        addi    r9, r9, 0x0007
+        mtspr   0x9e, r9
+
+        /* clear argc and argv */
+        xor     r3, r3, r3
+        xor     r4, r4, r4
+        
+        .extern SYM (boot_card)
+        b       SYM (boot_card)                  /* call the first C routine */
+
+/*
+ * bssclr - zero out bss
+ */
+bssclr:
+        lwz     r4, bss_addr-base_addr(r1)      /* Start of bss */
+        lwz     r5, bss_length-base_addr(r1)    /* Length of bss */
+
+        rlwinm. r5,r5,30,0x3FFFFFFF             /* form length/4 */
+        beqlr                                   /* no bss */
+        mtctr   r5                              /* set ctr reg */
+        xor     r6,r6,r6                        /* r6 = 0 */
+clear_bss:
+        stswi   r6,r4,0x4                       /* store r6 */
+        addi    r4,r4,0x4                       /* update r2 */
+
+        bdnz    clear_bss                       /* dec counter and loop */
+        blr                                     /* return */
Index: c/src/lib/libbsp/powerpc/eth_comm/startup/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/startup/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/startup/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,61 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@:@srcdir@/../../../shared
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/startup.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=bspclean bsplibc bsppost bspstart main sbrk setvec alloc860 mmu
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+	$(INSTALL) $(srcdir)/linkcmds ${PROJECT_RELEASE}/lib
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
+
Index: c/src/lib/libbsp/powerpc/eth_comm/startup/alloc860.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/startup/alloc860.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/startup/alloc860.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,117 @@
+/*
+ * MPC860 buffer descriptor allocation routines
+ *
+ * Modified from original code by Jay Monkman (jmonkman@frasca.com)
+ *
+ * Original was written by:
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ *  $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <rtems/rtems/intr.h>
+#include <rtems/error.h>
+#include <mpc860.h>
+#include <info.h>
+
+/*
+ * Send a command to the CPM RISC processer
+ */
+void M860ExecuteRISC(rtems_unsigned16 command)
+{
+  rtems_unsigned16 lvl;
+  
+  rtems_interrupt_disable(lvl);
+  while (m860.cpcr & M860_CR_FLG) {
+    continue;
+  }
+
+  m860.cpcr = command | M860_CR_FLG;
+  rtems_interrupt_enable (lvl);
+}
+
+
+/*
+ * Allocation order:
+ *      - Dual-Port RAM section 0
+ *      - Dual-Port RAM section 1
+ *      - Dual-Port RAM section 2
+ *      - Dual-Port RAM section 3
+ *      - Dual-Port RAM section 4
+ */
+static struct {
+  char          *base;
+  unsigned int  size;
+  unsigned int  used;
+} bdregions[] = {
+  { (char *)&m860.dpram0[0],    sizeof m860.dpram0,     0 },
+  { (char *)&m860.dpram1[0],    sizeof m860.dpram1,     0 },
+  { (char *)&m860.dpram2[0],    sizeof m860.dpram2,     0 },
+  { (char *)&m860.dpram3[0],    sizeof m860.dpram3,     0 },
+  { (char *)&m860.dpram4[0],    sizeof m860.dpram4,     0 },
+};
+
+void *
+M860AllocateBufferDescriptors (int count)
+{
+  unsigned int i;
+  ISR_Level level;
+  void *bdp = NULL;
+  unsigned int want = count * sizeof(m860BufferDescriptor_t);
+  
+  /*
+   * Running with interrupts disabled is usually considered bad
+   * form, but this routine is probably being run as part of an
+   * initialization sequence so the effect shouldn't be too severe.
+   */
+  _ISR_Disable (level);
+  for (i = 0 ; i < sizeof(bdregions) / sizeof(bdregions[0]) ; i++) {
+    /*
+     * Verify that the region exists.
+     * This test is necessary since some chips have
+     * less dual-port RAM.
+     */
+    if (bdregions[i].used == 0) {
+      volatile unsigned char *cp = bdregions[i].base;
+      *cp = 0xAA;
+      if (*cp != 0xAA) {
+        bdregions[i].used = bdregions[i].size;
+        continue;
+      }
+      *cp = 0x55;
+      if (*cp != 0x55) {
+        bdregions[i].used = bdregions[i].size;
+        continue;
+      }
+      *cp = 0x0;
+    }
+    if (bdregions[i].size - bdregions[i].used >= want) {
+      bdp = bdregions[i].base + bdregions[i].used;
+      bdregions[i].used += want;
+      break;
+    }
+  }
+  _ISR_Enable(level);
+  if (bdp == NULL)
+    rtems_panic("Can't allocate %d buffer descriptor(s).\n", count);
+  return bdp;
+}
+
+void *
+M860AllocateRiscTimers (int count)
+{
+  /*
+   * Convert the count to the number of buffer descriptors
+   * of equal or larger size.  This ensures that all buffer
+   * descriptors are allocated with appropriate alignment.
+   */
+  return M860AllocateBufferDescriptors (((count * 4) +
+                                         sizeof(m860BufferDescriptor_t) - 1) / 
+                                        sizeof(m860BufferDescriptor_t));
+}
Index: c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/startup/bspstart.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,187 @@
+/*  bsp_start()
+ *
+ *  This routine starts the application.  It includes application,
+ *  board, and monitor specific initialization and configuration.
+ *  The generic CPU dependent initialization has been performed
+ *  before this routine is invoked.
+ *
+ *  The MPC860 specific stuff was written by Jay Monkman (jmonkman@frasca.com)
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <mpc860.h>
+#include <rtems/libio.h>
+ 
+#include <libcsupport.h>
+ 
+#include <string.h>
+#include <info.h>
+ 
+#ifdef STACK_CHECKER_ON
+#include <stackchk.h>
+#endif
+
+boardinfo_t M860_binfo;
+
+
+/*
+ *  The original table from the application and our copy of it with
+ *  some changes.
+ */
+extern rtems_configuration_table Configuration;
+
+rtems_configuration_table  BSP_Configuration;
+
+rtems_cpu_table Cpu_table;
+
+char *rtems_progname;
+
+/*
+ *  Use the shared implementations of the following routines
+ */
+void bsp_postdriver_hook(void);
+void bsp_libc_init( void *, unsigned32, int );
+
+/*
+ *  Function:   bsp_pretasking_hook
+ *  Created:    95/03/10
+ *
+ *  Description:
+ *      BSP pretasking hook.  Called just before drivers are initialized.
+ *      Used to setup libc and install any BSP extensions.
+ *
+ *  NOTES:
+ *      Must not use libc (to do io) from here, since drivers are
+ *      not yet initialized.
+ *
+ */
+ 
+void
+bsp_pretasking_hook(void)
+{
+  extern int       _end;
+  rtems_unsigned32  heap_start;
+
+  /* 
+   * Let's check to see if the size of M860_binfo is what
+   * it should be. It might not be if the info.h files
+   * for RTEMS and the bootloader define boardinfo_t
+   * differently.
+   */
+
+  /* Oops. printf() won't work yet, since the console is not initialized.
+     I should probably find some way of doing this though.
+  if (M860_binfo.size != sizeof(boardinfo_t)) {
+      printf("The size of the Board Info Block appears to be incorrect.\n");
+      printf(" This could occur if the 'info.h' files for RTEMS and the\n");
+      printf(" bootloader differ in their definition of boardinfo_t\n");
+  }
+  */
+  heap_start = (rtems_unsigned32) &_end;
+
+  /* Align the heap on a natural boundary (4 bytes?) */
+  if (heap_start & (CPU_ALIGNMENT-1)) {
+    heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+  }
+  /* set up a 256K heap */
+  bsp_libc_init((void *) heap_start, 256 * 1024, 0);
+  
+#ifdef STACK_CHECKER_ON
+  /*
+   *  Initialize the stack bounds checker
+   *  We can either turn it on here or from the app.
+   */
+  
+  Stack_check_Initialize();
+#endif
+  
+#ifdef RTEMS_DEBUG
+  rtems_debug_enable( RTEMS_DEBUG_ALL_MASK );
+#endif
+}
+
+
+void bsp_start(void)
+{
+  extern int _end;
+  rtems_unsigned32  heap_start;
+  rtems_unsigned32  ws_start;
+  /*
+   *  Allocate the memory for the RTEMS Work Space.  This can come from
+   *  a variety of places: hard coded address, malloc'ed from outside
+   *  RTEMS world (e.g. simulator or primitive memory manager), or (as
+   *  typically done by stock BSPs) by subtracting the required amount
+   *  of work space from the last physical address on the CPU board.
+   */
+
+  /*
+   *  Need to "allocate" the memory for the RTEMS Workspace and
+   *  tell the RTEMS configuration where it is.  This memory is
+   *  not malloc'ed.  It is just "pulled from the air".
+   */
+
+  heap_start = (rtems_unsigned32) &_end;
+  if (heap_start & (CPU_ALIGNMENT-1))
+    heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1);
+
+
+  ws_start = heap_start + (256 * 1024);
+  if (ws_start & ((512 * 1024) - 1)) {  /* align to 512K boundary */
+    ws_start = (ws_start + (512 * 1024)) & ~((512 * 1024) - 1);
+  }
+
+  BSP_Configuration.work_space_start = (void *)ws_start;
+  BSP_Configuration.work_space_size = 512 * 1024; 
+
+  /*
+   *  initialize the CPU table for this BSP
+   */
+
+  Cpu_table.pretasking_hook = bsp_pretasking_hook;  /* init libc, etc. */
+  Cpu_table.postdriver_hook = bsp_postdriver_hook;
+  Cpu_table.interrupt_stack_size = 4 * 1024;
+
+  Cpu_table.clicks_per_usec = 1;  /* for 4MHz extclk */
+  Cpu_table.serial_per_sec = 10000000;
+  Cpu_table.serial_external_clock = 1;
+  Cpu_table.serial_xon_xoff = 0;
+  Cpu_table.serial_cts_rts = 1;
+  Cpu_table.serial_rate = 9600;
+  Cpu_table.timer_average_overhead = 0;
+  Cpu_table.timer_least_valid = 0;
+  Cpu_table.clock_speed = 40000000;
+
+  /* 
+   * Call this in case we use TERMIOS for console I/O
+   */
+  m860_console_reserve_resources(&BSP_Configuration);
+
+  /*
+   * Since we are currently autodetecting whether to use SCC1 or
+   * the FEC for ethernet, we set up a register in the ethernet
+   * transciever that is used for 10/100 Mbps ethernet now, so that 
+   * we can attempt to read it later in rtems_enet_driver_attach()
+  */
+  m860.fec.mii_speed = 0x0a;
+  m860.fec.mii_data = 0x680a0000;
+
+
+  m860.scc2.sccm=0;
+  m860.scc2p.rbase=0;
+  m860.scc2p.tbase=0;
+  M860ExecuteRISC(M860_CR_OP_STOP_TX | M860_CR_CHAN_SCC2);
+
+  mmu_init(); 
+}
+
+
Index: c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/startup/linkcmds	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,153 @@
+/*
+ *  This file contains directives for the GNU linker which are specific
+ *  to the Ethernet-Comm Board
+ *
+ *  $Id$
+ */
+
+OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
+              "elf32-powerpc")
+OUTPUT_ARCH(powerpc)
+ SEARCH_DIR(/usr/local/powerpc-rtems/lib);
+ 
+ENTRY(start)
+ 
+MEMORY
+	{
+	ram : org = 0x0, l = 4M
+	dpram : org = 0xff000000, l = 16K
+	canbus : org = 0xff100000, l = 12K
+	flash : org = 0xfff00000, l = 512K
+	}
+
+
+SECTIONS
+{
+	.vectors :
+	{
+	  *(.vectors)
+	} >ram
+
+	/* 
+	 * The stack will live in this area - between the vectors and
+	 * the text section.
+	 */
+	
+	.text 0x10000:
+  	{
+	     text.start = .;
+	     *(.entry)
+	     *(.entry2)
+	     *(.text)
+	     *(.rodata)
+	     *(.rodata1)
+	     *(.descriptors)
+	     *(rom_ver)
+	     etext = ALIGN(0x10);
+	     _etext = .;
+	
+	     __CTOR_LIST__ = .;
+	     LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+	     *(.ctors)
+	     LONG(0)
+	     __CTOR_END__ = .;
+	
+	     __DTOR_LIST__ = .;
+	     LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+	     *(.dtors)
+	     LONG(0)
+	     __DTOR_END__ = .;
+	
+	     *(.lit)
+	     *(.shdata)
+	     *(.init)
+	     *(.fini)
+	     _endtext = .;
+	     text.end = .;
+	} > ram
+ 
+	/* R/W Data */
+	.data :
+	{
+	  *(.data)
+	  *(.data1)
+	  PROVIDE (__SDATA_START__ = .);
+	  *(.sdata)
+	} > ram
+	
+	PROVIDE (__EXCEPT_START__ = .);
+	.gcc_except_table   : { *(.gcc_except_table) } >RAM
+	PROVIDE (__EXCEPT_END__ = .);
+	__GOT_START__ = .;
+	.got :
+	{
+	   s.got = .;
+	   *(.got.plt) *(.got)
+	} > ram
+	__GOT_END__ = .;
+	
+	.got1		  : { *(.got1) 		} >ram
+	PROVIDE (__GOT2_START__ = .);
+	PROVIDE (_GOT2_START_ = .);
+	.got2		  :  { *(.got2) 	} >ram
+	PROVIDE (__GOT2_END__ = .);
+	PROVIDE (_GOT2_END_ = .);
+	
+	PROVIDE (__FIXUP_START__ = .);
+	PROVIDE (_FIXUP_START_ = .);
+	.fixup	  : { *(.fixup) 	} >ram
+	PROVIDE (_FIXUP_END_ = .);
+	PROVIDE (__FIXUP_END__ = .);
+	 
+	PROVIDE (__SDATA2_START__ = .);
+	.sdata2   	  : { *(.sdata2) 	} >ram
+	.sbss2   	  : { *(.sbss2) 	} >ram
+	PROVIDE (__SBSS2_END__ = .);
+	
+	.sbss2   	  : { *(.sbss2) 	} >ram
+	PROVIDE (__SBSS2_END__ = .);
+	
+	__SBSS_START__ = .;
+	.bss :
+	{
+	  bss.start = .;
+	  *(.bss) *(.sbss) *(COMMON)
+	  . = ALIGN(4);
+	  bss.end = .;
+	} > ram
+	__SBSS_END__ = .;
+
+	bss.size = bss.end - bss.start;
+	text.size = text.end - text.start;
+	PROVIDE(_end = bss.end);
+	
+        dpram : 
+	{
+          m860 = .;
+          _m860 = .;
+          . += (8 * 1024);
+        } >dpram
+
+	canbus :
+	{
+	  canbus0 = .;
+	  . += (0x1000);
+	  canbus1 = .;
+	  . += (0x1000);
+	  canbus2 = .;
+	  . += (0x1000);
+	} >canbus
+
+
+	.line 0 : { *(.line) }
+	.debug 0 : { *(.debug) }
+	.debug_sfnames 0 : { *(.debug_sfnames) }
+	.debug_srcinfo 0 : { *(.debug_srcinfo) }
+	.debug_pubnames 0 : { *(.debug_pubnames) }
+	.debug_aranges 0 : { *(.debug_aranges) }
+	.debug_aregion 0 : { *(.debug_aregion) }
+	.debug_macinfo 0 : { *(.debug_macinfo) }
+	.stab 0 : { *(.stab) }
+	.stabstr 0 : { *(.stabstr) }
+
+}
Index: c/src/lib/libbsp/powerpc/eth_comm/startup/mmu.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/startup/mmu.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/startup/mmu.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,126 @@
+/* 
+ *  mmu.c - this file contains functions for initializing the MMU 
+ *
+ *  Written by Jay Monkman (jmonkman@frasca.com)
+ */
+
+#include <bsp.h>
+#include <mpc860.h>
+
+/* Macros for handling all the MMU SPRs */
+#define PUT_MI_CTR(r)   __asm__ volatile ("mtspr 0x310,%0\n" ::"r"(r))
+#define GET_MI_CTR(r)   __asm__ volatile ("mfspr %0,0x310\n" :"=r"(r))
+#define PUT_MD_CTR(r)   __asm__ volatile ("mtspr 0x318,%0\n" ::"r"(r))
+#define GET_MD_CTR(r)   __asm__ volatile ("mfspr %0,0x318\n" :"=r"(r))
+#define PUT_M_CASID(r)  __asm__ volatile ("mtspr 0x319,%0\n" ::"r"(r))
+#define GET_M_CASID(r)  __asm__ volatile ("mfspr %0,0x319\n" :"=r"(r))
+#define PUT_MI_EPN(r)   __asm__ volatile ("mtspr 0x313,%0\n" ::"r"(r))
+#define GET_MI_EPN(r)   __asm__ volatile ("mfspr %0,0x313\n" :"=r"(r))
+#define PUT_MI_TWC(r)   __asm__ volatile ("mtspr 0x315,%0\n" ::"r"(r))
+#define GET_MI_TWC(r)   __asm__ volatile ("mfspr %0,0x315\n" :"=r"(r))
+#define PUT_MI_RPN(r)   __asm__ volatile ("mtspr 0x316,%0\n" ::"r"(r))
+#define GET_MI_RPN(r)   __asm__ volatile ("mfspr %0,0x316\n" :"=r"(r))
+#define PUT_MD_EPN(r)   __asm__ volatile ("mtspr 0x313,%0\n" ::"r"(r))
+#define GET_MD_EPN(r)   __asm__ volatile ("mfspr %0,0x313\n" :"=r"(r))
+#define PUT_M_TWB(r)    __asm__ volatile ("mtspr 0x31c,%0\n" ::"r"(r))
+#define GET_M_TWB(r)    __asm__ volatile ("mfspr %0,0x31c\n" :"=r"(r))
+#define PUT_MD_TWC(r)   __asm__ volatile ("mtspr 0x31d,%0\n" ::"r"(r))
+#define GET_MD_TWC(r)   __asm__ volatile ("mfspr %0,0x31d\n" :"=r"(r))
+#define PUT_MD_RPN(r)   __asm__ volatile ("mtspr 0x31e,%0\n" ::"r"(r))
+#define GET_MD_RPN(r)   __asm__ volatile ("mfspr %0,0x31e\n" :"=r"(r))
+#define PUT_MI_AP(r)    __asm__ volatile ("mtspr 0x312,%0\n" ::"r"(r))
+#define GET_MI_AP(r)    __asm__ volatile ("mfspr %0,0x312\n" :"=r"(r))
+#define PUT_MD_AP(r)    __asm__ volatile ("mtspr 0x31a,%0\n" ::"r"(r))
+#define GET_MD_AP(r)    __asm__ volatile ("mfspr %0,0x31a\n" :"=r"(r))
+#define PUT_M_TW(r)     __asm__ volatile ("mtspr 0x31f,%0\n" ::"r"(r))
+#define GET_M_TW(r)     __asm__ volatile ("mfspr %0,0x31f\n" :"=r"(r))
+#define PUT_MI_DCAM(r)  __asm__ volatile ("mtspr 0x330,%0\n" ::"r"(r))
+#define GET_MI_DCAM(r)  __asm__ volatile ("mfspr %0,0x330\n" :"=r"(r))
+#define PUT_MI_DRAM0(r) __asm__ volatile ("mtspr 0x331,%0\n" ::"r"(r))
+#define GET_MI_DRAM0(r) __asm__ volatile ("mfspr %0,0x331\n" :"=r"(r))
+#define PUT_MI_DRAM1(r) __asm__ volatile ("mtspr 0x332,%0\n" ::"r"(r))
+#define GET_MI_DRAM1(r) __asm__ volatile ("mfspr %0,0x332\n" :"=r"(r))
+#define PUT_MD_DCAM(r)  __asm__ volatile ("mtspr 0x338,%0\n" ::"r"(r))
+#define GET_MD_DCAM(r)  __asm__ volatile ("mfspr %0,0x338\n" :"=r"(r))
+#define PUT_MD_DRAM0(r) __asm__ volatile ("mtspr 0x339,%0\n" ::"r"(r))
+#define GET_MD_DRAM0(r) __asm__ volatile ("mfspr %0,0x339\n" :"=r"(r))
+#define PUT_MD_DRAM1(r) __asm__ volatile ("mtspr 0x33a,%0\n" ::"r"(r))
+#define GET_MD_DRAM1(r) __asm__ volatile ("mfspr %0,0x33a\n" :"=r"(r))
+#define PUT_IC_CST(r)   __asm__ volatile ("mtspr 0x230,%0\n" ::"r"(r))
+#define GET_IC_CST(r)   __asm__ volatile ("mfspr %0,0x230\n" :"=r"(r))
+#define PUT_DC_CST(r)   __asm__ volatile ("mtspr 0x238,%0\n" ::"r"(r))
+#define GET_DC_CST(r)   __asm__ volatile ("mfspr %0,0x238\n" :"=r"(r))
+#define PUT_IC_ADR(r)   __asm__ volatile ("mtspr 0x231,%0\n" ::"r"(r))
+#define GET_IC_ADR(r)   __asm__ volatile ("mfspr %0,0x231\n" :"=r"(r))
+#define PUT_IC_DAT(r)   __asm__ volatile ("mtspr 0x232,%0\n" ::"r"(r))
+#define GET_IC_DAT(r)   __asm__ volatile ("mfspr %0,0x232\n" :"=r"(r))
+
+extern rtems_configuration_table BSP_Configuration;
+
+void mmu_init(void)
+{
+  register unsigned long t1, t2;
+
+  /* Let's clear MSR[IR] and MSR[DR] */ 
+  t2 = PPC_MSR_IR | PPC_MSR_DR;
+  __asm__ volatile (
+    "mfmsr    %0\n"
+    "andc     %0, %0, %1\n"
+    "mtmsr    %0\n" :"=r"(t1), "=r"(t2):
+    "1"(t2));
+
+  /* Invalidate the TLBs */
+  __asm__ volatile ("tlbia\n"::);
+  __asm__ volatile ("isync\n"::);
+
+  /* make sure no TLB entries are reserved */
+  t1 = 0;
+  PUT_MI_CTR(t1);
+
+  t1 = M860_MD_CTR_TWAM;   /* 4K pages */
+  /*  PUT_MD_CTR(t1); */
+
+  t1 = M860_MI_EPN_VALID;    /* make entry valid */
+  /*  PUT_MD_EPN(t1); */
+  PUT_MI_EPN(t1);
+
+  t1 = M860_MI_TWC_PS8 | M860_MI_TWC_VALID;   /* 8 MB pages, valid */
+  /*  PUT_MD_TWC(t1); */
+  PUT_MI_TWC(t1);
+
+  t1 = M860_MD_RPN_CHANGE | M860_MD_RPN_F | M860_MD_RPN_16K | 
+       M860_MD_RPN_SHARED | M860_MD_RPN_VALID;
+  /*  PUT_MD_RPN(t1); */
+  PUT_MI_RPN(t1);
+
+  t1 = M860_MI_AP_Kp << 30;  
+  PUT_MI_AP(t1);
+  /*  PUT_MD_AP(t1); */
+  
+  t1 = M860_CACHE_CMD_UNLOCK;
+  /*  PUT_DC_CST(t1); */
+  PUT_IC_CST(t1);
+
+  t1 = M860_CACHE_CMD_INVALIDATE;
+  /*  PUT_DC_CST(t1); */
+  PUT_IC_CST(t1);
+
+  t1 = M860_CACHE_CMD_ENABLE;
+  PUT_IC_CST(t1);
+
+  t1 = M860_CACHE_CMD_SFWT;
+  /*  PUT_DC_CST(t1); */
+  t1 = M860_CACHE_CMD_ENABLE;
+  /*  PUT_DC_CST(t1);*/
+
+
+
+  /* Let's set MSR[IR]  */ 
+  t2 = PPC_MSR_IR;
+  __asm__ volatile (
+    "mfmsr    %0\n"
+    "or       %0, %0, %1\n"
+    "mtmsr    %0\n" :"=r"(t1), "=r"(t2):
+    "1"(t2));
+
+}
Index: c/src/lib/libbsp/powerpc/eth_comm/startup/setvec.c
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/startup/setvec.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/startup/setvec.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,44 @@
+/*  set_vector
+ *
+ *  This routine installs an interrupt vector on the target Board/CPU.
+ *  This routine is allowed to be as board dependent as necessary.
+ *
+ *  INPUT:
+ *    handler - interrupt handler entry point
+ *    vector  - vector number
+ *    type    - 0 indicates raw hardware connect
+ *              1 indicates RTEMS interrupt connect
+ *
+ *  RETURNS:
+ *    address of previous interrupt handler
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+
+rtems_isr_entry set_vector(                     /* returns old vector */
+  rtems_isr_entry     handler,                  /* isr routine        */
+  rtems_vector_number vector,                   /* vector number      */
+  int                 type                      /* RTEMS or RAW intr  */
+)
+{
+  rtems_isr_entry previous_isr;
+  
+  if (type) {
+    rtems_interrupt_catch(handler, vector, (rtems_isr_entry *) &previous_isr );
+  } else {
+    /* XXX: install non-RTEMS ISR as "raw" interupt */
+  }
+  return previous_isr;
+}
+
Index: c/src/lib/libbsp/powerpc/eth_comm/times
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/times	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/times	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,194 @@
+#
+#  Timing Test Suite Results for the NO_BSP
+#
+#  NOTE: This is just a template.  The times are irrelevant since this BSP
+#        can only be compiled -- not executed.
+#
+#  $Id$
+#
+
+Board:  
+CPU: include coprocessor if applicable
+Clock Speed:
+Memory Configuration: SRAM, DRAM, cache, etc
+Wait States:
+
+Times Reported in: cycles, microseconds, etc
+Timer Source: Count Down Timer, on-CPU cycle counter, etc
+
+Column X:
+Column Y:
+
+#                          DESCRIPTION                                 A    B
+== =================================================================  ==== ====
+ 1 rtems_semaphore_create                                               20
+   rtems_semaphore_delete                                               21
+   rtems_semaphore_obtain: available                                    15
+   rtems_semaphore_obtain: not available -- NO_WAIT                     15
+   rtems_semaphore_release: no waiting tasks                            16
+
+ 2 rtems_semaphore_obtain: not available -- caller blocks               62
+
+ 3 rtems_semaphore_release: task readied -- preempts caller             55
+
+ 4 rtems_task_restart: blocked task -- preempts caller                  77
+   rtems_task_restart: ready task -- preempts caller                    70
+   rtems_semaphore_release: task readied -- returns to caller           25
+   rtems_task_create                                                    57
+   rtems_task_start                                                     31
+   rtems_task_restart: suspended task -- returns to caller              36
+   rtems_task_delete: suspended task                                    47
+   rtems_task_restart: ready task -- returns to caller                  37
+   rtems_task_restart: blocked task -- returns to caller                46
+   rtems_task_delete: blocked task                                      50
+
+ 5 rtems_task_suspend: calling task                                     51
+   rtems_task_resume: task readied -- preempts caller                   49
+
+ 6 rtems_task_restart: calling task                                     59
+   rtems_task_suspend: returns to caller                                18
+   rtems_task_resume: task readied -- returns to caller                 19
+   rtems_task_delete: ready task                                        50
+
+ 7 rtems_task_restart: suspended task -- preempts caller                70
+
+ 8 rtems_task_set_priority: obtain current priority                     12
+   rtems_task_set_priority: returns to caller                           27
+   rtems_task_mode: obtain current mode                                  5
+   rtems_task_mode: no reschedule                                        5
+   rtems_task_mode: reschedule -- returns to caller                      8
+   rtems_task_mode: reschedule -- preempts caller                       39
+   rtems_task_set_note                                                  13
+   rtems_task_get_note                                                  13
+   rtems_clock_set                                                      33
+   rtems_clock_get                                                       3
+
+ 9 rtems_message_queue_create                                          110
+   rtems_message_queue_send: no waiting tasks                           37
+   rtems_message_queue_urgent: no waiting tasks                         37
+   rtems_message_queue_receive: available                               31
+   rtems_message_queue_flush: no messages flushed                       12
+   rtems_message_queue_flush: messages flushed                          16
+   rtems_message_queue_delete                                           26
+
+10 rtems_message_queue_receive: not available -- NO_WAIT                15
+   rtems_message_queue_receive: not available -- caller blocks          62
+
+11 rtems_message_queue_send: task readied -- preempts caller            72
+
+12 rtems_message_queue_send: task readied -- returns to caller          39
+
+13 rtems_message_queue_urgent: task readied -- preempts caller          72
+
+14 rtems_message_queue_urgent: task readied -- returns to caller        39
+
+15 rtems_event_receive: obtain current events                            1
+   rtems_event_receive: not available -- NO_WAIT                        12
+   rtems_event_receive: not available -- caller blocks                  56
+   rtems_event_send: no task readied                                    12
+   rtems_event_receive: available                                       12
+   rtems_event_send: task readied -- returns to caller                  24
+
+16 rtems_event_send: task readied -- preempts caller                    55
+
+17 rtems_task_set_priority: preempts caller                             62
+
+18 rtems_task_delete: calling task                                      83
+
+19 rtems_signal_catch                                                    9
+   rtems_signal_send: returns to caller                                 15
+   rtems_signal_send: signal to self                                    18
+   exit ASR overhead: returns to calling task                           22
+   exit ASR overhead: returns to preempting task                        49
+
+20 rtems_partition_create                                               35
+   rtems_region_create                                                  23
+   rtems_partition_get_buffer: available                                15
+   rtems_partition_get_buffer: not available                            13
+   rtems_partition_return_buffer                                        18
+   rtems_partition_delete                                               16
+   rtems_region_get_segment: available                                  22
+   rtems_region_get_segment: not available -- NO_WAIT                   21
+   rtems_region_return_segment: no waiting tasks                        19
+   rtems_region_get_segment: not available -- caller blocks             64
+   rtems_region_return_segment: task readied -- preempts caller         74
+   rtems_region_return_segment: task readied -- returns to caller       44
+   rtems_region_delete                                                  16
+   rtems_io_initialize                                                   2
+   rtems_io_open                                                         1
+   rtems_io_close                                                        1
+   rtems_io_read                                                         1
+   rtems_io_write                                                        1
+   rtems_io_control                                                      1
+
+21 rtems_task_ident                                                    149
+   rtems_message_queue_ident                                           145
+   rtems_semaphore_ident                                               156
+   rtems_partition_ident                                               145
+   rtems_region_ident                                                  148
+   rtems_port_ident                                                    145
+   rtems_timer_ident                                                   145
+   rtems_rate_monotonic_ident                                          145
+
+22 rtems_message_queue_broadcast: task readied -- returns to caller     42
+   rtems_message_queue_broadcast: no waiting tasks                      17
+   rtems_message_queue_broadcast: task readied -- preempts caller       78
+
+23 rtems_timer_create                                                   14
+   rtems_timer_fire_after: inactive                                     22
+   rtems_timer_fire_after: active                                       24
+   rtems_timer_cancel: active                                           15
+   rtems_timer_cancel: inactive                                         13
+   rtems_timer_reset: inactive                                          21
+   rtems_timer_reset: active                                            23
+   rtems_timer_fire_when: inactive                                      34
+   rtems_timer_fire_when: active                                        34
+   rtems_timer_delete: active                                           19
+   rtems_timer_delete: inactive                                         17
+   rtems_task_wake_when                                                 69
+
+24 rtems_task_wake_after: yield -- returns to caller                     9
+   rtems_task_wake_after: yields -- preempts caller                     45
+
+25 rtems_clock_tick                                                      4
+
+26 _ISR_Disable                                                          0
+   _ISR_Flash                                                            1
+   _ISR_Enable                                                           1
+   _Thread_Disable_dispatch                                              0
+   _Thread_Enable_dispatch                                               7
+   _Thread_Set_state                                                    11
+   _Thread_Disptach (NO FP)                                             31
+   context switch: no floating point contexts                           21
+   context switch: self                                                 10
+   context switch: to another task                                      10
+   context switch: restore 1st FP task                                  25
+   fp context switch: save idle, restore idle                           31
+   fp context switch: save idle, restore initialized                    19
+   fp context switch: save initialized, restore initialized             20
+   _Thread_Resume                                                        7
+   _Thread_Unblock                                                       7
+   _Thread_Ready                                                         9
+   _Thread_Get                                                           4
+   _Semaphore_Get                                                        2
+   _Thread_Get: invalid id                                               0
+
+27 interrupt entry overhead: returns to interrupted task                 6
+   interrupt exit overhead: returns to interrupted task                  6
+   interrupt entry overhead: returns to nested interrupt                 6
+   interrupt exit overhead: returns to nested interrupt                  5
+   interrupt entry overhead: returns to preempting task                  7
+   interrupt exit overhead: returns to preempting task                  36
+
+28 rtems_port_create                                                    16
+   rtems_port_external_to_internal                                      11
+   rtems_port_internal_to_external                                      11
+   rtems_port_delete                                                    16
+
+29 rtems_rate_monotonic_create                                          15
+   rtems_rate_monotonic_period: initiate period -- returns to caller    21
+   rtems_rate_monotonic_period: obtain status                           13
+   rtems_rate_monotonic_cancel                                          16
+   rtems_rate_monotonic_delete: inactive                                18
+   rtems_rate_monotonic_delete: active                                  20
+   rtems_rate_monotonic_period: conclude periods -- caller blocks       53
Index: c/src/lib/libbsp/powerpc/eth_comm/wrapup/Makefile.in
===================================================================
--- c/src/lib/libbsp/powerpc/eth_comm/wrapup/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libbsp/powerpc/eth_comm/wrapup/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,60 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+# We only build the networking device driver if HAS_NETWORKING was defined
+NETWORKING_DRIVER_yes_V = network
+NETWORKING_DRIVER = $(NETWORKING_DRIVER_$(HAS_NETWORKING)_V)
+
+BSP_PIECES=startup start canbus console $(NETWORKING_DRIVER)
+# pieces to pick up out of libcpu/ppc
+CPU_PIECES=mpc860/clock mpc860/timer mpc860/console-generic mpc860/vectors
+GENERIC_PIECES=
+
+# bummer; have to use $foreach since % pattern subst rules only replace 1x
+OBJS=$(foreach piece, $(BSP_PIECES), ../$(piece)/$(ARCH)/$(piece).rel) \
+     $(foreach piece, $(CPU_PIECES), \
+         ../../../../libcpu/$(RTEMS_CPU)/$(piece)/$(ARCH)/$(notdir $(piece)).rel) \
+     $(foreach piece, $(GENERIC_PIECES), \
+         ../../../$(piece)/$(ARCH)/$(piece).rel)
+LIB=$(ARCH)/libbsp.a
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/lib.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+$(LIB): ${OBJS}
+	$(make-library)
+
+all:	${ARCH} $(SRCS) $(LIB)
+	$(INSTALL_VARIANT) -m 644 $(LIB) ${PROJECT_RELEASE}/lib
+
+install:  all
+
Index: c/src/lib/libcpu/powerpc/mpc860/Makefile.in
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,14 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/directory.cfg
+
+SUB_DIRS=include console-generic clock timer vectors
Index: c/src/lib/libcpu/powerpc/mpc860/README
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,22 @@
+#
+#  $Id$
+#
+
+Various non BSP dependant support routines.
+
+clock - Uses the 403 PIT (Programmable interval timer) to
+	generate RTEMS clock ticks.
+
+console - Uses the 403 Internal serial port to do RTEMS
+	console I/O.  Not ALL members of the 403 family
+	have this.
+
+include - Currently empty
+
+timer - Uses the 403 timebase register for timing
+	tests.  Other PowerPCs have slightly different
+	timebase register definitions.
+
+vectors - PowerPC 403 specific vector entry points.
+	Includes CPU dependant, application independant
+	handlers: alignment.
Index: c/src/lib/libcpu/powerpc/mpc860/clock/Makefile.in
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/clock/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/clock/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,60 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/clock.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=clock
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS += 
+CFLAGS   += $(CFLAGS_OS_V)
+
+LD_PATHS  += 
+LD_LIBS   += 
+LDFLAGS   += 
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by
+#    libbsp/hppa/BSP/wrapup/Makefile
+install:  all
Index: c/src/lib/libcpu/powerpc/mpc860/clock/clock.c
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/clock/clock.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/clock/clock.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,186 @@
+/*  clock.c
+ *
+ *  This routine initializes the PIT on the MPC860.
+ *  The tick frequency is specified by the bsp.
+ *
+ *  Author: Jay Monkman (jmonkman@frasca.com)
+ *  Copyright (C) 1998 by Frasca International, Inc.
+ *
+ *  Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
+ *
+ *  Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ *  Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <clockdrv.h>
+#include <rtems/libio.h>
+
+#include <stdlib.h>                     /* for atexit() */
+#include <mpc860.h>
+
+extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
+
+volatile rtems_unsigned32 Clock_driver_ticks;
+extern volatile m860_t m860;
+
+void Clock_exit( void );
+ 
+/*
+ * These are set by clock driver during its init
+ */
+ 
+rtems_device_major_number rtems_clock_major = ~0;
+rtems_device_minor_number rtems_clock_minor;
+ 
+/*
+ *  ISR Handler
+ */
+rtems_isr Clock_isr(rtems_vector_number vector)
+{
+  m860.piscr |= M860_PISCR_PS;
+  Clock_driver_ticks++;
+  rtems_clock_tick();
+}
+
+void Install_clock(rtems_isr_entry clock_isr)
+{
+  rtems_isr_entry previous_isr;
+  rtems_unsigned32 pit_value;
+  
+  Clock_driver_ticks = 0;
+  
+  pit_value = BSP_Configuration.microseconds_per_tick *
+               Cpu_table.clicks_per_usec;
+  if (pit_value == 0) {
+    pit_value = 0xffff;
+  } else {
+    pit_value--;
+  }
+  
+  if (pit_value > 0xffff) {           /* pit is only 16 bits long */
+    rtems_fatal_error_occurred(-1);
+  }  
+  if (BSP_Configuration.ticks_per_timeslice) {
+    
+    /*
+     * initialize the interval here
+     * First tick is set to right amount of time in the future
+     * Future ticks will be incremented over last value set
+     * in order to provide consistent clicks in the face of
+     * interrupt overhead
+     */
+    
+    rtems_interrupt_catch(clock_isr, PPC_IRQ_LVL0, &previous_isr);
+    
+    m860.sccr &= ~(1<<24);
+    m860.pitc = pit_value;
+    
+    /* set PIT irq level, enable PIT, PIT interrupts */
+    /*  and clear int. status */
+    m860.piscr = M860_PISCR_PIRQ(0) |
+      M860_PISCR_PTE | M860_PISCR_PS | M860_PISCR_PIE; 
+    
+    m860.simask |= M860_SIMASK_LVM0;
+  }
+  atexit(Clock_exit);
+}
+
+void
+ReInstall_clock(rtems_isr_entry new_clock_isr)
+{
+  rtems_isr_entry previous_isr;
+  rtems_unsigned32 isrlevel = 0;
+  
+  rtems_interrupt_disable(isrlevel);
+  
+  rtems_interrupt_catch(new_clock_isr, PPC_IRQ_LVL0, &previous_isr);
+  
+  rtems_interrupt_enable(isrlevel);
+}
+
+
+/*
+ * Called via atexit()
+ * Remove the clock interrupt handler by setting handler to NULL
+ */
+void
+Clock_exit(void)
+{
+  if ( BSP_Configuration.ticks_per_timeslice ) {
+    /* disable PIT and PIT interrupts */
+    m860.piscr &= ~(M860_PISCR_PTE | M860_PISCR_PIE); 
+    
+    (void) set_vector(0, PPC_IRQ_LVL0, 1);
+  }
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+ 
+  /*
+   * make major/minor avail to others such as shared memory driver
+   */
+ 
+  rtems_clock_major = major;
+  rtems_clock_minor = minor;
+ 
+  return RTEMS_SUCCESSFUL;
+}
+ 
+rtems_device_driver Clock_control(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  rtems_libio_ioctl_args_t *args = pargp;
+  
+  if (args == 0)
+    goto done;
+  
+  /*
+   * This is hokey, but until we get a defined interface
+   * to do this, it will just be this simple...
+   */
+  
+  if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
+    Clock_isr(PPC_IRQ_LVL0);
+  }
+  else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
+    ReInstall_clock(args->buffer);
+  }
+  
+ done:
+  return RTEMS_SUCCESSFUL;
+}
+
Index: c/src/lib/libcpu/powerpc/mpc860/console-generic/Makefile.in
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/console-generic/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/console-generic/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,59 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/console-generic.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=console-generic
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
Index: c/src/lib/libcpu/powerpc/mpc860/console-generic/console-generic.c
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/console-generic/console-generic.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/console-generic/console-generic.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,938 @@
+/*
+ *  General Serial I/O functions.
+ *
+ * This file contains the functions for performing serial I/O.
+ * The actual system calls (console_*) should be in the BSP part
+ * of the source tree. That way different BSPs can use whichever
+ * SMCs and SCCs they want. Originally, all the stuff was in
+ * this file, and it caused problems with one BSP using SCC2 
+ * as /dev/console, others using SMC1 for /dev/console, etc.
+ *
+ *  On-chip resources used:
+ *   resource   minor                note
+ *    SMC1       0
+ *    SMC2       1
+ *    SCC1       2                   (shared with ethernet driver)
+ *    SCC2       3
+ *    SCC3       4
+ *    SCC4       5
+ *    BRG1
+ *    BRG2
+ *    BRG3
+ *    BRG4
+ *  Author: Jay Monkman (jmonkman@frasca.com)
+ *  Copyright (C) 1998 by Frasca International, Inc.
+ *
+ *  Derived from c/src/lib/libbsp/m68k/gen360/console/console.c:
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <rtems/libio.h>
+#include <mpc860.h>
+#include <mpc860/console.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+
+#define NIFACES 6        /* number of console devices (serial ports) */
+
+extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
+
+static Buf_t *rxBufList[NIFACES];
+static Buf_t *rxBufListTail[NIFACES];
+
+/*
+ * Interrupt-driven input buffer
+ */
+#define RXBUFSIZE       16
+
+
+/*
+ * I/O buffers and pointers to buffer descriptors
+ */
+static volatile char txBuf[NIFACES];
+
+static volatile m860BufferDescriptor_t *RxBd[NIFACES], *TxBd[NIFACES];
+
+/*
+ * Device-specific routines
+ */
+static int m860_get_brg_cd(int);
+unsigned char m860_get_brg_clk(int);
+void m860_console_reserve_resources(rtems_configuration_table *);
+unsigned char m860_get_brg_clk(int);
+
+
+/*
+ * Compute baud-rate-generator configuration register value
+ */
+static int
+m860_get_brg_cd (int baud)
+{
+  int divisor;
+  int div16 = 0;
+  
+  divisor = ((Cpu_table.clock_speed / 16) + (baud / 2)) / baud;
+  if (divisor > 4096) {
+    div16 = 1;
+    divisor = (divisor + 8) / 16;
+  }
+  return M860_BRG_EN | M860_BRG_EXTC_BRGCLK | 
+    ((divisor - 1) << 1) | div16;
+}
+
+
+/* this function will fail if more that 4 baud rates have been selected */
+/*  at any time since the OS started. It needs to be fixed. FIXME */
+unsigned char m860_get_brg_clk(int baud)
+{
+  static short brg_spd[4];
+  static char  brg_used[4];
+  int i;
+
+  /* first try to find a BRG that is already at the right speed */
+  for (i=0; i<4; i++) {
+    if (brg_spd[i] == baud) {
+      break;
+    }
+  }
+
+  if (i==4) { /* I guess we didn't find one */
+    for (i=0; i<4; i++) {
+      if (brg_used[i] == 0) {
+        break;
+      }
+    }
+  }
+  if (i != 4) {
+    brg_used[i]++;
+    brg_spd[i]=baud;
+    switch (i) {
+    case 0:
+      m860.brgc1 = M860_BRG_RST;
+      m860.brgc1 = m860_get_brg_cd(baud);
+      break;
+    case 1:
+      m860.brgc2 = M860_BRG_RST;
+      m860.brgc2 = m860_get_brg_cd(baud);
+      break;
+    case 2:
+      m860.brgc3 = M860_BRG_RST;
+      m860.brgc3 = m860_get_brg_cd(baud);
+      break;
+    case 3:
+      m860.brgc4 = M860_BRG_RST;
+      m860.brgc4 = m860_get_brg_cd(baud);
+      break;
+    }
+    return i;
+  }
+
+  else 
+    return 0xff;
+}
+
+/*
+ * Hardware-dependent portion of tcsetattr().
+ */
+int
+m860_smc_set_attributes (int minor, const struct termios *t)
+{
+  /*
+   * minor must be 0 or 1
+   */
+  int baud;
+  int brg;
+  switch (t->c_cflag & CBAUD) {
+  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;
+  }
+  if (baud > 0) {
+    brg = m860_get_brg_clk(baud);     /* 4 BRGs, 6 serial ports - hopefully */ 
+                                      /*  at least 2 ports will be the same */
+    m860.simode |= brg << (12 + ((minor) * 16));
+  }
+  return 0;
+}
+
+int
+m860_scc_set_attributes (int minor, const struct termios *t)
+{
+  /*
+   * minor must be 2, 3, 4 or 5
+   */
+  int baud;
+  int brg;
+  switch (t->c_cflag & CBAUD) {
+  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;
+  }
+  if (baud > 0) {
+    brg = m860_get_brg_clk(baud);     /* 4 BRGs, 5 serial ports - hopefully */ 
+                                      /*  at least 2 ports will be the same */
+    m860.sicr |= (brg << (3 + ((minor-2) * 8))) | 
+                 (brg << ((minor-2) * 8));
+  }
+  return 0;
+}
+
+void
+m860_scc_initialize (int port)  /* port is the SCC # (i.e. 1, 2, 3 or 4) */
+{
+  unsigned char                brg;
+  volatile m860SCCparms_t     *sccparms;
+  volatile m860SCCRegisters_t *sccregs;
+
+  /*
+   * Allocate buffer descriptors
+   */
+  RxBd[port+1] = M860AllocateBufferDescriptors(1);
+  TxBd[port+1] = M860AllocateBufferDescriptors(1);
+  
+  /*
+   * Configure ports A and B to enable TXDx and RXDx pins
+   */
+  m860.papar |=  (0xC << ((port-2) * 2));
+  m860.padir &= ~(0xC << ((port-2) * 2));
+  m860.pbdir |=  (0x04 << (port-2));
+  m860.paodr &= ~(0x8 << ((port-2) * 2));
+  m860.pbdat &= ~(0x04 << (port-2));
+  
+  /* SCC2 is the only one with handshaking lines */
+  /*
+    if (port == 2) {
+    m860.pcpar |= (0x02);
+    m860.pcpar &= ~(0xc0);
+    m860.pcdir &= ~(0xc2);
+    m860.pcso  |= (0xc0);
+    }
+  */
+  
+  brg = m860_get_brg_clk(9600);     /* 4 BRGs, 5 serial ports - hopefully */ 
+                                    /*  at least 2 ports will be the same */
+  
+  /*
+   * Set up SDMA 
+   */
+  m860.sdcr = 0x01; /* as recommended p 16-80, sec 16.10.2.1 MPC860UM/AD */
+  
+
+  m860.sicr &= ~(0xff << ((port-1) * 8));
+  m860.sicr |= (brg << (3 + ((port-1) * 8))) | (brg << ((port-1) * 8));
+  
+  /*
+   * Set up SMC1 parameter RAM common to all protocols
+   */
+  if (port == 1) {
+    sccparms = (m860SCCparms_t*)&m860.scc1p;
+    sccregs = &m860.scc1;
+  }
+  else if (port == 2) {
+    sccparms = &m860.scc2p;
+    sccregs = &m860.scc2;
+  }
+  else if (port == 3) {
+    sccparms = &m860.scc3p;
+    sccregs = &m860.scc3;
+  }
+  else {
+    sccparms = &m860.scc4p;
+    sccregs = &m860.scc4;
+  }
+  
+  sccparms->rbase = (char *)RxBd[port+1] - (char *)&m860;
+  sccparms->tbase = (char *)TxBd[port+1] - (char *)&m860;
+  
+  if (port == 1)
+    M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC1);
+  else if (port == 2)
+    M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC2);
+  else if (port == 3)
+    M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC3);
+  else if (port == 4)
+    M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SCC4);
+  
+  sccparms->rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
+  sccparms->tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
+  sccparms->mrblr = RXBUFSIZE;
+  
+  sccparms->un.uart.max_idl = 10;
+  sccparms->un.uart.brklen = 0;
+  sccparms->un.uart.brkec = 0;
+  sccparms->un.uart.brkcr = 1;
+  
+  sccparms->un.uart.parec = 0;
+  sccparms->un.uart.frmec = 0;
+  sccparms->un.uart.nosec = 0;
+  
+  sccparms->un.uart.uaddr[0] = 0;
+  sccparms->un.uart.uaddr[1] = 0;
+  sccparms->un.uart.toseq  = 0;
+  
+  sccparms->un.uart.character[0] = 0x8000;
+  sccparms->un.uart.character[1] = 0x8000;
+  sccparms->un.uart.character[2] = 0x8000;
+  sccparms->un.uart.character[3] = 0x8000;
+  sccparms->un.uart.character[4] = 0x8000;
+  sccparms->un.uart.character[5] = 0x8000;
+  sccparms->un.uart.character[6] = 0x8000;
+  sccparms->un.uart.character[7] = 0x8000;
+  
+  sccparms->un.uart.rccm = 0xc0ff;
+  
+  /*
+   * Set up the Receive Buffer Descriptor
+   */
+  RxBd[port+1]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+    M860_BD_INTERRUPT;
+  RxBd[port+1]->length = 0;
+  RxBd[port+1]->buffer = malloc(RXBUFSIZE);
+  
+  /*
+   * Setup the Transmit Buffer Descriptor
+   */
+  TxBd[port+1]->status = M860_BD_WRAP;
+  
+  /*
+   * Set up SCCx general and protocol-specific mode registers
+   */
+  sccregs->scce = 0xffff;
+  sccregs->sccm = 0x0000;
+  sccregs->gsmr_h = 0x00000020;
+  sccregs->gsmr_l = 0x00028004;
+  sccregs->psmr   = 0x3000;
+  sccregs->gsmr_l = 0x00028034;
+}
+
+void
+m860_smc_initialize (int port)  /* port is the SMC number (i.e. 1 or 2) */
+{
+  unsigned char brg;
+
+  /*
+   * Allocate buffer descriptors
+   */
+  RxBd[port-1] = M860AllocateBufferDescriptors (1);
+  TxBd[port-1] = M860AllocateBufferDescriptors (1);
+
+  /*
+   * Configure port B pins to enable SMTXDx and SMRXDx pins
+   */
+  m860.pbpar |=  (0xC0 << ((port-1) * 4));
+  m860.pbdir &= ~(0xC0 << ((port-1) * 4));
+  m860.pbdir |=  (0x01 << (port-1));
+  m860.pbodr &= ~(0xC0 << ((port-1) * 4));
+  m860.pbdat &= ~(0x01 << (port-1));
+  
+  /*
+   * Set up BRG1 (9,600 baud)
+   */
+  brg = m860_get_brg_clk(9600);     /* 4 BRGs, 5 serial ports - hopefully */ 
+                                    /*  at least 2 ports will be the same */
+
+  /*
+   * Put SMC in NMSI mode, connect SMC to BRG
+   */
+  m860.simode &= ~0x7000 << ((port-1) * 8);
+  m860.simode |= brg << (12 + ((port-1) * 8));
+
+  /*
+   * Set up SMC1 parameter RAM common to all protocols
+   */
+  if (port == 1) {
+    m860.smc1p.rbase = (char *)RxBd[port-1] - (char *)&m860;
+    m860.smc1p.tbase = (char *)TxBd[port-1] - (char *)&m860;
+    m860.smc1p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
+    m860.smc1p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
+    m860.smc1p.mrblr = RXBUFSIZE;
+    
+    /*
+     * Set up SMC1 parameter RAM UART-specific parameters
+     */
+    m860.smc1p.un.uart.max_idl = 10;
+    m860.smc1p.un.uart.brklen = 0;
+    m860.smc1p.un.uart.brkec = 0;
+    m860.smc1p.un.uart.brkcr = 0;
+    
+  }
+  else {
+    m860.smc2p.rbase = (char *)RxBd[port-1] - (char *)&m860;
+    m860.smc2p.tbase = (char *)TxBd[port-1] - (char *)&m860;
+    m860.smc2p.rfcr = M860_RFCR_MOT | M860_RFCR_DMA_SPACE(0);
+    m860.smc2p.tfcr = M860_TFCR_MOT | M860_TFCR_DMA_SPACE(0);
+    m860.smc2p.mrblr = RXBUFSIZE;
+    
+    /*
+     * Set up SMC2 parameter RAM UART-specific parameters
+     */
+    m860.smc2p.un.uart.max_idl = 10;
+    m860.smc2p.un.uart.brklen = 0;
+    m860.smc2p.un.uart.brkec = 0;
+    m860.smc2p.un.uart.brkcr = 0;
+  }      
+  
+  /*
+   * Set up the Receive Buffer Descriptor
+   */
+  RxBd[port-1]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                  M860_BD_INTERRUPT;
+  RxBd[port-1]->length = 0;
+  RxBd[port+3]->buffer = malloc(RXBUFSIZE);
+         
+  /*
+   * Setup the Transmit Buffer Descriptor
+   */
+  TxBd[port-1]->status = M860_BD_WRAP;
+  
+  /*
+   * Set up SMCx general and protocol-specific mode registers
+   */
+  if (port == 1) {
+    m860.smc1.smce = ~0;        /* Clear any pending events */
+    m860.smc1.smcm = 0; /* Mask all interrupt/event sources */
+    m860.smc1.smcmr = M860_SMCMR_CLEN(9) | M860_SMCMR_SM_UART;
+    
+    /*
+     * Send "Init parameters" command
+     */
+    M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SMC1);
+    
+    /*
+     * Enable receiver and transmitter
+     */
+    m860.smc1.smcmr |= M860_SMCMR_TEN | M860_SMCMR_REN;
+  }
+  else {
+    m860.smc2.smce = ~0;        /* Clear any pending events */
+    m860.smc2.smcm = 0; /* Mask all interrupt/event sources */
+    m860.smc2.smcmr = M860_SMCMR_CLEN(9) | M860_SMCMR_SM_UART;
+    
+    /*
+     * Send "Init parameters" command
+     */
+    M860ExecuteRISC (M860_CR_OP_INIT_RX_TX | M860_CR_CHAN_SMC2);
+    
+    /*
+     * Enable receiver and transmitter
+     */
+    m860.smc2.smcmr |= M860_SMCMR_TEN | M860_SMCMR_REN;
+  }
+}
+
+int
+m860_char_poll_read (int minor)
+{
+  unsigned char c;
+  rtems_unsigned32 level;
+
+  _CPU_ISR_Disable(level);  
+  if (RxBd[minor]->status & M860_BD_EMPTY) {
+    _CPU_ISR_Enable(level);
+    return -1;
+  }
+  c = ((char *)RxBd[minor]->buffer)[0];
+  RxBd[minor]->status = M860_BD_EMPTY | M860_BD_WRAP;
+  _CPU_ISR_Enable(level);
+  return c;
+}
+
+int
+m860_char_poll_write (int minor, const char *buf, int len)
+{
+  while (len--) {
+    while (TxBd[minor]->status & M860_BD_READY)
+      continue;
+    txBuf[minor] = *buf++;
+    TxBd[minor]->buffer = &txBuf[minor];
+    TxBd[minor]->length = 1;
+    TxBd[minor]->status = M860_BD_READY | M860_BD_WRAP;
+  }
+  return 0;
+}
+
+/*
+ * Interrupt handler
+ */
+rtems_isr
+m860_scc1_console_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Buffer received?
+   */
+  if ((m860.scc1.sccm & 0x1) && (m860.scc1.scce & 0x1)) {
+    m860.scc1.scce = 0x1;
+    /*    m860.scc1.sccm &= ~0x1;*/
+    
+    while ((RxBd[SCC1_MINOR]->status & M860_BD_EMPTY) == 0) {
+      rxBufListTail[SCC1_MINOR]->next = malloc(sizeof(Buf_t));
+      if (rxBufListTail[SCC1_MINOR]->next) {
+        rxBufListTail[SCC1_MINOR] = rxBufListTail[SCC1_MINOR]->next;
+        rxBufListTail[SCC1_MINOR]->buf = RxBd[SCC1_MINOR]->buffer;
+        rxBufListTail[SCC1_MINOR]->len = RxBd[SCC1_MINOR]->length;
+        rxBufListTail[SCC1_MINOR]->pos = 0;
+        rxBufListTail[SCC1_MINOR]->next = 0;
+
+        RxBd[SCC1_MINOR]->buffer = malloc(RXBUFSIZE);
+      }
+      RxBd[SCC1_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                 M860_BD_INTERRUPT;
+    }
+  }
+  
+  /*
+   * Buffer transmitted?
+   */
+#if 0
+  if (m860.smc1.smce & 0x2) {
+    m860.smc1.smce = 0x2;
+    if ((smcTxBd->status & M360_BD_READY) == 0)
+      rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
+  }
+#endif
+  m860.cisr = 1UL << 30;  /* Clear SCC1 interrupt-in-service bit */
+}
+
+rtems_isr
+m860_scc2_console_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Buffer received?
+   */
+  if ((m860.scc2.sccm & 0x1) && (m860.scc2.scce & 0x1)) {
+    m860.scc2.scce = 0x1;
+    /*    m860.scc2.sccm &= ~0x1;*/
+    
+    while ((RxBd[SCC2_MINOR]->status & M860_BD_EMPTY) == 0) {
+      rxBufListTail[SCC2_MINOR]->next = malloc(sizeof(Buf_t));
+      if (rxBufListTail[SCC2_MINOR]->next) {
+        rxBufListTail[SCC2_MINOR] = rxBufListTail[SCC2_MINOR]->next;
+        rxBufListTail[SCC2_MINOR]->buf = RxBd[SCC2_MINOR]->buffer;
+        rxBufListTail[SCC2_MINOR]->len = RxBd[SCC2_MINOR]->length;
+        rxBufListTail[SCC2_MINOR]->pos = 0;
+        rxBufListTail[SCC2_MINOR]->next = 0;
+
+        RxBd[SCC2_MINOR]->buffer = malloc(RXBUFSIZE);
+      }
+      RxBd[SCC2_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                 M860_BD_INTERRUPT;
+    }
+  }
+  
+  /*
+   * Buffer transmitted?
+   */
+#if 0
+  if (m860.smc1.smce & 0x2) {
+    m860.smc1.smce = 0x2;
+    if ((smcTxBd->status & M360_BD_READY) == 0)
+      rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
+  }
+#endif
+  m860.cisr = 1UL << 29;  /* Clear SCC2 interrupt-in-service bit */
+}
+
+rtems_isr
+m860_scc3_console_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Buffer received?
+   */
+  if ((m860.scc3.sccm & 0x1) && (m860.scc3.scce & 0x1)) {
+    m860.scc3.scce = 0x1;
+    /*    m860.scc3.sccm &= ~0x1;*/
+    
+    while ((RxBd[SCC3_MINOR]->status & M860_BD_EMPTY) == 0) {
+      rxBufListTail[SCC3_MINOR]->next = malloc(sizeof(Buf_t));
+      if (rxBufListTail[SCC3_MINOR]->next) {
+        rxBufListTail[SCC3_MINOR] = rxBufListTail[SCC3_MINOR]->next;
+        rxBufListTail[SCC3_MINOR]->buf = RxBd[SCC3_MINOR]->buffer;
+        rxBufListTail[SCC3_MINOR]->len = RxBd[SCC3_MINOR]->length;
+        rxBufListTail[SCC3_MINOR]->pos = 0;
+        rxBufListTail[SCC3_MINOR]->next = 0;
+
+        RxBd[SCC3_MINOR]->buffer = malloc(RXBUFSIZE);
+      }
+      RxBd[SCC3_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                 M860_BD_INTERRUPT;
+    }
+  }
+  
+  /*
+   * Buffer transmitted?
+   */
+#if 0
+  if (m860.smc1.smce & 0x2) {
+    m860.smc1.smce = 0x2;
+    if ((smcTxBd->status & M360_BD_READY) == 0)
+      rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
+  }
+#endif
+  m860.cisr = 1UL << 28;  /* Clear SCC3 interrupt-in-service bit */
+}
+
+rtems_isr
+m860_scc4_console_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Buffer received?
+   */
+  if ((m860.scc4.sccm & 0x1) && (m860.scc4.scce & 0x1)) {
+    m860.scc4.scce = 0x1;
+    /*    m860.scc4.sccm &= ~0x1;*/
+    
+    while ((RxBd[SCC4_MINOR]->status & M860_BD_EMPTY) == 0) {
+      rxBufListTail[SCC4_MINOR]->next = malloc(sizeof(Buf_t));
+      if (rxBufListTail[SCC4_MINOR]->next) {
+        rxBufListTail[SCC4_MINOR] = rxBufListTail[SCC4_MINOR]->next;
+        rxBufListTail[SCC4_MINOR]->buf = RxBd[SCC4_MINOR]->buffer;
+        rxBufListTail[SCC4_MINOR]->len = RxBd[SCC4_MINOR]->length;
+        rxBufListTail[SCC4_MINOR]->pos = 0;
+        rxBufListTail[SCC4_MINOR]->next = 0;
+
+        RxBd[SCC4_MINOR]->buffer = malloc(RXBUFSIZE);
+      }
+      RxBd[SCC4_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                 M860_BD_INTERRUPT;
+    }
+  }
+  
+  /*
+   * Buffer transmitted?
+   */
+#if 0
+  if (m860.smc1.smce & 0x2) {
+    m860.smc1.smce = 0x2;
+    if ((smcTxBd->status & M360_BD_READY) == 0)
+      rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
+  }
+#endif
+  m860.cisr = 1UL << 27;  /* Clear SCC4 interrupt-in-service bit */
+}
+
+rtems_isr
+m860_smc1_console_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Buffer received?
+   */
+  if (m860.smc1.smce & 0x1) {
+    m860.smc1.smce = 0x1;
+    /*    m860.scc2.sccm &= ~0x1;*/
+    
+    while ((RxBd[SMC1_MINOR]->status & M860_BD_EMPTY) == 0) {
+      rxBufListTail[SMC1_MINOR]->next = malloc(sizeof(Buf_t));
+      if (rxBufListTail[SMC1_MINOR]->next) {
+        rxBufListTail[SMC1_MINOR] = rxBufListTail[SMC1_MINOR]->next;
+        rxBufListTail[SMC1_MINOR]->buf = RxBd[SMC1_MINOR]->buffer;
+        rxBufListTail[SMC1_MINOR]->len = RxBd[SMC1_MINOR]->length;
+        rxBufListTail[SMC1_MINOR]->pos = 0;
+        rxBufListTail[SMC1_MINOR]->next = 0;
+
+        RxBd[SMC1_MINOR]->buffer = malloc(RXBUFSIZE);
+      }
+      RxBd[SMC1_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                 M860_BD_INTERRUPT;
+    }
+  }
+  
+  /*
+   * Buffer transmitted?
+   */
+#if 0
+  if (m860.smc1.smce & 0x2) {
+    m860.smc1.smce = 0x2;
+    if ((smcTxBd->status & M360_BD_READY) == 0)
+      rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
+  }
+#endif
+  m860.cisr = 1UL << 4;  /* Clear SMC1 interrupt-in-service bit */
+}
+
+rtems_isr
+m860_smc2_console_interrupt_handler (rtems_vector_number v)
+{
+  /*
+   * Buffer received?
+   */
+  if (m860.smc2.smce & 0x1) {
+    m860.smc2.smce = 0x1;
+    
+    while ((RxBd[SMC2_MINOR]->status & M860_BD_EMPTY) == 0) {
+      rxBufListTail[SMC2_MINOR]->next = malloc(sizeof(Buf_t));
+      if (rxBufListTail[SMC2_MINOR]->next) {
+        rxBufListTail[SMC2_MINOR] = rxBufListTail[SMC2_MINOR]->next;
+        rxBufListTail[SMC2_MINOR]->buf = RxBd[SMC2_MINOR]->buffer;
+        rxBufListTail[SMC2_MINOR]->len = RxBd[SMC2_MINOR]->length;
+        rxBufListTail[SMC2_MINOR]->pos = 0;
+        rxBufListTail[SMC2_MINOR]->next = 0;
+
+        RxBd[SMC2_MINOR]->buffer = malloc(RXBUFSIZE);
+      }
+      RxBd[SMC2_MINOR]->status = M860_BD_EMPTY | M860_BD_WRAP | 
+                                 M860_BD_INTERRUPT;
+    }
+  }
+  
+  /*
+   * Buffer transmitted?
+   */
+#if 0
+  if (m860.smc1.smce & 0x2) {
+    m860.smc1.smce = 0x2;
+    if ((smcTxBd->status & M360_BD_READY) == 0)
+      rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
+  }
+#endif
+  m860.cisr = 1UL << 3;  /* Clear SMC2 interrupt-in-service bit */
+}
+
+
+int
+m860_buf_poll_read (int minor, char **buf)
+{
+  int len;
+
+  if (RxBd[minor]->status & M860_BD_EMPTY)
+    return -1;
+  
+  RxBd[minor]->buffer = malloc(RXBUFSIZE); /* I hope this succeeds ... */
+  len = RxBd[minor]->length;
+  RxBd[minor]->status = M860_BD_EMPTY | M860_BD_WRAP;
+  
+  return len;
+}
+
+int
+m860_buf_poll_write (int minor, char *buf, int len)
+{
+  static char *last_buf[6];
+
+  while (TxBd[minor]->status & M860_BD_READY)
+    continue;
+  if (last_buf[minor])
+    free(last_buf[minor]);
+  last_buf[minor] = buf;
+  TxBd[minor]->buffer = buf;
+  TxBd[minor]->length = len;
+  TxBd[minor]->status = M860_BD_READY | M860_BD_WRAP;
+  return 0;
+}
+
+/*
+ * This is needed in case we use TERMIOS
+ */
+void m860_console_reserve_resources(rtems_configuration_table *configuration)
+{
+  rtems_termios_reserve_resources (configuration, 1);
+}
+
+void m860_console_initialize(void)
+{
+  int i;
+
+  for (i=0; i < NIFACES; i++) {
+    rxBufList[i] = malloc(sizeof(Buf_t));
+    rxBufListTail[i] = rxBufList[i];
+    rxBufList[i]->buf  = 0;
+    rxBufList[i]->len  = 0;
+    rxBufList[i]->pos  = 0;
+    rxBufList[i]->next = 0;
+  }
+}
+
+rtems_device_driver m860_console_read(rtems_device_major_number major,
+                                      rtems_device_minor_number minor,
+                                      void *arg)
+{
+  rtems_libio_rw_args_t *rw_args;
+  char *buffer;
+  int maximum;
+  int count;
+  Buf_t *tmp_buf;
+  rtems_unsigned32 level;
+
+  /*
+   * Set up interrupts
+   * FIXME: DANGER: WARNING:
+   * CICR and SIMASK must be set in any module that uses
+   *   the CPM. Currently those are console-generic.c and
+   *   network.c. If the registers are not set the same
+   *   in both places, strange things may happen.
+   *   If they are only set in one place, then an application
+   *   that used the other module won't work correctly.
+   *   Put this comment in each module that sets these 2 registers
+   */
+  m860.cicr = 0x00e43e80;   /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3, 
+			       SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
+  m860.simask |= M860_SIMASK_LVM1; 
+
+  rw_args = (rtems_libio_rw_args_t *) arg;
+  buffer = rw_args->buffer;
+  maximum = rw_args->count;
+  count = 0;
+
+  while (count == 0) {
+    if (rxBufList[minor]->len) {
+      while ((count < maximum) && 
+             (rxBufList[minor]->pos < rxBufList[minor]->len)) {
+        buffer[count++] = rxBufList[minor]->buf[rxBufList[minor]->pos++];
+      }
+      _CPU_ISR_Disable(level);
+      if (rxBufList[minor]->pos == rxBufList[minor]->len) {
+        if (rxBufList[minor]->next) {
+          tmp_buf=rxBufList[minor]->next;
+          free (rxBufList[minor]->buf);
+          free (rxBufList[minor]);
+          rxBufList[minor]=tmp_buf;
+        }
+        else {
+          free(rxBufList[minor]->buf);
+          rxBufList[minor]->buf=0;
+          rxBufList[minor]->len=0;
+          rxBufList[minor]->pos=0;
+        }
+      }
+      _CPU_ISR_Enable(level);
+    }
+    else
+      if(rxBufList[minor]->next && !rxBufList[minor]->len) {
+        tmp_buf = rxBufList[minor];
+        rxBufList[minor] = rxBufList[minor]->next;
+        free(tmp_buf);
+      }
+    /*      sleep(1);*/
+  }
+  rw_args->bytes_moved = count;
+  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
+}
+  
+rtems_device_driver m860_console_write(rtems_device_major_number major,
+                                       rtems_device_minor_number minor,
+                                       void *arg)
+{
+  int count;
+  int maximum;
+  rtems_libio_rw_args_t *rw_args;
+  char *in_buffer;
+  char *out_buffer;
+  int n;
+
+  /*
+   * Set up interrupts
+   * FIXME: DANGER: WARNING:
+   * CICR and SIMASK must be set in any module that uses
+   *   the CPM. Currently those are console-generic.c and
+   *   network.c. If the registers are not set the same
+   *   in both places, strange things may happen.
+   *   If they are only set in one place, then an application
+   *   that used the other module won't work correctly.
+   *   Put this comment in each module that sets these 2 registers
+   */
+/*  m860.cicr = 0x00e43e80;   /* SCaP=SCC1, SCbP=SCC2, SCcP=SCC3, 
+			       SCdP=SCC4, IRL=1, HP=SCC1, IEN=1 */
+/*  m860.simask |= M860_SIMASK_LVM1;  */
+
+  rw_args = (rtems_libio_rw_args_t *) arg;
+
+  in_buffer = rw_args->buffer;
+  maximum = rw_args->count;
+
+  out_buffer = malloc(maximum*2);  /* This is wasteful, but it won't */
+                                   /*  be too small */
+
+  if (!out_buffer) {
+    rw_args->bytes_moved = 0;
+    return RTEMS_NO_MEMORY;
+  }
+  n=0;
+  for (count = 0; count < maximum; count++) {
+    if ( in_buffer[ count ] == '\n') {
+      out_buffer[count + n] = '\r';
+      n++;
+    }
+    out_buffer[count + n] = in_buffer[count];
+  }
+  m860_buf_poll_write(minor, out_buffer, maximum+n);
+  rw_args->bytes_moved = maximum;
+  return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ *  How to use the console. 
+ *   In your BSP, have the following functions:
+ *
+ *  rtems_device_driver console_initialize(rtems_device_major_number  major,
+ *                                         rtems_device_minor_number  minor,
+ *                                         void *arg)
+ *  rtems_device_driver console_open(rtems_device_major_number major,
+ *                                   rtems_device_minor_number minor,
+ *                                   void *arg)
+ *  rtems_device_driver console_close(rtems_device_major_number major,
+ *                                    rtems_device_minor_number minor,
+ *                                    void *arg)
+ *  rtems_device_driver console_read(rtems_device_major_number major,
+ *                                   rtems_device_minor_number minor,
+ *                                   void *arg)
+ *  rtems_device_driver console_write(rtems_device_major_number major,
+ *                                    rtems_device_minor_number minor,
+ *                                    void *arg)
+ *  rtems_device_driver console_control(rtems_device_major_number major,
+ *                                      rtems_device_minor_number minor,
+ *                                      void *arg)
+ *
+ */
Index: c/src/lib/libcpu/powerpc/mpc860/include/Makefile.in
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/include/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/include/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,29 @@
+#
+#  $Id$
+#
+# Install any include files needed by libcpu.
+# Mainly this just means bsp.h which would normally be installed
+# after libcpu is built.
+# This is a bit of a hack.
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+H_FILES = $(wildcard $(srcdir)/*.h)
+SRCS=$(H_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+all:	install
+
+install:
+	test -d $(PROJECT_INCLUDE)/mpc860 || $(MKDIR) $(PROJECT_INCLUDE)/mpc860
+	$(INSTALL) -m 444 $(H_FILES) $(PROJECT_INCLUDE)/mpc860
+
+all: FORCEIT
+	cd ../../../../libbsp/$(RTEMS_CPU)/$(RTEMS_BSP)/include; $(MAKE) all
+
Index: c/src/lib/libcpu/powerpc/mpc860/include/console.h
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/include/console.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/include/console.h	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,44 @@
+#ifndef _M860_CONSOLE_H_
+#define _M860_CONSOLE_H_
+
+#include <rtems/libio.h>
+
+int m860_smc_set_attributes(int, const struct termios*);
+int m860_scc_set_attributes(int, const struct termios*);
+void m860_scc_initialize(int);
+void m860_smc_initialize(int);
+int m860_char_poll_read(int);
+int m860_char_poll_write(int, const char*, int);
+rtems_isr m860_scc1_console_interrupt_handler(rtems_vector_number);
+rtems_isr m860_scc2_console_interrupt_handler(rtems_vector_number);
+rtems_isr m860_scc3_console_interrupt_handler(rtems_vector_number);
+rtems_isr m860_scc4_console_interrupt_handler(rtems_vector_number);
+rtems_isr m860_smc1_console_interrupt_handler(rtems_vector_number);
+rtems_isr m860_smc2_console_interrupt_handler(rtems_vector_number);
+int m860_buf_poll_read(int, char**);
+int m860_buf_poll_write(int, char*, int);
+void m860_console_initialize(void);
+rtems_device_driver m860_console_read(rtems_device_major_number,
+				      rtems_device_minor_number,
+				      void*);
+rtems_device_driver m860_console_write(rtems_device_major_number,
+				       rtems_device_minor_number,
+				       void*);
+
+
+typedef struct Buf_t_ {
+  struct Buf_t_ *next;
+  volatile char *buf;
+  volatile int   len;
+  int   pos;
+} Buf_t;
+
+#define SMC1_MINOR    0
+#define SMC2_MINOR    1
+#define SCC1_MINOR    2
+#define SCC2_MINOR    3
+#define SCC3_MINOR    4
+#define SCC4_MINOR    5
+
+
+#endif
Index: c/src/lib/libcpu/powerpc/mpc860/timer/Makefile.in
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/timer/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/timer/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,60 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/timer.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=timer
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=
+S_FILES=$(S_PIECES:%=%.s)
+S_O_FILES=$(S_FILES:%.s=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   += $(CFLAGS_OS_V)
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by
+#    libbsp/hppa/BSP/wrapup/Makefile
+install:  all
Index: c/src/lib/libcpu/powerpc/mpc860/timer/timer.c
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/timer/timer.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/timer/timer.c	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,104 @@
+/*  timer.c
+ *
+ *  This file manages the interval timer on the PowerPC MPC860.
+ *  NOTE: This is not the PIT, but rather the RTEMS interval
+ *        timer
+ *  We shall use the bottom 32 bits of the timebase register,
+ *
+ *  The following was in the 403 version of this file. I don't
+ *  know what it means. JTM 5/19/98
+ *  NOTE: It is important that the timer start/stop overhead be
+ *        determined when porting or modifying this code.
+ *
+ *  Author: Jay Monkman (jmonkman@frasca.com)
+ *  Copywright (C) 1998 by Frasca International, Inc.
+ *
+ *  Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
+ *
+ *  Author:     Andrew Bray <andy@i-cubed.co.uk>
+ *
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ *  Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
+ *
+ *  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.
+ *
+ *  $Id$
+ */
+
+#include <bsp.h>
+#include <rtems.h>
+#include <mpc860.h>
+
+extern rtems_cpu_table           Cpu_table;             /* owned by BSP */
+
+static volatile rtems_unsigned32 Timer_starting;
+static rtems_boolean Timer_driver_Find_average_overhead;
+
+/*
+ *  This is so small that this code will be reproduced where needed.
+ */
+static inline rtems_unsigned32 get_itimer(void)
+{
+   rtems_unsigned32 ret;
+
+   asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
+
+   return ret;
+}
+
+void Timer_initialize(void)
+{
+  /* set interrupt level and enable timebase. This should never */
+  /*  generate an interrupt however. */
+  m860.tbscr |= M860_TBSCR_TBIRQ(4) | M860_TBSCR_TBE;
+  
+  Timer_starting = get_itimer();
+}
+
+int Read_timer(void)
+{
+  rtems_unsigned32 clicks;
+  rtems_unsigned32 total;
+
+  clicks = get_itimer();
+
+  total = clicks - Timer_starting;
+
+  if ( Timer_driver_Find_average_overhead == 1 )
+    return total;          /* in XXX microsecond units */
+
+  else {
+    if ( total < Cpu_table.timer_least_valid ) {
+      return 0;            /* below timer resolution */
+    }
+    return (total - Cpu_table.timer_average_overhead);
+  }
+}
+
+rtems_status_code Empty_function(void)
+{
+  return RTEMS_SUCCESSFUL;
+}
+
+void Set_find_average_overhead(rtems_boolean find_flag)
+{
+  Timer_driver_Find_average_overhead = find_flag;
+}
Index: c/src/lib/libcpu/powerpc/mpc860/vectors/Makefile.in
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/vectors/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/vectors/Makefile.in	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,59 @@
+#
+#  $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/vectors.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+# Assembly source names, if any, go here -- minus the .s
+S_PIECES=vectors align_h
+S_FILES=$(S_PIECES:%=%.S)
+S_O_FILES=$(S_FILES:%.S=${ARCH}/%.o)
+
+SRCS=$(C_FILES) $(CC_FILES) $(H_FILES) $(S_FILES)
+OBJS=$(C_O_FILES) $(CC_O_FILES) $(S_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES  +=
+CPPFLAGS +=
+CFLAGS   +=
+
+LD_PATHS  +=
+LD_LIBS   +=
+LDFLAGS   +=
+
+#
+# Add your list of files to delete here.  The config files
+#  already know how to delete some stuff, so you may want
+#  to just run 'make clean' first to see what gets missed.
+#  'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+	$(make-rel)
+
+all:	${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install:  all
Index: c/src/lib/libcpu/powerpc/mpc860/vectors/README
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/vectors/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/vectors/README	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,25 @@
+#
+#  $Id$
+#
+
+The location of the vectors file object is critical.
+
+From the comments at the head of vectors.s:
+
+  The issue with this file is getting it loaded at the right place.
+  The first vector MUST be at address 0x????0100.
+  How this is achieved is dependant on the tool chain.
+
+  However the basic mechanism for ELF assemblers is to create a
+  section called ".vectors", which will be loaded to an address
+  between 0x????0000 and 0x????0100 (inclusive) via a link script.
+
+  The basic mechanism for XCOFF assemblers is to place it in the
+  normal text section, and arrange for this file to be located
+  at an appropriate position on the linker command line.
+
+  The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
+  offset from 0x????0000 to the first location in the file.  This
+  will usually be 0x0000 or 0x0100.
+
+Andrew Bray 18/8/1995
Index: c/src/lib/libcpu/powerpc/mpc860/vectors/align_h.S
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/vectors/align_h.S	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/vectors/align_h.S	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,435 @@
+/*  align_h.s	1.1 - 95/12/04
+ *
+ *  This file contains the assembly code for the PowerPC 403
+ *  alignment exception handler for RTEMS.
+ *
+ *  Based upon IBM provided code with the following release:
+ *
+ *  This source code has been made available to you by IBM on an AS-IS
+ *  basis.  Anyone receiving this source is licensed under IBM
+ *  copyrights to use it in any way he or she deems fit, including
+ *  copying it, modifying it, compiling it, and redistributing it either
+ *  with or without modifications.  No license under IBM patents or
+ *  patent applications is to be implied by the copyright license.
+ *
+ *  Any user of this software should understand that IBM cannot provide
+ *  technical support for this software and will not be responsible for
+ *  any consequences resulting from the use of this software.
+ *
+ *  Any person who transfers this source code or any derivative work
+ *  must include the IBM copyright notice, this paragraph, and the
+ *  preceding two paragraphs in the transferred software.
+ *
+ *      COPYRIGHT   I B M   CORPORATION 1995
+ *      LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ *
+ * Modifications:
+ *
+ *  Author:	Andrew Bray <andy@i-cubed.co.uk>
+ *
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ *  $Id$
+ */
+
+#include "asm.h"
+/*#include "bsp.h"*/
+#define ALIGN_REGS 0x0140
+
+.set    CACHE_SIZE,16           # cache line size of 32 bytes
+.set    CACHE_SIZE_L2,4         # cache line size, log 2
+
+.set	Open_gpr0,0
+.set	Open_gpr1,4
+.set	Open_gpr2,8
+.set	Open_gpr3,12
+.set	Open_gpr4,16
+.set	Open_gpr5,20
+.set	Open_gpr6,24
+.set	Open_gpr7,28
+.set	Open_gpr8,32
+.set	Open_gpr9,36
+.set	Open_gpr10,40
+.set	Open_gpr11,44
+.set	Open_gpr12,48
+.set	Open_gpr13,52
+.set	Open_gpr14,56
+.set	Open_gpr15,60
+.set	Open_gpr16,64
+.set	Open_gpr17,68
+.set	Open_gpr18,72
+.set	Open_gpr19,76
+.set	Open_gpr20,80
+.set	Open_gpr21,84
+.set	Open_gpr22,88
+.set	Open_gpr23,92
+.set	Open_gpr24,96
+.set	Open_gpr25,100
+.set	Open_gpr26,104
+.set	Open_gpr27,108
+.set	Open_gpr28,112
+.set	Open_gpr29,116
+.set	Open_gpr30,120
+.set	Open_gpr31,124
+.set	Open_xer,128
+.set	Open_lr,132
+.set	Open_ctr,136
+.set	Open_cr,140
+.set	Open_srr2,144
+.set	Open_srr3,148
+.set	Open_srr0,152
+.set	Open_srr1,156
+
+
+/*
+ *  This code makes several assumptions for processing efficiency
+ *  *  General purpose registers are continuous in the image, beginning with
+ *     Open_gpr0
+ *  *  Hash table is highly dependent on opcodes - opcode changes *will*
+ *     require rework of the instruction decode mechanism.
+ */
+
+        .text
+        .globl  align_h
+
+	.align	CACHE_SIZE_L2
+align_h:
+        /*-----------------------------------------------------------------------
+         * Store GPRs in Open Reg save area
+         * Set up r2 as base reg, r1 pointing to Open Reg save area
+         *----------------------------------------------------------------------*/
+        stmw    r0,ALIGN_REGS(r0)
+	li	r1,ALIGN_REGS
+        /*-----------------------------------------------------------------------
+         * Store special purpose registers in reg save area
+         *----------------------------------------------------------------------*/
+        mfxer   r7
+        mflr    r8
+        mfcr    r9
+        mfctr   r10
+        stw     r7,Open_xer(r1)
+        stw     r8,Open_lr(r1)
+        stw     r9,Open_cr(r1)
+        stw     r10,Open_ctr(r1)
+        mfspr	r7, srr2		/* SRR 2 */
+        mfspr	r8, srr3		/* SRR 3 */
+        mfspr	r9, srr0		/* SRR 0 */
+        mfspr	r10, srr1		/* SRR 1 */
+        stw     r7,Open_srr2(r1)
+        stw     r8,Open_srr3(r1)
+        stw     r9,Open_srr0(r1)
+        stw     r10,Open_srr1(r1)
+
+/*      Set up common registers */
+        mfspr	r5, dear		/* DEAR: R5 is data exception address */
+        lwz     r9,Open_srr0(r1)        /* get faulting instruction */
+        addi    r7,r9,4                 /* bump instruction */
+        stw     r7,Open_srr0(r1)        /* restore to image */
+        lwz     r9, 0(r9)               /* retrieve actual instruction */
+        rlwinm  r6,r9,18,25,29          /* r6 is RA * 4 field from instruction */
+        rlwinm  r7,r9,6,26,31           /* r7 is primary opcode */
+        bl      ref_point               /* establish addressibility */
+ref_point:
+        mflr    r11                     /* r11 is the anchor point for ref_point */
+        addi    r10, r7, -31            /* r10 = r7 - 31 */
+        rlwinm  r10,r10,2,2,31          /* r10 *= 4 */
+        add     r10, r10, r11           /* r10 += anchor point */
+        lwz     r10, primary_jt-ref_point(r10)
+        mtlr    r10
+        rlwinm  r8,r9,13,25,29          /* r8 is RD * 4 */
+        la      r7,Open_gpr0(r1)        /* r7 is address of GPR 0 in list */
+        blr
+primary_jt:
+        .long   xform
+        .long   lwz
+        .long   lwzu
+        .long   0
+        .long   0
+        .long   stw
+        .long   stwu
+        .long   0
+        .long   0
+        .long   lhz
+        .long   lhzu
+        .long   lha
+        .long   lhau
+        .long   sth
+        .long   sthu
+        .long   lmw
+        .long   stmw
+/*
+ *   handlers
+ */
+/*
+ * xform instructions require an additional decode.  Fortunately, a relatively
+ * simple hash step breaks the instructions out with no collisions
+ */
+xform:
+        rlwinm  r7,r9,31,22,31          /* r7 is secondary opcode */
+        rlwinm  r10,r7,27,5,31          /* r10 = r7 >> 5 */
+        add     r10,r7,r10              /* r10 = r7 + r10 */
+        rlwinm  r10,r10,2,25,29         /* r10 = (r10 & 0x1F) * 4 */
+        add     r10,r10,r11             /* r10 += anchor point */
+        lwz     r10, secondary_ht-ref_point(r10)
+        mtlr    r10
+        la      r7,Open_gpr0(r1)        /* r7 is address of GPR 0 in list */
+        rlwinm  r8,r9,13,25,29          /* r8 is RD * 4 */
+        blrl
+
+secondary_ht:
+        .long   lhzux                   /* b 0  0x137 */
+        .long   lhax                    /* b 1  0x157 */
+        .long   lhaux                   /* b 2  0x177 */
+        .long   sthx                    /* b 3  0x197 */
+        .long   sthux                   /* b 4  0x1b7 */
+        .long   0                       /* b 5 */
+        .long   lwbrx                   /* b 6  0x216 */
+        .long   0                       /* b 7 */
+        .long   0                       /* b 8 */
+        .long   0                       /* b 9 */
+        .long   stwbrx                  /* b A  0x296 */
+        .long   0                       /* b B */
+        .long   0                       /* b C */
+        .long   0                       /* b D */
+        .long   lhbrx                   /* b E   0x316 */
+        .long   0                       /* b F */
+        .long   0                       /* b 10 */
+        .long   0                       /* b 11 */
+        .long   sthbrx                  /* b 12  0x396 */
+        .long   0                       /* b 13 */
+        .long   lwarx                   /* b 14  0x014 */
+        .long   dcbz                    /* b 15  0x3f6 */
+        .long   0                       /* b 16 */
+        .long   lwzx                    /* b 17  0x017 */
+        .long   lwzux                   /* b 18  0x037 */
+        .long   0                       /* b 19 */
+        .long   stwcx                   /* b 1A  0x096 */
+        .long   stwx                    /* b 1B  0x097 */
+        .long   stwux                   /* b 1C  0x0B7 */
+        .long   0                       /* b 1D */
+        .long   0                       /* b 1E */
+        .long   lhzx                    /* b 1F 0x117 */
+
+/*
+ * for all handlers
+ *       r4 - Addressability to interrupt context
+ *       r5 - DEAR address (faulting data address)
+ *       r6 - RA field * 4
+ *       r7 - Address of GPR 0 in image
+ *       r8 - RD field * 4
+ *       r9 - Failing instruction
+ */
+
+/*       Load halfword algebraic with update */
+lhau:
+/*       Load halfword algebraic with update indexed */
+lhaux:
+        stwx    r5,r7,r6                /* update RA with effective addr */
+
+/*       Load halfword algebraic */
+lha:
+/*       Load halfword algebraic indexed */
+lhax:
+        lswi    r10,r5,2                /* load two bytes into r10 */
+        srawi   r10,r10,16              /* shift right 2 bytes, extending sign */
+        stwx    r10,r7,r8               /* update reg image */
+        b       align_complete          /* return */
+
+/*       Load Half Word Byte-Reversed Indexed */
+lhbrx:
+        lswi    r10,r5,2                /* load two bytes from DEAR into r10 */
+        rlwinm  r10,r10,0,0,15          /* mask off lower 2 bytes */
+        stwbrx  r10,r7,r8               /* store reversed in reg image */
+        b       align_complete          /* return */
+
+/*       Load Half Word and Zero with Update */
+lhzu:
+/*       Load Half Word and Zero with Update Indexed */
+lhzux:
+        stwx    r5,r7,r6                /* update RA with effective addr */
+
+/*       Load Half Word and Zero */
+lhz:
+/*       Load Half Word and Zero Indexed */
+lhzx:
+        lswi    r10,r5,2                /* load two bytes from DEAR into r10 */
+        rlwinm  r10,r10,16,16,31        /* shift right 2 bytes, with zero fill */
+        stwx    r10,r7,r8               /* update reg image */
+        b       align_complete          /* return */
+
+/*
+ *       Load Multiple Word
+ */
+lmw:
+        lwzx    r9,r6,r7                /* R9 contains saved value of RA */
+        addi    r10,r7,32*4             /* r10 points to r31 in image  + 4 */
+        rlwinm  r8,r8,30,2,31           /* r8 >>= 2  (recovers RT) */
+        subfic  r8,r8,32                /* r8 is reg count to load */
+        mtctr   r8                      /* load counter */
+        addi    r8,r8,-1                /* r8-- */
+        rlwinm  r8,r8,2,2,31            /* r8 *= 4 */
+        add     r5,r5,r8                /* update DEAR to point to last reg */
+lwmloop:
+        lswi    r11,r5,4                /* load r11 with 4 bytes from DEAR */
+        stwu    r11,-4(r10)             /* load image and decrement pointer */
+        addi    r5,r5,-4                /* decrement effective address */
+        bdnz    lwmloop
+        stwx    r9,r6,r7                /* restore RA (in case it was trashed) */
+        b       align_complete          /* return */
+
+/*
+ *       Load Word and Reserve Indexed
+ */
+lwarx:
+        lswi    r10,r5,4                /* load four bytes from DEAR into r10 */
+        stwx    r10,r7,r8               /* update reg image */
+        rlwinm  r5,r5,0,0,29            /* Word align address */
+        lwarx   r10,0,r5                /* Set reservation */
+        b       align_complete          /* return */
+
+/*
+ *       Load Word Byte-Reversed Indexed
+ */
+lwbrx:
+        lswi    r10,r5,4                /* load four bytes from DEAR into r10 */
+        stwbrx  r10,r7,r8               /* store reversed in reg image */
+        b       align_complete          /* return */
+
+/*       Load Word and Zero with Update */
+lwzu:
+/*       Load Word and Zero with Update Indexed */
+lwzux:
+        stwx    r5,r7,r6                /* update RA with effective addr */
+
+/*       Load Word and Zero */
+lwz:
+/*       Load Word and Zero Indexed */
+lwzx:
+        lswi    r10,r5,4                /* load four bytes from DEAR into r10 */
+        stwx    r10,r7,r8               /* update reg image */
+        b       align_complete          /* return */
+
+/*    Store instructions */
+
+/* */
+/*       Store Half Word and Update */
+sthu:
+/*       Store Half Word and Update Indexed */
+sthux:
+        stwx    r5,r7,r6                /* Update RA with effective address */
+
+/*       Store Half Word */
+sth:
+/*       Store Half Word Indexed */
+sthx:
+        lwzx    r10,r8,r7               /* retrieve source register value */
+        rlwinm  r10,r10,16,0,15         /* move two bytes to high end of reg */
+        stswi   r10,r5,2                /* store bytes to DEAR address */
+        b       align_complete          /* return */
+
+/* */
+/*       Store Half Word Byte-Reversed Indexed */
+sthbrx:
+        lwbrx   r10,r8,r7               /* retrieve src reg value byte reversed */
+        stswi   r10,r5,2                /* move two bytes to DEAR address */
+        b       align_complete          /* return */
+
+/* */
+/*       Store Multiple Word */
+stmw:
+        addi    r10,r7,32*4             /* r10 points to r31 in image  + 4 */
+        rlwinm  r8,r8,30,2,31           /* r8 >>= 2  (recovers RT) */
+        subfic  r8,r8,32                /* r8 is reg count to load */
+        mtctr   r8                      /* load counter */
+        addi    r8,r8,-1                /* r8-- */
+        rlwinm  r8,r8,2,2,31            /* r8 *= 4 */
+        add     r5,r5,r8                /* update DEAR to point to last reg */
+stmloop:
+        lwzu    r11,-4(r10)             /* get register value */
+        stswi   r11,r5,4                /* output to DEAR address */
+        addi    r5,r5,-4                /* decrement effective address */
+        bdnz    stmloop
+        b       align_complete          /* return */
+
+/* */
+/*       Store Word and Update */
+stwu:
+/*       Store Word and Update Indexed */
+stwux:
+        stwx    r5,r7,r6                /* Update RA with effective address */
+
+/*       Store Word */
+stw:
+/*       Store Word Indexed */
+stwx:
+        lwzx    r10,r8,r7               /* retrieve source register value */
+        stswi   r10,r5,4                /* store bytes to DEAR address */
+        b       align_complete          /* return */
+
+/* */
+/*       Store Word Byte-Reversed Indexed */
+stwbrx:
+        lwbrx   r10,r8,r7               /* retrieve src reg value byte reversed */
+        stswi   r10,r5,4                /* move two bytes to DEAR address */
+        b       align_complete          /* return */
+
+/* */
+/*       Store Word Conditional Indexed */
+stwcx:
+        rlwinm  r10,r5,0,0,29           /* r10 = word aligned DEAR */
+        lwz     r11,0(r10)              /* save original value of store */
+        stwcx.  r11,r0,r10              /* attempt store to address */
+        bne     stwcx_moveon            /* store failed, move on */
+        stw     r11,0(r10)              /* repair damage */
+        lwzx    r9,r7,r8                /* get register value */
+        stswi   r10,r5,4                /* store bytes to DEAR address */
+stwcx_moveon:
+        mfcr    r11                     /* get condition reg */
+        lwz     r9,Open_cr(r1)          /* get condition reg image */
+        rlwimi  r9,r11,0,0,2            /* insert 3 CR bits into cr image */
+        lwz     r11,Open_xer(r1)        /* get XER reg */
+        rlwimi  r9,r11,29,2,2           /* insert XER SO bit into cr image */
+        stw     r9,Open_cr(r1)          /* store cr image */
+        b       align_complete          /* return */
+
+/* */
+/*       Data Cache Block Zero */
+dcbz:
+        rlwinm  r5,r5,0,0,31-CACHE_SIZE_L2
+                                        /* get address to nearest Cache line */
+        addi    r5,r5,-4                /* adjust by a word */
+        addi    r10,r0,CACHE_SIZE/4     /* set counter value */
+        mtctr   r10
+        addi    r11,r0,0                /* r11 = 0 */
+dcbz_loop:
+        stwu    r11,4(r5)               /* store a word and update EA */
+        bdnz    dcbz_loop
+        b       align_complete          /* return */
+
+align_complete:
+        /*-----------------------------------------------------------------------
+         * Restore regs and return from the interrupt
+         *----------------------------------------------------------------------*/
+        lmw     r24,Open_xer+ALIGN_REGS(r0)
+        mtxer   r24
+        mtlr    r25
+        mtctr   r26
+        mtcrf   0xFF, r27
+        mtspr	srr2, r28		/* SRR 2 */
+        mtspr	srr3, r29		/* SRR 3 */
+        mtspr	srr0, r30		/* SRR 0 */
+        mtspr	srr1, r31		/* SRR 1 */
+        lmw     r1,Open_gpr1+ALIGN_REGS(r0)
+        lwz     r0,Open_gpr0+ALIGN_REGS(r0)
+        rfi
Index: c/src/lib/libcpu/powerpc/mpc860/vectors/vectors.S
===================================================================
--- c/src/lib/libcpu/powerpc/mpc860/vectors/vectors.S	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
+++ c/src/lib/libcpu/powerpc/mpc860/vectors/vectors.S	(revision ee733965291f61dd959c0f75659b0482df7a64ca)
@@ -0,0 +1,952 @@
+/*  vectors.s	1.1 - 95/12/04
+ *
+ *  This file contains the assembly code for the PowerPC MPC860
+ *  interrupt veneers for RTEMS.
+ * 
+ *  Author: Jay Monkman (jmonkman@frasca.com)
+ *
+ *  Copyright (C) 1998 by Frasca International, Inc.
+ *
+ *  Derived from c/src/lib/libcpu/ppc/ppc403/vectors/vectors.s:
+ *
+ *  Author:	Andrew Bray <andy@i-cubed.co.uk>
+ *
+ *  COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ *  To anyone who acknowledges that this file is provided "AS IS"
+ *  without any express or implied warranty:
+ *      permission to use, copy, modify, and distribute this file
+ *      for any purpose is hereby granted without fee, provided that
+ *      the above copyright notice and this notice appears in all
+ *      copies, and that the name of i-cubed limited not be used in
+ *      advertising or publicity pertaining to distribution of the
+ *      software without specific, written prior permission.
+ *      i-cubed limited makes no representations about the suitability
+ *      of this software for any purpose.
+ *
+ */
+
+/*
+ *  The issue with this file is getting it loaded at the right place.
+ *  The first vector MUST be at address 0x????0100.
+ *  How this is achieved is dependant on the tool chain.
+ *
+ *  However the basic mechanism for ELF assemblers is to create a
+ *  section called ".vectors", which will be loaded to an address
+ *  between 0x????0000 and 0x????0100 (inclusive) via a link script.
+ *
+ *  The basic mechanism for XCOFF assemblers is to place it in the
+ *  normal text section, and arrange for this file to be located
+ *  at an appropriate position on the linker command line.
+ *
+ *  The variable 'PPC_VECTOR_FILE_BASE' must be defined to be the
+ *  offset from 0x????0000 to the first location in the file.  This
+ *  will be either 0x0000 or 0xfff0.
+ *
+ *  $Id$
+ */
+
+#include "asm.h"
+#include <mpc860.h>
+
+#ifndef PPC_VECTOR_FILE_BASE
+#error "PPC_VECTOR_FILE_BASE is not defined."
+#endif
+
+	/* Where this file will be loaded */
+	.set	file_base, PPC_VECTOR_FILE_BASE
+
+	/* Offset to store reg 0 */
+
+	.set	IP_LINK, 0
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+	.set	IP_0, (IP_LINK + 56)
+#else
+	.set	IP_0, (IP_LINK + 8)
+#endif
+	.set	IP_2, (IP_0 + 4)
+
+	.set	IP_3, (IP_2 + 4)
+	.set	IP_4, (IP_3 + 4)
+	.set	IP_5, (IP_4 + 4)
+	.set	IP_6, (IP_5 + 4)
+	
+	.set	IP_7, (IP_6 + 4)
+	.set	IP_8, (IP_7 + 4)
+	.set	IP_9, (IP_8 + 4)
+	.set	IP_10, (IP_9 + 4)
+	
+	.set	IP_11, (IP_10 + 4)
+	.set	IP_12, (IP_11 + 4)
+	.set	IP_13, (IP_12 + 4)
+	.set	IP_28, (IP_13 + 4)
+	
+	.set	IP_29, (IP_28 + 4)
+	.set	IP_30, (IP_29 + 4)
+	.set	IP_31, (IP_30 + 4)
+	.set	IP_CR, (IP_31 + 4)
+	
+	.set	IP_CTR, (IP_CR + 4)
+	.set	IP_XER, (IP_CTR + 4)
+	.set	IP_LR, (IP_XER + 4)
+	.set	IP_PC, (IP_LR + 4)
+	
+	.set	IP_MSR, (IP_PC + 4)
+	
+	.set	IP_END, (IP_MSR + 16)
+
+	/* Vector offsets			 */
+	.set    begin_vector,     0x0000
+	.set    reset_vector,     0x0100
+	.set    mach_vector,      0x0200
+	.set    dsi_vector,       0x0300
+	.set    isi_vector,       0x0400
+	.set    ext_vector,       0x0500
+	.set    align_vector,     0x0600
+	.set    prog_vector,      0x0700
+	.set    float_vector,     0x0800
+	.set    dec_vector,       0x0900
+	.set    sys_vector,       0x0C00
+	.set    trace_vector,     0x0d00
+	.set	syscall_vector,   0x0c00
+	.set	fpassist_vector,  0x0e00
+	.set	software_vector,  0x1000
+	.set	itlbm_vector,     0x1100
+	.set	dtlbm_vector,     0x1200
+	.set	itlbe_vector,     0x1300
+	.set	dtlbe_vector,     0x1400
+	.set	databkpt_vector,  0x1c00
+	.set	insbkpt_vector,   0x1d00
+	.set	perbkpt_vector,   0x1e00
+	.set	dev_vector,       0x1f00
+	.set    siu_vector,       0x2000
+	.set    cpm_vector,       0x2600
+
+/* Go to the right section */
+#if PPC_ASM == PPC_ASM_ELF
+	.section .vectors,"awx",@progbits
+#elif PPC_ASM == PPC_ASM_XCOFF
+	.csect	.text[PR]
+#endif
+
+	PUBLIC_VAR (__vectors)
+SYM (__vectors):
+	
+/* Critical error handling */
+	.org	reset_vector - file_base 
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_SYSTEM_RESET
+	b       PROC (_ISR_Handler)
+	
+/* Machine check exception */
+	.org	mach_vector - file_base 
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_MCHECK
+	b       PROC (_ISR_Handler)
+	
+/* Protection exception */
+	.org	dsi_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_PROTECT
+	b       PROC (_ISR_Handler)
+
+/* Instruction Storage exception */
+	.org	isi_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_ISI
+	b       PROC (_ISR_Handler)
+
+/* External interrupt */
+/* When an external interrupt occurs, we must find out what caused it */
+/*  before calling the RTEMS handler. First we use SIVEC to decide    */
+/*  what signalled the interrupt to the SIU.                          */
+	.org	ext_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+        stw     r9, IP_9(r1)  	/* r9 will be restored in the next level */
+        stw     r10, IP_10(r1)
+
+	lis  	r9, m860@ha
+        addi 	r9, r9, m860@l
+	lbz   	r10, 0x1c(r9)		/* SIVEC */
+        rlwinm	r10, r10, 4, 0, 27	/* each psuedo vector will have */
+        				/* room for 16 instructions */
+	addis	r10, r10, siu_vectors@ha
+	addi 	r10, r10, siu_vectors@l
+	mflr	r0
+	mtlr	r10
+	lwz 	r10, IP_10(r1)
+	blr
+
+/* Align exception */
+	.org	align_vector - file_base
+	.extern	align_h
+	b	align_h
+	
+/* Program exception */
+	.org	prog_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_PROGRAM
+	b       PROC (_ISR_Handler)
+
+/* Float exception */
+	.org    float_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_NOFP
+	b       PROC (_ISR_Handler)
+
+/* Decrementer exception */
+	.org	dec_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_PROGRAM
+	b       PROC (_ISR_Handler)
+	
+/* System call */
+	.org	sys_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_SCALL
+	b       PROC (_ISR_Handler)
+			
+/* Trace interrupt */
+	.org	trace_vector - file_base
+#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
+#if (PPC_HAS_FPU)
+	stwu	r1, -(20*4 + 18*8 + IP_END)(r1)
+#else
+	stwu	r1, -(20*4 + IP_END)(r1)
+#endif
+#else
+	stwu	r1, -(IP_END)(r1)
+#endif
+	stw	r0, IP_0(r1)
+
+	li      r0, PPC_IRQ_TRACE
+	b       PROC (_ISR_Handler)
+
+	.org	itlbm_vector - file_base
+itlbm_vectors:
+	mfspr	r2, 784      /* MI_CTR */
+	mfspr	r3, 792      /* MD_CTR */
+	mfspr	r4, 787      /* MI_EPN */
+	mfspr	r5, 789      /* MI_TWC */
+	mfspr	r6, 797      /* MD_TWC */
+	mfspr	r7, 789      /* MI_TWC */
+	mfspr	r8, 790      /* MI_RPN */
+	mfspr	r9, 798      /* MD_RPN */
+	mfspr	r10, 796      /* M_TWB */
+	mfspr	r11, 793      /* M_CASID */
+	mfspr	r12, 786      /* MI_AP */
+	mfspr	r13, 794      /* MD_AP */
+	mfspr	r14, 799      /* M_TW */
+	mfspr	r15, 816      /* MI_CAM */
+	mfspr	r16, 817      /* MI_RAM0 */
+	mfspr	r17, 818      /* MI_RAM1 */
+	mfspr	r18, 824      /* MD_CAM */
+	mfspr	r19, 825      /* M_RAM0 */
+	mfspr	r20, 826      /* M_RAM1 */
+	.long   0
+
+	.org	dtlbm_vector - file_base
+dtlbm_vectors:
+	mfspr	r1, 0x1a
+	mfspr	r2, 784      /* MI_CTR */
+	mfspr	r3, 792      /* MD_CTR */
+	lis	r3, 0x400
+	mtspr	792, r3
+	mfspr	r4, 787      /* MI_EPN */
+	mfspr	r5, 789      /* MI_TWC */
+	mfspr	r6, 797      /* MD_TWC */
+	mfspr	r7, 789      /* MI_TWC */
+	mfspr	r8, 790      /* MI_RPN */
+	mfspr	r9, 798      /* MD_RPN */
+	mfspr	r10, 796      /* M_TWB */
+	mfspr	r11, 793      /* M_CASID */
+	mfspr	r12, 786      /* MI_AP */
+	mfspr	r13, 794      /* MD_AP */
+	mfspr	r14, 799      /* M_TW */
+	mfspr	r15, 816      /* MI_CAM */
+	mfspr	r16, 817      /* MI_RAM0 */
+	mfspr	r17, 818      /* MI_RAM1 */
+	mtspr	824, r18 
+	mfspr	r18, 824      /* MD_CAM */
+	mfspr	r19, 825      /* M_RAM0 */
+	mfspr	r20, 826      /* M_RAM1 */
+	.long   0
+
+	.org	itlbe_vector - file_base
+itlbe_vectors:
+	mfspr	r2, 784      /* MI_CTR */
+	mfspr	r3, 792      /* MD_CTR */
+	mfspr	r4, 787      /* MI_EPN */
+	mfspr	r5, 789      /* MI_TWC */
+	mfspr	r6, 797      /* MD_TWC */
+	mfspr	r7, 789      /* MI_TWC */
+	mfspr	r8, 790      /* MI_RPN */
+	mfspr	r9, 798      /* MD_RPN */
+	mfspr	r10, 796      /* M_TWB */
+	mfspr	r11, 793      /* M_CASID */
+	mfspr	r12, 786      /* MI_AP */
+	mfspr	r13, 794      /* MD_AP */
+	mfspr	r14, 799      /* M_TW */
+	mfspr	r15, 816      /* MI_CAM */
+	mfspr	r16, 817      /* MI_RAM0 */
+	mfspr	r17, 818      /* MI_RAM1 */
+	mfspr	r18, 824      /* MD_CAM */
+	mfspr	r19, 825      /* M_RAM0 */
+	mfspr	r20, 826      /* M_RAM1 */
+	.long   0
+
+	.org	dtlbe_vector - file_base
+dtlbe_vectors:
+	mfspr	r2, 784      /* MI_CTR */
+	mfspr	r3, 792      /* MD_CTR */
+	mfspr	r4, 787      /* MI_EPN */
+	mfspr	r5, 789      /* MI_TWC */
+	mfspr	r6, 797      /* MD_TWC */
+	mfspr	r7, 789      /* MI_TWC */
+	mfspr	r8, 790      /* MI_RPN */
+	mfspr	r9, 798      /* MD_RPN */
+	mfspr	r10, 796      /* M_TWB */
+	mfspr	r11, 793      /* M_CASID */
+	mfspr	r12, 786      /* MI_AP */
+	mfspr	r13, 794      /* MD_AP */
+	mfspr	r14, 799      /* M_TW */
+	mfspr	r15, 816      /* MI_CAM */
+	mfspr	r16, 817      /* MI_RAM0 */
+	mfspr	r17, 818      /* MI_RAM1 */
+	mfspr	r18, 824      /* MD_CAM */
+	mfspr	r19, 825      /* M_RAM0 */
+	mfspr	r20, 826      /* M_RAM1 */
+	.long   0
+
+
+	
+/* Now we look at what signaled the interrupt to the SIU. */
+/*   I needed to do this in order to decode the CPM interrupts before  */
+/*    calling _ISR_Handler                                             */
+
+/* *IRQ0 */
+	.org    siu_vector - file_base
+siu_vectors:
+	mtlr  	r0
+	lwz 	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ0
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 0 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL0
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* *IRQ1 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ1
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* This is probably not the "correct" way to do this. I need to have a 
+ *  way of calling _ISR_Handler for the CPM interrupts and this is the
+ *  simplest way I can think of. Since I have the CPM interrupt mapped
+ *  to the SIU interrupt level 1 on the eth-comm board, I put it here.
+ *  It would probably be ok if I moved this directory to under libbsp
+ *  instead of libcpu. For now, deal with it.
+*/
+/* Level 1 - CPM */
+/* Now we need to get the CPM interrupt vector */
+	/* Registers:                                 */
+	/*   R0 - has stored value of LR 	      */
+	/*   R9 - pointer to m860 struct 	      */
+	/*   R10 has already been saved and restored  */
+	li	r10, 1
+	sth	r10, 0x930(r9)	     /* CIVR */
+	lbz	r10, 0x930(r9)	     /* if we use this as an offset into a */
+	rlwinm	r10, r10, 1, 0, 31   /*  table, each entry will have room  */
+				     /*  4 instructions.                   */
+	addis	r10, r10, cpm_vectors@ha
+	addi	r10, r10, cpm_vectors@l
+
+	mtlr	r10
+	lwz	r10, IP_10(r1)
+	blr
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+#if 0
+/* Level 1 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL1
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+#endif
+
+/* *IRQ2 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ2
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 2 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL2
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* *IRQ3 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ3
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 3 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL3
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* *IRQ4 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ4
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 4 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL4
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* *IRQ5 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ5
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 5 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL5
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* *IRQ6 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ6
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 6 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL6
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* *IRQ7 */
+	mtlr  	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_IRQ7
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+/* Level 7 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li      r0, PPC_IRQ_LVL7
+	b       PROC (_ISR_Handler)
+
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	
+/*	.org	cpm_vector - file_base*/
+cpm_vectors:		
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_RESERVED_0
+        .long   0
+
+	/* PC4 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC4
+	b	PROC (_ISR_Handler)
+
+	/* PC5 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC5
+	b	PROC (_ISR_Handler)
+
+	/* SMC2 / PIP */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SMC2
+	b	PROC (_ISR_Handler)
+
+	/* SMC1 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SMC1
+	b	PROC (_ISR_Handler)
+
+	/* SPI */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SPI
+	b	PROC (_ISR_Handler)
+
+	/* PC6 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC6
+	b	PROC (_ISR_Handler)
+
+	/* Timer 4 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_TIMER4
+	b	PROC (_ISR_Handler)
+
+	/* Reserved - we should never see this */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_RESERVED_8
+        .long   0
+
+	/* PC7 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC7
+	b	PROC (_ISR_Handler)
+
+	/* PC8 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC8
+	b	PROC (_ISR_Handler)
+
+	/* PC9 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC9
+	b	PROC (_ISR_Handler)
+
+	/* Timer 3 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_TIMER3
+	b	PROC (_ISR_Handler)
+
+	/* Reserved - we should never get here */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_RESERVED_D
+        .long   0
+
+	/* PC10 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC10
+	b	PROC (_ISR_Handler)
+
+	/* PC11 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC11
+	b	PROC (_ISR_Handler)
+
+	/* I2C */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_I2C
+	b	PROC (_ISR_Handler)
+
+	/* RISC Timer Table */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_RISC_TIMER
+	b	PROC (_ISR_Handler)
+
+	/* Timer 2 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_TIMER2
+	b	PROC (_ISR_Handler)
+
+	/* Reserved - we should never get here */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_RESERVED_13
+        .long   0
+
+	/* IDMA2 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_IDMA2
+	b	PROC (_ISR_Handler)
+
+	/* IDMA1 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_IDMA1
+	b	PROC (_ISR_Handler)
+
+	/* SDMA Channel Bus Error */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SDMA_ERROR
+	b	PROC (_ISR_Handler)
+
+	/* PC12 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC12
+	b	PROC (_ISR_Handler)
+
+	/* PC13 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC13
+	b	PROC (_ISR_Handler)
+
+	/* Timer 1 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_TIMER1
+	b	PROC (_ISR_Handler)
+
+	/* PC14 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC14
+	b	PROC (_ISR_Handler)
+
+	/* SCC4 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SCC4
+	b	PROC (_ISR_Handler)
+
+	/* SCC3 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SCC3
+	b	PROC (_ISR_Handler)
+
+	/* SCC2 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SCC2
+	b	PROC (_ISR_Handler)
+
+	/* SCC1 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_SCC1
+	b	PROC (_ISR_Handler)
+
+	/* PC15 */
+	mtlr	r0
+	lwz	r9, IP_9(r1)
+	li	r0, PPC_IRQ_CPM_PC15
+	b	PROC (_ISR_Handler)
+
+
+
