Ticket #1395: mvme5500-rtems4.9.1-20090401.diff

File mvme5500-rtems4.9.1-20090401.diff, 99.1 KB (added by feng1, on 04/01/09 at 15:43:10)

This is an updated patch. Please discard the previous patch that I sent on 3/20.

  • ChangeLog

    diff -Naur mvme5500.orig/ChangeLog mvme5500/ChangeLog
    old new  
     12009-02-24      Kate Feng <feng1@bnl.gov>
     2        * Updated the changes from RTEMS-4.8.0, which were made since Oct. 2007.
     3       
     4        2008-03-18      Kate Feng <feng1@bnl.gov>
     5        * network/if_1GHz/if_wm.c : fixed some bugs in the 1GHz driver.
     6               
     7        2007-11-31      Kate Feng <feng1@bnl.gov>
     8        * pci/pci_interface.c : Enabled PCI "Read", "Read Line", and "Read Multiple"
     9        *  Agressive Prefetch to improve the performance of the PCI based
     10        *  applications (e.g. 1GHz NIC).
     11       
     12        2007-11-30      Kate Feng <feng1@bnl.gov>
     13        * irq/BSP_irq.c : Replaced the irq/irq.c, and used GT_GPP_Value
     14        * register to monitor the cause of the level sensitive interrupts.
     15        * This unique solution solves various bugs in the 1GHz network drivers
     16        * Fixed bugs in compute_pic_masks_from_prio()
     17       
     182009-02-12      Kate Feng <feng1@bnl.gov>
     19        * pci/pci.c : Updated it to be consistent with the original pci.c
     20        * written by Eric Valette.  There is no change in its function.
     21
     222009-01-30      Kate Feng <feng1@bnl.gov>
     23        * irq/irq_init.c : set defaultIrq->next_handler to be 0
     24        * for BSP_SHARED_HANDLER_SUPPORT.
     25       
    1262008-12-08      Ralf Corsépius <ralf.corsepius@rtems.org>
    227
    328        * bsp_specs: Backport from CVS-HEAD.
  • GT64260/gtreg.h

    diff -Naur mvme5500.orig/GT64260/gtreg.h mvme5500/GT64260/gtreg.h
    old new  
    190190#define GT_MPP_Control2                 0xf008
    191191#define GT_MPP_Control3                 0xf00c
    192192
    193 /* <skf> added */
     193/* <skf> added for GT64260 */
    194194#define GT_MPP_SerialPortMultiplex      0xf010
    195195
    196196#define GT_GPP_IO_Control               0xf100
     
    789789#define TWSI_BAUDE_RATE         0xc00c
    790790#define TWSI_SFT_RST            0xc01c
    791791
    792 /* Interrupt Controller - Interrupt Controller Registers */
    793792/* Section 25.2 : Table 734 <skf> */
    794793
    795 #define GT_MAIN_INT_CAUSE_LO    0xc18 /* read Only */
    796 #define GT_MAIN_INT_CAUSE_HI   0xc68 /* read Only */
    797 #define GT_CPU_INT_MASK_LO      0xc1c
    798 #define GT_CPU_INT_MASK_HI      0xc6c
    799 #define GT_CPU_SEL_CAUSE        0xc70 /* read Only */
     794#define GT64260_MAIN_INT_CAUSE_LO       0xc18 /* read Only */
     795#define GT64260_MAIN_INT_CAUSE_HI       0xc68 /* read Only */
     796#define GT64260_CPU_INT_MASK_LO         0xc1c
     797#define GT64260_CPU_INT_MASK_HI         0xc6c
     798#define GT64260_CPU_SEL_CAUSE   0xc70 /* read Only */
    800799#define GT_PCI0_INT_MASK_LO     0xc24
    801800#define GT_PCI0_INT_MASK_HI     0xc64
    802801#define GT_PCI0_SEL_CAUSE       0xc74 /* read Only */
  • include/bsp.h

    diff -Naur mvme5500.orig/include/bsp.h mvme5500/include/bsp.h
    old new  
    77 *  found in found in the file LICENSE in this distribution or at
    88 *  http://www.rtems.com/license/LICENSE.
    99 *
    10  *  S. Kate Feng 2003-2007 : Modified it to support the mvme5500 BSP.
     10 *  (C) S. Kate Feng 2003-2007 : Modified it to support the mvme5500 BSP.
     11 *
    1112 *
    1213 */
    1314
     
    2223#include <libcpu/io.h>
    2324#include <bsp/vectors.h>
    2425
    25 #include <bsp/bspMvme5500.h>
     26/* Board type */
     27typedef enum {
     28        undefined = 0,
     29        MVME5500,
     30        MVME6100
     31} BSP_BoardTypes;
     32
     33BSP_BoardTypes BSP_getBoardType();
     34
     35/* Board type */
     36typedef enum {
     37        Undefined,
     38        UNIVERSE2,
     39        TSI148,
     40} BSP_VMEchipTypes;
     41
     42BSP_VMEchipTypes BSP_getVMEchipType();
     43
     44/* The version of Discovery system controller */
     45
     46typedef enum {
     47        notdefined,
     48        GT64260A,
     49        GT64260B,           
     50        MV64360,
     51} DiscoveryChipVersion;
     52
     53DiscoveryChipVersion BSP_getDiscoveryChipVersion();
     54
     55#define _256M           0x10000000
     56#define _512M           0x20000000
     57
     58#define GT64x60_REG_BASE        0xf1000000  /* Base of GT64260 Reg Space */
     59#define GT64x60_REG_SPACE_SIZE  0x10000     /* 64Kb Internal Reg Space */
     60
     61#define GT64x60_DEV1_BASE       0xf1100000  /* Device bank1(chip select 1) base
     62                                             */
     63#define GT64260_DEV1_SIZE       0x00100000 /* Device bank size */
    2664
    2765/* fundamental addresses for this BSP (PREPxxx are from libcpu/io.h) */
    28 #define _IO_BASE GT64260_REG_BASE
     66#define _IO_BASE GT64x60_REG_BASE
     67
     68#define BSP_NVRAM_BASE_ADDR     0xf1110000
     69
     70#define BSP_RTC_INTA_REG        0x7ff0
     71#define BSP_RTC_SECOND          0x7ff2 
     72#define BSP_RTC_MINUTE          0x7ff3
     73#define BSP_RTC_HOUR            0x7ff4 
     74#define BSP_RTC_DATE            0x7ff5
     75#define BSP_RTC_INTERRUPTS      0x7ff6
     76#define BSP_RTC_WATCHDOG        0x7ff7
    2977
    3078/* PCI0 Domain I/O space */
    3179#define PCI0_IO_BASE            0xf0000000
     
    69117 */
    70118
    71119#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
     120#define BSP_INTERRUPT_STACK_SIZE  (16 * 1024) /* <skf> 2/09 wants it to be adjustable by BSP */
    72121
    73122/* uart.c uses out_8 instead of outb  */
    74 #define BSP_UART_IOBASE_COM1    GT64260_DEV1_BASE + 0x20000
    75 #define BSP_UART_IOBASE_COM2    GT64260_DEV1_BASE + 0x21000
     123#define BSP_UART_IOBASE_COM1    GT64x60_DEV1_BASE + 0x20000
     124#define BSP_UART_IOBASE_COM2    GT64x60_DEV1_BASE + 0x21000
    76125
    77126#define BSP_CONSOLE_PORT                BSP_UART_COM1  /* console */
    78127#define BSP_UART_BAUD_BASE              115200
    79128
    80129/*
    81  * Vital Board data Start using DATA RESIDUAL
    82  */
    83 /*
    84130 * Total memory using RESIDUAL DATA
    85131 */
    86132extern unsigned int BSP_mem_size;
     
    100146#define BSP_Convert_decrementer( _value ) \
    101147  ((unsigned long long) ((((unsigned long long)BSP_time_base_divisor) * 1000000ULL) /((unsigned long long) BSP_bus_frequency)) * ((unsigned long long) (_value)))
    102148
     149extern rtems_configuration_table  BSP_Configuration;
    103150extern void BSP_panic(char *s);
    104151extern void bsp_reset(void);
    105152/* extern int printk(const char *, ...) __attribute__((format(printf, 1, 2))); */
     
    118165#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_i82544EI_driver_attach
    119166#endif
    120167
    121 extern int
    122 RTEMS_BSP_NETWORK_DRIVER_ATTACH(/* struct rtems_bsdnet_ifconfig * */);
     168extern int RTEMS_BSP_NETWORK_DRIVER_ATTACH();
    123169
    124170/*
    125171 *  BSP Configuration Default Overrides
    126172 */
    127173#define BSP_ZERO_WORKSPACE_AUTOMATICALLY TRUE
    128174
    129 /* As per Linux, This should be in the ppc/system.h */
     175#define gccMemBar() RTEMS_COMPILER_MEMORY_BARRIER()
    130176
     177static inline void lwmemBar()
     178{
     179    asm volatile("lwsync":::"memory");
     180}
     181
     182static inline void io_flush()
     183{
     184    asm volatile("isync":::"memory");
     185}
    131186static inline void memBar()
    132187{
    133188    asm volatile("sync":::"memory");
    134189}
    135 
    136190static inline void ioBar()
    137191{
    138     asm volatile("eieio");
     192    asm volatile("eieio":::"memory");
    139193}
    140194
    141195#endif
  • irq/BSP_irq.c

    diff -Naur mvme5500.orig/irq/BSP_irq.c mvme5500/irq/BSP_irq.c
    old new  
     1/*  BSP_irq.c
     2 *
     3 *  This file contains the implementation of the function described in irq.h
     4 *
     5 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
     6 *
     7 *  The license and distribution terms for this file may be
     8 *  found in the file LICENSE in this distribution or at
     9 *  http://www.OARcorp.com/rtems/license.html.
     10 *
     11 *  Acknowledgement to Till Straumann <strauman@slac.stanford.edu>
     12 *  for some inputs in May 2004.
     13 *
     14 *  Copyright 2003, 2004, 2005, 2007  Shuchen Kate Feng <feng1@bnl.gov>,
     15 *            NSLS, Brookhaven National Laboratory. All rights reserved.
     16 *
     17 *  1) Used GT_GPP_Value register instead of the GT_GPP_Interrupt_Cause
     18 *     register to monitor the cause of the level sensitive interrupts.
     19 *     (Copyright : NDA item)
     20 *  2) The implementation of picPrioTable[] is an original work by the
     21 *     author to optimize the software IRQ priority scheduling because
     22 *     Discovery controller does not provide H/W IRQ priority schedule.
     23 *     It ensures the fastest/faster interrupt service to the
     24 *     highest/higher priority IRQ, if pendig.
     25 *  3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER()
     26 *
     27 */
     28
     29#include <stdio.h> 
     30#include <rtems/system.h>
     31#include <bsp.h>
     32#include <bsp/irq.h>
     33#include <rtems/score/thread.h>
     34#include <rtems/score/apiext.h>
     35#include <libcpu/raw_exception.h>
     36#include <rtems/rtems/intr.h>
     37#include <libcpu/io.h>
     38#include <libcpu/byteorder.h>
     39#include <bsp/vectors.h>
     40
     41#include <rtems/bspIo.h> /* for printk */
     42#include "bsp/gtreg.h"
     43
     44#define HI_INT_CAUSE 0x40000000
     45
     46#define MAX_IRQ_LOOP 20
     47
     48#define _MSR_GET( _mask) \
     49  do { \
     50     RTEMS_COMPILER_MEMORY_BARRIER(); \
     51     _CPU_MSR_GET( _mask); \
     52     RTEMS_COMPILER_MEMORY_BARRIER(); \
     53  } while (0);
     54
     55#define _MSR_SET( _mask) \
     56  do { \
     57     RTEMS_COMPILER_MEMORY_BARRIER(); \
     58     _CPU_MSR_SET( _mask); \
     59     RTEMS_COMPILER_MEMORY_BARRIER(); \
     60  } while (0);
     61
     62/* #define DEBUG_IRQ*/
     63
     64/*
     65 * pointer to the mask representing the additionnal irq vectors
     66 * that must be disabled when a particular entry is activated.
     67 * They will be dynamically computed from the table given
     68 * in BSP_rtems_irq_mngt_set();
     69 * CAUTION : this table is accessed directly by interrupt routine
     70 *           prologue.
     71 */
     72static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
     73
     74/*
     75 * location used to store initial tables used for interrupt
     76 * management.BSP copy of the configuration
     77 */
     78static rtems_irq_global_settings        BSP_config;
     79static rtems_irq_connect_data*          rtems_hdl_tbl;
     80
     81/*
     82 * default handler connected on each irq after bsp initialization
     83 * (locally cached copy)
     84 */
     85void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
     86
     87
     88static volatile unsigned  *BSP_irqMask_reg[3];
     89static volatile unsigned  *BSP_irqCause_reg[3];
     90static volatile unsigned  BSP_irqMask_cache[3]={0,0,0};
     91
     92static int picPrioTblPtr=0;
     93static unsigned int GPPIrqInTbl=0;
     94static unsigned long long MainIrqInTbl=0;
     95
     96/*
     97 * The software developers are forbidden to setup picPrioTable[],
     98 * as it is a powerful engine for the BSP to find the pending
     99 * highest priority IRQ at run time.  It ensures the fastest/faster
     100 * interrupt service to the highest/higher priority IRQ, if pendig.
     101 *
     102 * The picPrioTable[96] is updated dynamically at run time
     103 * based on the priority levels set at BSPirqPrioTable[96],
     104 * while the BSP_enable_irq_at_pic(), and BSP_disable_irq_at_pic()
     105 * commands are invoked.
     106 *
     107 * The picPrioTable[96] lists the enabled CPU main and GPP external interrupt
     108 * numbers [0 (lowest)- 95 (highest)] starting from the highest priority
     109 * one to the lowest priority one. The highest priority interrupt is
     110 * located at picPrioTable[0], and the lowest priority interrupt is located
     111 * at picPrioTable[picPrioTblPtr-1].
     112 *
     113 *
     114 */
     115#define DynamicIsrTable
     116#ifdef DynamicIsrTable
     117/* BitNums for Main Interrupt Lo/High Cause, -1 means invalid bit */
     118static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
     119     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     120     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     121     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     122     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     123     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     124     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     125     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     126     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     127     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     128     -1, -1, -1, -1, -1, -1 };
     129#else
     130static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
     131     80, 84, 76, 77, 32, -1, -1, -1, -1, -1,
     132     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     133     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     134     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     135     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     136     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     137     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     138     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     139     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     140     -1, -1, -1, -1, -1, -1 };
     141#endif
     142
     143/*
     144 * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ
     145 */
     146static inline int is_pic_irq(const rtems_irq_number irqLine)
     147{
     148  return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
     149          ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
     150         );
     151}
     152
     153/*
     154 * Check if IRQ is a Porcessor IRQ
     155 */
     156static inline int is_processor_irq(const rtems_irq_number irqLine)
     157{
     158  return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
     159          ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
     160         );
     161}
     162
     163/*
     164 * ------------------------ RTEMS Irq helper functions ----------------
     165 */
     166 
     167/*
     168 * Caution : this function assumes the variable "BSP_config"
     169 * is already set and that the tables it contains are still valid
     170 * and accessible.
     171 */
     172static void compute_pic_masks_from_prio()
     173{
     174  int i,j, k, isGppMain;
     175  unsigned long long irq_prio_mask=0;
     176
     177  /*
     178   * Always mask at least current interrupt to prevent re-entrance
     179   */
     180  for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
     181    switch(i) {
     182      case BSP_MAIN_GPP7_0_IRQ:
     183      case BSP_MAIN_GPP15_8_IRQ:
     184      case BSP_MAIN_GPP23_16_IRQ:
     185      case BSP_MAIN_GPP31_24_IRQ:
     186        for (k=0; k< 3; k++)
     187            BSP_irq_prio_mask_tbl[k][i]=0;
     188
     189        irq_prio_mask =0;
     190        isGppMain =1;
     191        break;
     192      default :
     193        isGppMain =0;
     194        irq_prio_mask = (unsigned long long) (1LLU << i);
     195        break;
     196    }
     197    if ( isGppMain) continue;
     198    for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
     199        /*
     200         * Mask interrupts at PIC level that have a lower priority
     201         */
     202        if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
     203           irq_prio_mask |= (unsigned long long)(1LLU << j);
     204    }
     205   
     206
     207    BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
     208    BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
     209#if 0
     210    printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
     211           BSP_irq_prio_mask_tbl[0][i]);
     212#endif
     213
     214    BSP_irq_prio_mask_tbl[2][i] = 1<<i;
     215    /* Compute for the GPP priority interrupt mask */
     216    for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {     
     217      if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
     218           BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
     219    }
     220#if 0
     221    printk("GPPirq_mask_prio_tbl[%d]:0x%8x\n",i,BSP_irq_prio_mask_tbl[2][i]);
     222#endif
     223  }
     224}
     225
     226static void UpdateMainIrqTbl(int irqNum)
     227{
     228  int i=0, j, shifted=0;
     229
     230  switch (irqNum) {
     231    case BSP_MAIN_GPP7_0_IRQ:
     232    case BSP_MAIN_GPP15_8_IRQ:
     233    case BSP_MAIN_GPP23_16_IRQ:
     234    case BSP_MAIN_GPP31_24_IRQ: 
     235      return;  /* Do nothing, let GPP take care of it */
     236      break;
     237  }
     238#ifdef SHOW_MORE_INIT_SETTINGS
     239  unsigned long val2, val1;
     240#endif
     241
     242  /* If entry not in table*/
     243  if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
     244        (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
     245       ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
     246        (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
     247  {
     248      while ( picPrioTable[i]!=-1) {
     249        if (BSP_config.irqPrioTbl[irqNum]>BSP_config.irqPrioTbl[picPrioTable[i]]) {
     250          /* all other lower priority entries shifted right */
     251          for (j=picPrioTblPtr;j>i; j--) {
     252              picPrioTable[j]=picPrioTable[j-1];
     253          }
     254          picPrioTable[i]=irqNum;
     255          shifted=1;
     256          break;
     257       }
     258       i++;
     259     }
     260     if (!shifted) picPrioTable[picPrioTblPtr] =irqNum;
     261
     262     if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
     263        GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
     264     else     
     265        MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
     266     picPrioTblPtr++;
     267  }
     268#ifdef SHOW_MORE_INIT_SETTINGS
     269  val2 = (MainIrqInTbl>>32) & 0xffffffff;
     270  val1 = MainIrqInTbl&0xffffffff;
     271  printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
     272  BSP_printPicIsrTbl();
     273#endif
     274
     275}
     276
     277
     278static void CleanMainIrqTbl(int irqNum)
     279{
     280  int i, j;
     281
     282  switch (irqNum) {
     283    case BSP_MAIN_GPP7_0_IRQ:
     284    case BSP_MAIN_GPP15_8_IRQ:
     285    case BSP_MAIN_GPP23_16_IRQ:
     286    case BSP_MAIN_GPP31_24_IRQ:
     287      return;  /* Do nothing, let GPP take care of it */
     288      break; 
     289  }
     290  if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
     291        ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
     292       ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
     293        (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
     294  { /* If entry in table*/
     295     for (i=0; i<64; i++) {
     296       if (picPrioTable[i]==irqNum) {/*remove it from the entry */
     297          /* all other lower priority entries shifted left */
     298          for (j=i;j<picPrioTblPtr; j++) {
     299              picPrioTable[j]=picPrioTable[j+1];
     300          }
     301          if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
     302            GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
     303          else     
     304            MainIrqInTbl &= ~(1LLU << irqNum);
     305          picPrioTblPtr--;
     306          break;
     307       }
     308     }
     309  }
     310}
     311
     312void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
     313{
     314  unsigned bitNum, regNum;
     315  unsigned int level;
     316
     317  if ( !is_pic_irq(irqNum) )
     318        return;
     319
     320  bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
     321  regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
     322
     323  rtems_interrupt_disable(level);
     324
     325#ifdef DynamicIsrTable
     326  UpdateMainIrqTbl((int) irqNum);
     327#endif
     328  BSP_irqMask_cache[regNum] |= (1 << bitNum);
     329
     330  out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
     331  while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
     332
     333  rtems_interrupt_enable(level);
     334}
     335
     336void BSP_enable_pic_irq(const rtems_irq_number irqNum)
     337{
     338        BSP_enable_irq_at_pic(irqNum);
     339}
     340
     341int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
     342{
     343  int      rval;
     344  unsigned bitNum, regNum;
     345  unsigned int level;
     346
     347  if ( ! is_pic_irq(irqNum) )
     348        return -1;
     349
     350  bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
     351  regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
     352
     353  rtems_interrupt_disable(level);
     354
     355#ifdef DynamicIsrTable
     356  CleanMainIrqTbl((int) irqNum);
     357#endif
     358
     359  rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
     360
     361  BSP_irqMask_cache[regNum] &=  ~(1 << bitNum);
     362
     363  out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
     364  while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
     365
     366  rtems_interrupt_enable(level);
     367
     368  return rval ? 1 : 0;
     369}
     370
     371void BSP_disable_pic_irq(const rtems_irq_number irqNum)
     372{
     373        (void)BSP_disable_irq_at_pic(irqNum);
     374}
     375
     376/* Use shared/irq : 2008 */
     377int BSP_setup_the_pic(rtems_irq_global_settings* config) 
     378{
     379    int i;
     380
     381    BSP_config = *config;
     382    default_rtems_hdl = config->defaultEntry.hdl;
     383    rtems_hdl_tbl     = config->irqHdlTbl;
     384
     385    /* Get ready for discovery BSP */
     386    BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_LO);
     387    BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_HI);
     388    BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_LO);
     389    BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_HI);
     390    BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Interrupt_Mask);
     391    BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Value);
     392
     393    /* Page 401, Table 598:
     394     * Comm Unit Arbiter Control register :
     395     * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
     396     * MOTload default is set as level sensitive(1). Set it agin to make sure.
     397     */
     398    out_le32(GT_CommUnitArb_Ctrl, (in_le32(GT_CommUnitArb_Ctrl)| (1<<10)));
     399
     400#if 0
     401    printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
     402           in_le32(BSP_irqMask_reg[0]),
     403           in_le32(BSP_irqCause_reg[0]));
     404    printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
     405           in_le32(BSP_irqMask_reg[1]),
     406           in_le32(BSP_irqCause_reg[1]));
     407    printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
     408           in_le32(BSP_irqMask_reg[2]),
     409           in_le32(BSP_irqCause_reg[2]));
     410#endif
     411
     412    /* Initialize the interrupt related  registers */
     413    for (i=0; i<3; i++) {
     414      out_le32(BSP_irqCause_reg[i], 0);
     415      out_le32(BSP_irqMask_reg[i], 0);
     416    }         
     417    in_le32(BSP_irqMask_reg[2]);
     418    compute_pic_masks_from_prio();
     419
     420#if 0
     421    printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
     422           in_le32(BSP_irqMask_reg[0]),
     423           in_le32(BSP_irqCause_reg[0]));
     424    printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
     425           in_le32(BSP_irqMask_reg[1]),
     426           in_le32(BSP_irqCause_reg[1]));
     427    printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
     428           in_le32(BSP_irqMask_reg[2]),
     429           in_le32(BSP_irqCause_reg[2]));
     430#endif
     431
     432    /*
     433     *
     434     */
     435    for (i=BSP_MICL_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET ; i++) {
     436      if ( BSP_config.irqHdlTbl[i].hdl != BSP_config.defaultEntry.hdl) {
     437        BSP_enable_irq_at_pic(i);
     438        BSP_config.irqHdlTbl[i].on(&BSP_config.irqHdlTbl[i]);
     439      }
     440      else {
     441        BSP_config.irqHdlTbl[i].off(&BSP_config.irqHdlTbl[i]);
     442        BSP_disable_irq_at_pic(i);
     443      }
     444    }
     445    for (i= BSP_MAIN_GPP7_0_IRQ; i < BSP_MAIN_GPP31_24_IRQ; i++)
     446      BSP_enable_irq_at_pic(i);
     447   
     448    return(1);
     449}
     450
     451/*
     452 * High level IRQ handler called from shared_raw_irq_code_entry
     453 */
     454int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
     455{
     456  register unsigned msr, new_msr;
     457  unsigned long irqCause[3]={0, 0,0};
     458  unsigned oldMask[3]={0,0,0};
     459  int loop=0, wloop=0, i=0, j;
     460  register irq=0, group=0;
     461
     462  if (excNum == ASM_DEC_VECTOR) {
     463      bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
     464      return 0;   
     465  }
     466
     467  for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
     468  for (j=0; j<3; j++) irqCause[j] = in_le32(BSP_irqCause_reg[j]) & in_le32(BSP_irqMask_reg[j]);
     469
     470  while (((irq = picPrioTable[i++])!=-1)&& (loop++ < MAX_IRQ_LOOP))
     471  {   
     472    if (irqCause[group= irq/32] & ( 1<<(irq % 32))) {
     473      for (j=0; j<3; j++)
     474        BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
     475
     476      out_le32(BSP_irqMask_reg[0], BSP_irqMask_cache[0]);
     477      out_le32(BSP_irqMask_reg[1], BSP_irqMask_cache[1]);
     478      out_le32(BSP_irqMask_reg[2], BSP_irqMask_cache[2]);
     479      in_le32(BSP_irqMask_reg[2]);
     480
     481      bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
     482
     483      for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
     484 
     485      out_le32(BSP_irqMask_reg[0], oldMask[0]);
     486      out_le32(BSP_irqMask_reg[1], oldMask[1]);
     487      out_le32(BSP_irqMask_reg[2], oldMask[2]);
     488      in_le32(BSP_irqMask_reg[2]);
     489    }
     490  }
     491
     492  return 0;
     493}
     494
     495/* Only print part of the entries for now */
     496void BSP_printPicIsrTbl()
     497{
     498  int i;
     499
     500  printf("picPrioTable[12]={ {irq# : ");
     501  for (i=0; i<12; i++)
     502    printf("%d,", picPrioTable[i]);
     503  printf("}\n");
     504
     505  printf("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
     506}
  • irq/irq.c

    diff -Naur mvme5500.orig/irq/irq.c mvme5500/irq/irq.c
    old new  
    1 /*  irq.c
    2  *
    3  *  This file contains the implementation of the function described in irq.h
    4  *
    5  *  Copyright (C) 1998, 1999 valette@crf.canon.fr
    6  *
    7  *  The license and distribution terms for this file may be
    8  *  found in the file LICENSE in this distribution or at
    9  *  http://www.OARcorp.com/rtems/license.html.
    10  *
    11  *  Acknowledgement May 2004 : to Till Straumann <strauman@slac.stanford.edu>
    12  *  for some inputs.
    13  *
    14  *  Copyright 2003, 2004, 2005, 2007  Shuchen Kate Feng <feng1@bnl.gov>,
    15  *                  NSLS,Brookhaven National Laboratory
    16  *  1) Modified and added support for the MVME5500 board.
    17  *  2) The implementation of picIsrTable[] is an original work by the
    18  *     author to optimize the software IRQ priority scheduling because
    19  *     Discovery controller does not provide H/W IRQ priority schedule.
    20  *     It ensures the fastest/faster interrupt service to the
    21  *     highest/higher priority IRQ, if pendig.
    22  *  3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER()
    23  *
    24  */
    25  
    26 #include <rtems/system.h>
    27 #include <bsp.h>
    28 #include <bsp/irq.h>
    29 #include <rtems/score/thread.h>
    30 #include <rtems/score/apiext.h>
    31 #include <libcpu/raw_exception.h>
    32 #include <rtems/rtems/intr.h>
    33 #include <libcpu/io.h>
    34 #include <libcpu/byteorder.h>
    35 #include <bsp/vectors.h>
    36 
    37 #include <rtems/bspIo.h> /* for printk */
    38 #include "bsp/gtreg.h"
    39 
    40 #define HI_INT_CAUSE 0x40000000
    41 
    42 #define MAX_IRQ_LOOP 30
    43 
    44 #define EDGE_TRIGGER
    45 
    46 /* #define DEBUG_IRQ*/
    47 
    48 /*
    49  * pointer to the mask representing the additionnal irq vectors
    50  * that must be disabled when a particular entry is activated.
    51  * They will be dynamically computed from the table given
    52  * in BSP_rtems_irq_mngt_set();
    53  * CAUTION : this table is accessed directly by interrupt routine
    54  *           prologue.
    55  */
    56 static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
    57 
    58 /*
    59  * location used to store initial tables used for interrupt
    60  * management.
    61  */
    62 static rtems_irq_global_settings*       internal_config;
    63 /* handler table (cached copy ) */
    64 static rtems_irq_connect_data*          rtems_hdl_tbl;
    65 /*
    66  * default handler connected on each irq after bsp initialization
    67  * (locally cached copy)
    68  */
    69 void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
    70 
    71 
    72 static volatile unsigned  *BSP_irqMask_reg[3];
    73 static volatile unsigned  *BSP_irqCause_reg[3];
    74 static volatile unsigned  BSP_irqMask_cache[3]={0,0,0};
    75 
    76 
    77 static int picIsrTblPtr=0;
    78 static unsigned int GPPIrqInTbl=0;
    79 static unsigned long long MainIrqInTbl=0;
    80 
    81 /*
    82  * The software developers are forbidden to setup picIsrTable[],
    83  * as it is a powerful engine for the BSP to find the pending
    84  * highest priority IRQ at run time.  It ensures the fastest/faster
    85  * interrupt service to the highest/higher priority IRQ, if pendig.
    86  *
    87  * The picIsrTable[96] is updated dynamically at run time
    88  * based on the priority levels set at BSPirqPrioTable[96],
    89  * while the BSP_enable_pic_irq(), and BSP_disable_pic_irq()
    90  * commands are invoked.
    91  *
    92  * The picIsrTable[96] lists the enabled CPU main and GPP external interrupt
    93  * numbers [0 (lowest)- 95 (highest)] starting from the highest priority
    94  * one to the lowest priority one. The highest priority interrupt is
    95  * located at picIsrTable[0], and the lowest priority interrupt is located
    96  * at picIsrTable[picIsrTblPtr-1].
    97  *
    98  *
    99  */
    100 /* BitNums for Main Interrupt Lo/High Cause and GPP, -1 means invalid bit */
    101 static unsigned int picIsrTable[BSP_PIC_IRQ_NUMBER]={ 
    102      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    103      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    104      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    105      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    106      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    107      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    108      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    109      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    110      -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    111      -1, -1, -1, -1, -1, -1 };
    112 
    113 
    114 /*
    115  * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ
    116  */
    117 static inline int is_pic_irq(const rtems_irq_number irqLine)
    118 {
    119   return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
    120           ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
    121          );
    122 }
    123 
    124 /*
    125  * Check if IRQ is a Porcessor IRQ
    126  */
    127 static inline int is_processor_irq(const rtems_irq_number irqLine)
    128 {
    129   return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
    130           ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
    131          );
    132 }
    133 
    134 static inline unsigned int divIrq32(unsigned irq)
    135 {
    136   return(irq/32);
    137 }
    138 
    139 static inline unsigned int modIrq32(unsigned irq)
    140 {
    141    return(irq%32);
    142 }
    143 
    144 /*
    145  * ------------------------ RTEMS Irq helper functions ----------------
    146  */
    147  
    148 /*
    149  * Caution : this function assumes the variable "internal_config"
    150  * is already set and that the tables it contains are still valid
    151  * and accessible.
    152  */
    153 static void compute_pic_masks_from_prio(rtems_irq_global_settings *config)
    154 {
    155   int i,j, k;
    156   unsigned long long irq_prio_mask=0;
    157 
    158   /*
    159    * Always mask at least current interrupt to prevent re-entrance
    160    */
    161   for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
    162     switch(i) {
    163       case BSP_MAIN_GPP7_0_IRQ:
    164       case BSP_MAIN_GPP15_8_IRQ:
    165       case BSP_MAIN_GPP23_16_IRQ:
    166       case BSP_MAIN_GPP31_24_IRQ:
    167         for (k=0; k< 3; k++)
    168             BSP_irq_prio_mask_tbl[k][i]=0;
    169 
    170         irq_prio_mask =0;
    171         break;
    172       default :
    173         irq_prio_mask = (unsigned long long) (1LLU << i);
    174         break;
    175     }
    176    
    177     if (irq_prio_mask) {
    178     for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
    179         /*
    180          * Mask interrupts at PIC level that have a lower priority
    181          * or <Till Straumann> a equal priority.
    182          */
    183         if (config->irqPrioTbl [i] >= config->irqPrioTbl [j])
    184            irq_prio_mask |= (unsigned long long)(1LLU << j);
    185     }
    186    
    187 
    188     BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
    189     BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
    190 #ifdef DEBUG
    191     printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
    192            BSP_irq_prio_mask_tbl[0][i]);
    193 #endif
    194 
    195     BSP_irq_prio_mask_tbl[2][i] = 1<<i;
    196     /* Compute for the GPP priority interrupt mask */
    197     for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {     
    198       if (config->irqPrioTbl [i] >= config->irqPrioTbl [j])
    199            BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
    200     }
    201     }
    202   }
    203 }
    204 
    205 
    206 static void UpdateMainIrqTbl(int irqNum)
    207 {
    208   int i=0, j, shifted=0;
    209 
    210   switch (irqNum) {
    211     case BSP_MAIN_GPP7_0_IRQ:
    212     case BSP_MAIN_GPP15_8_IRQ:
    213     case BSP_MAIN_GPP23_16_IRQ:
    214     case BSP_MAIN_GPP31_24_IRQ: 
    215       return;  /* Do nothing, let GPP take care of it */
    216       break;
    217   }
    218 #ifdef SHOW_MORE_INIT_SETTINGS
    219   unsigned long val2, val1;
    220 #endif
    221 
    222   /* If entry not in table*/
    223   if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
    224         (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
    225        ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
    226         (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
    227   {
    228       while ( picIsrTable[i]!=-1) {
    229         if (internal_config->irqPrioTbl[irqNum]>internal_config->irqPrioTbl[picIsrTable[i]]) {
    230           /* all other lower priority entries shifted right */
    231           for (j=picIsrTblPtr;j>i; j--)
    232               picIsrTable[j]=picIsrTable[j-1];
    233           picIsrTable[i]=irqNum;
    234           shifted=1;
    235           break;
    236        }
    237        i++;
    238      }
    239      if (!shifted) picIsrTable[picIsrTblPtr]=irqNum;
    240      if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
    241         GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
    242      else     
    243         MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
    244      picIsrTblPtr++;
    245   }
    246 #ifdef SHOW_MORE_INIT_SETTINGS
    247   val2 = (MainIrqInTbl>>32) & 0xffffffff;
    248   val1 = MainIrqInTbl&0xffffffff;
    249   printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
    250   BSP_printPicIsrTbl();
    251 #endif
    252 
    253 }
    254 
    255 
    256 static void CleanMainIrqTbl(int irqNum)
    257 {
    258   int i, j;
    259 
    260   switch (irqNum) {
    261     case BSP_MAIN_GPP7_0_IRQ:
    262     case BSP_MAIN_GPP15_8_IRQ:
    263     case BSP_MAIN_GPP23_16_IRQ:
    264     case BSP_MAIN_GPP31_24_IRQ:
    265       return;  /* Do nothing, let GPP take care of it */
    266       break; 
    267   }
    268   if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
    269         ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
    270        ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
    271         (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
    272   { /* If entry in table*/
    273      for (i=0; i<64; i++) {
    274        if (picIsrTable[i]==irqNum) {/*remove it from the entry */
    275           /* all other lower priority entries shifted left */
    276           for (j=i;j<picIsrTblPtr; j++)
    277               picIsrTable[j]=picIsrTable[j+1];
    278           if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
    279             GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
    280           else     
    281             MainIrqInTbl &= ~(1LLU << irqNum);
    282           picIsrTblPtr--;
    283           break;
    284        }
    285      }
    286   }
    287 }
    288 
    289 void BSP_enable_pic_irq(const rtems_irq_number irqNum)
    290 {
    291   unsigned bitNum, regNum;
    292   unsigned int level;
    293 
    294   if ( !is_pic_irq(irqNum) )
    295         return;
    296 
    297   bitNum = modIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
    298   regNum = divIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
    299 
    300   rtems_interrupt_disable(level);
    301 
    302   UpdateMainIrqTbl((int) irqNum);
    303   BSP_irqMask_cache[regNum] |= (1 << bitNum);
    304 
    305   out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
    306   while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
    307 
    308   rtems_interrupt_enable(level);
    309 }
    310 
    311 void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
    312 {
    313         BSP_enable_pic_irq(irqNum);
    314 }
    315 
    316 int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
    317 {
    318   int      rval;
    319   unsigned bitNum, regNum;
    320   unsigned int level;
    321 
    322   if ( ! is_pic_irq(irqNum) )
    323         return -1;
    324 
    325   bitNum = modIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
    326   regNum = divIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
    327 
    328   rtems_interrupt_disable(level);
    329 
    330   CleanMainIrqTbl((int) irqNum);
    331 
    332   rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
    333 
    334   BSP_irqMask_cache[regNum] &=  ~(1 << bitNum);
    335 
    336   out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
    337   while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
    338 
    339   rtems_interrupt_enable(level);
    340 
    341   return rval ? 1 : 0;
    342 }
    343 
    344 void BSP_disable_pic_irq(const rtems_irq_number irqNum)
    345 {
    346         (void)BSP_disable_irq_at_pic(irqNum);
    347 }
    348 
    349 int BSP_setup_the_pic(rtems_irq_global_settings *config)  /* adapt the same name as shared/irq */
    350 {
    351     int i;
    352 
    353         internal_config   = config;
    354         default_rtems_hdl = config->defaultEntry.hdl;
    355         rtems_hdl_tbl     = config->irqHdlTbl;
    356 
    357     /* Get ready for discovery BSP */
    358     BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64260_REG_BASE + GT_CPU_INT_MASK_LO);
    359     BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64260_REG_BASE + GT_CPU_INT_MASK_HI);
    360     BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64260_REG_BASE + GT_GPP_Interrupt_Mask);
    361 
    362     BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64260_REG_BASE + GT_MAIN_INT_CAUSE_LO);
    363     BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64260_REG_BASE + GT_MAIN_INT_CAUSE_HI);
    364     BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64260_REG_BASE + GT_GPP_Interrupt_Cause);
    365 
    366 #ifdef EDGE_TRIGGER
    367 
    368     /* Page 401, Table 598:
    369      * Comm Unit Arbiter Control register :
    370      * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
    371      * We set the GPP interrupts to be edge sensitive.
    372      * MOTload default is set as level sensitive(1).
    373      */
    374     outl((inl(GT_CommUnitArb_Ctrl)& (~(1<<10))), GT_CommUnitArb_Ctrl);
    375 #else
    376     outl((inl(GT_CommUnitArb_Ctrl)| (1<<10)), GT_CommUnitArb_Ctrl);
    377 #endif
    378 
    379 #if 0
    380     printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
    381            in_le32(BSP_irqMask_reg[0]),
    382            in_le32(BSP_irqCause_reg[0]));
    383     printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
    384            in_le32(BSP_irqMask_reg[1]),
    385            in_le32(BSP_irqCause_reg[1]));
    386     printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
    387            in_le32(BSP_irqMask_reg[2]),
    388            in_le32(BSP_irqCause_reg[2]));
    389 #endif
    390 
    391     /* Initialize the interrupt related GT64260 registers */
    392     for (i=0; i<3; i++) {
    393       out_le32(BSP_irqCause_reg[i], 0);
    394       out_le32(BSP_irqMask_reg[i], 0);
    395     }         
    396     in_le32(BSP_irqMask_reg[2]);
    397     compute_pic_masks_from_prio(config);
    398 
    399 #if 0
    400     printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
    401            in_le32(BSP_irqMask_reg[0]),
    402            in_le32(BSP_irqCause_reg[0]));
    403     printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
    404            in_le32(BSP_irqMask_reg[1]),
    405            in_le32(BSP_irqCause_reg[1]));
    406     printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
    407            in_le32(BSP_irqMask_reg[2]),
    408            in_le32(BSP_irqCause_reg[2]));
    409 #endif
    410 
    411     return(1);
    412 }
    413 
    414 /*
    415  * This function check that the value given for the irq line
    416  * is valid.
    417  */
    418 
    419 /*
    420  * High level IRQ handler called from shared_raw_irq_code_entry
    421  */
    422 
    423 int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
    424 {
    425   unsigned long irqCause[3]={0, 0,0};
    426   register unsigned long selectCause;
    427   unsigned oldMask[3]={0,0,0};
    428   register unsigned i=0, j, irq=0, bitmask=0, group=0;
    429 
    430   if (excNum == ASM_DEC_VECTOR) {
    431 
    432         bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
    433 
    434     return 0;
    435    
    436   }
    437 
    438   for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
    439 
    440   if ((selectCause= in_le32((volatile unsigned *)0xf1000c70)) & HI_INT_CAUSE ){
    441     irqCause[1] = (selectCause & BSP_irqMask_cache[1]);
    442     irqCause[2] = in_le32(BSP_irqCause_reg[2]) & BSP_irqMask_cache[2];
    443   }
    444   else {
    445     irqCause[0] = (selectCause & BSP_irqMask_cache[0]);
    446     if ((irqCause[1] =(in_le32((volatile unsigned *)0xf1000c68)&BSP_irqMask_cache[1])))
    447        irqCause[2] = in_le32(BSP_irqCause_reg[2]) & BSP_irqMask_cache[2];
    448   }
    449  
    450   while ((irq = picIsrTable[i++])!=-1)
    451   {
    452     if (irqCause[group=(irq/32)] && (irqCause[group]&(bitmask=(1<<(irq % 32))))) {
    453       for (j=0; j<3; j++)
    454         BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
    455 
    456       RTEMS_COMPILER_MEMORY_BARRIER();
    457       out_le32((volatile unsigned *)0xf1000c1c, BSP_irqMask_cache[0]);
    458       out_le32((volatile unsigned *)0xf1000c6c, BSP_irqMask_cache[1]);
    459       out_le32((volatile unsigned *)0xf100f10c, BSP_irqMask_cache[2]);
    460       in_le32((volatile unsigned *)0xf100f10c);
    461 
    462 #ifdef EDGE_TRIGGER
    463       if (irq > BSP_MICH_IRQ_MAX_OFFSET)
    464          out_le32(BSP_irqCause_reg[2], ~bitmask);/* Till Straumann: Ack the edge triggered GPP IRQ */
    465 #endif
    466 
    467           bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
    468      
    469       for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
    470       break;
    471     }
    472   }
    473 
    474   out_le32((volatile unsigned *)0xf1000c1c, oldMask[0]);
    475   out_le32((volatile unsigned *)0xf1000c6c, oldMask[1]);
    476   out_le32((volatile unsigned *)0xf100f10c, oldMask[2]);
    477   in_le32((volatile unsigned *)0xf100f10c);
    478 
    479   return 0;
    480 }
    481 
    482 /* Only print part of the entries for now */
    483 void BSP_printPicIsrTbl()
    484 {
    485   int i;
    486 
    487   printk("picIsrTable[12]={");
    488   for (i=0; i<12; i++)
    489     printk("%d,", picIsrTable[i]);
    490   printk("}\n");
    491 
    492   printk("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
    493 }
  • irq/irq_init.c

    diff -Naur mvme5500.orig/irq/irq_init.c mvme5500/irq/irq_init.c
    old new  
    3636
    3737static rtems_irq_connect_data           rtemsIrq[BSP_IRQ_NUMBER];
    3838static rtems_irq_global_settings        initial_config;
     39
     40#ifdef BSP_SHARED_HANDLER_SUPPORT
     41static rtems_irq_connect_data           defaultIrq = {
     42  /* vectorIdex,  hdl       ,handle  , on       , off      , isOn      ,next_handler, */
     43  0,              nop_func  , NULL   , nop_func , nop_func , not_connected, 0
     44};
     45#else
    3946static rtems_irq_connect_data           defaultIrq = {
    4047  /* vectorIdex,         hdl      , handle      , on            , off           , isOn */
    4148  0,                     nop_func  , NULL       , nop_func      , nop_func      , not_connected
    4249};
     50#endif
    4351
    4452rtems_irq_prio BSPirqPrioTable[BSP_PIC_IRQ_NUMBER]={
    4553  /*
     
    135143#ifdef TRACE_IRQ_INIT 
    136144  printk("Done setup irq mngt configuration\n");
    137145#endif
    138  
    139   /* I don't really understand why all sources are enable here... (T.S) */
    140   for (i= BSP_MAIN_GPP7_0_IRQ; i <= BSP_MAIN_GPP31_24_IRQ; i++)
    141       BSP_enable_pic_irq(i);
    142 
    143   rtems_interrupt_enable(l);
    144146
    145147#ifdef TRACE_IRQ_INIT 
    146148  printk("RTEMS IRQ management is now operationnal\n");
  • Makefile.am

    diff -Naur mvme5500.orig/Makefile.am mvme5500/Makefile.am
    old new  
    3232    ../../powerpc/shared/startup/sbrk.c ../../shared/bootcard.c \
    3333    ../../shared/bsppredriverhook.c startup/bspclean.c \
    3434    ../../shared/bsplibc.c ../../shared/bsppost.c \
    35     ../../shared/gnatinstallhandler.c startup/reboot.c
     35    ../../shared/gnatinstallhandler.c startup/reboot.c \
     36    ../../powerpc/shared/startup/probeMemEnd.c
     37
    3638pclock_SOURCES = ../../powerpc/shared/clock/p_clock.c
    3739
    3840include_bsp_HEADERS = ../../powerpc/shared/console/uart.h
     
    4547    pci/pcifinddevice.c
    4648
    4749include_bsp_HEADERS += irq/irq.h
    48 irq_SOURCES = irq/irq_init.c irq/irq.c
     50irq_SOURCES = irq/irq_init.c irq/BSP_irq.c
    4951
    5052nodist_include_HEADERS += ../../shared/tod.h
    5153tod_SOURCES = ../../shared/tod.c tod/todcfg.c
  • network/if_100MHz/GT64260eth.c

    diff -Naur mvme5500.orig/network/if_100MHz/GT64260eth.c mvme5500/network/if_100MHz/GT64260eth.c
    old new  
    77 * Acknowledgements:
    88 * netBSD : Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
    99 * Marvell : NDA document for the discovery system controller
    10  * The author referenced two RTEMS network drivers of other NICs.
    11  * rtems : 1) dec21140.c, a network driver for for TULIP based Ethernet Controller
    12  *            (C) 1999 Emmanuel Raguet. raguet@crf.canon.fr
    13  *
    14  *         2) yellowfin.c, a network driver for the SVGM5 BSP.
    15  *           Stanford Linear Accelerator Center, Till Straumann
    1610 *
    1711 * Some notes from the author, S. Kate Feng :
    1812 *
     
    366360  if (unit < 0) return 0;
    367361 
    368362  printk("\nEthernet driver name %s unit %d \n",name, unit);
    369   printk("(c) 2004, Brookhaven National Lab. <feng1@bnl.gov> (RTEMS/mvme5500 port)\n");
    370 
     363  printk("RTEMS-mvme5500 BSP Copyright (c) 2004, Brookhaven National Lab., Shuchen Kate Feng \n");
    371364  /* Make certain elements e.g. descriptor lists are aligned. */
    372365  softc_mem = rtems_bsdnet_malloc(sizeof(*sc) + SOFTC_ALIGN, M_FREE, M_NOWAIT);
    373366
     
    11371130  sc->arpcom.ac_if.if_timer = 0;
    11381131}
    11391132
    1140 /* TOCHECK : Should it be about rx or tx ? */
    11411133static void GTeth_ifchange(struct GTeth_softc *sc)
    11421134{
    11431135  if (GTeth_debug>0) printk("GTeth_ifchange(");
     
    14451437#endif
    14461438}
    14471439
     1440#ifdef GT64260eth_DEBUG
    14481441static void GT64260eth_error(struct GTeth_softc *sc)
    14491442{
    14501443  struct ifnet          *ifp = &sc->arpcom.ac_if;
     
    14741467  sc->intr_errsts[sc->intr_err_ptr1++]=0; 
    14751468  sc->intr_err_ptr1 %= INTR_ERR_SIZE;   /* Till Straumann */
    14761469}
    1477 
     1470#endif
    14781471
    14791472/* The daemon does all of the work; RX, TX and cleaning up buffers/descriptors */
    14801473static void GT64260eth_daemon(void *arg)
     
    15481541       ifp->if_flags &= ~IFF_OACTIVE;
    15491542
    15501543       /* Log errors and other uncommon events. */
     1544#ifdef GT64260eth_DEBUG
    15511545       if (events & ERR_EVENT) GT64260eth_error(sc);
     1546#endif
    15521547  } /* end for(;;) { rtems_bsdnet_event_receive() .....*/
    15531548
    15541549  ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
  • network/if_1GHz/if_wm.c

    diff -Naur mvme5500.orig/network/if_1GHz/if_wm.c mvme5500/network/if_1GHz/if_wm.c
    old new  
    11/*
    22 * Copyright (c) 2004,2005 RTEMS/Mvme5500 port by S. Kate Feng <feng1@bnl.gov>
     3 *      under the Deaprtment of Energy contract DE-AC02-98CH10886
    34 *      Brookhaven National Laboratory, All rights reserved
    45 *
    56 * Acknowledgements:
     
    2526 *    hardware auto-neg. state machine disabled. PCI control "snoop
    2627 *    to WB region", MII mode (PHY) instead of TBI mode.
    2728 * 6) We currently only use 32-bit (instead of 64-bit) DMA addressing.
    28  * 7) Support for checksum offloading and TCP segmentation offload will
    29  *    be available for releasing in 2008, upon request, if I still believe.
     29 * 7) Implementation for Jumbo Frame and TCP checksum is not completed yet.
    3030 *   
    3131 */
    3232
     
    3434
    3535#define INET
    3636
     37/*#define RTEMS_ETHERMTU_JUMBO*/
     38
    3739#include <rtems.h>
    3840#include <rtems/bspIo.h>      /* printk */
     41
    3942#include <stdio.h>            /* printf for statistics */
    4043#include <string.h>
    4144
     
    6467#include <net/if_dl.h>
    6568#include <netinet/in.h>
    6669#include <netinet/if_ether.h>
     70#include <net/ethernet.h>
    6771
    6872#ifdef INET
    6973#include <netinet/in_var.h>
     
    8286#define i82544EI_TASK_NAME "IGHZ"
    8387#define SOFTC_ALIGN        4095
    8488
    85 #define INTR_ERR_SIZE        16
     89#define IF_ERR_BUFSZE        16
    8690
    8791/*#define WM_DEBUG*/
    8892#ifdef WM_DEBUG
     
    109113 
    110114#define ALL_EVENTS (KILL_EVENT|START_TRANSMIT_EVENT|RX_EVENT|TX_EVENT|ERR_EVENT|INIT_EVENT)
    111115
    112 
    113 #define NTXDESC                 128
     116/* <skf> used 64 in 4.8.0, TOD; try 4096 */
     117#define NTXDESC                 256
    114118#define NTXDESC_MASK            (NTXDESC - 1)
    115119#define WM_NEXTTX(x)            (((x) + 1) & NTXDESC_MASK)
    116120
    117 #define NRXDESC                 64
     121#define NRXDESC                 256
    118122#define NRXDESC_MASK            (NRXDESC - 1)
    119123#define WM_NEXTRX(x)            (((x) + 1) & NRXDESC_MASK)
    120124#define WM_PREVRX(x)            (((x) - 1) & NRXDESC_MASK)
     
    123127#define WM_CDTXOFF(x)   WM_CDOFF(sc_txdescs[(x)])
    124128#define WM_CDRXOFF(x)   WM_CDOFF(sc_rxdescs[(x)])
    125129
    126 #define TXQ_HiLmt_OFF 64
     130#define TXQ_HiLmt_OFF 32
    127131
    128132static uint32_t TxDescCmd;
     133static unsigned BSP_1GHz_membase;
    129134
    130135/*
    131136 * Software state per device.
     
    136141        struct mbuf *txs_mbuf[NTXDESC];        /* transmit buffer memory */
    137142        struct mbuf *rxs_mbuf[NRXDESC];        /* receive buffer memory */
    138143        struct wm_softc *next_module;
    139         volatile unsigned int intr_errsts[INTR_ERR_SIZE]; /* intr_status */
    140         unsigned int intr_err_ptr1;     /* ptr used in i82544EI_error() */
    141         unsigned int intr_err_ptr2;     /* ptr used in ISR */
     144        volatile unsigned int if_errsts[IF_ERR_BUFSZE]; /* intr_status */
     145        unsigned int if_err_ptr1;     /* ptr used in i82544EI_error() */
     146        unsigned int if_err_ptr2;     /* ptr used in ISR */
    142147        int txs_firstdesc;              /* first descriptor in packet */
    143148        int txs_lastdesc;               /* last descriptor in packet */
    144149        int txs_ndesc;                  /* # of descriptors used */
     
    168173        int     sc_rxptr;               /* next ready Rx descriptor/queue ent */
    169174        int     sc_rxdiscard;
    170175        int     sc_rxlen;
     176
    171177        uint32_t sc_ctrl;               /* prototype CTRL register */
    172 #if 0
    173178        uint32_t sc_ctrl_ext;           /* prototype CTRL_EXT register */
    174 #endif
     179
    175180        uint32_t sc_icr;                /* prototype interrupt bits */
    176181        uint32_t sc_tctl;               /* prototype TCTL register */
    177182        uint32_t sc_rctl;               /* prototype RCTL register */
    178183        uint32_t sc_tipg;               /* prototype TIPG register */
    179184        uint32_t sc_fcrtl;              /* prototype FCRTL register */
     185        uint32_t sc_pba;                /* prototype PBA register */
    180186
    181187        int sc_mchash_type;             /* multicast filter offset */
    182188
     
    184190        struct {
    185191          volatile unsigned long     rxInterrupts;
    186192          volatile unsigned long     txInterrupts;
    187           unsigned long     txMultiBuffPacket;
    188           unsigned long     txMultiMaxLen;
    189           unsigned long     txSinglMaxLen;
    190           unsigned long     txMultiMaxLoop;
    191           unsigned long     txBuffMaxLen;
    192193          unsigned long     linkInterrupts;
    193194          unsigned long     length_errors;
    194195          unsigned long     frame_errors;
     
    224225static struct wm_softc *root_i82544EI_dev = NULL;
    225226
    226227static void i82544EI_ifstart(struct ifnet *ifp);
    227 static int  wm_ioctl(struct ifnet *ifp, u_long cmd,uint32_t data);
     228static int  wm_ioctl(struct ifnet *ifp, ioctl_command_t cmd,caddr_t data);
    228229static void i82544EI_ifinit(void *arg);
    229230static void wm_stop(struct ifnet *ifp, int disable);
     231static void wm_gmii_mediainit(struct wm_softc *sc);
    230232
    231233static void wm_rxdrain(struct wm_softc *sc);
    232234static int  wm_add_rxbuf(struct wm_softc *sc, int idx);
    233235static int  wm_read_eeprom(struct wm_softc *sc,int word,int wordcnt, uint16_t *data);
    234236static void i82544EI_daemon(void *arg);
    235237static void wm_set_filter(struct wm_softc *sc);
    236 
    237 static void i82544EI_isr(void);
     238static void i82544EI_rx(struct wm_softc *sc);
     239static void i82544EI_isr(rtems_irq_hdl_param handle);
    238240static void i82544EI_sendpacket(struct wm_softc *sc, struct mbuf *m);
    239 extern int pci_mem_find(int b, int d, int f, int reg, unsigned *basep,unsigned *sizep);
    240 extern int pci_io_find(int b, int d, int f, int reg,unsigned *basep,unsigned *sizep);
    241 extern int pci_get_capability(int b, int d, int f, int capid,int *offset,uint32_t *value);
    242 extern char * ether_sprintf1(void);
     241extern int  pci_mem_find(), pci_io_find(), pci_get_capability();
    243242
    244243static void i82544EI_irq_on(const rtems_irq_connect_data *irq)
    245244{
     
    271270static rtems_irq_connect_data i82544IrqData={
    272271        BSP_GPP_82544_IRQ,
    273272        (rtems_irq_hdl) i82544EI_isr,
     273        (rtems_irq_hdl_param) NULL,
    274274        (rtems_irq_enable) i82544EI_irq_on,
    275275        (rtems_irq_disable) i82544EI_irq_off,
    276276        (rtems_irq_is_enabled) i82544EI_irq_is_on,
     
    290290
    291291  unit = rtems_bsdnet_parse_driver_name(config, &name);
    292292  if (unit < 0) return 0;
    293  
    294   printk("\nEthernet driver name %s unit %d \n",name, unit);
    295   printk("Copyright (c) 2004,2005 S. Kate Feng <feng1@bnl.gov> (RTEMS/mvme5500 port)\n");
     293
     294  if ( !strncmp((const char *)name,"autoz",5))
     295     memcpy(name,"gtGHz",5);
     296         
     297  printk("\nAttaching MVME5500 1GHz NIC%d\n", unit);
     298  printk("RTEMS-mvme5500 BSP Copyright (c) 2004,2005,2008, Brookhaven National Lab., Shuchen Kate Feng \n");
    296299
    297300  /* Make sure certain elements e.g. descriptor lists are aligned.*/
    298301  softc_mem = rtems_bsdnet_malloc(sizeof(*sc) + SOFTC_ALIGN, M_FREE, M_NOWAIT);
     
    310313                        unit-1,&b, &d, &f))
    311314    rtems_panic("i82544EI device ID not found\n");
    312315
    313 #if WM_DEBUG
     316#ifdef WM_DEBUG
    314317  printk("82544EI:b%d, d%d, f%d\n", b, d,f);
    315318#endif
    316319
     
    318321  if ( pci_mem_find(b,d,f,PCI_MAPREG_START, &sc->sc_membase, &sc->sc_memsize))
    319322     rtems_panic("i82544EI: unable to map memory space\n");
    320323
     324#ifdef WM_DEBUG
     325  printk("Memory base addr 0x%x\n", sc->sc_membase);
     326#endif
     327  BSP_1GHz_membase= sc->sc_membase;
     328
    321329#ifdef WM_DEBUG
    322330  printk("Memory base addr 0x%x\n", sc->sc_membase);
    323331  printk("txdesc[0] addr:0x%x, rxdesc[0] addr:0x%x, sizeof sc %d\n",&sc->sc_txdescs[0], &sc->sc_rxdescs[0], sizeof(*sc));     
    324332#endif
    325333
    326334
    327   sc->sc_ctrl |=CSR_READ(sc,WMREG_CTRL); 
     335  sc->sc_ctrl=CSR_READ(sc,WMREG_CTRL); 
    328336  /*
    329337   * Determine a few things about the bus we're connected to.
    330338   */
     
    362370  enaddr[4] = myea[2] & 0xff;
    363371  enaddr[5] = myea[2] >> 8;
    364372
    365 
    366373  memcpy(sc->arpcom.ac_enaddr, enaddr, ETHER_ADDR_LEN);
    367374#ifdef WM_DEBUG
    368375  printk("%s: Ethernet address %s\n", sc->dv_xname,
    369             ether_sprintf1(enaddr));
     376            ether_sprintf(enaddr));
    370377#endif
    371378
    372379  /*
     
    397404  CSR_WRITE(sc,WMREG_CTRL_EXT, sc->sc_ctrl_ext);
    398405#endif
    399406
     407  /*
     408   * Determine if we're TBI or GMII mode, and initialize the
     409   * media structures accordingly.
     410   */
     411  if ((CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
     412    /* 1000BASE-X : fiber  (TBI mode)
     413       wm_tbi_mediainit(sc); */
     414  } else {   /* 1000BASE-T : copper (internal PHY mode), for the mvme5500 */
     415           wm_gmii_mediainit(sc);
     416  } 
     417
    400418  ifp = &sc->arpcom.ac_if;
    401419  /* set this interface's name and unit */
    402420  ifp->if_unit = unit;
    403421  ifp->if_name = name;
    404422  ifp->if_softc = sc;
    405423  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
     424#ifdef RTEMS_ETHERMTU_JUMBO
     425  sc->arpcom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
     426  ifp->if_mtu = config->mtu ? config->mtu : ETHERMTU_JUMBO;
     427#else
    406428  ifp->if_mtu = config->mtu ? config->mtu : ETHERMTU;
     429#endif
     430#ifdef RTEMS_CKSUM_OFFLOAD
     431  /* < skf> The following is really not related to jumbo frame
     432  sc->arpcom.ec_capabilities |= ETHERCAP_VLAN_MTU;*/
     433  ifp->if_capabilities |= IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
     434                    IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
     435                    IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
     436                    IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx |
     437                    IFCAP_TSOv4;  /* TCP segmentation offload. */
     438#endif
     439
    407440  ifp->if_ioctl = wm_ioctl;
    408441  ifp->if_start = i82544EI_ifstart;
    409442  /*  ifp->if_watchdog = wm_watchdog;*/
     
    418451     rtems_build_name('I','G','H','Z'),0,0,0,&sc->daemonSync))
    419452     rtems_panic("i82544EI: semaphore creation failed");
    420453
    421   sc->next_module = root_i82544EI_dev;
     454  i82544IrqData.handle= (rtems_irq_hdl_param) sc;
     455  /* sc->next_module = root_i82544EI_dev;*/
    422456  root_i82544EI_dev = sc;
    423457
    424458  /* Attach the interface. */
     
    432466}
    433467
    434468/*
     469 * wm_reset:
     470 *
     471 *      Reset the i82544 chip.
     472 */
     473static void wm_reset(struct wm_softc *sc)
     474{
     475  int i;
     476
     477  sc->sc_pba = sc->arpcom.ac_if.if_mtu > 8192 ? PBA_40K : PBA_48K;
     478  CSR_WRITE(sc, WMREG_PBA, sc->sc_pba);
     479
     480  /* device reset */
     481  CSR_WRITE(sc, WMREG_CTRL, CTRL_RST);
     482  rtems_bsp_delay(10000);
     483
     484  for (i = 0; i < 1000; i++) {
     485      if ((CSR_READ(sc, WMREG_CTRL) & CTRL_RST) == 0)
     486        break;
     487      rtems_bsp_delay(20);
     488  }
     489  if (CSR_READ(sc, WMREG_CTRL) & CTRL_RST)
     490      printk("Intel 82544 1GHz reset failed to complete\n");
     491
     492  sc->sc_ctrl_ext = CSR_READ(sc,WMREG_CTRL_EXT);
     493  sc->sc_ctrl_ext |= CTRL_EXT_EE_RST;
     494  CSR_WRITE(sc, WMREG_CTRL_EXT, sc->sc_ctrl_ext); 
     495  CSR_READ(sc, WMREG_STATUS);
     496  /* Wait for EEPROM reload */
     497  rtems_bsp_delay(2000);
     498  sc->sc_ctrl= CSR_READ(sc, WMREG_CTRL);
     499}
     500
     501/*
    435502 * i82544EI_ifstart:            [ifnet interface function]
    436503 *
    437504 *      Start packet transmission on the interface.
     
    463530{
    464531  struct ifnet *ifp = &sc->arpcom.ac_if;
    465532
    466   printf("       Rx Interrupts:%-8u\n", sc->stats.rxInterrupts);
     533  printf("    Ghost Interrupts:%-8lu\n", sc->stats.ghostInterrupts);
     534  printf("       Rx Interrupts:%-8lu\n", sc->stats.rxInterrupts);
    467535  printf("     Receive Packets:%-8u\n", CSR_READ(sc,WMREG_GPRC));
    468   printf("     Receive Overrun:%-8u\n", sc->stats.rxOvrRunInterrupts);
     536  printf("     Receive Overrun:%-8lu\n", sc->stats.rxOvrRunInterrupts);
    469537  printf("     Receive  errors:%-8u\n", CSR_READ(sc,WMREG_RXERRC));
    470   printf("   Rx sequence error:%-8u\n", sc->stats.rxSeqErr);
    471   printf("      Rx /C/ ordered:%-8u\n", sc->stats.rxC_ordered);
     538  printf("   Rx sequence error:%-8lu\n", sc->stats.rxSeqErr);
     539  printf("      Rx /C/ ordered:%-8lu\n", sc->stats.rxC_ordered);
    472540  printf("    Rx Length Errors:%-8u\n", CSR_READ(sc,WMREG_RLEC));
    473   printf("       Tx Interrupts:%-8u\n", sc->stats.txInterrupts);
    474 #if 0
    475   printf("Multi-BuffTx Packets:%-8u\n", sc->stats.txMultiBuffPacket);
    476   printf("Multi-BuffTx max len:%-8u\n", sc->stats.txMultiMaxLen);
    477   printf("SingleBuffTx max len:%-8u\n", sc->stats.txSinglMaxLen);
    478   printf("Multi-BuffTx maxloop:%-8u\n", sc->stats.txMultiMaxLoop);
    479   printf("Tx buffer max len   :%-8u\n", sc->stats.txBuffMaxLen);
    480 #endif
     541  printf("       Tx Interrupts:%-8lu\n", sc->stats.txInterrupts);
    481542  printf("   Transmitt Packets:%-8u\n", CSR_READ(sc,WMREG_GPTC));
    482   printf("   Transmitt  errors:%-8u\n", ifp->if_oerrors);
    483   printf("         Active Txqs:%-8u\n", sc->txq_nactive);
     543  printf("   Transmitt  errors:%-8lu\n", ifp->if_oerrors);
     544  printf("         Active Txqs:%-8lu\n", sc->txq_nactive);
    484545  printf("          collisions:%-8u\n", CSR_READ(sc,WMREG_COLC));
    485546  printf("          Crc Errors:%-8u\n", CSR_READ(sc,WMREG_CRCERRS));
    486   printf("  Link Status Change:%-8u\n", sc->stats.linkStatusChng);
     547  printf("  Link Status Change:%-8lu\n", sc->stats.linkStatusChng);
    487548}
    488549
    489550/*
     
    491552 *
    492553 *      Handle control requests from the operator.
    493554 */
    494 static int wm_ioctl(struct ifnet *ifp, u_long cmd,uint32_t data)
     555static int wm_ioctl(struct ifnet *ifp, ioctl_command_t cmd,caddr_t data)
    495556{
    496557  struct wm_softc *sc = ifp->if_softc;
    497558  int error=0;
     
    523584 *
    524585 *      Interrupt service routine.
    525586 */
    526 static void i82544EI_isr()
     587static void i82544EI_isr(rtems_irq_hdl_param handle)
    527588{
    528   volatile struct wm_softc *sc = root_i82544EI_dev;
     589  volatile struct wm_softc *sc = (struct wm_softc *) handle;
    529590  uint32_t icr;
    530591  rtems_event_set  events=0;
    531592
     
    549610     events |= INIT_EVENT;
    550611  }
    551612  if (icr & ICR_RXSEQ) /* framing error */ {
    552      sc->intr_errsts[sc->intr_err_ptr2++]=icr;
    553      sc->intr_err_ptr2 %=INTR_ERR_SIZE; /* Till Straumann */
     613     sc->if_errsts[sc->if_err_ptr2++]=icr;
     614     if ( sc->if_err_ptr2 ==IF_ERR_BUFSZE) sc->if_err_ptr2=0;
    554615     events |= ERR_EVENT;
    555616     sc->stats.rxSeqErr++;
    556617  }
     
    608669         * The other way is effective for packets < 2K
    609670         */
    610671        if ( ((y=(len+mtp->m_len)) > sizeof(union mcluster))) {
    611           printk(">2048, use next descriptor\n");
     672          printk(" >%d, use next descriptor\n", sizeof(union mcluster));
    612673          break;
    613674        }
    614675        memcpy((void *)pt,(char *)mtp->m_data, mtp->m_len);
    615676        pt += mtp->m_len;
    616677        len += mtp->m_len;
    617 #if 0
    618         sc->stats.txSinglMaxLen= MAX(mtp->m_len, sc->stats.txSinglMaxLen);
    619 #endif
    620678      } /* end for loop */
    621679      mdest->m_len=len;
    622680      sc->txs_mbuf[sc->txq_next] = mdest;
     
    630688         sc->txq_free--;
    631689      else
    632690         rtems_panic("i8254EI : no more free descriptors");
    633 #if 0
    634       sc->stats.txMultiMaxLen= MAX(mdest->m_len, sc->stats.txMultiMaxLen);
    635       sc->stats.txMultiBuffPacket++;
    636 #endif
    637691    } /* end for while */
    638692    /* free old mbuf chain */
    639 #if 0
    640     sc->stats.txMultiMaxLoop=MAX(loop, sc->stats.txMultiMaxLoop);
    641 #endif
    642693    m_freem(m);
    643694    m=0;
    644695  }  /* end  multiple mbufs */
     
    744795                    sc->dv_xname, i));
    745796
    746797    status = sc->sc_rxdescs[i].wrx_status;
     798    if ((status & WRX_ST_DD) == 0)  break; /* descriptor not done */
     799
    747800    errors = sc->sc_rxdescs[i].wrx_errors;
    748801    len = le16toh(sc->sc_rxdescs[i].wrx_len);
    749802    m = sc->rxs_mbuf[i];
    750 
    751     if ((status & WRX_ST_DD) == 0)  break; /* descriptor not done */
    752 
    753803    if (sc->sc_rxdiscard) {
    754804       printk("RX: discarding contents of descriptor %d\n", i);
    755805       wm_init_rxdesc(sc, i);
     
    821871  int i,error;
    822872  uint8_t cksumfields;
    823873
     874#if 0
     875  /* KATETODO : sc_align_tweak */
     876        /*
     877         * *_HDR_ALIGNED_P is constant 1 if __NO_STRICT_ALIGMENT is set.
     878         * There is a small but measurable benefit to avoiding the adjusment
     879         * of the descriptor so that the headers are aligned, for normal mtu,
     880         * on such platforms.  One possibility is that the DMA itself is
     881         * slightly more efficient if the front of the entire packet (instead
     882         * of the front of the headers) is aligned.
     883         *
     884         * Note we must always set align_tweak to 0 if we are using
     885         * jumbo frames.
     886         */
     887#ifdef __NO_STRICT_ALIGNMENT
     888        sc->sc_align_tweak = 0;
     889#else
     890        if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN) > (MCLBYTES - 2))
     891                sc->sc_align_tweak = 0;
     892        else
     893                sc->sc_align_tweak = 2;
     894#endif /* __NO_STRICT_ALIGNMENT */
     895#endif
     896
    824897  /* Cancel any pending I/O. */
    825898  wm_stop(ifp, 0);
    826899
     900  /* update statistics before reset */
     901  ifp->if_collisions += CSR_READ(sc, WMREG_COLC);
     902  ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC);
     903
     904  /* Reset the chip to a known state. */
     905  wm_reset(sc);
     906
    827907  /* Initialize the error buffer ring */
    828   sc->intr_err_ptr1=0;
    829   sc->intr_err_ptr2=0;
    830   for (i=0; i< INTR_ERR_SIZE; i++) sc->intr_errsts[i]=0;
     908  sc->if_err_ptr1=0;
     909  sc->if_err_ptr2=0;
     910  for (i=0; i< IF_ERR_BUFSZE; i++) sc->if_errsts[i]=0;
    831911
    832912  /* Initialize the transmit descriptor ring. */
    833   memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
     913  memset( (void *) sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
    834914  sc->txq_free = NTXDESC;
    835915  sc->txq_next = 0;
    836916  sc->txs_lastdesc = 0;
     
    849929  CSR_WRITE(sc,WMREG_TDLEN, sizeof(sc->sc_txdescs));
    850930  CSR_WRITE(sc,WMREG_TDH, 0);
    851931  CSR_WRITE(sc,WMREG_TDT, 0);
    852   CSR_WRITE(sc,WMREG_TIDV, 64 );
    853   CSR_WRITE(sc,WMREG_TADV, 128);
     932  CSR_WRITE(sc,WMREG_TIDV, 0 );
     933  /* CSR_WRITE(sc,WMREG_TADV, 128);  not for 82544 */
    854934
    855935  CSR_WRITE(sc,WMREG_TXDCTL, TXDCTL_PTHRESH(0) |
    856936                    TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0));
     
    864944   * Set up checksum offload parameters for
    865945   * this packet.
    866946   */
    867 #ifdef CKSUM_OFFLOAD
    868   if (m0->m_pkthdr.csum_flags &
    869      (M_CSUM_IPv4|M_CSUM_TCPv4|M_CSUM_UDPv4)) {
    870      if (wm_tx_cksum(sc, txs, &TxDescCmd,&cksumfields) != 0) {
     947#ifdef RTEMS_CKSUM_OFFLOAD
     948  if (m0->m_pkthdr.csum_flags & (M_CSUM_TSOv4|M_CSUM_TSOv6|
     949                    M_CSUM_IPv4|M_CSUM_TCPv4|M_CSUM_UDPv4|
     950                                 M_CSUM_TCPv6|M_CSUM_UDPv6)) {
     951     if (wm_tx_offload(sc, txs, &TxDescCmd,&cksumfields) != 0) {
    871952         /* Error message already displayed. */
    872953         continue;
    873954     }
     
    875956#endif
    876957     TxDescCmd = 0;
    877958     cksumfields = 0;
    878 #ifdef CKSUM_OFFLOAD
     959#ifdef RTEMS_CKSUM_OFFLOAD
    879960  }
    880961#endif
    881962
     
    894975   * Initialize the receive descriptor and receive job
    895976   * descriptor rings.
    896977   */
    897   memset(sc->sc_rxdescs, 0, sizeof(sc->sc_rxdescs));
     978  memset( (void *) sc->sc_rxdescs, 0, sizeof(sc->sc_rxdescs));
    898979  CSR_WRITE(sc,WMREG_RDBAH, 0);
    899980  CSR_WRITE(sc,WMREG_RDBAL, WM_CDRXADDR(sc));
    900981  CSR_WRITE(sc,WMREG_RDLEN, sizeof(sc->sc_rxdescs));
    901982  CSR_WRITE(sc,WMREG_RDH, 0);
    902983  CSR_WRITE(sc,WMREG_RDT, 0);
    903984  CSR_WRITE(sc,WMREG_RDTR, 0 |RDTR_FPD);
    904   CSR_WRITE(sc, WMREG_RADV, 256);
     985  /* CSR_WRITE(sc, WMREG_RADV, 256);  not for 82544.  */
    905986
    906987  for (i = 0; i < NRXDESC; i++) {
    907988      if (sc->rxs_mbuf[i] == NULL) {
     
    9451026
    9461027  CSR_WRITE(sc,WMREG_FCRTH, FCRTH_DFLT);
    9471028  CSR_WRITE(sc,WMREG_FCRTL, sc->sc_fcrtl);
    948   CSR_WRITE(sc,WMREG_FCTTV, FCTTV_DFLT);
     1029  /*KATETO   CSR_WRITE(sc,WMREG_FCTTV, FCTTV_DFLT);*/
     1030  CSR_WRITE(sc,WMREG_FCTTV, 0x100);
    9491031
    9501032  sc->sc_ctrl &= ~CTRL_VME;
    951   /*sc->sc_ctrl |= CTRL_TFCE | CTRL_RFCE;*/
    952   /* enable Big Endian Mode for the powerPC
    953   sc->sc_ctrl |= CTRL_BEM;*/
     1033  /* KATETODo : not here.
     1034     Configures flow control settings after link is established
     1035     sc->sc_ctrl |= CTRL_TFCE | CTRL_RFCE; */
    9541036
    9551037  /* Write the control registers. */
    9561038  CSR_WRITE(sc,WMREG_CTRL, sc->sc_ctrl);
     
    9581040  CSR_WRITE(sc,WMREG_CTRL_EXT, sc->sc_ctrl_ext);
    9591041#endif
    9601042
    961   /* MOTLoad : WMREG_RXCSUM (0x5000)= 0, no Rx checksum offloading */ 
     1043  /* MOTLoad : WMREG_RXCSUM (0x5000)= 0, no Rx checksum offloading */
     1044#ifdef RTEMS_CKSUM_OFFLOAD
     1045  /*
     1046   * Set up checksum offload parameters.
     1047   */
     1048   reg = CSR_READ(sc, WMREG_RXCSUM);
     1049   reg &= ~(RXCSUM_IPOFL | RXCSUM_IPV6OFL | RXCSUM_TUOFL);
     1050   if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx)
     1051            reg |= RXCSUM_IPOFL;
     1052   if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx))
     1053            reg |= RXCSUM_IPOFL | RXCSUM_TUOFL;
     1054   if (ifp->if_capenable & (IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx))
     1055            reg |= RXCSUM_IPV6OFL | RXCSUM_TUOFL;
     1056   CSR_WRITE(sc, WMREG_RXCSUM, reg);
     1057#endif
    9621058
    9631059  /*
    9641060   * Set up the interrupt registers.
     
    9871083   * we resolve the media type.
    9881084   */
    9891085  sc->sc_tctl = TCTL_EN | TCTL_PSP | TCTL_CT(TX_COLLISION_THRESHOLD) |
    990             TCTL_COLD(TX_COLLISION_DISTANCE_FDX) | TCTL_RTLC; /*transmitter enable*/
     1086            TCTL_COLD(TX_COLLISION_DISTANCE_FDX) |
     1087            TCTL_RTLC /* transmit on late collision */;
    9911088
    9921089  /*
    9931090   * Set up the receive control register; we actually program
     
    9951092   * address offset type 0.
    9961093   *
    9971094   * Only the i82544 has the ability to strip the incoming
    998    * CRC, so we don't enable that feature. (TODO)
     1095   * CRC, so we don't enable that feature. (TODO: |RCTL_SECRC)
    9991096   */
    10001097  sc->sc_mchash_type = 0;
    10011098  sc->sc_rctl = RCTL_EN | RCTL_LBM_NONE | RCTL_RDMTS_1_2 | RCTL_LPE |
    1002             RCTL_DPF | RCTL_MO(sc->sc_mchash_type);
     1099    RCTL_DPF | RCTL_MO(sc->sc_mchash_type)|RCTL_SECRC;
    10031100
    1004   /* (MCLBYTES == 2048) */
    1005   sc->sc_rctl |= RCTL_2k;
     1101  if (MCLBYTES == 2048) {
     1102     sc->sc_rctl |= RCTL_2k;
     1103  } else {
     1104        switch(MCLBYTES) {
     1105        case 4096:
     1106             sc->sc_rctl |= RCTL_BSEX | RCTL_BSEX_4k;
     1107             break;
     1108        case 8192:
     1109             sc->sc_rctl |= RCTL_BSEX | RCTL_BSEX_8k;
     1110             break;
     1111        case 16384:
     1112             sc->sc_rctl |= RCTL_BSEX | RCTL_BSEX_16k;
     1113             break;
     1114        default:
     1115             rtems_panic("wm_init: MCLBYTES %d unsupported",
     1116                    MCLBYTES);
     1117             break;
     1118        }
     1119  }
    10061120
    10071121#ifdef WM_DEBUG
    10081122  printk("RDBAL 0x%x,RDLEN %d, RDT %d\n",CSR_READ(sc,WMREG_RDBAL),CSR_READ(sc,WMREG_RDLEN), CSR_READ(sc,WMREG_RDT));
     
    10201134  return(0);
    10211135}
    10221136
     1137void BSP_rdTIDV()
     1138{
     1139  printf("Reg TIDV: 0x%x\n", in_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_TIDV)));
     1140}
     1141void BSP_rdRDTR()
     1142{
     1143  printf("Reg RDTR: 0x%x\n", in_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_RDTR)));
     1144}
     1145
     1146void BSP_setTIDV(int val)
     1147{
     1148  out_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_TIDV), val);
     1149}
     1150
     1151void BSP_setRDTR(int val)
     1152{
     1153  out_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_RDTR), val);
     1154}
    10231155/*
    10241156 * i82544EI_ifinit:             [ifnet interface function]
    10251157 *
     
    12351367  return (0);
    12361368}
    12371369
     1370#if 0
    12381371/*
    12391372 * wm_acquire_eeprom:
    12401373 *
     
    12661399
    12671400  return (0);
    12681401}
     1402#endif
    12691403
    12701404/*
    12711405 * wm_read_eeprom:
     
    13701504  mta_reg = WMREG_CORDOVA_MTA;
    13711505  sc->sc_rctl &= ~(RCTL_BAM | RCTL_UPE | RCTL_MPE);
    13721506
    1373   /*  if (ifp->if_flags & IFF_BROADCAST)*/
     1507  if (ifp->if_flags & IFF_BROADCAST)
    13741508     sc->sc_rctl |= RCTL_BAM;
    13751509  if (ifp->if_flags & IFF_PROMISC) {
    13761510     sc->sc_rctl |= RCTL_UPE;
     
    14401574static void i82544EI_error(struct wm_softc *sc)
    14411575{
    14421576  struct ifnet          *ifp = &sc->arpcom.ac_if;
    1443   unsigned long         intr_status= sc->intr_errsts[sc->intr_err_ptr1++];
     1577  unsigned long         intr_status= sc->if_errsts[sc->if_err_ptr1];
    14441578
    14451579  /* read and reset the status; because this is written
    14461580   * by the ISR, we must disable interrupts here
    14471581   */
    1448   sc->intr_err_ptr1 %=INTR_ERR_SIZE; /* Till Straumann */
    14491582  if (intr_status) {
    14501583    printk("Error %s%d:", ifp->if_name, ifp->if_unit);
    14511584    if (intr_status & ICR_RXSEQ) {
     
    14551588  }
    14561589  else
    14571590    printk("%s%d: Ghost interrupt ?\n",ifp->if_name,ifp->if_unit);
     1591  sc->if_errsts[sc->if_err_ptr1]=0; 
     1592  if ((++sc->if_err_ptr1)==IF_ERR_BUFSZE) sc->if_err_ptr1=0; /* Till Straumann */
    14581593}
    14591594
    14601595void i82544EI_printStats()
     
    14951630                                &events);
    14961631     if (KILL_EVENT & events)  break;
    14971632
    1498      if (events & RX_EVENT)  i82544EI_rx(sc);
     1633     if (events & RX_EVENT)  i82544EI_rx(sc); /* in ISR instead */
    14991634
    15001635     /* clean up and try sending packets */
    15011636     do {
     
    15031638
    15041639        while (sc->txq_free>0) {
    15051640           if (sc->txq_free>TXQ_HiLmt_OFF) {
     1641              m=0;
    15061642              IF_DEQUEUE(&ifp->if_snd,m);
    15071643              if (m==0) break;
    15081644              i82544EI_sendpacket(sc, m);
     
    15111647              i82544EI_txq_done(sc);
    15121648              break;
    15131649           }
    1514            if (events & RX_EVENT)  i82544EI_rx(sc);
    15151650        }
    15161651         /* we leave this loop
    15171652          *  - either because there's no free buffer
     
    15191654          *  - or there's nothing to send (IF_DEQUEUE
    15201655          *    returned 0
    15211656          */
    1522      } while (m && sc->txq_free);
     1657     } while (m);
    15231658
    15241659     ifp->if_flags &= ~IFF_OACTIVE;
    15251660
     
    15561691   */
    15571692  rtems_task_delete(RTEMS_SELF);
    15581693}
     1694
     1695/*
     1696 * wm_gmii_reset:
     1697 *
     1698 *      Reset the PHY.
     1699 */
     1700static void wm_gmii_reset(struct wm_softc *sc)
     1701{
     1702
     1703  CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET);
     1704  rtems_bsp_delay(20000);
     1705
     1706  CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
     1707  rtems_bsp_delay(20000);
     1708
     1709}
     1710
     1711/*
     1712 * wm_gmii_mediainit:
     1713 *
     1714 *      Initialize media for use on 1000BASE-T devices.
     1715 */
     1716static void wm_gmii_mediainit(struct wm_softc *sc)
     1717{
     1718  /*  struct ifnet *ifp = &sc->arpcom.ac_if;*/
     1719
     1720  /* We have MII. */
     1721  sc->sc_flags |= WM_F_HAS_MII;
     1722
     1723  sc->sc_tipg = TIPG_1000T_DFLT; /* 0x602008 */
     1724
     1725  /*
     1726   * Let the chip set speed/duplex on its own based on
     1727   * signals from the PHY.
     1728   * XXXbouyer - I'm not sure this is right for the 80003,
     1729   * the em driver only sets CTRL_SLU here - but it seems to work.
     1730   */
     1731  sc->sc_ctrl |= CTRL_SLU;
     1732  CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
     1733
     1734  wm_gmii_reset(sc);
     1735
     1736#if 0
     1737  /* Initialize our media structures and probe the GMII. */
     1738  sc->sc_mii.mii_ifp = ifp;
     1739
     1740  sc->sc_mii.mii_readreg = wm_gmii_i82544_readreg;
     1741  sc->sc_mii.mii_writereg = wm_gmii_i82544_writereg;
     1742  sc->sc_mii.mii_statchg = wm_gmii_statchg;
     1743
     1744  ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, wm_gmii_mediachange,
     1745            wm_gmii_mediastatus);
     1746
     1747  mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
     1748            MII_OFFSET_ANY, MIIF_DOPAUSE);
     1749  if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
     1750     ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
     1751     ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
     1752  } else
     1753      ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
     1754#endif
     1755}
  • network/if_1GHz/if_wmreg.h

    diff -Naur mvme5500.orig/network/if_1GHz/if_wmreg.h mvme5500/network/if_1GHz/if_wmreg.h
    old new  
    55 * All rights reserved.
    66 *
    77 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
     8 * Some are added by Shuchen Kate Feng <feng1@bnl.gov>,
     9 *            NSLS, Brookhaven National Laboratory. All rights reserved.
     10 *            under the Deaprtment of Energy contract DE-AC02-98CH10886
    811 *
    912 * Redistribution and use in source and binary forms, with or without
    1013 * modification, are permitted provided that the following conditions
     
    5659 * The receive descriptor ring must be aligned to a 4K boundary,
    5760 * and there must be an even multiple of 8 descriptors in the ring.
    5861 */
    59 typedef struct wiseman_rxdesc {
     62typedef volatile struct wiseman_rxdesc {
    6063        wiseman_addr_t  wrx_addr;       /* buffer address */
    6164
    6265        uint16_t        wrx_len;        /* buffer length */
     
    103106        uint8_t wtxu_options;           /* options */
    104107        uint16_t wtxu_vlan;             /* VLAN info */
    105108} __attribute__((__packed__)) wiseman_txfields_t;
    106 typedef struct wiseman_txdesc {
     109typedef volatile struct wiseman_txdesc {
    107110        wiseman_addr_t  wtx_addr;       /* buffer address */
    108111        uint32_t        wtx_cmdlen;     /* command and length */
    109112        wiseman_txfields_t wtx_fields;  /* fields; see below */
  • network/if_1GHz/pcireg.h

    diff -Naur mvme5500.orig/network/if_1GHz/pcireg.h mvme5500/network/if_1GHz/pcireg.h
    old new  
    44 * Copyright (c) 1995, 1996, 1999, 2000
    55 *     Christopher G. Demetriou.  All rights reserved.
    66 * Copyright (c) 1994, 1996 Charles M. Hannum.  All rights reserved.
     7 * Copyright (C) 2007 Brookhaven National Laboratory, Shuchen Kate Feng
    78 *
    89 * Redistribution and use in source and binary forms, with or without
    910 * modification, are permitted provided that the following conditions
     
    3031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    3132 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    3233 */
     34#include <bsp.h>
    3335
    3436/*
    3537 * PCI Class and Revision Register; defines type and revision of device.
     
    305307#define PCI_MAPREG_MEM64_ADDR_MASK              0xfffffffffffffff0ULL
    306308
    307309#define PCI_MAPREG_IO_ADDR(mr)                                          \
    308             ((mr) & PCI_MAPREG_IO_ADDR_MASK)
     310            ((mr+PCI0_IO_BASE) & PCI_MAPREG_IO_ADDR_MASK)
    309311#define PCI_MAPREG_IO_SIZE(mr)                                          \
    310312            (PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr))
    311313#define PCI_MAPREG_IO_ADDR_MASK                 0xfffffffc
  • network/if_1GHz/POSSIBLEBUG

    diff -Naur mvme5500.orig/network/if_1GHz/POSSIBLEBUG mvme5500/network/if_1GHz/POSSIBLEBUG
    old new  
    1 S. Kate Feng <feng1@bnl.gov>, Sept. 06, 2007
    2 
    3 This driver boots smoothly with the 1GHZ media.
    4 It might not boot with the 10/100MHZ media.
  • pci/pci.c

    diff -Naur mvme5500.orig/pci/pci.c mvme5500/pci/pci.c
    old new  
    1313 *  found in the file LICENSE in this distribution or at
    1414 *  http://www.rtems.com/rtems/license.html.
    1515 *
    16  *  Copyright 2004, Brookhaven National Laboratory and
    17  *                  Shuchen K. Feng, <feng1@bnl.gov>, 2004
    18  *   - modified and added support for MVME5500 board
    19  *   - added 2nd PCI support for the mvme5500/GT64260 PCI bridge
    20  *   - added bus support for the expansion of PMCSpan, thanks to
    21  *     Peter Dufault (dufault@hda.com) for inputs.
     16 *  pci.c,v 1.2 2002/05/14 17:10:16 joel Exp
    2217 *
    23  * $Id: pci.c,v 1.13 2008/08/20 08:56:56 ralf Exp $
     18 *  Copyright 2004, 2008 Brookhaven National Laboratory and
     19 *                  Shuchen K. Feng, <feng1@bnl.gov>
     20 *   
     21 *   - to be consistent with the original pci.c written by Eric Valette
     22 *   - added 2nd PCI support for discovery based PCI bridge (e.g. mvme5500/mvme6100)
     23 *   - added bus support for the expansion of PMCSpan as per request by Peter
    2424 */
    2525#define PCI_MAIN
    2626
    2727#include <libcpu/io.h>
    2828#include <rtems/bspIo.h>            /* printk */
    2929
     30#include <bsp/irq.h>
    3031#include <bsp/pci.h>
    3132#include <bsp/gtreg.h>
    3233#include <bsp/gtpcireg.h>
     34#include <bsp.h>
    3335
    3436#include <stdio.h>
    3537#include <string.h>
    3638
    3739#define PCI_DEBUG 0
    38 #define PCI_PRINT 0
     40#define PCI_PRINT 1
    3941
    4042/* allow for overriding these definitions */
    4143#ifndef PCI_CONFIG_ADDR
     
    5658#define PCI_MULTI_FUNCTION              0x80
    5759#define HOSTBRIDGET_ERROR               0xf0000000
    5860
    59 /* define a shortcut */
    60 #define pci     BSP_pci_configuration
     61#define GT64x60_PCI_CONFIG_ADDR         GT64x60_REG_BASE + PCI_CONFIG_ADDR
     62#define GT64x60_PCI_CONFIG_DATA         GT64x60_REG_BASE + PCI_CONFIG_DATA
     63
     64#define GT64x60_PCI1_CONFIG_ADDR        GT64x60_REG_BASE + PCI1_CONFIG_ADDR
     65#define GT64x60_PCI1_CONFIG_DATA        GT64x60_REG_BASE + PCI1_CONFIG_DATA
     66
     67static int      numPCIDevs=0;
     68static DiscoveryChipVersion BSP_sysControllerVersion = 0;
     69static BSP_VMEchipTypes BSP_VMEinterface = 0;
     70static pci_config BSP_pci[2]={
     71  {(volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR),
     72   (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA),
     73   0 /* defined at BSP_pci_configuration */},
     74  {(volatile unsigned char*) (GT64x60_PCI1_CONFIG_ADDR),
     75   (volatile unsigned char*) (GT64x60_PCI1_CONFIG_DATA),
     76   0 /* defined at BSP_pci_configuration */}
     77};
    6178
    62 static int                numPCIDevs=0;
    6379extern void pci_interface(void);
    6480
    6581/* Pack RegNum,FuncNum,DevNum,BusNum,and ConfigEnable for
    6682 * PCI Configuration Address Register
    6783 */
    6884#define pciConfigPack(bus,dev,func,offset)\
    69 (((func&7)<<8)|((dev&0x1f )<<11)|(( bus&0xff)<<16)|(offset&0xfc))|0x80000000
     85((offset&~3)<<24)|(PCI_DEVFN(dev,func)<<16)|(bus<<8)|0x80
    7086
    7187/*
    7288 * Bit encode for PCI_CONFIG_HEADER_TYPE register
     
    7591
    7692/* Please note that PCI0 and PCI1 does not correlate with the busNum 0 and 1.
    7793 */
    78 static int direct_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func,
     94static int indirect_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func,
    7995unsigned char offset,unsigned char *val)
    8096{
    81   volatile unsigned char *config_addr, *config_data;
     97  int n=0;
    8298
    8399  if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
    84100     bus-=BSP_MAX_PCI_BUS_ON_PCI0;
    85      config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
    86      config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
    87   }
    88   else {
    89      config_addr = pci.pci_config_addr;
    90      config_data = pci.pci_config_data;
     101     n=1;
    91102  }
     103
    92104  *val = 0xff;
    93105  if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER;
    94106#if 0
    95   printk("addr %x, data %x, pack %x \n", config_addr,
    96     config_data,pciConfigPack(bus,dev,func,offset));
     107  printk("addr %x, data %x, pack %x \n", BSP_pci[n].pci_config_addr),
     108    BSP_pci[n].config_data,pciConfigPack(bus,dev,func,offset));
    97109#endif
    98   outl(pciConfigPack(bus,dev,func,offset),config_addr);
    99   *val = inb(config_data + (offset&3));
     110
     111  out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
     112  *val = in_8(BSP_pci[n].pci_config_data + (offset&3));
    100113  return PCIBIOS_SUCCESSFUL;
    101114}
    102115
    103 static int direct_pci_read_config_word(unsigned char bus, unsigned char dev,
     116static int indirect_pci_read_config_word(unsigned char bus, unsigned char dev,
    104117unsigned char func, unsigned char offset, unsigned short *val)
    105118{
    106   volatile unsigned char *config_addr, *config_data;
     119  int n=0;
    107120
    108121  if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
    109122     bus-=BSP_MAX_PCI_BUS_ON_PCI0;
    110      config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
    111      config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
    112   }
    113   else {
    114      config_addr = (volatile unsigned char*) pci.pci_config_addr;
    115      config_data = (volatile unsigned char*) pci.pci_config_data;
     123     n=1;
    116124  }
    117125
    118126  *val = 0xffff;
     
    121129  printk("addr %x, data %x, pack %x \n", config_addr,
    122130    config_data,pciConfigPack(bus,dev,func,offset));
    123131#endif
    124   outl(pciConfigPack(bus,dev,func,offset),config_addr);
    125   *val = inw(config_data + (offset&2));
     132  out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
     133  *val = in_le16(BSP_pci[n].pci_config_data + (offset&2));
    126134  return PCIBIOS_SUCCESSFUL;
    127135}
    128136
    129 static int direct_pci_read_config_dword(unsigned char bus, unsigned char dev,
     137static int indirect_pci_read_config_dword(unsigned char bus, unsigned char dev,
    130138unsigned char func, unsigned char offset, unsigned int *val)
    131139{
    132   volatile unsigned char *config_addr, *config_data;
     140  int n=0;
    133141
    134142  if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
    135143     bus-=BSP_MAX_PCI_BUS_ON_PCI0;
    136      config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
    137      config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
    138   }
    139   else {
    140      config_addr = (volatile unsigned char*) pci.pci_config_addr;
    141      config_data = (volatile unsigned char*) pci.pci_config_data;
     144     n=1;
    142145  }
    143146
    144147  *val = 0xffffffff;
    145148  if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER;
    146 #if 0
    147   printk("addr %x, data %x, pack %x \n", config_addr,
    148     pci.pci_config_data,pciConfigPack(bus,dev,func,offset));
    149 #endif
    150   outl(pciConfigPack(bus,dev,func,offset),config_addr);
    151   *val = inl(config_data);
     149
     150  out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
     151  *val = in_le32(BSP_pci[n].pci_config_data);
    152152  return PCIBIOS_SUCCESSFUL;
    153153}
    154154
    155 static int direct_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val)
     155static int indirect_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val)
    156156{
    157   volatile unsigned char *config_addr, *config_data;
     157  int n=0;
    158158
    159159  if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
    160160     bus-=BSP_MAX_PCI_BUS_ON_PCI0;
    161      config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
    162      config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
    163   }
    164   else {
    165      config_addr = pci.pci_config_addr;
    166      config_data = pci.pci_config_data;
     161     n=1;
    167162  }
    168163
    169164  if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER;
    170 #if 0
    171   printk("addr %x, data %x, pack %x \n", config_addr,
    172     config_data,pciConfigPack(bus,dev,func,offset));
    173 #endif
    174165
    175   outl(pciConfigPack(bus,dev,func,offset), config_addr);
    176   outb(val, config_data + (offset&3));
     166  out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
     167  out_8(BSP_pci[n].pci_config_data + (offset&3), val);
    177168  return PCIBIOS_SUCCESSFUL;
    178169}
    179170
    180 static int direct_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val)
     171static int indirect_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val)
    181172{
    182   volatile unsigned char *config_addr, *config_data;
     173  int n=0;
    183174
    184175  if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
    185176     bus-=BSP_MAX_PCI_BUS_ON_PCI0;
    186      config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
    187      config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
    188   }
    189   else {
    190      config_addr = (volatile unsigned char*) pci.pci_config_addr;
    191      config_data = (volatile unsigned char*) pci.pci_config_data;
     177     n=1;
    192178  }
    193179
    194180  if ((offset&1)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER;
    195 #if 0
    196   printk("addr %x, data %x, pack %x \n", config_addr,
    197     config_data,pciConfigPack(bus,dev,func,offset));
    198 #endif
    199   outl(pciConfigPack(bus,dev,func,offset),config_addr);
    200   outw(val, config_data + (offset&3));
     181
     182  out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
     183  out_le16(BSP_pci[n].pci_config_data + (offset&3), val);
    201184  return PCIBIOS_SUCCESSFUL;
    202185}
    203186
    204 static int direct_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val)
     187static int indirect_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val)
    205188{
    206   volatile unsigned char *config_addr, *config_data;
     189  int n=0;
    207190
    208191  if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
    209192     bus-=BSP_MAX_PCI_BUS_ON_PCI0;
    210      config_addr = (volatile unsigned char *) PCI1_CONFIG_ADDR;
    211      config_data = (volatile unsigned char *) PCI1_CONFIG_DATA;
    212   }
    213   else {
    214      config_addr = (volatile unsigned char*) pci.pci_config_addr;
    215      config_data = (volatile unsigned char*) pci.pci_config_data;
     193     n=1;
    216194  }
    217195
    218196  if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER;
    219 #if 0
    220   printk("addr %x, data %x, pack %x \n", config_addr,
    221     config_data,pciConfigPack(bus,dev,func,offset));
    222 #endif
    223   outl(pciConfigPack(bus,dev,func,offset),config_addr);
    224   outl(val,config_data);
     197
     198  out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
     199  out_le32(BSP_pci[n].pci_config_data, val);
    225200  return PCIBIOS_SUCCESSFUL;
    226201}
    227202
    228 const pci_config_access_functions pci_direct_functions = {
    229         direct_pci_read_config_byte,
    230         direct_pci_read_config_word,
    231         direct_pci_read_config_dword,
    232         direct_pci_write_config_byte,
    233         direct_pci_write_config_word,
    234         direct_pci_write_config_dword
     203const pci_config_access_functions pci_indirect_functions = {
     204        indirect_pci_read_config_byte,
     205        indirect_pci_read_config_word,
     206        indirect_pci_read_config_dword,
     207        indirect_pci_write_config_byte,
     208        indirect_pci_write_config_word,
     209        indirect_pci_write_config_dword
    235210};
    236211
    237212
    238 pci_config BSP_pci_configuration = {(volatile unsigned char*) PCI_CONFIG_ADDR,
    239                          (volatile unsigned char*)PCI_CONFIG_DATA,
    240                                     &pci_direct_functions};
     213pci_config BSP_pci_configuration = {
     214           (volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR),
     215           (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA),
     216           &pci_indirect_functions};
     217
     218DiscoveryChipVersion BSP_getDiscoveryChipVersion(void)
     219{
     220  return(BSP_sysControllerVersion);
     221}
     222
     223BSP_VMEchipTypes BSP_getVMEchipType(void)
     224{
     225  return(BSP_VMEinterface);
     226}
    241227
    242228/*
    243229 * This routine determines the maximum bus number in the system.
     
    248234int pci_initialize(void)
    249235{
    250236  int deviceFound;
    251   unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs;
    252   unsigned int ulHeader;
    253   unsigned int pcidata, ulClass, ulDeviceID;
     237  unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs, data8;
     238  uint32_t ulHeader, ulClass, ulDeviceID;
     239#if PCI_DEBUG
     240  uint32_t pcidata;
     241#endif
    254242
    255   pci_interface();
    256  
    257243  /*
    258244   * Scan PCI0 and PCI1 buses
    259245   */
     
    279265      if (!deviceFound) deviceFound=1;
    280266      switch(ulDeviceID) {
    281267        case (PCI_VENDOR_ID_MARVELL+(PCI_DEVICE_ID_MARVELL_GT6426xAB<<16)):
     268          pci_read_config_byte(0,0,0,PCI_REVISION_ID, &data8);
     269          switch(data8) {
     270          case 0x10:
     271            BSP_sysControllerVersion = GT64260A;
    282272#if PCI_PRINT
    283           printk("Marvell GT6426xA/B hostbridge detected at bus%d slot%d\n",
     273            printk("Marvell GT64260A (Discovery I) hostbridge detected at bus%d slot%d\n",
    284274                 ucBusNumber,ucSlotNumber);
    285275#endif
    286           break;
    287         case (PCI_VENDOR_ID_PLX2+(PCI_DEVICE_ID_PLX2_PCI6154_HB2<<16)):
     276            break;
     277          case 0x20:
     278            BSP_sysControllerVersion = GT64260B;
    288279#if PCI_PRINT
    289           printk("PLX PCI6154 PCI-PCI bridge detected at bus%d slot%d\n",
     280            printk("Marvell GT64260B (Discovery I) hostbridge detected at bus%d slot%d\n",
    290281                 ucBusNumber,ucSlotNumber);
    291282#endif
    292           break;
     283            break;
     284          default:
     285            printk("Undefined revsion of GT64260 chip\n");
     286            break;
     287          }
     288          break;
    293289        case PCI_VENDOR_ID_TUNDRA:
    294290#if PCI_PRINT
    295291          printk("TUNDRA PCI-VME bridge detected at bus%d slot%d\n",
    296292                 ucBusNumber,ucSlotNumber);
    297293#endif
    298294          break;
    299       case (PCI_VENDOR_ID_INTEL+(PCI_DEVICE_INTEL_82544EI_COPPER<<16)):
    300 #if PCI_PRINT
    301           printk("INTEL 82544EI COPPER network controller detected at bus%d slot%d\n",
    302                  ucBusNumber,ucSlotNumber);
    303 #endif
    304           break;
    305295      case (PCI_VENDOR_ID_DEC+(PCI_DEVICE_ID_DEC_21150<<16)):
    306  #if PCI_PRINT
     296#if PCI_PRINT
    307297          printk("DEC21150 PCI-PCI bridge detected at bus%d slot%d\n",
    308298                 ucBusNumber,ucSlotNumber);
    309299#endif
    310300          break;
    311301       default :
     302#if PCI_PRINT
    312303          printk("BSP unlisted vendor, Bus%d Slot%d DeviceID 0x%x \n",
    313304             ucBusNumber,ucSlotNumber, ulDeviceID);
     305#endif
     306          /* Kate Feng : device not supported by BSP needs to remap the IRQ line on mvme5500/mvme6100 */
     307          pci_read_config_byte(ucBusNumber,ucSlotNumber,0,PCI_INTERRUPT_LINE,&data8);
     308          if (data8 < BSP_GPP_IRQ_LOWEST_OFFSET)  pci_write_config_byte(ucBusNumber,
     309             ucSlotNumber,0,PCI_INTERRUPT_LINE,BSP_GPP_IRQ_LOWEST_OFFSET+data8);
     310
    314311          break;
    315312      }
    316313
     
    403400#endif
    404401
    405402      }
    406 
    407       pci_read_config_dword(ucBusNumber,
    408                                ucSlotNumber,
    409                                0,
    410                           PCI_COMMAND,
    411                           &pcidata);
    412 #if PCI_DEBUG
    413       printk("MOTLoad command staus 0x%x, ", pcidata);
    414 #endif
    415       /* Clear the error on the host bridge */
    416       if ( (ucBusNumber==0) && (ucSlotNumber==0))
    417         pcidata |= PCI_STATUS_CLRERR_MASK;
    418       /* Enable bus,I/O and memory master access. */
    419       pcidata |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY);
    420       pci_write_config_dword(ucBusNumber,
    421                                ucSlotNumber,
    422                                0,
    423                           PCI_COMMAND,
    424                           pcidata);
    425 
    426       pci_read_config_dword(ucBusNumber,
    427                                ucSlotNumber,
    428                                0,
    429                           PCI_COMMAND,
    430                           &pcidata);
    431 #if PCI_DEBUG     
    432       printk("Now command/staus 0x%x\n", pcidata);
    433 #endif
    434403    }
    435404    if (deviceFound) ucMaxPCIBus++;
    436405  } /* for (ucBusNumber=0; ucBusNumber<BSP_MAX_PCI_BUS; ... */
     
    438407  printk("number of PCI buses: %d, numPCIDevs %d\n",
    439408         pci_bus_count(), numPCIDevs);
    440409#endif
     410  pci_interface();
    441411  return(0);
    442412}
    443413
  • pci/pci_interface.c

    diff -Naur mvme5500.orig/pci/pci_interface.c mvme5500/pci/pci_interface.c
    old new  
    77 * found in the file LICENSE in this distribution.
    88 *
    99 * 8/17/2006 : S. Kate Feng
    10  *             uses in_le32()/out_le32(), instead of inl()/outl() so that
    11  *             it is easier to be ported.
     10 *             uses in_le32()/out_le32(), instead of inl()/outl() for compatibility.
    1211 *
     12 * 11/2008 : Enable "PCI Read Agressive Prefetch",
     13 *           "PCI Read Line Agressive Prefetch", and
     14 *           "PCI Read Multiple Agressive Prefetch" to improve the
     15 *           performance of the PCI based applications (e.g. 1GHz NIC).
    1316 */
     17
    1418#include <libcpu/io.h>
    1519#include <rtems/bspIo.h>            /* printk */
    1620
     
    1923#include <bsp/gtreg.h>
    2024#include <bsp/gtpcireg.h>
    2125
    22 #define REG32_READ(reg) in_le32((volatile unsigned int *)(GT64260_REG_BASE+reg))
    23 #define REG32_WRITE(data, reg) out_le32((volatile unsigned int *)(GT64260_REG_BASE+reg), data)
    24 
    2526#define PCI_DEBUG     0
    2627
    27 /* Please reference the GT64260B datasheet, for the PCI interface,
    28  * Synchronization Barriers and PCI ordering.
    29  *
    30  * Some PCI devices require Synchronization Barriers or PCI ordering
    31  * for synchronization (only one mechanism allowed. See section 11.1.2).
    32  * To use the former mechanism(default), one needs to call
    33  * CPU0_PciEnhanceSync() or CPU1_PciEnhanceSync() to perform software
    34  * synchronization between the CPU and PCI activities.
    35  *
    36  * To use the PCI-ordering, one can call pciToCpuSync() to trigger
    37  * the PCI-to-CPU sync barrier after the out_xx(). In this mode,
    38  * PCI configuration reads suffer sync barrier latency. Please reference
    39  * the datasheet to explore other options.
    40  *
    41  * Note : If PCI_ORDERING is needed for the PCI0, while disabling the
    42  * deadlock  for the PCI0, one should keep the CommDLEn bit enabled
    43  * for the deadlock mechanism so that the 10/100 MB ethernet will
    44  * function correctly.
    45  *
    46  */
    47 /*#define PCI_ORDERING*/
    48 
    49 #define EN_SYN_BAR   /* take MOTLoad default for enhanced SYN Barrier mode */
    50 
    51 /*#define PCI_DEADLOCK*/
     28#if 0
     29#define CPU2PCI_ORDER
     30#define PCI2CPU_ORDER
     31#endif
    5232
    53 #ifdef PCI_ORDERING
    54 #define PCI_ACCCTLBASEL_VALUE          0x01009000
     33/* PCI Read Agressive Prefetch Enable (1<<16 ),
     34 * PCI Read Line Agressive Prefetch Enable( 1<<17),
     35 * PCI Read Multiple Agressive Prefetch Enable (1<<18).
     36 */
     37#ifdef PCI2CPU_ORDER
     38#define PCI_ACCCTLBASEL_VALUE          0x01079000
    5539#else
    56 #define PCI_ACCCTLBASEL_VALUE          0x01001000
     40#define PCI_ACCCTLBASEL_VALUE          0x01071000
    5741#endif
    5842
     43
    5944#define ConfSBDis     0x10000000  /* 1: disable, 0: enable */
    6045#define IOSBDis       0x20000000  /* 1: disable, 0: enable */
    6146#define ConfIOSBDis   0x30000000
    6247#define CpuPipeline   0x00002000  /* optional, 1:enable, 0:disable */
    6348
    64 #define CPU0_SYNC_TRIGGER   0xD0  /* CPU0 Sync Barrier trigger */
    65 #define CPU0_SYNC_VIRTUAL   0xC0  /* CPU0 Sync Barrier Virtual */
    66 
    67 #define CPU1_SYNC_TRIGGER   0xD8  /* CPU1 Sync Barrier trigger */
    68 #define CPU1_SYNC_VIRTUAL   0xC8  /* CPU1 Sync Barrier Virtual */
    69 
    70 
    7149/* CPU to PCI ordering register */
    7250#define DLOCK_ORDER_REG    0x2D0  /* Deadlock and Ordering register */
    7351#define PCI0OrEn      0x00000001
     
    9169void pci_interface(void)
    9270{
    9371
    94 #ifdef PCI_DEADLOCK
    95   REG32_WRITE(0x07fff600, CNT_SYNC_REG);
     72#ifdef CPU2PCI_ORDER
     73    /* MOTLOad deafult : 0x07ff8600 */
     74    out_le32((volatile unsigned int *)(GT64x60_REG_BASE+CNT_SYNC_REG), 0x07fff600);
    9675#endif
    97 #ifdef PCI_ORDERING
    98   /* Let's leave this to be MOTLOad deafult : 0x80070000
    99      REG32_WRITE(0xc0070000, DLOCK_ORDER_REG);*/
    100   /* Leave the CNT_SYNC_REG b/c MOTload default had the SyncBarMode set to 1 */
    101 #endif
    102 
    103   /* asserts SERR upon various detection */
    104   REG32_WRITE(0x3fffff, 0xc28);
    105 
    106   pciAccessInit();
     76    /* asserts SERR upon various detection */
     77    out_le32((volatile unsigned int *)(GT64x60_REG_BASE+0xc28), 0x3fffff);
     78    pciAccessInit();
    10779}
    108 /* Use MOTLoad default for Writeback Priority and Buffer Depth
    109  */
     80
    11081void pciAccessInit(void)
    11182{
    11283  unsigned int PciLocal, data;
    11384
    11485  for (PciLocal=0; PciLocal < 2; PciLocal++) {
    115     /* MOTLoad combines the two banks of SDRAM into
    116      * one PCI access control because the top = 0x1ff
    117      */
    118     data = REG32_READ(GT_SCS0_Low_Decode) & 0xfff;
     86    data = in_le32((volatile unsigned int *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)));
     87#if 0
     88    printk("PCI%d_ACCESS_CNTL_BASE0_LOW was 0x%x\n",PciLocal,data);
     89#endif
    11990    data |= PCI_ACCCTLBASEL_VALUE;
    12091    data &= ~0x300000;
    121     REG32_WRITE(data, PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80));
    122 #if PCI_DEBUG
    123     printk("PCI%d_ACCESS_CNTL_BASE0_LOW 0x%x\n",PciLocal,REG32_READ(PCI_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)));
     92    out_le32((volatile unsigned int *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)), data);
     93#if 0
     94      printf("PCI%d_ACCESS_CNTL_BASE0_LOW now 0x%x\n",PciLocal,in_le32((volatile unsigned int *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80))));
    12495#endif
    125 
    12696  }
    12797}
    12898
    129 /* Sync Barrier Trigger. A write to the CPU_SYNC_TRIGGER register triggers
    130  * the sync barrier process.  The three bits, define which buffers should
    131  * be flushed.
    132  * Bit 0 = PCI0 slave write buffer.
    133  * Bit 1 = PCI1 slave write buffer.
    134  * Bit 2 = SDRAM snoop queue.
    135  */
    136 void CPU0_PciEnhanceSync(unsigned int syncVal)
    137 {
    138   REG32_WRITE(syncVal,CPU0_SYNC_TRIGGER);
    139   while (REG32_READ(CPU0_SYNC_VIRTUAL));
    140 }
    141 
    142 void CPU1_PciEnhanceSync(unsigned int syncVal)
    143 {
    144   REG32_WRITE(syncVal,CPU1_SYNC_TRIGGER);
    145   while (REG32_READ(CPU1_SYNC_VIRTUAL));
    146 }
    147 
    148 /* Currently, if PCI_ordering is used for synchronization, configuration
    149  * reads is programmed to be the PCI slave "synchronization barrier"
    150  * cycles.
    151  */
    152 void pciToCpuSync(int pci_num)
    153 {
    154   unsigned char data;
    155   unsigned char bus=0;
    156 
    157   if (pci_num) bus += BSP_MAX_PCI_BUS_ON_PCI0;
    158   pci_read_config_byte(bus,0,0,4, &data);
    159 }
  • mvme5500

    diff -Naur mvme5500.orig/README mvme5500/README
    old new  
    11#
    2 #  $Id: README,v 1.3.1  Shuchen Kate Feng, NSLS, BNL (08/27/07)
     2#  $Id: README,v 1.4.1  Shuchen Kate Feng, NSLS, BNL (03/16/2009)
    33#
    44
    55Please reference README.booting for the boot/load process.
     
    77For the priority setting of the Interrupt Requests (IRQs), please
    88reference README.irq
    99
    10 The BSP is built and tested on the 4.7.1 and 4.7.99.2 CVS RTEMS release.
     10The BSP is built and tested on the RTEMS 4.9.1 release. The
     11PR1385 patch for c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S
     12is not needed for the mvme5500 BSP because the PowerPC BSPs
     13use the shared exception framework in the RTEMS 4.9 release.
    1114
    1215I believe in valuable real-time programming, where technical neatness,
    1316performance and truth are.  I hope I still believe. Any suggestion,
  • README.booting

    diff -Naur mvme5500.orig/README.booting mvme5500/README.booting
    old new  
    1 README.booting: written by S. Kate Feng <feng1@bnl.gov>, Aug. 28, 2007
     1README.booting: written by S. Kate Feng <feng1@bnl.gov>, March 16, 2009
    22
    3 The bootloader is adapted from Till Straumann's Generic Mini-loader,
    4 which he wrote originally for the SVGM powerpc board.
    5 The BSP is built and tested on the 4.7 CVS RTEMS release.
     3The BSP is built and tested on the RTEMS 4.9.1 release. The
     4PR1385 patch for c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S
     5is not needed for the mvme5500 BSP because the PowerPC BSPs
     6use the shared exception framework in the RTEMS 4.9 release.
    67
    78Booting requirement :
    89-------------------------
     
    1112   or /etc/dhcpd.conf (DHCP) properly to boot the system.
    1213   (Note : EPICS needs a NTP server).
    1314 
    14 2) Please copy the prebuilt RTEMS binary (e.g. misc/rtems5500-cexp.bin)
    15    and perhaps others (e.g. misc/st.sys) to the /tftpboot/epics/hostname/bin/
    16    directory or the TFTPBOOT one you specified in the 'tftpGet'
    17    command of the boot script (as shown in the following example).
    18 
    19 3) Example of the boot script setup carried out on the MOTLoad
     152) Example of the boot script setup carried out on the MOTLoad
    2016   command line :
    2117
    2218MVME5500> gevEdit mot-script-boot
     
    3228Note : (cxx.xx.xx.xx is the client IP address and
    3329        sxx.xx.xx.xx is the server IP address)
    3430
    35 4) Other reference web sites for mvme5500 BSP:
    36 http://lansce.lanl.gov/EPICS/presentations/KateFeng%20RTEMS-mvme55001.ppt
     313) Other reference web sites for mvme5500 BSP:
    3732http://www.nsls.bnl.gov/facility/expsys/software/EPICS/
    38 http://www.nsls.bnl.gov/facility/expsys/software/EPICS/FAQ.txt
    3933
    40 5) When generating code (especially C++) for this system, one should
    41    use at least gcc-3.2 (preferrably a copy downloaded from the RTEMS
    42    site [snapshot area] )
    4334
    44 6) To reboot the RTEMS-MVME5500 (board reset), one can invoke the
     354) To reboot the RTEMS-MVME5500 (board reset), one can invoke the
    4536   rtemsReboot() command at Cexp> prompt.
    4637 
    47 7) Please reference http://www.slac.stanford.edu/~strauman/rtems
    48 for the source code and installation guidance of cexp, GeSys and
    49 other useful utilities such as telnet, nfs, and so on.
    50 
    51 8) To get started with RTEMS/EPICS and to build development
     385) To get started with RTEMS/EPICS and to build development
    5239tools and BSP, I would recommend one to reference
    5340http://www.aps.anl.gov/epics/base/RTEMS/tutorial/
    5441in additional to the RTEMS document.
  • startup/bspclean.c

    diff -Naur mvme5500.orig/startup/bspclean.c mvme5500/startup/bspclean.c
    old new  
     1/* Copyright 2003, Shuchen Kate Feng <feng1@bnl.gov>,
     2 *                    NSLS,Brookhaven National Laboratory
     3 */
    14#include <bsp.h>
    25#include <rtems/bspIo.h>
    36#include <libcpu/stackTrace.h>
  • startup/bspstart.c

    diff -Naur mvme5500.orig/startup/bspstart.c mvme5500/startup/bspstart.c
    old new  
    2424 *  $Id: bspstart.c,v 1.23 2008/08/20 08:56:56 ralf Exp $
    2525 */
    2626
    27 #warning The interrupt disable mask is now stored in SPRG0, please verify that this is compatible to this BSP (see also bootcard.c).
    28 
    2927#include <string.h>
    3028#include <stdlib.h>
    3129#include <ctype.h>
     
    5250#undef __RTEMS_APPLICATION__
    5351#endif
    5452
    55 /*
    56 #define SHOW_MORE_INIT_SETTINGS
     53
     54/*#define SHOW_MORE_INIT_SETTINGS
     55#define CONF_VPD
    5756#define SHOW_LCR1_REGISTER
    5857#define SHOW_LCR2_REGISTER
    5958#define SHOW_LCR3_REGISTER
    60 #define CONF_VPD
    6159*/
    6260
    6361/* there is no public Workspace_Free() variant :-( */
     
    7371extern void BSP_pgtbl_activate(Triv121PgTbl);
    7472extern int I2Cread_eeprom(unsigned char I2cBusAddr, uint32_t devA2A1A0, uint32_t AddrBytes, unsigned char *pBuff, uint32_t numBytes);
    7573extern void BSP_vme_config(void);
     74extern uint32_t probeMemoryEnd();
    7675
    7776uint32_t bsp_clicks_per_usec;
    7877
     
    267266  setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);
    268267
    269268  /* Till Straumann: 2004
    270    * map the PCI 0, 1 Domain I/O space, GT64260B registers
    271    * and the reserved area so that the size is the power of 2.
    272    *
     269   * map the PCI 0, 1 Domain I/O space, GT64260B registers,
     270   * Flash Bank 0 and Flash Bank 2.
    273271   */
    274   setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x2000000, IO_PAGE);
    275 
     272  setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x10000000, IO_PAGE);
    276273
    277274  /*
    278275   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
     
    327324  printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
    328325  printk("-----------------------------------------\n");
    329326
    330 #ifdef TEST_RETURN_TO_PPCBUG 
    331   printk("Hit <Enter> to return to PPCBUG monitor\n");
    332   printk("When Finished hit GO. It should print <Back from monitor>\n");
    333   debug_getc();
    334   _return_to_ppcbug();
    335   printk("Back from monitor\n");
    336   _return_to_ppcbug();
    337 #endif /* TEST_RETURN_TO_PPCBUG  */
    338 
    339 #ifdef TEST_RAW_EXCEPTION_CODE 
    340   printk("Testing exception handling Part 1\n");
    341   /*
    342    * Cause a software exception
    343    */
    344   __asm__ __volatile ("sc");
    345   /*
    346    * Check we can still catch exceptions and returned coorectly.
    347    */
    348   printk("Testing exception handling Part 2\n");
    349   __asm__ __volatile ("sc");
    350 #endif 
    351 
    352   BSP_mem_size         =  _512M;
     327  BSP_mem_size         =  probeMemoryEnd();
    353328  /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
    354329   *       of System Status  register
    355330   */
     
    421396#endif
    422397    BSP_pgtbl_activate(pt);
    423398  }
     399  /* Read Configuration Vital Product Data (VPD) */
     400  if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
     401     printk("I2Cread_eeprom() error \n");
     402  else {
     403#ifdef CONF_VPD
     404    printk("\n");
     405    for (i=0; i<150; i++) {
     406      printk("%2x ", ConfVPD_buff[i]); 
     407      if ((i % 20)==0 ) printk("\n");
     408    }
     409    printk("\n");
     410#endif
     411  }
    424412
    425413  /*
    426414   * PCI 1 domain memory space
     
    444432   */
    445433  _BSP_clear_hostbridge_errors(0, 1 /*quiet*/);
    446434
    447   /* Read Configuration Vital Product Data (VPD) */
    448   if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
    449      printk("I2Cread_eeprom() error \n");
    450   else {
    451 #ifdef CONF_VPD
    452     printk("\n");
    453     for (i=0; i<150; i++) {
    454       printk("%2x ", ConfVPD_buff[i]); 
    455       if ((i % 20)==0 ) printk("\n");
    456     }
    457     printk("\n");
    458 #endif
    459   }
    460 
    461435#ifdef SHOW_MORE_INIT_SETTINGS
    462436  printk("MSR %x \n", _read_MSR());
    463437  printk("Exit from bspstart\n");
  • startup/reboot.c

    diff -Naur mvme5500.orig/startup/reboot.c mvme5500/startup/reboot.c
    old new  
     1/* Copyright 2003, Shuchen Kate Feng <feng1@bnl.gov>,
     2 *                    NSLS,Brookhaven National Laboratory
     3 *
     4 * Ported it from powerpc/shared/console/reboot.c for mvme5500
     5 *
     6 */
     7
    18#include <rtems.h>
    29#include <bsp.h>
    310#include <rtems/bspIo.h>
     
    1219
    1320  printk("RTEMS terminated; Rebooting ...\n");
    1421  /* Mvme5500 board reset : 2004 S. Kate Feng <feng1@bnl.gov>  */
    15   out_8((volatile unsigned char*) (GT64260_DEV1_BASE +2), 0x80);
     22  out_8((volatile unsigned char*) (GT64x60_DEV1_BASE +2), 0x80);
    1623}
  • vectors/exceptionhandler.c

    diff -Naur mvme5500.orig/vectors/exceptionhandler.c mvme5500/vectors/exceptionhandler.c
    old new  
    134134       /* register dump */
    135135       printk("\t Next PC or Address of fault = %x, ", excPtr->EXC_SRR0);
    136136       printk("Mvme5500 Saved MSR = %x\n", excPtr->EXC_SRR1);
     137       printk("The Interrupt mask (e.g. MSR_EE) stored in SPRG0= 0x%x\n",
     138              ppc_interrupt_get_disable_mask());
    137139       printk("\t R0  = %08x", excPtr->GPR0);
    138140       printk(" R1  = %08x", excPtr->GPR1);
    139141       printk(" R2  = %08x", excPtr->GPR2);