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) |
---|
-
ChangeLog
diff -Naur mvme5500.orig/ChangeLog mvme5500/ChangeLog
old new 1 2009-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 18 2009-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 22 2009-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 1 26 2008-12-08 Ralf Corsépius <ralf.corsepius@rtems.org> 2 27 3 28 * bsp_specs: Backport from CVS-HEAD. -
GT64260/gtreg.h
diff -Naur mvme5500.orig/GT64260/gtreg.h mvme5500/GT64260/gtreg.h
old new 190 190 #define GT_MPP_Control2 0xf008 191 191 #define GT_MPP_Control3 0xf00c 192 192 193 /* <skf> added */193 /* <skf> added for GT64260 */ 194 194 #define GT_MPP_SerialPortMultiplex 0xf010 195 195 196 196 #define GT_GPP_IO_Control 0xf100 … … 789 789 #define TWSI_BAUDE_RATE 0xc00c 790 790 #define TWSI_SFT_RST 0xc01c 791 791 792 /* Interrupt Controller - Interrupt Controller Registers */793 792 /* Section 25.2 : Table 734 <skf> */ 794 793 795 #define GT _MAIN_INT_CAUSE_LO 0xc18 /* read Only */796 #define GT _MAIN_INT_CAUSE_HI0xc68 /* read Only */797 #define GT _CPU_INT_MASK_LO 0xc1c798 #define GT _CPU_INT_MASK_HI0xc6c799 #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 */ 800 799 #define GT_PCI0_INT_MASK_LO 0xc24 801 800 #define GT_PCI0_INT_MASK_HI 0xc64 802 801 #define GT_PCI0_SEL_CAUSE 0xc74 /* read Only */ -
include/bsp.h
diff -Naur mvme5500.orig/include/bsp.h mvme5500/include/bsp.h
old new 7 7 * found in found in the file LICENSE in this distribution or at 8 8 * http://www.rtems.com/license/LICENSE. 9 9 * 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 * 11 12 * 12 13 */ 13 14 … … 22 23 #include <libcpu/io.h> 23 24 #include <bsp/vectors.h> 24 25 25 #include <bsp/bspMvme5500.h> 26 /* Board type */ 27 typedef enum { 28 undefined = 0, 29 MVME5500, 30 MVME6100 31 } BSP_BoardTypes; 32 33 BSP_BoardTypes BSP_getBoardType(); 34 35 /* Board type */ 36 typedef enum { 37 Undefined, 38 UNIVERSE2, 39 TSI148, 40 } BSP_VMEchipTypes; 41 42 BSP_VMEchipTypes BSP_getVMEchipType(); 43 44 /* The version of Discovery system controller */ 45 46 typedef enum { 47 notdefined, 48 GT64260A, 49 GT64260B, 50 MV64360, 51 } DiscoveryChipVersion; 52 53 DiscoveryChipVersion 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 */ 26 64 27 65 /* 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 29 77 30 78 /* PCI0 Domain I/O space */ 31 79 #define PCI0_IO_BASE 0xf0000000 … … 69 117 */ 70 118 71 119 #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 */ 72 121 73 122 /* uart.c uses out_8 instead of outb */ 74 #define BSP_UART_IOBASE_COM1 GT64 260_DEV1_BASE + 0x2000075 #define BSP_UART_IOBASE_COM2 GT64 260_DEV1_BASE + 0x21000123 #define BSP_UART_IOBASE_COM1 GT64x60_DEV1_BASE + 0x20000 124 #define BSP_UART_IOBASE_COM2 GT64x60_DEV1_BASE + 0x21000 76 125 77 126 #define BSP_CONSOLE_PORT BSP_UART_COM1 /* console */ 78 127 #define BSP_UART_BAUD_BASE 115200 79 128 80 129 /* 81 * Vital Board data Start using DATA RESIDUAL82 */83 /*84 130 * Total memory using RESIDUAL DATA 85 131 */ 86 132 extern unsigned int BSP_mem_size; … … 100 146 #define BSP_Convert_decrementer( _value ) \ 101 147 ((unsigned long long) ((((unsigned long long)BSP_time_base_divisor) * 1000000ULL) /((unsigned long long) BSP_bus_frequency)) * ((unsigned long long) (_value))) 102 148 149 extern rtems_configuration_table BSP_Configuration; 103 150 extern void BSP_panic(char *s); 104 151 extern void bsp_reset(void); 105 152 /* extern int printk(const char *, ...) __attribute__((format(printf, 1, 2))); */ … … 118 165 #define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_i82544EI_driver_attach 119 166 #endif 120 167 121 extern int 122 RTEMS_BSP_NETWORK_DRIVER_ATTACH(/* struct rtems_bsdnet_ifconfig * */); 168 extern int RTEMS_BSP_NETWORK_DRIVER_ATTACH(); 123 169 124 170 /* 125 171 * BSP Configuration Default Overrides 126 172 */ 127 173 #define BSP_ZERO_WORKSPACE_AUTOMATICALLY TRUE 128 174 129 /* As per Linux, This should be in the ppc/system.h */ 175 #define gccMemBar() RTEMS_COMPILER_MEMORY_BARRIER() 130 176 177 static inline void lwmemBar() 178 { 179 asm volatile("lwsync":::"memory"); 180 } 181 182 static inline void io_flush() 183 { 184 asm volatile("isync":::"memory"); 185 } 131 186 static inline void memBar() 132 187 { 133 188 asm volatile("sync":::"memory"); 134 189 } 135 136 190 static inline void ioBar() 137 191 { 138 asm volatile("eieio" );192 asm volatile("eieio":::"memory"); 139 193 } 140 194 141 195 #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 */ 72 static 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 */ 78 static rtems_irq_global_settings BSP_config; 79 static rtems_irq_connect_data* rtems_hdl_tbl; 80 81 /* 82 * default handler connected on each irq after bsp initialization 83 * (locally cached copy) 84 */ 85 void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1; 86 87 88 static volatile unsigned *BSP_irqMask_reg[3]; 89 static volatile unsigned *BSP_irqCause_reg[3]; 90 static volatile unsigned BSP_irqMask_cache[3]={0,0,0}; 91 92 static int picPrioTblPtr=0; 93 static unsigned int GPPIrqInTbl=0; 94 static 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 */ 118 static 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 130 static 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 */ 146 static 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 */ 156 static 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 */ 172 static 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 226 static 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 278 static 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 312 void 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 336 void BSP_enable_pic_irq(const rtems_irq_number irqNum) 337 { 338 BSP_enable_irq_at_pic(irqNum); 339 } 340 341 int 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 371 void 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 */ 377 int 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 */ 454 int 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 */ 496 void 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.c2 *3 * This file contains the implementation of the function described in irq.h4 *5 * Copyright (C) 1998, 1999 valette@crf.canon.fr6 *7 * The license and distribution terms for this file may be8 * found in the file LICENSE in this distribution or at9 * 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 Laboratory16 * 1) Modified and added support for the MVME5500 board.17 * 2) The implementation of picIsrTable[] is an original work by the18 * author to optimize the software IRQ priority scheduling because19 * Discovery controller does not provide H/W IRQ priority schedule.20 * It ensures the fastest/faster interrupt service to the21 * 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 0x4000000041 42 #define MAX_IRQ_LOOP 3043 44 #define EDGE_TRIGGER45 46 /* #define DEBUG_IRQ*/47 48 /*49 * pointer to the mask representing the additionnal irq vectors50 * that must be disabled when a particular entry is activated.51 * They will be dynamically computed from the table given52 * in BSP_rtems_irq_mngt_set();53 * CAUTION : this table is accessed directly by interrupt routine54 * 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 interrupt60 * 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 initialization67 * (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 pending84 * highest priority IRQ at run time. It ensures the fastest/faster85 * interrupt service to the highest/higher priority IRQ, if pendig.86 *87 * The picIsrTable[96] is updated dynamically at run time88 * 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 interrupt93 * numbers [0 (lowest)- 95 (highest)] starting from the highest priority94 * one to the lowest priority one. The highest priority interrupt is95 * located at picIsrTable[0], and the lowest priority interrupt is located96 * 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 IRQ116 */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 IRQ126 */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 valid151 * 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-entrance160 */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 priority181 * 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 DEBUG191 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 #endif194 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_SETTINGS219 unsigned long val2, val1;220 #endif221 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 else243 MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);244 picIsrTblPtr++;245 }246 #ifdef SHOW_MORE_INIT_SETTINGS247 val2 = (MainIrqInTbl>>32) & 0xffffffff;248 val1 = MainIrqInTbl&0xffffffff;249 printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);250 BSP_printPicIsrTbl();251 #endif252 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 else281 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_TRIGGER367 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 #else376 outl((inl(GT_CommUnitArb_Ctrl)| (1<<10)), GT_CommUnitArb_Ctrl);377 #endif378 379 #if 0380 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 #endif390 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 0400 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 #endif410 411 return(1);412 }413 414 /*415 * This function check that the value given for the irq line416 * is valid.417 */418 419 /*420 * High level IRQ handler called from shared_raw_irq_code_entry421 */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_TRIGGER463 if (irq > BSP_MICH_IRQ_MAX_OFFSET)464 out_le32(BSP_irqCause_reg[2], ~bitmask);/* Till Straumann: Ack the edge triggered GPP IRQ */465 #endif466 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 36 36 37 37 static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER]; 38 38 static rtems_irq_global_settings initial_config; 39 40 #ifdef BSP_SHARED_HANDLER_SUPPORT 41 static 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 39 46 static rtems_irq_connect_data defaultIrq = { 40 47 /* vectorIdex, hdl , handle , on , off , isOn */ 41 48 0, nop_func , NULL , nop_func , nop_func , not_connected 42 49 }; 50 #endif 43 51 44 52 rtems_irq_prio BSPirqPrioTable[BSP_PIC_IRQ_NUMBER]={ 45 53 /* … … 135 143 #ifdef TRACE_IRQ_INIT 136 144 printk("Done setup irq mngt configuration\n"); 137 145 #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);144 146 145 147 #ifdef TRACE_IRQ_INIT 146 148 printk("RTEMS IRQ management is now operationnal\n"); -
Makefile.am
diff -Naur mvme5500.orig/Makefile.am mvme5500/Makefile.am
old new 32 32 ../../powerpc/shared/startup/sbrk.c ../../shared/bootcard.c \ 33 33 ../../shared/bsppredriverhook.c startup/bspclean.c \ 34 34 ../../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 36 38 pclock_SOURCES = ../../powerpc/shared/clock/p_clock.c 37 39 38 40 include_bsp_HEADERS = ../../powerpc/shared/console/uart.h … … 45 47 pci/pcifinddevice.c 46 48 47 49 include_bsp_HEADERS += irq/irq.h 48 irq_SOURCES = irq/irq_init.c irq/ irq.c50 irq_SOURCES = irq/irq_init.c irq/BSP_irq.c 49 51 50 52 nodist_include_HEADERS += ../../shared/tod.h 51 53 tod_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 7 7 * Acknowledgements: 8 8 * netBSD : Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc. 9 9 * 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 Controller12 * (C) 1999 Emmanuel Raguet. raguet@crf.canon.fr13 *14 * 2) yellowfin.c, a network driver for the SVGM5 BSP.15 * Stanford Linear Accelerator Center, Till Straumann16 10 * 17 11 * Some notes from the author, S. Kate Feng : 18 12 * … … 366 360 if (unit < 0) return 0; 367 361 368 362 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"); 371 364 /* Make certain elements e.g. descriptor lists are aligned. */ 372 365 softc_mem = rtems_bsdnet_malloc(sizeof(*sc) + SOFTC_ALIGN, M_FREE, M_NOWAIT); 373 366 … … 1137 1130 sc->arpcom.ac_if.if_timer = 0; 1138 1131 } 1139 1132 1140 /* TOCHECK : Should it be about rx or tx ? */1141 1133 static void GTeth_ifchange(struct GTeth_softc *sc) 1142 1134 { 1143 1135 if (GTeth_debug>0) printk("GTeth_ifchange("); … … 1445 1437 #endif 1446 1438 } 1447 1439 1440 #ifdef GT64260eth_DEBUG 1448 1441 static void GT64260eth_error(struct GTeth_softc *sc) 1449 1442 { 1450 1443 struct ifnet *ifp = &sc->arpcom.ac_if; … … 1474 1467 sc->intr_errsts[sc->intr_err_ptr1++]=0; 1475 1468 sc->intr_err_ptr1 %= INTR_ERR_SIZE; /* Till Straumann */ 1476 1469 } 1477 1470 #endif 1478 1471 1479 1472 /* The daemon does all of the work; RX, TX and cleaning up buffers/descriptors */ 1480 1473 static void GT64260eth_daemon(void *arg) … … 1548 1541 ifp->if_flags &= ~IFF_OACTIVE; 1549 1542 1550 1543 /* Log errors and other uncommon events. */ 1544 #ifdef GT64260eth_DEBUG 1551 1545 if (events & ERR_EVENT) GT64260eth_error(sc); 1546 #endif 1552 1547 } /* end for(;;) { rtems_bsdnet_event_receive() .....*/ 1553 1548 1554 1549 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 1 1 /* 2 2 * Copyright (c) 2004,2005 RTEMS/Mvme5500 port by S. Kate Feng <feng1@bnl.gov> 3 * under the Deaprtment of Energy contract DE-AC02-98CH10886 3 4 * Brookhaven National Laboratory, All rights reserved 4 5 * 5 6 * Acknowledgements: … … 25 26 * hardware auto-neg. state machine disabled. PCI control "snoop 26 27 * to WB region", MII mode (PHY) instead of TBI mode. 27 28 * 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. 30 30 * 31 31 */ 32 32 … … 34 34 35 35 #define INET 36 36 37 /*#define RTEMS_ETHERMTU_JUMBO*/ 38 37 39 #include <rtems.h> 38 40 #include <rtems/bspIo.h> /* printk */ 41 39 42 #include <stdio.h> /* printf for statistics */ 40 43 #include <string.h> 41 44 … … 64 67 #include <net/if_dl.h> 65 68 #include <netinet/in.h> 66 69 #include <netinet/if_ether.h> 70 #include <net/ethernet.h> 67 71 68 72 #ifdef INET 69 73 #include <netinet/in_var.h> … … 82 86 #define i82544EI_TASK_NAME "IGHZ" 83 87 #define SOFTC_ALIGN 4095 84 88 85 #define I NTR_ERR_SIZE 1689 #define IF_ERR_BUFSZE 16 86 90 87 91 /*#define WM_DEBUG*/ 88 92 #ifdef WM_DEBUG … … 109 113 110 114 #define ALL_EVENTS (KILL_EVENT|START_TRANSMIT_EVENT|RX_EVENT|TX_EVENT|ERR_EVENT|INIT_EVENT) 111 115 112 113 #define NTXDESC 128116 /* <skf> used 64 in 4.8.0, TOD; try 4096 */ 117 #define NTXDESC 256 114 118 #define NTXDESC_MASK (NTXDESC - 1) 115 119 #define WM_NEXTTX(x) (((x) + 1) & NTXDESC_MASK) 116 120 117 #define NRXDESC 64121 #define NRXDESC 256 118 122 #define NRXDESC_MASK (NRXDESC - 1) 119 123 #define WM_NEXTRX(x) (((x) + 1) & NRXDESC_MASK) 120 124 #define WM_PREVRX(x) (((x) - 1) & NRXDESC_MASK) … … 123 127 #define WM_CDTXOFF(x) WM_CDOFF(sc_txdescs[(x)]) 124 128 #define WM_CDRXOFF(x) WM_CDOFF(sc_rxdescs[(x)]) 125 129 126 #define TXQ_HiLmt_OFF 64130 #define TXQ_HiLmt_OFF 32 127 131 128 132 static uint32_t TxDescCmd; 133 static unsigned BSP_1GHz_membase; 129 134 130 135 /* 131 136 * Software state per device. … … 136 141 struct mbuf *txs_mbuf[NTXDESC]; /* transmit buffer memory */ 137 142 struct mbuf *rxs_mbuf[NRXDESC]; /* receive buffer memory */ 138 143 struct wm_softc *next_module; 139 volatile unsigned int i ntr_errsts[INTR_ERR_SIZE]; /* intr_status */140 unsigned int i ntr_err_ptr1; /* ptr used in i82544EI_error() */141 unsigned int i ntr_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 */ 142 147 int txs_firstdesc; /* first descriptor in packet */ 143 148 int txs_lastdesc; /* last descriptor in packet */ 144 149 int txs_ndesc; /* # of descriptors used */ … … 168 173 int sc_rxptr; /* next ready Rx descriptor/queue ent */ 169 174 int sc_rxdiscard; 170 175 int sc_rxlen; 176 171 177 uint32_t sc_ctrl; /* prototype CTRL register */ 172 #if 0173 178 uint32_t sc_ctrl_ext; /* prototype CTRL_EXT register */ 174 #endif 179 175 180 uint32_t sc_icr; /* prototype interrupt bits */ 176 181 uint32_t sc_tctl; /* prototype TCTL register */ 177 182 uint32_t sc_rctl; /* prototype RCTL register */ 178 183 uint32_t sc_tipg; /* prototype TIPG register */ 179 184 uint32_t sc_fcrtl; /* prototype FCRTL register */ 185 uint32_t sc_pba; /* prototype PBA register */ 180 186 181 187 int sc_mchash_type; /* multicast filter offset */ 182 188 … … 184 190 struct { 185 191 volatile unsigned long rxInterrupts; 186 192 volatile unsigned long txInterrupts; 187 unsigned long txMultiBuffPacket;188 unsigned long txMultiMaxLen;189 unsigned long txSinglMaxLen;190 unsigned long txMultiMaxLoop;191 unsigned long txBuffMaxLen;192 193 unsigned long linkInterrupts; 193 194 unsigned long length_errors; 194 195 unsigned long frame_errors; … … 224 225 static struct wm_softc *root_i82544EI_dev = NULL; 225 226 226 227 static void i82544EI_ifstart(struct ifnet *ifp); 227 static int wm_ioctl(struct ifnet *ifp, u_long cmd,uint32_t data);228 static int wm_ioctl(struct ifnet *ifp, ioctl_command_t cmd,caddr_t data); 228 229 static void i82544EI_ifinit(void *arg); 229 230 static void wm_stop(struct ifnet *ifp, int disable); 231 static void wm_gmii_mediainit(struct wm_softc *sc); 230 232 231 233 static void wm_rxdrain(struct wm_softc *sc); 232 234 static int wm_add_rxbuf(struct wm_softc *sc, int idx); 233 235 static int wm_read_eeprom(struct wm_softc *sc,int word,int wordcnt, uint16_t *data); 234 236 static void i82544EI_daemon(void *arg); 235 237 static void wm_set_filter(struct wm_softc *sc); 236 237 static void i82544EI_isr( void);238 static void i82544EI_rx(struct wm_softc *sc); 239 static void i82544EI_isr(rtems_irq_hdl_param handle); 238 240 static 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); 241 extern int pci_mem_find(), pci_io_find(), pci_get_capability(); 243 242 244 243 static void i82544EI_irq_on(const rtems_irq_connect_data *irq) 245 244 { … … 271 270 static rtems_irq_connect_data i82544IrqData={ 272 271 BSP_GPP_82544_IRQ, 273 272 (rtems_irq_hdl) i82544EI_isr, 273 (rtems_irq_hdl_param) NULL, 274 274 (rtems_irq_enable) i82544EI_irq_on, 275 275 (rtems_irq_disable) i82544EI_irq_off, 276 276 (rtems_irq_is_enabled) i82544EI_irq_is_on, … … 290 290 291 291 unit = rtems_bsdnet_parse_driver_name(config, &name); 292 292 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"); 296 299 297 300 /* Make sure certain elements e.g. descriptor lists are aligned.*/ 298 301 softc_mem = rtems_bsdnet_malloc(sizeof(*sc) + SOFTC_ALIGN, M_FREE, M_NOWAIT); … … 310 313 unit-1,&b, &d, &f)) 311 314 rtems_panic("i82544EI device ID not found\n"); 312 315 313 #if WM_DEBUG316 #ifdef WM_DEBUG 314 317 printk("82544EI:b%d, d%d, f%d\n", b, d,f); 315 318 #endif 316 319 … … 318 321 if ( pci_mem_find(b,d,f,PCI_MAPREG_START, &sc->sc_membase, &sc->sc_memsize)) 319 322 rtems_panic("i82544EI: unable to map memory space\n"); 320 323 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 321 329 #ifdef WM_DEBUG 322 330 printk("Memory base addr 0x%x\n", sc->sc_membase); 323 331 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)); 324 332 #endif 325 333 326 334 327 sc->sc_ctrl |=CSR_READ(sc,WMREG_CTRL);335 sc->sc_ctrl=CSR_READ(sc,WMREG_CTRL); 328 336 /* 329 337 * Determine a few things about the bus we're connected to. 330 338 */ … … 362 370 enaddr[4] = myea[2] & 0xff; 363 371 enaddr[5] = myea[2] >> 8; 364 372 365 366 373 memcpy(sc->arpcom.ac_enaddr, enaddr, ETHER_ADDR_LEN); 367 374 #ifdef WM_DEBUG 368 375 printk("%s: Ethernet address %s\n", sc->dv_xname, 369 ether_sprintf 1(enaddr));376 ether_sprintf(enaddr)); 370 377 #endif 371 378 372 379 /* … … 397 404 CSR_WRITE(sc,WMREG_CTRL_EXT, sc->sc_ctrl_ext); 398 405 #endif 399 406 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 400 418 ifp = &sc->arpcom.ac_if; 401 419 /* set this interface's name and unit */ 402 420 ifp->if_unit = unit; 403 421 ifp->if_name = name; 404 422 ifp->if_softc = sc; 405 423 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 406 428 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 407 440 ifp->if_ioctl = wm_ioctl; 408 441 ifp->if_start = i82544EI_ifstart; 409 442 /* ifp->if_watchdog = wm_watchdog;*/ … … 418 451 rtems_build_name('I','G','H','Z'),0,0,0,&sc->daemonSync)) 419 452 rtems_panic("i82544EI: semaphore creation failed"); 420 453 421 sc->next_module = root_i82544EI_dev; 454 i82544IrqData.handle= (rtems_irq_hdl_param) sc; 455 /* sc->next_module = root_i82544EI_dev;*/ 422 456 root_i82544EI_dev = sc; 423 457 424 458 /* Attach the interface. */ … … 432 466 } 433 467 434 468 /* 469 * wm_reset: 470 * 471 * Reset the i82544 chip. 472 */ 473 static 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 /* 435 502 * i82544EI_ifstart: [ifnet interface function] 436 503 * 437 504 * Start packet transmission on the interface. … … 463 530 { 464 531 struct ifnet *ifp = &sc->arpcom.ac_if; 465 532 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); 467 535 printf(" Receive Packets:%-8u\n", CSR_READ(sc,WMREG_GPRC)); 468 printf(" Receive Overrun:%-8 u\n", sc->stats.rxOvrRunInterrupts);536 printf(" Receive Overrun:%-8lu\n", sc->stats.rxOvrRunInterrupts); 469 537 printf(" Receive errors:%-8u\n", CSR_READ(sc,WMREG_RXERRC)); 470 printf(" Rx sequence error:%-8 u\n", sc->stats.rxSeqErr);471 printf(" Rx /C/ ordered:%-8 u\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); 472 540 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); 481 542 printf(" Transmitt Packets:%-8u\n", CSR_READ(sc,WMREG_GPTC)); 482 printf(" Transmitt errors:%-8 u\n", ifp->if_oerrors);483 printf(" Active Txqs:%-8 u\n", sc->txq_nactive);543 printf(" Transmitt errors:%-8lu\n", ifp->if_oerrors); 544 printf(" Active Txqs:%-8lu\n", sc->txq_nactive); 484 545 printf(" collisions:%-8u\n", CSR_READ(sc,WMREG_COLC)); 485 546 printf(" Crc Errors:%-8u\n", CSR_READ(sc,WMREG_CRCERRS)); 486 printf(" Link Status Change:%-8 u\n", sc->stats.linkStatusChng);547 printf(" Link Status Change:%-8lu\n", sc->stats.linkStatusChng); 487 548 } 488 549 489 550 /* … … 491 552 * 492 553 * Handle control requests from the operator. 493 554 */ 494 static int wm_ioctl(struct ifnet *ifp, u_long cmd,uint32_t data)555 static int wm_ioctl(struct ifnet *ifp, ioctl_command_t cmd,caddr_t data) 495 556 { 496 557 struct wm_softc *sc = ifp->if_softc; 497 558 int error=0; … … 523 584 * 524 585 * Interrupt service routine. 525 586 */ 526 static void i82544EI_isr( )587 static void i82544EI_isr(rtems_irq_hdl_param handle) 527 588 { 528 volatile struct wm_softc *sc = root_i82544EI_dev;589 volatile struct wm_softc *sc = (struct wm_softc *) handle; 529 590 uint32_t icr; 530 591 rtems_event_set events=0; 531 592 … … 549 610 events |= INIT_EVENT; 550 611 } 551 612 if (icr & ICR_RXSEQ) /* framing error */ { 552 sc->i ntr_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; 554 615 events |= ERR_EVENT; 555 616 sc->stats.rxSeqErr++; 556 617 } … … 608 669 * The other way is effective for packets < 2K 609 670 */ 610 671 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)); 612 673 break; 613 674 } 614 675 memcpy((void *)pt,(char *)mtp->m_data, mtp->m_len); 615 676 pt += mtp->m_len; 616 677 len += mtp->m_len; 617 #if 0618 sc->stats.txSinglMaxLen= MAX(mtp->m_len, sc->stats.txSinglMaxLen);619 #endif620 678 } /* end for loop */ 621 679 mdest->m_len=len; 622 680 sc->txs_mbuf[sc->txq_next] = mdest; … … 630 688 sc->txq_free--; 631 689 else 632 690 rtems_panic("i8254EI : no more free descriptors"); 633 #if 0634 sc->stats.txMultiMaxLen= MAX(mdest->m_len, sc->stats.txMultiMaxLen);635 sc->stats.txMultiBuffPacket++;636 #endif637 691 } /* end for while */ 638 692 /* free old mbuf chain */ 639 #if 0640 sc->stats.txMultiMaxLoop=MAX(loop, sc->stats.txMultiMaxLoop);641 #endif642 693 m_freem(m); 643 694 m=0; 644 695 } /* end multiple mbufs */ … … 744 795 sc->dv_xname, i)); 745 796 746 797 status = sc->sc_rxdescs[i].wrx_status; 798 if ((status & WRX_ST_DD) == 0) break; /* descriptor not done */ 799 747 800 errors = sc->sc_rxdescs[i].wrx_errors; 748 801 len = le16toh(sc->sc_rxdescs[i].wrx_len); 749 802 m = sc->rxs_mbuf[i]; 750 751 if ((status & WRX_ST_DD) == 0) break; /* descriptor not done */752 753 803 if (sc->sc_rxdiscard) { 754 804 printk("RX: discarding contents of descriptor %d\n", i); 755 805 wm_init_rxdesc(sc, i); … … 821 871 int i,error; 822 872 uint8_t cksumfields; 823 873 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 824 897 /* Cancel any pending I/O. */ 825 898 wm_stop(ifp, 0); 826 899 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 827 907 /* Initialize the error buffer ring */ 828 sc->i ntr_err_ptr1=0;829 sc->i ntr_err_ptr2=0;830 for (i=0; i< I NTR_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; 831 911 832 912 /* 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)); 834 914 sc->txq_free = NTXDESC; 835 915 sc->txq_next = 0; 836 916 sc->txs_lastdesc = 0; … … 849 929 CSR_WRITE(sc,WMREG_TDLEN, sizeof(sc->sc_txdescs)); 850 930 CSR_WRITE(sc,WMREG_TDH, 0); 851 931 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 */ 854 934 855 935 CSR_WRITE(sc,WMREG_TXDCTL, TXDCTL_PTHRESH(0) | 856 936 TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0)); … … 864 944 * Set up checksum offload parameters for 865 945 * this packet. 866 946 */ 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) { 871 952 /* Error message already displayed. */ 872 953 continue; 873 954 } … … 875 956 #endif 876 957 TxDescCmd = 0; 877 958 cksumfields = 0; 878 #ifdef CKSUM_OFFLOAD959 #ifdef RTEMS_CKSUM_OFFLOAD 879 960 } 880 961 #endif 881 962 … … 894 975 * Initialize the receive descriptor and receive job 895 976 * descriptor rings. 896 977 */ 897 memset( sc->sc_rxdescs, 0, sizeof(sc->sc_rxdescs));978 memset( (void *) sc->sc_rxdescs, 0, sizeof(sc->sc_rxdescs)); 898 979 CSR_WRITE(sc,WMREG_RDBAH, 0); 899 980 CSR_WRITE(sc,WMREG_RDBAL, WM_CDRXADDR(sc)); 900 981 CSR_WRITE(sc,WMREG_RDLEN, sizeof(sc->sc_rxdescs)); 901 982 CSR_WRITE(sc,WMREG_RDH, 0); 902 983 CSR_WRITE(sc,WMREG_RDT, 0); 903 984 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. */ 905 986 906 987 for (i = 0; i < NRXDESC; i++) { 907 988 if (sc->rxs_mbuf[i] == NULL) { … … 945 1026 946 1027 CSR_WRITE(sc,WMREG_FCRTH, FCRTH_DFLT); 947 1028 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); 949 1031 950 1032 sc->sc_ctrl &= ~CTRL_VME; 951 /* sc->sc_ctrl |= CTRL_TFCE | CTRL_RFCE;*/952 /* enable Big Endian Mode for the powerPC953 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; */ 954 1036 955 1037 /* Write the control registers. */ 956 1038 CSR_WRITE(sc,WMREG_CTRL, sc->sc_ctrl); … … 958 1040 CSR_WRITE(sc,WMREG_CTRL_EXT, sc->sc_ctrl_ext); 959 1041 #endif 960 1042 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 962 1058 963 1059 /* 964 1060 * Set up the interrupt registers. … … 987 1083 * we resolve the media type. 988 1084 */ 989 1085 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 */; 991 1088 992 1089 /* 993 1090 * Set up the receive control register; we actually program … … 995 1092 * address offset type 0. 996 1093 * 997 1094 * 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) 999 1096 */ 1000 1097 sc->sc_mchash_type = 0; 1001 1098 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; 1003 1100 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 } 1006 1120 1007 1121 #ifdef WM_DEBUG 1008 1122 printk("RDBAL 0x%x,RDLEN %d, RDT %d\n",CSR_READ(sc,WMREG_RDBAL),CSR_READ(sc,WMREG_RDLEN), CSR_READ(sc,WMREG_RDT)); … … 1020 1134 return(0); 1021 1135 } 1022 1136 1137 void BSP_rdTIDV() 1138 { 1139 printf("Reg TIDV: 0x%x\n", in_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_TIDV))); 1140 } 1141 void BSP_rdRDTR() 1142 { 1143 printf("Reg RDTR: 0x%x\n", in_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_RDTR))); 1144 } 1145 1146 void BSP_setTIDV(int val) 1147 { 1148 out_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_TIDV), val); 1149 } 1150 1151 void BSP_setRDTR(int val) 1152 { 1153 out_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_RDTR), val); 1154 } 1023 1155 /* 1024 1156 * i82544EI_ifinit: [ifnet interface function] 1025 1157 * … … 1235 1367 return (0); 1236 1368 } 1237 1369 1370 #if 0 1238 1371 /* 1239 1372 * wm_acquire_eeprom: 1240 1373 * … … 1266 1399 1267 1400 return (0); 1268 1401 } 1402 #endif 1269 1403 1270 1404 /* 1271 1405 * wm_read_eeprom: … … 1370 1504 mta_reg = WMREG_CORDOVA_MTA; 1371 1505 sc->sc_rctl &= ~(RCTL_BAM | RCTL_UPE | RCTL_MPE); 1372 1506 1373 /* if (ifp->if_flags & IFF_BROADCAST)*/1507 if (ifp->if_flags & IFF_BROADCAST) 1374 1508 sc->sc_rctl |= RCTL_BAM; 1375 1509 if (ifp->if_flags & IFF_PROMISC) { 1376 1510 sc->sc_rctl |= RCTL_UPE; … … 1440 1574 static void i82544EI_error(struct wm_softc *sc) 1441 1575 { 1442 1576 struct ifnet *ifp = &sc->arpcom.ac_if; 1443 unsigned long intr_status= sc->i ntr_errsts[sc->intr_err_ptr1++];1577 unsigned long intr_status= sc->if_errsts[sc->if_err_ptr1]; 1444 1578 1445 1579 /* read and reset the status; because this is written 1446 1580 * by the ISR, we must disable interrupts here 1447 1581 */ 1448 sc->intr_err_ptr1 %=INTR_ERR_SIZE; /* Till Straumann */1449 1582 if (intr_status) { 1450 1583 printk("Error %s%d:", ifp->if_name, ifp->if_unit); 1451 1584 if (intr_status & ICR_RXSEQ) { … … 1455 1588 } 1456 1589 else 1457 1590 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 */ 1458 1593 } 1459 1594 1460 1595 void i82544EI_printStats() … … 1495 1630 &events); 1496 1631 if (KILL_EVENT & events) break; 1497 1632 1498 if (events & RX_EVENT) i82544EI_rx(sc); 1633 if (events & RX_EVENT) i82544EI_rx(sc); /* in ISR instead */ 1499 1634 1500 1635 /* clean up and try sending packets */ 1501 1636 do { … … 1503 1638 1504 1639 while (sc->txq_free>0) { 1505 1640 if (sc->txq_free>TXQ_HiLmt_OFF) { 1641 m=0; 1506 1642 IF_DEQUEUE(&ifp->if_snd,m); 1507 1643 if (m==0) break; 1508 1644 i82544EI_sendpacket(sc, m); … … 1511 1647 i82544EI_txq_done(sc); 1512 1648 break; 1513 1649 } 1514 if (events & RX_EVENT) i82544EI_rx(sc);1515 1650 } 1516 1651 /* we leave this loop 1517 1652 * - either because there's no free buffer … … 1519 1654 * - or there's nothing to send (IF_DEQUEUE 1520 1655 * returned 0 1521 1656 */ 1522 } while (m && sc->txq_free);1657 } while (m); 1523 1658 1524 1659 ifp->if_flags &= ~IFF_OACTIVE; 1525 1660 … … 1556 1691 */ 1557 1692 rtems_task_delete(RTEMS_SELF); 1558 1693 } 1694 1695 /* 1696 * wm_gmii_reset: 1697 * 1698 * Reset the PHY. 1699 */ 1700 static 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 */ 1716 static 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 5 5 * All rights reserved. 6 6 * 7 7 * 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 8 11 * 9 12 * Redistribution and use in source and binary forms, with or without 10 13 * modification, are permitted provided that the following conditions … … 56 59 * The receive descriptor ring must be aligned to a 4K boundary, 57 60 * and there must be an even multiple of 8 descriptors in the ring. 58 61 */ 59 typedef struct wiseman_rxdesc {62 typedef volatile struct wiseman_rxdesc { 60 63 wiseman_addr_t wrx_addr; /* buffer address */ 61 64 62 65 uint16_t wrx_len; /* buffer length */ … … 103 106 uint8_t wtxu_options; /* options */ 104 107 uint16_t wtxu_vlan; /* VLAN info */ 105 108 } __attribute__((__packed__)) wiseman_txfields_t; 106 typedef struct wiseman_txdesc {109 typedef volatile struct wiseman_txdesc { 107 110 wiseman_addr_t wtx_addr; /* buffer address */ 108 111 uint32_t wtx_cmdlen; /* command and length */ 109 112 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 4 4 * Copyright (c) 1995, 1996, 1999, 2000 5 5 * Christopher G. Demetriou. All rights reserved. 6 6 * Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved. 7 * Copyright (C) 2007 Brookhaven National Laboratory, Shuchen Kate Feng 7 8 * 8 9 * Redistribution and use in source and binary forms, with or without 9 10 * modification, are permitted provided that the following conditions … … 30 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 33 */ 34 #include <bsp.h> 33 35 34 36 /* 35 37 * PCI Class and Revision Register; defines type and revision of device. … … 305 307 #define PCI_MAPREG_MEM64_ADDR_MASK 0xfffffffffffffff0ULL 306 308 307 309 #define PCI_MAPREG_IO_ADDR(mr) \ 308 ((mr ) & PCI_MAPREG_IO_ADDR_MASK)310 ((mr+PCI0_IO_BASE) & PCI_MAPREG_IO_ADDR_MASK) 309 311 #define PCI_MAPREG_IO_SIZE(mr) \ 310 312 (PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr)) 311 313 #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, 20072 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 13 13 * found in the file LICENSE in this distribution or at 14 14 * http://www.rtems.com/rtems/license.html. 15 15 * 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 22 17 * 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 24 24 */ 25 25 #define PCI_MAIN 26 26 27 27 #include <libcpu/io.h> 28 28 #include <rtems/bspIo.h> /* printk */ 29 29 30 #include <bsp/irq.h> 30 31 #include <bsp/pci.h> 31 32 #include <bsp/gtreg.h> 32 33 #include <bsp/gtpcireg.h> 34 #include <bsp.h> 33 35 34 36 #include <stdio.h> 35 37 #include <string.h> 36 38 37 39 #define PCI_DEBUG 0 38 #define PCI_PRINT 040 #define PCI_PRINT 1 39 41 40 42 /* allow for overriding these definitions */ 41 43 #ifndef PCI_CONFIG_ADDR … … 56 58 #define PCI_MULTI_FUNCTION 0x80 57 59 #define HOSTBRIDGET_ERROR 0xf0000000 58 60 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 67 static int numPCIDevs=0; 68 static DiscoveryChipVersion BSP_sysControllerVersion = 0; 69 static BSP_VMEchipTypes BSP_VMEinterface = 0; 70 static 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 }; 61 78 62 static int numPCIDevs=0;63 79 extern void pci_interface(void); 64 80 65 81 /* Pack RegNum,FuncNum,DevNum,BusNum,and ConfigEnable for 66 82 * PCI Configuration Address Register 67 83 */ 68 84 #define pciConfigPack(bus,dev,func,offset)\ 69 (( (func&7)<<8)|((dev&0x1f )<<11)|(( bus&0xff)<<16)|(offset&0xfc))|0x8000000085 ((offset&~3)<<24)|(PCI_DEVFN(dev,func)<<16)|(bus<<8)|0x80 70 86 71 87 /* 72 88 * Bit encode for PCI_CONFIG_HEADER_TYPE register … … 75 91 76 92 /* Please note that PCI0 and PCI1 does not correlate with the busNum 0 and 1. 77 93 */ 78 static int direct_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func,94 static int indirect_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func, 79 95 unsigned char offset,unsigned char *val) 80 96 { 81 volatile unsigned char *config_addr, *config_data;97 int n=0; 82 98 83 99 if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { 84 100 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; 91 102 } 103 92 104 *val = 0xff; 93 105 if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER; 94 106 #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)); 97 109 #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)); 100 113 return PCIBIOS_SUCCESSFUL; 101 114 } 102 115 103 static int direct_pci_read_config_word(unsigned char bus, unsigned char dev,116 static int indirect_pci_read_config_word(unsigned char bus, unsigned char dev, 104 117 unsigned char func, unsigned char offset, unsigned short *val) 105 118 { 106 volatile unsigned char *config_addr, *config_data;119 int n=0; 107 120 108 121 if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { 109 122 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; 116 124 } 117 125 118 126 *val = 0xffff; … … 121 129 printk("addr %x, data %x, pack %x \n", config_addr, 122 130 config_data,pciConfigPack(bus,dev,func,offset)); 123 131 #endif 124 out l(pciConfigPack(bus,dev,func,offset),config_addr);125 *val = in w(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)); 126 134 return PCIBIOS_SUCCESSFUL; 127 135 } 128 136 129 static int direct_pci_read_config_dword(unsigned char bus, unsigned char dev,137 static int indirect_pci_read_config_dword(unsigned char bus, unsigned char dev, 130 138 unsigned char func, unsigned char offset, unsigned int *val) 131 139 { 132 volatile unsigned char *config_addr, *config_data;140 int n=0; 133 141 134 142 if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { 135 143 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; 142 145 } 143 146 144 147 *val = 0xffffffff; 145 148 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); 152 152 return PCIBIOS_SUCCESSFUL; 153 153 } 154 154 155 static int direct_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val)155 static int indirect_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val) 156 156 { 157 volatile unsigned char *config_addr, *config_data;157 int n=0; 158 158 159 159 if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { 160 160 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; 167 162 } 168 163 169 164 if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER; 170 #if 0171 printk("addr %x, data %x, pack %x \n", config_addr,172 config_data,pciConfigPack(bus,dev,func,offset));173 #endif174 165 175 out l(pciConfigPack(bus,dev,func,offset), config_addr);176 out b(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); 177 168 return PCIBIOS_SUCCESSFUL; 178 169 } 179 170 180 static int direct_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val)171 static int indirect_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val) 181 172 { 182 volatile unsigned char *config_addr, *config_data;173 int n=0; 183 174 184 175 if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { 185 176 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; 192 178 } 193 179 194 180 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); 201 184 return PCIBIOS_SUCCESSFUL; 202 185 } 203 186 204 static int direct_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val)187 static int indirect_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val) 205 188 { 206 volatile unsigned char *config_addr, *config_data;189 int n=0; 207 190 208 191 if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) { 209 192 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; 216 194 } 217 195 218 196 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); 225 200 return PCIBIOS_SUCCESSFUL; 226 201 } 227 202 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_dword203 const 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 235 210 }; 236 211 237 212 238 pci_config BSP_pci_configuration = {(volatile unsigned char*) PCI_CONFIG_ADDR, 239 (volatile unsigned char*)PCI_CONFIG_DATA, 240 &pci_direct_functions}; 213 pci_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 218 DiscoveryChipVersion BSP_getDiscoveryChipVersion(void) 219 { 220 return(BSP_sysControllerVersion); 221 } 222 223 BSP_VMEchipTypes BSP_getVMEchipType(void) 224 { 225 return(BSP_VMEinterface); 226 } 241 227 242 228 /* 243 229 * This routine determines the maximum bus number in the system. … … 248 234 int pci_initialize(void) 249 235 { 250 236 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 254 242 255 pci_interface();256 257 243 /* 258 244 * Scan PCI0 and PCI1 buses 259 245 */ … … 279 265 if (!deviceFound) deviceFound=1; 280 266 switch(ulDeviceID) { 281 267 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; 282 272 #if PCI_PRINT 283 printk("Marvell GT6426xA/Bhostbridge detected at bus%d slot%d\n",273 printk("Marvell GT64260A (Discovery I) hostbridge detected at bus%d slot%d\n", 284 274 ucBusNumber,ucSlotNumber); 285 275 #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; 288 279 #if PCI_PRINT 289 printk("PLX PCI6154 PCI-PCIbridge detected at bus%d slot%d\n",280 printk("Marvell GT64260B (Discovery I) hostbridge detected at bus%d slot%d\n", 290 281 ucBusNumber,ucSlotNumber); 291 282 #endif 292 break; 283 break; 284 default: 285 printk("Undefined revsion of GT64260 chip\n"); 286 break; 287 } 288 break; 293 289 case PCI_VENDOR_ID_TUNDRA: 294 290 #if PCI_PRINT 295 291 printk("TUNDRA PCI-VME bridge detected at bus%d slot%d\n", 296 292 ucBusNumber,ucSlotNumber); 297 293 #endif 298 294 break; 299 case (PCI_VENDOR_ID_INTEL+(PCI_DEVICE_INTEL_82544EI_COPPER<<16)):300 #if PCI_PRINT301 printk("INTEL 82544EI COPPER network controller detected at bus%d slot%d\n",302 ucBusNumber,ucSlotNumber);303 #endif304 break;305 295 case (PCI_VENDOR_ID_DEC+(PCI_DEVICE_ID_DEC_21150<<16)): 306 296 #if PCI_PRINT 307 297 printk("DEC21150 PCI-PCI bridge detected at bus%d slot%d\n", 308 298 ucBusNumber,ucSlotNumber); 309 299 #endif 310 300 break; 311 301 default : 302 #if PCI_PRINT 312 303 printk("BSP unlisted vendor, Bus%d Slot%d DeviceID 0x%x \n", 313 304 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 314 311 break; 315 312 } 316 313 … … 403 400 #endif 404 401 405 402 } 406 407 pci_read_config_dword(ucBusNumber,408 ucSlotNumber,409 0,410 PCI_COMMAND,411 &pcidata);412 #if PCI_DEBUG413 printk("MOTLoad command staus 0x%x, ", pcidata);414 #endif415 /* 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_DEBUG432 printk("Now command/staus 0x%x\n", pcidata);433 #endif434 403 } 435 404 if (deviceFound) ucMaxPCIBus++; 436 405 } /* for (ucBusNumber=0; ucBusNumber<BSP_MAX_PCI_BUS; ... */ … … 438 407 printk("number of PCI buses: %d, numPCIDevs %d\n", 439 408 pci_bus_count(), numPCIDevs); 440 409 #endif 410 pci_interface(); 441 411 return(0); 442 412 } 443 413 -
pci/pci_interface.c
diff -Naur mvme5500.orig/pci/pci_interface.c mvme5500/pci/pci_interface.c
old new 7 7 * found in the file LICENSE in this distribution. 8 8 * 9 9 * 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. 12 11 * 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). 13 16 */ 17 14 18 #include <libcpu/io.h> 15 19 #include <rtems/bspIo.h> /* printk */ 16 20 … … 19 23 #include <bsp/gtreg.h> 20 24 #include <bsp/gtpcireg.h> 21 25 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 25 26 #define PCI_DEBUG 0 26 27 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 52 32 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 55 39 #else 56 #define PCI_ACCCTLBASEL_VALUE 0x010 0100040 #define PCI_ACCCTLBASEL_VALUE 0x01071000 57 41 #endif 58 42 43 59 44 #define ConfSBDis 0x10000000 /* 1: disable, 0: enable */ 60 45 #define IOSBDis 0x20000000 /* 1: disable, 0: enable */ 61 46 #define ConfIOSBDis 0x30000000 62 47 #define CpuPipeline 0x00002000 /* optional, 1:enable, 0:disable */ 63 48 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 71 49 /* CPU to PCI ordering register */ 72 50 #define DLOCK_ORDER_REG 0x2D0 /* Deadlock and Ordering register */ 73 51 #define PCI0OrEn 0x00000001 … … 91 69 void pci_interface(void) 92 70 { 93 71 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); 96 75 #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(); 107 79 } 108 /* Use MOTLoad default for Writeback Priority and Buffer Depth 109 */ 80 110 81 void pciAccessInit(void) 111 82 { 112 83 unsigned int PciLocal, data; 113 84 114 85 for (PciLocal=0; PciLocal < 2; PciLocal++) { 115 /* MOTLoad combines the two banks of SDRAM into116 * 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 119 90 data |= PCI_ACCCTLBASEL_VALUE; 120 91 data &= ~0x300000; 121 REG32_WRITE(data, PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80));122 #if PCI_DEBUG123 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)))); 124 95 #endif 125 126 96 } 127 97 } 128 98 129 /* Sync Barrier Trigger. A write to the CPU_SYNC_TRIGGER register triggers130 * the sync barrier process. The three bits, define which buffers should131 * 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, configuration149 * 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 1 1 # 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) 3 3 # 4 4 5 5 Please reference README.booting for the boot/load process. … … 7 7 For the priority setting of the Interrupt Requests (IRQs), please 8 8 reference README.irq 9 9 10 The BSP is built and tested on the 4.7.1 and 4.7.99.2 CVS RTEMS release. 10 The BSP is built and tested on the RTEMS 4.9.1 release. The 11 PR1385 patch for c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S 12 is not needed for the mvme5500 BSP because the PowerPC BSPs 13 use the shared exception framework in the RTEMS 4.9 release. 11 14 12 15 I believe in valuable real-time programming, where technical neatness, 13 16 performance 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, 20071 README.booting: written by S. Kate Feng <feng1@bnl.gov>, March 16, 2009 2 2 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. 3 The BSP is built and tested on the RTEMS 4.9.1 release. The 4 PR1385 patch for c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S 5 is not needed for the mvme5500 BSP because the PowerPC BSPs 6 use the shared exception framework in the RTEMS 4.9 release. 6 7 7 8 Booting requirement : 8 9 ------------------------- … … 11 12 or /etc/dhcpd.conf (DHCP) properly to boot the system. 12 13 (Note : EPICS needs a NTP server). 13 14 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 15 2) Example of the boot script setup carried out on the MOTLoad 20 16 command line : 21 17 22 18 MVME5500> gevEdit mot-script-boot … … 32 28 Note : (cxx.xx.xx.xx is the client IP address and 33 29 sxx.xx.xx.xx is the server IP address) 34 30 35 4) Other reference web sites for mvme5500 BSP: 36 http://lansce.lanl.gov/EPICS/presentations/KateFeng%20RTEMS-mvme55001.ppt 31 3) Other reference web sites for mvme5500 BSP: 37 32 http://www.nsls.bnl.gov/facility/expsys/software/EPICS/ 38 http://www.nsls.bnl.gov/facility/expsys/software/EPICS/FAQ.txt39 33 40 5) When generating code (especially C++) for this system, one should41 use at least gcc-3.2 (preferrably a copy downloaded from the RTEMS42 site [snapshot area] )43 34 44 6) To reboot the RTEMS-MVME5500 (board reset), one can invoke the35 4) To reboot the RTEMS-MVME5500 (board reset), one can invoke the 45 36 rtemsReboot() command at Cexp> prompt. 46 37 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 38 5) To get started with RTEMS/EPICS and to build development 52 39 tools and BSP, I would recommend one to reference 53 40 http://www.aps.anl.gov/epics/base/RTEMS/tutorial/ 54 41 in 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 */ 1 4 #include <bsp.h> 2 5 #include <rtems/bspIo.h> 3 6 #include <libcpu/stackTrace.h> -
startup/bspstart.c
diff -Naur mvme5500.orig/startup/bspstart.c mvme5500/startup/bspstart.c
old new 24 24 * $Id: bspstart.c,v 1.23 2008/08/20 08:56:56 ralf Exp $ 25 25 */ 26 26 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 29 27 #include <string.h> 30 28 #include <stdlib.h> 31 29 #include <ctype.h> … … 52 50 #undef __RTEMS_APPLICATION__ 53 51 #endif 54 52 55 /* 56 #define SHOW_MORE_INIT_SETTINGS 53 54 /*#define SHOW_MORE_INIT_SETTINGS 55 #define CONF_VPD 57 56 #define SHOW_LCR1_REGISTER 58 57 #define SHOW_LCR2_REGISTER 59 58 #define SHOW_LCR3_REGISTER 60 #define CONF_VPD61 59 */ 62 60 63 61 /* there is no public Workspace_Free() variant :-( */ … … 73 71 extern void BSP_pgtbl_activate(Triv121PgTbl); 74 72 extern int I2Cread_eeprom(unsigned char I2cBusAddr, uint32_t devA2A1A0, uint32_t AddrBytes, unsigned char *pBuff, uint32_t numBytes); 75 73 extern void BSP_vme_config(void); 74 extern uint32_t probeMemoryEnd(); 76 75 77 76 uint32_t bsp_clicks_per_usec; 78 77 … … 267 266 setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE); 268 267 269 268 /* 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. 273 271 */ 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); 276 273 277 274 /* 278 275 * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function … … 327 324 printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version ); 328 325 printk("-----------------------------------------\n"); 329 326 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(); 353 328 /* TODO: calculate the BSP_bus_frequency using the REF_CLK bit 354 329 * of System Status register 355 330 */ … … 421 396 #endif 422 397 BSP_pgtbl_activate(pt); 423 398 } 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 } 424 412 425 413 /* 426 414 * PCI 1 domain memory space … … 444 432 */ 445 433 _BSP_clear_hostbridge_errors(0, 1 /*quiet*/); 446 434 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_VPD452 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 #endif459 }460 461 435 #ifdef SHOW_MORE_INIT_SETTINGS 462 436 printk("MSR %x \n", _read_MSR()); 463 437 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 1 8 #include <rtems.h> 2 9 #include <bsp.h> 3 10 #include <rtems/bspIo.h> … … 12 19 13 20 printk("RTEMS terminated; Rebooting ...\n"); 14 21 /* Mvme5500 board reset : 2004 S. Kate Feng <feng1@bnl.gov> */ 15 out_8((volatile unsigned char*) (GT64 260_DEV1_BASE +2), 0x80);22 out_8((volatile unsigned char*) (GT64x60_DEV1_BASE +2), 0x80); 16 23 } -
vectors/exceptionhandler.c
diff -Naur mvme5500.orig/vectors/exceptionhandler.c mvme5500/vectors/exceptionhandler.c
old new 134 134 /* register dump */ 135 135 printk("\t Next PC or Address of fault = %x, ", excPtr->EXC_SRR0); 136 136 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()); 137 139 printk("\t R0 = %08x", excPtr->GPR0); 138 140 printk(" R1 = %08x", excPtr->GPR1); 139 141 printk(" R2 = %08x", excPtr->GPR2);