Ralph Lange wrote:
Hm. We get the attached result when running the test harness on a 5500.
Are we missing something obvious? This is RTEMS 4.9.0 and the 5500 BSP
that is shipped with it.
It seems that you are using the version, which does not have the patch
I sent on March 18, 2009 for RTEMS 4.9.1, see
http://www.aps.anl.gov/epics/tech-talk/2009/msg00491.php
The patch I sent is not applied to the RTEMS 4.9.0 or 4.9.1 branch
yet. The RTEMS officials are very busy lately (e.g. office relocation
and so on).
Here is what you can do :
1) Download rtems-4.9.1.tar.bz2 from
http://www.rtems.org/ftp/pub/rtems/4.9.1/
2) Unpack the code :
bzcat rtems-4.9.1.tar.bz2 | tar xf -
3) copy the attached mvme5500-rtems4.9.1-20090401.diff
patch to the directory of rtems-4.9.1/c/src/lib/libbsp/powerpc
4) cd mvme5500
5) patch -p1 < ../mvme5500-rtems4.9.1-20090401.diff
6) recompile
Another option is to download the tar file from
http://www.nsls.bnl.gov/facility/expsys/software/EPICS/
Cheers,
Kate
Thanks,
Ralph
Copyright Motorola Inc. 1999-2003, All Rights Reserved
MOTLoad RTOS Version 2.0, PAL Version 1.1 RM02
Tue Jul 1 16:34:30 MST 2003
MPU-Int Clock Speed =1000MHz
MPU-Ext Clock Speed =133MHz
MPU-Number/Type = 0/MPC7455
MPU-Int Cache(L2) = 256K, Enabled, L2CR =0xC0000000
MPU-Ext Cache(L3) = 2MB, Enabled, 200MHz, L3CR =0xDF826000
Reset/Boot Vector =Flash1
Local Memory Found =20000000 (&536870912)
User Download Buffer =005C3000:007C2FFF
MVME5500> tftpGet -a4000000 -c193.149.12.200 -s193.149.12.29 -g0.0.0.0
-m255.255.255.0 -d/dev/ene
t1 -f/opt/tftpdir/IOC/rtems/rtems-4.9/rtems5500TestHarness.boot
Network Loading from: /dev/enet1
Loading File: /opt/tftpdir/IOC/rtems/rtems-4.9/rtems5500TestHarness.boot
Load Address: 04000000
Client IP Address = 193.149.12.200
Server IP Address = 193.149.12.29
Gateway IP Address = 193.149.12.253
Subnet IP Address Mask = 255.255.255.0
Network File Load in Progress...
Bytes Received =&1109192, Bytes Loaded =&1109192
Bytes/Second =&1109192, Elapsed Time =1 Second(s)
MVME5500> netShut
/dev/enet0 Disabled
/dev/enet1 Disabled
MV-----------------------------------------
Welcome to rtems-4.9.0(PowerPC/Generic (classic FPU)/mvme5500) on
MVME5500-0163
-----------------------------------------
Now BSP_mem_size = 0x1FE00000
rtems_configuration_get_work_space_size() = 1F4000
Universe II PCI-VME bridge detected at 0x82000000, IRQ 12
Universe Master Ports:
Port VME-Addr Size PCI-Adrs Mode:
0: 0x20000000 0x0E000000 0x90000000 A32, D64 [MBLT], Dat, Sup
1: 0x00000000 0x00FF0000 0x9F000000 A24, D64 [MBLT], Dat, Sup
2: 0x00000000 0x00010000 0x9FFF0000 A16, D64, Dat, Sup
Universe Slave Ports:
Port VME-Addr Size PCI-Adrs Mode:
0: 0x90000000 0x1FE00000 0x00000000 A32, Pgm, Dat, Sup, Usr, PWEN,
PREN
Overriding main IRQ line PCI info with 76
Registering /dev/console as minor 0 (==/dev/ttyS0)
***** Initializing network *****
Startup.
Ethernet driver name wmG unit 1
Copyright (c) 2004,2005 S. Kate Feng <[email protected]> (RTEMS/mvme5500
port)
Can't set default route: Network is unreachable
***** Initializing NFS *****
RTEMS-RPCIOD $Release$, Till Straumann, Stanford/SLAC/SSRL 2002, See
LICENSE file for licensing i
nfo.
RTEMS-NFS $Release$, Till Straumann, Stanford/SLAC/SSRL 2002, See
LICENSE file for licensing info
.
Trying to mount 193.149.12.29:/srv/IOC on /srv/IOC
***** Starting EPICS application *****
***** epicsEventTest *****
1..11
ok 1 - epicsEventWaitWithTimeout(event, 0.0) = 1
ok 2 - epicsEventWaitWithTimeout(event, 1.0) = 1
ok 3 - epicsEventTryWait(event) = 1
ok 4 - epicsEventWaitWithTimeout(event, 1.0) = 0
ok 5 - epicsEventWaitWithTimeout(event, DBL_MAX) = 0
ok 6 - epicsEventTryWait(event) = 0
# consumer: starting
# producer 0: starting
# producer 1: starting
# producer 2: starting
# setting quit
ok 7 - consumer: errors = 0
ok 8 - producer 2: errors = 0
ok 9 - producer 0: errors = 0
ok 10 - producer 1: errors = 0
# epicsEventWaitWithTimeout(1.000000) delay error 0.000000 sec
# epicsEventWaitWithTimeout(0.500000) delay error 0.000000 sec
# epicsEventWaitWithTimeout(0.250000) delay error 0.010000 sec
# epicsEventWaitWithTimeout(0.125000) delay error 0.005000 sec
# epicsEventWaitWithTimeout(0.062500) delay error 0.002500 sec
# epicsEventWaitWithTimeout(0.031250) delay error 0.011250 sec
# epicsEventWaitWithTimeout(0.015625) delay error 0.004375 sec
# epicsEventWaitWithTimeout(0.007812) delay error 0.012188 sec
# epicsEventWaitWithTimeout(0.003906) delay error 0.016094 sec
# epicsEventWaitWithTimeout(0.001953) delay error 0.018047 sec
# epicsEventWaitWithTimeout(0.000977) delay error 0.019023 sec
# epicsEventWaitWithTimeout(0.000488) delay error 0.019512 sec
# epicsEventWaitWithTimeout(0.000244) delay error 0.019756 sec
# epicsEventWaitWithTimeout(0.000122) delay error 0.019878 sec
# epicsEventWaitWithTimeout(0.000061) delay error 0.019939 sec
# epicsEventWaitWithTimeout(0.000031) delay error 0.019969 sec
# epicsEventWaitWithTimeout(0.000015) delay error 0.019985 sec
# epicsEventWaitWithTimeout(0.000008) delay error 0.019992 sec
# epicsEventWaitWithTimeout(0.000004) delay error 0.019996 sec
# epicsEventWaitWithTimeout(0.000002) delay error 0.019998 sec
# epicsEventWaitWithTimeout(0.000000) delay error 0.000000 sec
ok 11 - Average error 0.013214 sec
Results
=======
Tests: 11
Passed: 11 = 100.00%
In BSP_exceptionHandler()
Uhuuuh, Exception 10 in unknown task???
Next PC or Address of fault = C4A08, Mvme5500 Saved MSR = B032
R0 = 00000AE0 R1 = 1FC27B10 R2 = 00000000 R3 = 001AC778
R4 = 001075DC R5 = 000A2864 R6 = 00110000 R7 = 000AA6B4
R8 = 001AC748 R9 = 474E5543 R10 = 432B2B00 R11 = 0010EC60
R12 = 24400022 R13 = 001164D0 R14 = 00000000 R15 = 00000000
R16 = 00000000 R17 = 00000000 R18 = 00000000 R19 = 00000000
R20 = 00000000 R21 = 1FC288C8 R22 = 1FC288F0 R23 = 000EA970
R24 = 000EA9E4 R25 = 1FC28914 R26 = 00122870 R27 = 0000D45C
R28 = 00000023 R29 = 001AC778 R30 = 00114B14 R31 = FFFFFFFF
CR = 24400022
CTR = 00000000
XER = 00000000
LR = 000A237C
DAR = 00000000
Stack Trace:
IP: 0x000C4A08, LR: 0x000A237C
--^ 0x000A237C--^ 0x000A29F8--^ 0x000A2A18--^ 0x0000D208--^ 0x0000D47C
--^ 0x0001831C--^ 0x000104B0--^ 0x0000330C--^ 0x0002A6AC--^ 0x00067330
--^ 0x000672B0
unrecoverable exception!!! task 0A010001 suspended
***** epicsExceptionTest *****
1..4
diff -Naur mvme5500.orig/ChangeLog mvme5500/ChangeLog
--- mvme5500.orig/ChangeLog 2008-12-08 00:15:44.000000000 -0500
+++ mvme5500/ChangeLog 2009-04-01 11:58:19.000000000 -0400
@@ -1,3 +1,28 @@
+2009-02-24 Kate Feng <[email protected]>
+ * Updated the changes from RTEMS-4.8.0, which were made since Oct. 2007.
+
+ 2008-03-18 Kate Feng <[email protected]>
+ * network/if_1GHz/if_wm.c : fixed some bugs in the 1GHz driver.
+
+ 2007-11-31 Kate Feng <[email protected]>
+ * pci/pci_interface.c : Enabled PCI "Read", "Read Line", and "Read Multiple"
+ * Agressive Prefetch to improve the performance of the PCI based
+ * applications (e.g. 1GHz NIC).
+
+ 2007-11-30 Kate Feng <[email protected]>
+ * irq/BSP_irq.c : Replaced the irq/irq.c, and used GT_GPP_Value
+ * register to monitor the cause of the level sensitive interrupts.
+ * This unique solution solves various bugs in the 1GHz network drivers
+ * Fixed bugs in compute_pic_masks_from_prio()
+
+2009-02-12 Kate Feng <[email protected]>
+ * pci/pci.c : Updated it to be consistent with the original pci.c
+ * written by Eric Valette. There is no change in its function.
+
+2009-01-30 Kate Feng <[email protected]>
+ * irq/irq_init.c : set defaultIrq->next_handler to be 0
+ * for BSP_SHARED_HANDLER_SUPPORT.
+
2008-12-08 Ralf Corsépius <[email protected]>
* bsp_specs: Backport from CVS-HEAD.
diff -Naur mvme5500.orig/GT64260/gtreg.h mvme5500/GT64260/gtreg.h
--- mvme5500.orig/GT64260/gtreg.h 2004-10-20 11:21:05.000000000 -0400
+++ mvme5500/GT64260/gtreg.h 2009-02-25 15:07:57.000000000 -0500
@@ -190,7 +190,7 @@
#define GT_MPP_Control2 0xf008
#define GT_MPP_Control3 0xf00c
-/* <skf> added */
+/* <skf> added for GT64260 */
#define GT_MPP_SerialPortMultiplex 0xf010
#define GT_GPP_IO_Control 0xf100
@@ -789,14 +789,13 @@
#define TWSI_BAUDE_RATE 0xc00c
#define TWSI_SFT_RST 0xc01c
-/* Interrupt Controller - Interrupt Controller Registers */
/* Section 25.2 : Table 734 <skf> */
-#define GT_MAIN_INT_CAUSE_LO 0xc18 /* read Only */
-#define GT_MAIN_INT_CAUSE_HI 0xc68 /* read Only */
-#define GT_CPU_INT_MASK_LO 0xc1c
-#define GT_CPU_INT_MASK_HI 0xc6c
-#define GT_CPU_SEL_CAUSE 0xc70 /* read Only */
+#define GT64260_MAIN_INT_CAUSE_LO 0xc18 /* read Only */
+#define GT64260_MAIN_INT_CAUSE_HI 0xc68 /* read Only */
+#define GT64260_CPU_INT_MASK_LO 0xc1c
+#define GT64260_CPU_INT_MASK_HI 0xc6c
+#define GT64260_CPU_SEL_CAUSE 0xc70 /* read Only */
#define GT_PCI0_INT_MASK_LO 0xc24
#define GT_PCI0_INT_MASK_HI 0xc64
#define GT_PCI0_SEL_CAUSE 0xc74 /* read Only */
diff -Naur mvme5500.orig/include/bsp.h mvme5500/include/bsp.h
--- mvme5500.orig/include/bsp.h 2008-10-23 09:45:55.000000000 -0400
+++ mvme5500/include/bsp.h 2009-03-16 14:30:10.000000000 -0400
@@ -7,7 +7,8 @@
* found in found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
- * S. Kate Feng 2003-2007 : Modified it to support the mvme5500 BSP.
+ * (C) S. Kate Feng 2003-2007 : Modified it to support the mvme5500 BSP.
+ *
*
*/
@@ -22,10 +23,57 @@
#include <libcpu/io.h>
#include <bsp/vectors.h>
-#include <bsp/bspMvme5500.h>
+/* Board type */
+typedef enum {
+ undefined = 0,
+ MVME5500,
+ MVME6100
+} BSP_BoardTypes;
+
+BSP_BoardTypes BSP_getBoardType();
+
+/* Board type */
+typedef enum {
+ Undefined,
+ UNIVERSE2,
+ TSI148,
+} BSP_VMEchipTypes;
+
+BSP_VMEchipTypes BSP_getVMEchipType();
+
+/* The version of Discovery system controller */
+
+typedef enum {
+ notdefined,
+ GT64260A,
+ GT64260B,
+ MV64360,
+} DiscoveryChipVersion;
+
+DiscoveryChipVersion BSP_getDiscoveryChipVersion();
+
+#define _256M 0x10000000
+#define _512M 0x20000000
+
+#define GT64x60_REG_BASE 0xf1000000 /* Base of GT64260 Reg Space */
+#define GT64x60_REG_SPACE_SIZE 0x10000 /* 64Kb Internal Reg Space */
+
+#define GT64x60_DEV1_BASE 0xf1100000 /* Device bank1(chip select 1) base
+ */
+#define GT64260_DEV1_SIZE 0x00100000 /* Device bank size */
/* fundamental addresses for this BSP (PREPxxx are from libcpu/io.h) */
-#define _IO_BASE GT64260_REG_BASE
+#define _IO_BASE GT64x60_REG_BASE
+
+#define BSP_NVRAM_BASE_ADDR 0xf1110000
+
+#define BSP_RTC_INTA_REG 0x7ff0
+#define BSP_RTC_SECOND 0x7ff2
+#define BSP_RTC_MINUTE 0x7ff3
+#define BSP_RTC_HOUR 0x7ff4
+#define BSP_RTC_DATE 0x7ff5
+#define BSP_RTC_INTERRUPTS 0x7ff6
+#define BSP_RTC_WATCHDOG 0x7ff7
/* PCI0 Domain I/O space */
#define PCI0_IO_BASE 0xf0000000
@@ -69,18 +117,16 @@
*/
#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 2
+#define BSP_INTERRUPT_STACK_SIZE (16 * 1024) /* <skf> 2/09 wants it to be adjustable by BSP */
/* uart.c uses out_8 instead of outb */
-#define BSP_UART_IOBASE_COM1 GT64260_DEV1_BASE + 0x20000
-#define BSP_UART_IOBASE_COM2 GT64260_DEV1_BASE + 0x21000
+#define BSP_UART_IOBASE_COM1 GT64x60_DEV1_BASE + 0x20000
+#define BSP_UART_IOBASE_COM2 GT64x60_DEV1_BASE + 0x21000
#define BSP_CONSOLE_PORT BSP_UART_COM1 /* console */
#define BSP_UART_BAUD_BASE 115200
/*
- * Vital Board data Start using DATA RESIDUAL
- */
-/*
* Total memory using RESIDUAL DATA
*/
extern unsigned int BSP_mem_size;
@@ -100,6 +146,7 @@
#define BSP_Convert_decrementer( _value ) \
((unsigned long long) ((((unsigned long long)BSP_time_base_divisor) * 1000000ULL) /((unsigned long long) BSP_bus_frequency)) * ((unsigned long long) (_value)))
+extern rtems_configuration_table BSP_Configuration;
extern void BSP_panic(char *s);
extern void bsp_reset(void);
/* extern int printk(const char *, ...) __attribute__((format(printf, 1, 2))); */
@@ -118,24 +165,31 @@
#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_i82544EI_driver_attach
#endif
-extern int
-RTEMS_BSP_NETWORK_DRIVER_ATTACH(/* struct rtems_bsdnet_ifconfig * */);
+extern int RTEMS_BSP_NETWORK_DRIVER_ATTACH();
/*
* BSP Configuration Default Overrides
*/
#define BSP_ZERO_WORKSPACE_AUTOMATICALLY TRUE
-/* As per Linux, This should be in the ppc/system.h */
+#define gccMemBar() RTEMS_COMPILER_MEMORY_BARRIER()
+static inline void lwmemBar()
+{
+ asm volatile("lwsync":::"memory");
+}
+
+static inline void io_flush()
+{
+ asm volatile("isync":::"memory");
+}
static inline void memBar()
{
asm volatile("sync":::"memory");
}
-
static inline void ioBar()
{
- asm volatile("eieio");
+ asm volatile("eieio":::"memory");
}
#endif
diff -Naur mvme5500.orig/irq/BSP_irq.c mvme5500/irq/BSP_irq.c
--- mvme5500.orig/irq/BSP_irq.c 1969-12-31 19:00:00.000000000 -0500
+++ mvme5500/irq/BSP_irq.c 2009-04-01 11:11:25.000000000 -0400
@@ -0,0 +1,506 @@
+/* BSP_irq.c
+ *
+ * This file contains the implementation of the function described in irq.h
+ *
+ * Copyright (C) 1998, 1999 [email protected]
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * Acknowledgement to Till Straumann <[email protected]>
+ * for some inputs in May 2004.
+ *
+ * Copyright 2003, 2004, 2005, 2007 Shuchen Kate Feng <[email protected]>,
+ * NSLS, Brookhaven National Laboratory. All rights reserved.
+ *
+ * 1) Used GT_GPP_Value register instead of the GT_GPP_Interrupt_Cause
+ * register to monitor the cause of the level sensitive interrupts.
+ * (Copyright : NDA item)
+ * 2) The implementation of picPrioTable[] is an original work by the
+ * author to optimize the software IRQ priority scheduling because
+ * Discovery controller does not provide H/W IRQ priority schedule.
+ * It ensures the fastest/faster interrupt service to the
+ * highest/higher priority IRQ, if pendig.
+ * 3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER()
+ *
+ */
+
+#include <stdio.h>
+#include <rtems/system.h>
+#include <bsp.h>
+#include <bsp/irq.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/apiext.h>
+#include <libcpu/raw_exception.h>
+#include <rtems/rtems/intr.h>
+#include <libcpu/io.h>
+#include <libcpu/byteorder.h>
+#include <bsp/vectors.h>
+
+#include <rtems/bspIo.h> /* for printk */
+#include "bsp/gtreg.h"
+
+#define HI_INT_CAUSE 0x40000000
+
+#define MAX_IRQ_LOOP 20
+
+#define _MSR_GET( _mask) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_MSR_GET( _mask); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0);
+
+#define _MSR_SET( _mask) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_MSR_SET( _mask); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0);
+
+/* #define DEBUG_IRQ*/
+
+/*
+ * pointer to the mask representing the additionnal irq vectors
+ * that must be disabled when a particular entry is activated.
+ * They will be dynamically computed from the table given
+ * in BSP_rtems_irq_mngt_set();
+ * CAUTION : this table is accessed directly by interrupt routine
+ * prologue.
+ */
+static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
+
+/*
+ * location used to store initial tables used for interrupt
+ * management.BSP copy of the configuration
+ */
+static rtems_irq_global_settings BSP_config;
+static rtems_irq_connect_data* rtems_hdl_tbl;
+
+/*
+ * default handler connected on each irq after bsp initialization
+ * (locally cached copy)
+ */
+void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
+
+
+static volatile unsigned *BSP_irqMask_reg[3];
+static volatile unsigned *BSP_irqCause_reg[3];
+static volatile unsigned BSP_irqMask_cache[3]={0,0,0};
+
+static int picPrioTblPtr=0;
+static unsigned int GPPIrqInTbl=0;
+static unsigned long long MainIrqInTbl=0;
+
+/*
+ * The software developers are forbidden to setup picPrioTable[],
+ * as it is a powerful engine for the BSP to find the pending
+ * highest priority IRQ at run time. It ensures the fastest/faster
+ * interrupt service to the highest/higher priority IRQ, if pendig.
+ *
+ * The picPrioTable[96] is updated dynamically at run time
+ * based on the priority levels set at BSPirqPrioTable[96],
+ * while the BSP_enable_irq_at_pic(), and BSP_disable_irq_at_pic()
+ * commands are invoked.
+ *
+ * The picPrioTable[96] lists the enabled CPU main and GPP external interrupt
+ * numbers [0 (lowest)- 95 (highest)] starting from the highest priority
+ * one to the lowest priority one. The highest priority interrupt is
+ * located at picPrioTable[0], and the lowest priority interrupt is located
+ * at picPrioTable[picPrioTblPtr-1].
+ *
+ *
+ */
+#define DynamicIsrTable
+#ifdef DynamicIsrTable
+/* BitNums for Main Interrupt Lo/High Cause, -1 means invalid bit */
+static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1 };
+#else
+static unsigned int picPrioTable[BSP_PIC_IRQ_NUMBER]={
+ 80, 84, 76, 77, 32, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1 };
+#endif
+
+/*
+ * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ
+ */
+static inline int is_pic_irq(const rtems_irq_number irqLine)
+{
+ return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
+ );
+}
+
+/*
+ * Check if IRQ is a Porcessor IRQ
+ */
+static inline int is_processor_irq(const rtems_irq_number irqLine)
+{
+ return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
+ ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
+ );
+}
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+/*
+ * Caution : this function assumes the variable "BSP_config"
+ * is already set and that the tables it contains are still valid
+ * and accessible.
+ */
+static void compute_pic_masks_from_prio()
+{
+ int i,j, k, isGppMain;
+ unsigned long long irq_prio_mask=0;
+
+ /*
+ * Always mask at least current interrupt to prevent re-entrance
+ */
+ for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
+ switch(i) {
+ case BSP_MAIN_GPP7_0_IRQ:
+ case BSP_MAIN_GPP15_8_IRQ:
+ case BSP_MAIN_GPP23_16_IRQ:
+ case BSP_MAIN_GPP31_24_IRQ:
+ for (k=0; k< 3; k++)
+ BSP_irq_prio_mask_tbl[k][i]=0;
+
+ irq_prio_mask =0;
+ isGppMain =1;
+ break;
+ default :
+ isGppMain =0;
+ irq_prio_mask = (unsigned long long) (1LLU << i);
+ break;
+ }
+ if ( isGppMain) continue;
+ for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
+ /*
+ * Mask interrupts at PIC level that have a lower priority
+ */
+ if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
+ irq_prio_mask |= (unsigned long long)(1LLU << j);
+ }
+
+
+ BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
+ BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
+#if 0
+ printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
+ BSP_irq_prio_mask_tbl[0][i]);
+#endif
+
+ BSP_irq_prio_mask_tbl[2][i] = 1<<i;
+ /* Compute for the GPP priority interrupt mask */
+ for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {
+ if (BSP_config.irqPrioTbl [i] >= BSP_config.irqPrioTbl [j])
+ BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
+ }
+#if 0
+ printk("GPPirq_mask_prio_tbl[%d]:0x%8x\n",i,BSP_irq_prio_mask_tbl[2][i]);
+#endif
+ }
+}
+
+static void UpdateMainIrqTbl(int irqNum)
+{
+ int i=0, j, shifted=0;
+
+ switch (irqNum) {
+ case BSP_MAIN_GPP7_0_IRQ:
+ case BSP_MAIN_GPP15_8_IRQ:
+ case BSP_MAIN_GPP23_16_IRQ:
+ case BSP_MAIN_GPP31_24_IRQ:
+ return; /* Do nothing, let GPP take care of it */
+ break;
+ }
+#ifdef SHOW_MORE_INIT_SETTINGS
+ unsigned long val2, val1;
+#endif
+
+ /* If entry not in table*/
+ if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
+ (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
+ ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
+ (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
+ {
+ while ( picPrioTable[i]!=-1) {
+ if (BSP_config.irqPrioTbl[irqNum]>BSP_config.irqPrioTbl[picPrioTable[i]]) {
+ /* all other lower priority entries shifted right */
+ for (j=picPrioTblPtr;j>i; j--) {
+ picPrioTable[j]=picPrioTable[j-1];
+ }
+ picPrioTable[i]=irqNum;
+ shifted=1;
+ break;
+ }
+ i++;
+ }
+ if (!shifted) picPrioTable[picPrioTblPtr] =irqNum;
+
+ if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
+ GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
+ else
+ MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
+ picPrioTblPtr++;
+ }
+#ifdef SHOW_MORE_INIT_SETTINGS
+ val2 = (MainIrqInTbl>>32) & 0xffffffff;
+ val1 = MainIrqInTbl&0xffffffff;
+ printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
+ BSP_printPicIsrTbl();
+#endif
+
+}
+
+
+static void CleanMainIrqTbl(int irqNum)
+{
+ int i, j;
+
+ switch (irqNum) {
+ case BSP_MAIN_GPP7_0_IRQ:
+ case BSP_MAIN_GPP15_8_IRQ:
+ case BSP_MAIN_GPP23_16_IRQ:
+ case BSP_MAIN_GPP31_24_IRQ:
+ return; /* Do nothing, let GPP take care of it */
+ break;
+ }
+ if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
+ ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
+ ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
+ (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
+ { /* If entry in table*/
+ for (i=0; i<64; i++) {
+ if (picPrioTable[i]==irqNum) {/*remove it from the entry */
+ /* all other lower priority entries shifted left */
+ for (j=i;j<picPrioTblPtr; j++) {
+ picPrioTable[j]=picPrioTable[j+1];
+ }
+ if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
+ GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
+ else
+ MainIrqInTbl &= ~(1LLU << irqNum);
+ picPrioTblPtr--;
+ break;
+ }
+ }
+ }
+}
+
+void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
+{
+ unsigned bitNum, regNum;
+ unsigned int level;
+
+ if ( !is_pic_irq(irqNum) )
+ return;
+
+ bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
+ regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
+
+ rtems_interrupt_disable(level);
+
+#ifdef DynamicIsrTable
+ UpdateMainIrqTbl((int) irqNum);
+#endif
+ BSP_irqMask_cache[regNum] |= (1 << bitNum);
+
+ out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
+ while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
+
+ rtems_interrupt_enable(level);
+}
+
+void BSP_enable_pic_irq(const rtems_irq_number irqNum)
+{
+ BSP_enable_irq_at_pic(irqNum);
+}
+
+int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
+{
+ int rval;
+ unsigned bitNum, regNum;
+ unsigned int level;
+
+ if ( ! is_pic_irq(irqNum) )
+ return -1;
+
+ bitNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)%32;
+ regNum = (((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET)>>5;
+
+ rtems_interrupt_disable(level);
+
+#ifdef DynamicIsrTable
+ CleanMainIrqTbl((int) irqNum);
+#endif
+
+ rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
+
+ BSP_irqMask_cache[regNum] &= ~(1 << bitNum);
+
+ out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
+ while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
+
+ rtems_interrupt_enable(level);
+
+ return rval ? 1 : 0;
+}
+
+void BSP_disable_pic_irq(const rtems_irq_number irqNum)
+{
+ (void)BSP_disable_irq_at_pic(irqNum);
+}
+
+/* Use shared/irq : 2008 */
+int BSP_setup_the_pic(rtems_irq_global_settings* config)
+{
+ int i;
+
+ BSP_config = *config;
+ default_rtems_hdl = config->defaultEntry.hdl;
+ rtems_hdl_tbl = config->irqHdlTbl;
+
+ /* Get ready for discovery BSP */
+ BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_LO);
+ BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_CPU_INT_MASK_HI);
+ BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_LO);
+ BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64x60_REG_BASE + GT64260_MAIN_INT_CAUSE_HI);
+ BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Interrupt_Mask);
+ BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64x60_REG_BASE + GT_GPP_Value);
+
+ /* Page 401, Table 598:
+ * Comm Unit Arbiter Control register :
+ * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
+ * MOTload default is set as level sensitive(1). Set it agin to make sure.
+ */
+ out_le32(GT_CommUnitArb_Ctrl, (in_le32(GT_CommUnitArb_Ctrl)| (1<<10)));
+
+#if 0
+ printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
+ in_le32(BSP_irqMask_reg[0]),
+ in_le32(BSP_irqCause_reg[0]));
+ printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
+ in_le32(BSP_irqMask_reg[1]),
+ in_le32(BSP_irqCause_reg[1]));
+ printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
+ in_le32(BSP_irqMask_reg[2]),
+ in_le32(BSP_irqCause_reg[2]));
+#endif
+
+ /* Initialize the interrupt related registers */
+ for (i=0; i<3; i++) {
+ out_le32(BSP_irqCause_reg[i], 0);
+ out_le32(BSP_irqMask_reg[i], 0);
+ }
+ in_le32(BSP_irqMask_reg[2]);
+ compute_pic_masks_from_prio();
+
+#if 0
+ printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
+ in_le32(BSP_irqMask_reg[0]),
+ in_le32(BSP_irqCause_reg[0]));
+ printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
+ in_le32(BSP_irqMask_reg[1]),
+ in_le32(BSP_irqCause_reg[1]));
+ printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
+ in_le32(BSP_irqMask_reg[2]),
+ in_le32(BSP_irqCause_reg[2]));
+#endif
+
+ /*
+ *
+ */
+ for (i=BSP_MICL_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET ; i++) {
+ if ( BSP_config.irqHdlTbl[i].hdl != BSP_config.defaultEntry.hdl) {
+ BSP_enable_irq_at_pic(i);
+ BSP_config.irqHdlTbl[i].on(&BSP_config.irqHdlTbl[i]);
+ }
+ else {
+ BSP_config.irqHdlTbl[i].off(&BSP_config.irqHdlTbl[i]);
+ BSP_disable_irq_at_pic(i);
+ }
+ }
+ for (i= BSP_MAIN_GPP7_0_IRQ; i < BSP_MAIN_GPP31_24_IRQ; i++)
+ BSP_enable_irq_at_pic(i);
+
+ return(1);
+}
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
+{
+ register unsigned msr, new_msr;
+ unsigned long irqCause[3]={0, 0,0};
+ unsigned oldMask[3]={0,0,0};
+ int loop=0, wloop=0, i=0, j;
+ register irq=0, group=0;
+
+ if (excNum == ASM_DEC_VECTOR) {
+ bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
+ return 0;
+ }
+
+ for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
+ for (j=0; j<3; j++) irqCause[j] = in_le32(BSP_irqCause_reg[j]) & in_le32(BSP_irqMask_reg[j]);
+
+ while (((irq = picPrioTable[i++])!=-1)&& (loop++ < MAX_IRQ_LOOP))
+ {
+ if (irqCause[group= irq/32] & ( 1<<(irq % 32))) {
+ for (j=0; j<3; j++)
+ BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
+
+ out_le32(BSP_irqMask_reg[0], BSP_irqMask_cache[0]);
+ out_le32(BSP_irqMask_reg[1], BSP_irqMask_cache[1]);
+ out_le32(BSP_irqMask_reg[2], BSP_irqMask_cache[2]);
+ in_le32(BSP_irqMask_reg[2]);
+
+ bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
+
+ for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
+
+ out_le32(BSP_irqMask_reg[0], oldMask[0]);
+ out_le32(BSP_irqMask_reg[1], oldMask[1]);
+ out_le32(BSP_irqMask_reg[2], oldMask[2]);
+ in_le32(BSP_irqMask_reg[2]);
+ }
+ }
+
+ return 0;
+}
+
+/* Only print part of the entries for now */
+void BSP_printPicIsrTbl()
+{
+ int i;
+
+ printf("picPrioTable[12]={ {irq# : ");
+ for (i=0; i<12; i++)
+ printf("%d,", picPrioTable[i]);
+ printf("}\n");
+
+ printf("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
+}
diff -Naur mvme5500.orig/irq/irq.c mvme5500/irq/irq.c
--- mvme5500.orig/irq/irq.c 2007-12-11 20:16:34.000000000 -0500
+++ mvme5500/irq/irq.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,493 +0,0 @@
-/* irq.c
- *
- * This file contains the implementation of the function described in irq.h
- *
- * Copyright (C) 1998, 1999 [email protected]
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.OARcorp.com/rtems/license.html.
- *
- * Acknowledgement May 2004 : to Till Straumann <[email protected]>
- * for some inputs.
- *
- * Copyright 2003, 2004, 2005, 2007 Shuchen Kate Feng <[email protected]>,
- * NSLS,Brookhaven National Laboratory
- * 1) Modified and added support for the MVME5500 board.
- * 2) The implementation of picIsrTable[] is an original work by the
- * author to optimize the software IRQ priority scheduling because
- * Discovery controller does not provide H/W IRQ priority schedule.
- * It ensures the fastest/faster interrupt service to the
- * highest/higher priority IRQ, if pendig.
- * 3) _CPU_MSR_SET() needs RTEMS_COMPILER_MEMORY_BARRIER()
- *
- */
-
-#include <rtems/system.h>
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <rtems/score/thread.h>
-#include <rtems/score/apiext.h>
-#include <libcpu/raw_exception.h>
-#include <rtems/rtems/intr.h>
-#include <libcpu/io.h>
-#include <libcpu/byteorder.h>
-#include <bsp/vectors.h>
-
-#include <rtems/bspIo.h> /* for printk */
-#include "bsp/gtreg.h"
-
-#define HI_INT_CAUSE 0x40000000
-
-#define MAX_IRQ_LOOP 30
-
-#define EDGE_TRIGGER
-
-/* #define DEBUG_IRQ*/
-
-/*
- * pointer to the mask representing the additionnal irq vectors
- * that must be disabled when a particular entry is activated.
- * They will be dynamically computed from the table given
- * in BSP_rtems_irq_mngt_set();
- * CAUTION : this table is accessed directly by interrupt routine
- * prologue.
- */
-static unsigned int BSP_irq_prio_mask_tbl[3][BSP_PIC_IRQ_NUMBER];
-
-/*
- * location used to store initial tables used for interrupt
- * management.
- */
-static rtems_irq_global_settings* internal_config;
-/* handler table (cached copy ) */
-static rtems_irq_connect_data* rtems_hdl_tbl;
-/*
- * default handler connected on each irq after bsp initialization
- * (locally cached copy)
- */
-void (*default_rtems_hdl)(rtems_irq_hdl_param) = (void(*)(rtems_irq_hdl_param)) -1;
-
-
-static volatile unsigned *BSP_irqMask_reg[3];
-static volatile unsigned *BSP_irqCause_reg[3];
-static volatile unsigned BSP_irqMask_cache[3]={0,0,0};
-
-
-static int picIsrTblPtr=0;
-static unsigned int GPPIrqInTbl=0;
-static unsigned long long MainIrqInTbl=0;
-
-/*
- * The software developers are forbidden to setup picIsrTable[],
- * as it is a powerful engine for the BSP to find the pending
- * highest priority IRQ at run time. It ensures the fastest/faster
- * interrupt service to the highest/higher priority IRQ, if pendig.
- *
- * The picIsrTable[96] is updated dynamically at run time
- * based on the priority levels set at BSPirqPrioTable[96],
- * while the BSP_enable_pic_irq(), and BSP_disable_pic_irq()
- * commands are invoked.
- *
- * The picIsrTable[96] lists the enabled CPU main and GPP external interrupt
- * numbers [0 (lowest)- 95 (highest)] starting from the highest priority
- * one to the lowest priority one. The highest priority interrupt is
- * located at picIsrTable[0], and the lowest priority interrupt is located
- * at picIsrTable[picIsrTblPtr-1].
- *
- *
- */
-/* BitNums for Main Interrupt Lo/High Cause and GPP, -1 means invalid bit */
-static unsigned int picIsrTable[BSP_PIC_IRQ_NUMBER]={
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1 };
-
-
-/*
- * Check if IRQ is a MAIN CPU internal IRQ or GPP external IRQ
- */
-static inline int is_pic_irq(const rtems_irq_number irqLine)
-{
- return (((int) irqLine <= BSP_GPP_IRQ_MAX_OFFSET) &
- ((int) irqLine >= BSP_MICL_IRQ_LOWEST_OFFSET)
- );
-}
-
-/*
- * Check if IRQ is a Porcessor IRQ
- */
-static inline int is_processor_irq(const rtems_irq_number irqLine)
-{
- return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) &
- ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET)
- );
-}
-
-static inline unsigned int divIrq32(unsigned irq)
-{
- return(irq/32);
-}
-
-static inline unsigned int modIrq32(unsigned irq)
-{
- return(irq%32);
-}
-
-/*
- * ------------------------ RTEMS Irq helper functions ----------------
- */
-
-/*
- * Caution : this function assumes the variable "internal_config"
- * is already set and that the tables it contains are still valid
- * and accessible.
- */
-static void compute_pic_masks_from_prio(rtems_irq_global_settings *config)
-{
- int i,j, k;
- unsigned long long irq_prio_mask=0;
-
- /*
- * Always mask at least current interrupt to prevent re-entrance
- */
- for (i=0; i <BSP_PIC_IRQ_NUMBER; i++) {
- switch(i) {
- case BSP_MAIN_GPP7_0_IRQ:
- case BSP_MAIN_GPP15_8_IRQ:
- case BSP_MAIN_GPP23_16_IRQ:
- case BSP_MAIN_GPP31_24_IRQ:
- for (k=0; k< 3; k++)
- BSP_irq_prio_mask_tbl[k][i]=0;
-
- irq_prio_mask =0;
- break;
- default :
- irq_prio_mask = (unsigned long long) (1LLU << i);
- break;
- }
-
- if (irq_prio_mask) {
- for (j = 0; j <BSP_MAIN_IRQ_NUMBER; j++) {
- /*
- * Mask interrupts at PIC level that have a lower priority
- * or <Till Straumann> a equal priority.
- */
- if (config->irqPrioTbl [i] >= config->irqPrioTbl [j])
- irq_prio_mask |= (unsigned long long)(1LLU << j);
- }
-
-
- BSP_irq_prio_mask_tbl[0][i] = irq_prio_mask & 0xffffffff;
- BSP_irq_prio_mask_tbl[1][i] = (irq_prio_mask>>32) & 0xffffffff;
-#ifdef DEBUG
- printk("irq_mask_prio_tbl[%d]:0x%8x%8x\n",i,BSP_irq_prio_mask_tbl[1][i],
- BSP_irq_prio_mask_tbl[0][i]);
-#endif
-
- BSP_irq_prio_mask_tbl[2][i] = 1<<i;
- /* Compute for the GPP priority interrupt mask */
- for (j=BSP_GPP_IRQ_LOWEST_OFFSET; j <BSP_PROCESSOR_IRQ_LOWEST_OFFSET; j++) {
- if (config->irqPrioTbl [i] >= config->irqPrioTbl [j])
- BSP_irq_prio_mask_tbl[2][i] |= 1 << (j-BSP_GPP_IRQ_LOWEST_OFFSET);
- }
- }
- }
-}
-
-
-static void UpdateMainIrqTbl(int irqNum)
-{
- int i=0, j, shifted=0;
-
- switch (irqNum) {
- case BSP_MAIN_GPP7_0_IRQ:
- case BSP_MAIN_GPP15_8_IRQ:
- case BSP_MAIN_GPP23_16_IRQ:
- case BSP_MAIN_GPP31_24_IRQ:
- return; /* Do nothing, let GPP take care of it */
- break;
- }
-#ifdef SHOW_MORE_INIT_SETTINGS
- unsigned long val2, val1;
-#endif
-
- /* If entry not in table*/
- if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
- (!((unsigned long long)(1LLU << irqNum) & MainIrqInTbl))) ||
- ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
- (!(( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl))))
- {
- while ( picIsrTable[i]!=-1) {
- if (internal_config->irqPrioTbl[irqNum]>internal_config->irqPrioTbl[picIsrTable[i]]) {
- /* all other lower priority entries shifted right */
- for (j=picIsrTblPtr;j>i; j--)
- picIsrTable[j]=picIsrTable[j-1];
- picIsrTable[i]=irqNum;
- shifted=1;
- break;
- }
- i++;
- }
- if (!shifted) picIsrTable[picIsrTblPtr]=irqNum;
- if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
- GPPIrqInTbl |= (1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
- else
- MainIrqInTbl |= (unsigned long long)(1LLU << irqNum);
- picIsrTblPtr++;
- }
-#ifdef SHOW_MORE_INIT_SETTINGS
- val2 = (MainIrqInTbl>>32) & 0xffffffff;
- val1 = MainIrqInTbl&0xffffffff;
- printk("irqNum %d, MainIrqInTbl 0x%x%x\n", irqNum, val2, val1);
- BSP_printPicIsrTbl();
-#endif
-
-}
-
-
-static void CleanMainIrqTbl(int irqNum)
-{
- int i, j;
-
- switch (irqNum) {
- case BSP_MAIN_GPP7_0_IRQ:
- case BSP_MAIN_GPP15_8_IRQ:
- case BSP_MAIN_GPP23_16_IRQ:
- case BSP_MAIN_GPP31_24_IRQ:
- return; /* Do nothing, let GPP take care of it */
- break;
- }
- if ( ((irqNum<BSP_GPP_IRQ_LOWEST_OFFSET) &&
- ((unsigned long long)(1LLU << irqNum) & MainIrqInTbl)) ||
- ((irqNum>BSP_MICH_IRQ_MAX_OFFSET) &&
- (( 1 << (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET)) & GPPIrqInTbl)))
- { /* If entry in table*/
- for (i=0; i<64; i++) {
- if (picIsrTable[i]==irqNum) {/*remove it from the entry */
- /* all other lower priority entries shifted left */
- for (j=i;j<picIsrTblPtr; j++)
- picIsrTable[j]=picIsrTable[j+1];
- if (irqNum >BSP_MICH_IRQ_MAX_OFFSET)
- GPPIrqInTbl &= ~(1<< (irqNum-BSP_GPP_IRQ_LOWEST_OFFSET));
- else
- MainIrqInTbl &= ~(1LLU << irqNum);
- picIsrTblPtr--;
- break;
- }
- }
- }
-}
-
-void BSP_enable_pic_irq(const rtems_irq_number irqNum)
-{
- unsigned bitNum, regNum;
- unsigned int level;
-
- if ( !is_pic_irq(irqNum) )
- return;
-
- bitNum = modIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
- regNum = divIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
-
- rtems_interrupt_disable(level);
-
- UpdateMainIrqTbl((int) irqNum);
- BSP_irqMask_cache[regNum] |= (1 << bitNum);
-
- out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
- while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
-
- rtems_interrupt_enable(level);
-}
-
-void BSP_enable_irq_at_pic(const rtems_irq_number irqNum)
-{
- BSP_enable_pic_irq(irqNum);
-}
-
-int BSP_disable_irq_at_pic(const rtems_irq_number irqNum)
-{
- int rval;
- unsigned bitNum, regNum;
- unsigned int level;
-
- if ( ! is_pic_irq(irqNum) )
- return -1;
-
- bitNum = modIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
- regNum = divIrq32(((unsigned int)irqNum) - BSP_MICL_IRQ_LOWEST_OFFSET);
-
- rtems_interrupt_disable(level);
-
- CleanMainIrqTbl((int) irqNum);
-
- rval = BSP_irqMask_cache[regNum] & (1<<bitNum);
-
- BSP_irqMask_cache[regNum] &= ~(1 << bitNum);
-
- out_le32(BSP_irqMask_reg[regNum], BSP_irqMask_cache[regNum]);
- while (in_le32(BSP_irqMask_reg[regNum]) != BSP_irqMask_cache[regNum]);
-
- rtems_interrupt_enable(level);
-
- return rval ? 1 : 0;
-}
-
-void BSP_disable_pic_irq(const rtems_irq_number irqNum)
-{
- (void)BSP_disable_irq_at_pic(irqNum);
-}
-
-int BSP_setup_the_pic(rtems_irq_global_settings *config) /* adapt the same name as shared/irq */
-{
- int i;
-
- internal_config = config;
- default_rtems_hdl = config->defaultEntry.hdl;
- rtems_hdl_tbl = config->irqHdlTbl;
-
- /* Get ready for discovery BSP */
- BSP_irqMask_reg[0]= (volatile unsigned int *) (GT64260_REG_BASE + GT_CPU_INT_MASK_LO);
- BSP_irqMask_reg[1]= (volatile unsigned int *) (GT64260_REG_BASE + GT_CPU_INT_MASK_HI);
- BSP_irqMask_reg[2]= (volatile unsigned int *) (GT64260_REG_BASE + GT_GPP_Interrupt_Mask);
-
- BSP_irqCause_reg[0]= (volatile unsigned int *) (GT64260_REG_BASE + GT_MAIN_INT_CAUSE_LO);
- BSP_irqCause_reg[1]= (volatile unsigned int *) (GT64260_REG_BASE + GT_MAIN_INT_CAUSE_HI);
- BSP_irqCause_reg[2]= (volatile unsigned int *) (GT64260_REG_BASE + GT_GPP_Interrupt_Cause);
-
-#ifdef EDGE_TRIGGER
-
- /* Page 401, Table 598:
- * Comm Unit Arbiter Control register :
- * bit 10:GPP interrupts as level sensitive(1) or edge sensitive(0).
- * We set the GPP interrupts to be edge sensitive.
- * MOTload default is set as level sensitive(1).
- */
- outl((inl(GT_CommUnitArb_Ctrl)& (~(1<<10))), GT_CommUnitArb_Ctrl);
-#else
- outl((inl(GT_CommUnitArb_Ctrl)| (1<<10)), GT_CommUnitArb_Ctrl);
-#endif
-
-#if 0
- printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
- in_le32(BSP_irqMask_reg[0]),
- in_le32(BSP_irqCause_reg[0]));
- printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
- in_le32(BSP_irqMask_reg[1]),
- in_le32(BSP_irqCause_reg[1]));
- printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
- in_le32(BSP_irqMask_reg[2]),
- in_le32(BSP_irqCause_reg[2]));
-#endif
-
- /* Initialize the interrupt related GT64260 registers */
- for (i=0; i<3; i++) {
- out_le32(BSP_irqCause_reg[i], 0);
- out_le32(BSP_irqMask_reg[i], 0);
- }
- in_le32(BSP_irqMask_reg[2]);
- compute_pic_masks_from_prio(config);
-
-#if 0
- printk("BSP_irqMask_reg[0] = 0x%x, BSP_irqCause_reg[0] 0x%x\n",
- in_le32(BSP_irqMask_reg[0]),
- in_le32(BSP_irqCause_reg[0]));
- printk("BSP_irqMask_reg[1] = 0x%x, BSP_irqCause_reg[1] 0x%x\n",
- in_le32(BSP_irqMask_reg[1]),
- in_le32(BSP_irqCause_reg[1]));
- printk("BSP_irqMask_reg[2] = 0x%x, BSP_irqCause_reg[2] 0x%x\n",
- in_le32(BSP_irqMask_reg[2]),
- in_le32(BSP_irqCause_reg[2]));
-#endif
-
- return(1);
-}
-
-/*
- * This function check that the value given for the irq line
- * is valid.
- */
-
-/*
- * High level IRQ handler called from shared_raw_irq_code_entry
- */
-
-int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
-{
- unsigned long irqCause[3]={0, 0,0};
- register unsigned long selectCause;
- unsigned oldMask[3]={0,0,0};
- register unsigned i=0, j, irq=0, bitmask=0, group=0;
-
- if (excNum == ASM_DEC_VECTOR) {
-
- bsp_irq_dispatch_list( rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_hdl);
-
- return 0;
-
- }
-
- for (j=0; j<3; j++ ) oldMask[j] = BSP_irqMask_cache[j];
-
- if ((selectCause= in_le32((volatile unsigned *)0xf1000c70)) & HI_INT_CAUSE ){
- irqCause[1] = (selectCause & BSP_irqMask_cache[1]);
- irqCause[2] = in_le32(BSP_irqCause_reg[2]) & BSP_irqMask_cache[2];
- }
- else {
- irqCause[0] = (selectCause & BSP_irqMask_cache[0]);
- if ((irqCause[1] =(in_le32((volatile unsigned *)0xf1000c68)&BSP_irqMask_cache[1])))
- irqCause[2] = in_le32(BSP_irqCause_reg[2]) & BSP_irqMask_cache[2];
- }
-
- while ((irq = picIsrTable[i++])!=-1)
- {
- if (irqCause[group=(irq/32)] && (irqCause[group]&(bitmask=(1<<(irq % 32))))) {
- for (j=0; j<3; j++)
- BSP_irqMask_cache[j] &= (~ BSP_irq_prio_mask_tbl[j][irq]);
-
- RTEMS_COMPILER_MEMORY_BARRIER();
- out_le32((volatile unsigned *)0xf1000c1c, BSP_irqMask_cache[0]);
- out_le32((volatile unsigned *)0xf1000c6c, BSP_irqMask_cache[1]);
- out_le32((volatile unsigned *)0xf100f10c, BSP_irqMask_cache[2]);
- in_le32((volatile unsigned *)0xf100f10c);
-
-#ifdef EDGE_TRIGGER
- if (irq > BSP_MICH_IRQ_MAX_OFFSET)
- out_le32(BSP_irqCause_reg[2], ~bitmask);/* Till Straumann: Ack the edge triggered GPP IRQ */
-#endif
-
- bsp_irq_dispatch_list( rtems_hdl_tbl, irq, default_rtems_hdl);
-
- for (j=0; j<3; j++ ) BSP_irqMask_cache[j] = oldMask[j];
- break;
- }
- }
-
- out_le32((volatile unsigned *)0xf1000c1c, oldMask[0]);
- out_le32((volatile unsigned *)0xf1000c6c, oldMask[1]);
- out_le32((volatile unsigned *)0xf100f10c, oldMask[2]);
- in_le32((volatile unsigned *)0xf100f10c);
-
- return 0;
-}
-
-/* Only print part of the entries for now */
-void BSP_printPicIsrTbl()
-{
- int i;
-
- printk("picIsrTable[12]={");
- for (i=0; i<12; i++)
- printk("%d,", picIsrTable[i]);
- printk("}\n");
-
- printk("GPPIrqInTbl: 0x%x :\n", GPPIrqInTbl);
-}
diff -Naur mvme5500.orig/irq/irq_init.c mvme5500/irq/irq_init.c
--- mvme5500.orig/irq/irq_init.c 2008-08-20 04:56:56.000000000 -0400
+++ mvme5500/irq/irq_init.c 2009-02-25 14:50:55.000000000 -0500
@@ -36,10 +36,18 @@
static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER];
static rtems_irq_global_settings initial_config;
+
+#ifdef BSP_SHARED_HANDLER_SUPPORT
+static rtems_irq_connect_data defaultIrq = {
+ /* vectorIdex, hdl ,handle , on , off , isOn ,next_handler, */
+ 0, nop_func , NULL , nop_func , nop_func , not_connected, 0
+};
+#else
static rtems_irq_connect_data defaultIrq = {
/* vectorIdex, hdl , handle , on , off , isOn */
0, nop_func , NULL , nop_func , nop_func , not_connected
};
+#endif
rtems_irq_prio BSPirqPrioTable[BSP_PIC_IRQ_NUMBER]={
/*
@@ -135,12 +143,6 @@
#ifdef TRACE_IRQ_INIT
printk("Done setup irq mngt configuration\n");
#endif
-
- /* I don't really understand why all sources are enable here... (T.S) */
- for (i= BSP_MAIN_GPP7_0_IRQ; i <= BSP_MAIN_GPP31_24_IRQ; i++)
- BSP_enable_pic_irq(i);
-
- rtems_interrupt_enable(l);
#ifdef TRACE_IRQ_INIT
printk("RTEMS IRQ management is now operationnal\n");
diff -Naur mvme5500.orig/Makefile.am mvme5500/Makefile.am
--- mvme5500.orig/Makefile.am 2008-09-24 01:38:43.000000000 -0400
+++ mvme5500/Makefile.am 2009-03-16 13:57:56.000000000 -0400
@@ -32,7 +32,9 @@
../../powerpc/shared/startup/sbrk.c ../../shared/bootcard.c \
../../shared/bsppredriverhook.c startup/bspclean.c \
../../shared/bsplibc.c ../../shared/bsppost.c \
- ../../shared/gnatinstallhandler.c startup/reboot.c
+ ../../shared/gnatinstallhandler.c startup/reboot.c \
+ ../../powerpc/shared/startup/probeMemEnd.c
+
pclock_SOURCES = ../../powerpc/shared/clock/p_clock.c
include_bsp_HEADERS = ../../powerpc/shared/console/uart.h
@@ -45,7 +47,7 @@
pci/pcifinddevice.c
include_bsp_HEADERS += irq/irq.h
-irq_SOURCES = irq/irq_init.c irq/irq.c
+irq_SOURCES = irq/irq_init.c irq/BSP_irq.c
nodist_include_HEADERS += ../../shared/tod.h
tod_SOURCES = ../../shared/tod.c tod/todcfg.c
diff -Naur mvme5500.orig/network/if_100MHz/GT64260eth.c mvme5500/network/if_100MHz/GT64260eth.c
--- mvme5500.orig/network/if_100MHz/GT64260eth.c 2008-08-20 07:32:46.000000000 -0400
+++ mvme5500/network/if_100MHz/GT64260eth.c 2009-03-12 14:19:40.000000000 -0400
@@ -7,12 +7,6 @@
* Acknowledgements:
* netBSD : Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
* Marvell : NDA document for the discovery system controller
- * The author referenced two RTEMS network drivers of other NICs.
- * rtems : 1) dec21140.c, a network driver for for TULIP based Ethernet Controller
- * (C) 1999 Emmanuel Raguet. [email protected]
- *
- * 2) yellowfin.c, a network driver for the SVGM5 BSP.
- * Stanford Linear Accelerator Center, Till Straumann
*
* Some notes from the author, S. Kate Feng :
*
@@ -366,8 +360,7 @@
if (unit < 0) return 0;
printk("\nEthernet driver name %s unit %d \n",name, unit);
- printk("(c) 2004, Brookhaven National Lab. <[email protected]> (RTEMS/mvme5500 port)\n");
-
+ printk("RTEMS-mvme5500 BSP Copyright (c) 2004, Brookhaven National Lab., Shuchen Kate Feng \n");
/* Make certain elements e.g. descriptor lists are aligned. */
softc_mem = rtems_bsdnet_malloc(sizeof(*sc) + SOFTC_ALIGN, M_FREE, M_NOWAIT);
@@ -1137,7 +1130,6 @@
sc->arpcom.ac_if.if_timer = 0;
}
-/* TOCHECK : Should it be about rx or tx ? */
static void GTeth_ifchange(struct GTeth_softc *sc)
{
if (GTeth_debug>0) printk("GTeth_ifchange(");
@@ -1445,6 +1437,7 @@
#endif
}
+#ifdef GT64260eth_DEBUG
static void GT64260eth_error(struct GTeth_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ac_if;
@@ -1474,7 +1467,7 @@
sc->intr_errsts[sc->intr_err_ptr1++]=0;
sc->intr_err_ptr1 %= INTR_ERR_SIZE; /* Till Straumann */
}
-
+#endif
/* The daemon does all of the work; RX, TX and cleaning up buffers/descriptors */
static void GT64260eth_daemon(void *arg)
@@ -1548,7 +1541,9 @@
ifp->if_flags &= ~IFF_OACTIVE;
/* Log errors and other uncommon events. */
+#ifdef GT64260eth_DEBUG
if (events & ERR_EVENT) GT64260eth_error(sc);
+#endif
} /* end for(;;) { rtems_bsdnet_event_receive() .....*/
ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
diff -Naur mvme5500.orig/network/if_1GHz/if_wm.c mvme5500/network/if_1GHz/if_wm.c
--- mvme5500.orig/network/if_1GHz/if_wm.c 2008-08-20 07:32:46.000000000 -0400
+++ mvme5500/network/if_1GHz/if_wm.c 2009-04-01 11:18:55.000000000 -0400
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2004,2005 RTEMS/Mvme5500 port by S. Kate Feng <[email protected]>
+ * under the Deaprtment of Energy contract DE-AC02-98CH10886
* Brookhaven National Laboratory, All rights reserved
*
* Acknowledgements:
@@ -25,8 +26,7 @@
* hardware auto-neg. state machine disabled. PCI control "snoop
* to WB region", MII mode (PHY) instead of TBI mode.
* 6) We currently only use 32-bit (instead of 64-bit) DMA addressing.
- * 7) Support for checksum offloading and TCP segmentation offload will
- * be available for releasing in 2008, upon request, if I still believe.
+ * 7) Implementation for Jumbo Frame and TCP checksum is not completed yet.
*
*/
@@ -34,8 +34,11 @@
#define INET
+/*#define RTEMS_ETHERMTU_JUMBO*/
+
#include <rtems.h>
#include <rtems/bspIo.h> /* printk */
+
#include <stdio.h> /* printf for statistics */
#include <string.h>
@@ -64,6 +67,7 @@
#include <net/if_dl.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
+#include <net/ethernet.h>
#ifdef INET
#include <netinet/in_var.h>
@@ -82,7 +86,7 @@
#define i82544EI_TASK_NAME "IGHZ"
#define SOFTC_ALIGN 4095
-#define INTR_ERR_SIZE 16
+#define IF_ERR_BUFSZE 16
/*#define WM_DEBUG*/
#ifdef WM_DEBUG
@@ -109,12 +113,12 @@
#define ALL_EVENTS (KILL_EVENT|START_TRANSMIT_EVENT|RX_EVENT|TX_EVENT|ERR_EVENT|INIT_EVENT)
-
-#define NTXDESC 128
+/* <skf> used 64 in 4.8.0, TOD; try 4096 */
+#define NTXDESC 256
#define NTXDESC_MASK (NTXDESC - 1)
#define WM_NEXTTX(x) (((x) + 1) & NTXDESC_MASK)
-#define NRXDESC 64
+#define NRXDESC 256
#define NRXDESC_MASK (NRXDESC - 1)
#define WM_NEXTRX(x) (((x) + 1) & NRXDESC_MASK)
#define WM_PREVRX(x) (((x) - 1) & NRXDESC_MASK)
@@ -123,9 +127,10 @@
#define WM_CDTXOFF(x) WM_CDOFF(sc_txdescs[(x)])
#define WM_CDRXOFF(x) WM_CDOFF(sc_rxdescs[(x)])
-#define TXQ_HiLmt_OFF 64
+#define TXQ_HiLmt_OFF 32
static uint32_t TxDescCmd;
+static unsigned BSP_1GHz_membase;
/*
* Software state per device.
@@ -136,9 +141,9 @@
struct mbuf *txs_mbuf[NTXDESC]; /* transmit buffer memory */
struct mbuf *rxs_mbuf[NRXDESC]; /* receive buffer memory */
struct wm_softc *next_module;
- volatile unsigned int intr_errsts[INTR_ERR_SIZE]; /* intr_status */
- unsigned int intr_err_ptr1; /* ptr used in i82544EI_error() */
- unsigned int intr_err_ptr2; /* ptr used in ISR */
+ volatile unsigned int if_errsts[IF_ERR_BUFSZE]; /* intr_status */
+ unsigned int if_err_ptr1; /* ptr used in i82544EI_error() */
+ unsigned int if_err_ptr2; /* ptr used in ISR */
int txs_firstdesc; /* first descriptor in packet */
int txs_lastdesc; /* last descriptor in packet */
int txs_ndesc; /* # of descriptors used */
@@ -168,15 +173,16 @@
int sc_rxptr; /* next ready Rx descriptor/queue ent */
int sc_rxdiscard;
int sc_rxlen;
+
uint32_t sc_ctrl; /* prototype CTRL register */
-#if 0
uint32_t sc_ctrl_ext; /* prototype CTRL_EXT register */
-#endif
+
uint32_t sc_icr; /* prototype interrupt bits */
uint32_t sc_tctl; /* prototype TCTL register */
uint32_t sc_rctl; /* prototype RCTL register */
uint32_t sc_tipg; /* prototype TIPG register */
uint32_t sc_fcrtl; /* prototype FCRTL register */
+ uint32_t sc_pba; /* prototype PBA register */
int sc_mchash_type; /* multicast filter offset */
@@ -184,11 +190,6 @@
struct {
volatile unsigned long rxInterrupts;
volatile unsigned long txInterrupts;
- unsigned long txMultiBuffPacket;
- unsigned long txMultiMaxLen;
- unsigned long txSinglMaxLen;
- unsigned long txMultiMaxLoop;
- unsigned long txBuffMaxLen;
unsigned long linkInterrupts;
unsigned long length_errors;
unsigned long frame_errors;
@@ -224,22 +225,20 @@
static struct wm_softc *root_i82544EI_dev = NULL;
static void i82544EI_ifstart(struct ifnet *ifp);
-static int wm_ioctl(struct ifnet *ifp, u_long cmd,uint32_t data);
+static int wm_ioctl(struct ifnet *ifp, ioctl_command_t cmd,caddr_t data);
static void i82544EI_ifinit(void *arg);
static void wm_stop(struct ifnet *ifp, int disable);
+static void wm_gmii_mediainit(struct wm_softc *sc);
static void wm_rxdrain(struct wm_softc *sc);
static int wm_add_rxbuf(struct wm_softc *sc, int idx);
static int wm_read_eeprom(struct wm_softc *sc,int word,int wordcnt, uint16_t *data);
static void i82544EI_daemon(void *arg);
static void wm_set_filter(struct wm_softc *sc);
-
-static void i82544EI_isr(void);
+static void i82544EI_rx(struct wm_softc *sc);
+static void i82544EI_isr(rtems_irq_hdl_param handle);
static void i82544EI_sendpacket(struct wm_softc *sc, struct mbuf *m);
-extern int pci_mem_find(int b, int d, int f, int reg, unsigned *basep,unsigned *sizep);
-extern int pci_io_find(int b, int d, int f, int reg,unsigned *basep,unsigned *sizep);
-extern int pci_get_capability(int b, int d, int f, int capid,int *offset,uint32_t *value);
-extern char * ether_sprintf1(void);
+extern int pci_mem_find(), pci_io_find(), pci_get_capability();
static void i82544EI_irq_on(const rtems_irq_connect_data *irq)
{
@@ -271,6 +270,7 @@
static rtems_irq_connect_data i82544IrqData={
BSP_GPP_82544_IRQ,
(rtems_irq_hdl) i82544EI_isr,
+ (rtems_irq_hdl_param) NULL,
(rtems_irq_enable) i82544EI_irq_on,
(rtems_irq_disable) i82544EI_irq_off,
(rtems_irq_is_enabled) i82544EI_irq_is_on,
@@ -290,9 +290,12 @@
unit = rtems_bsdnet_parse_driver_name(config, &name);
if (unit < 0) return 0;
-
- printk("\nEthernet driver name %s unit %d \n",name, unit);
- printk("Copyright (c) 2004,2005 S. Kate Feng <[email protected]> (RTEMS/mvme5500 port)\n");
+
+ if ( !strncmp((const char *)name,"autoz",5))
+ memcpy(name,"gtGHz",5);
+
+ printk("\nAttaching MVME5500 1GHz NIC%d\n", unit);
+ printk("RTEMS-mvme5500 BSP Copyright (c) 2004,2005,2008, Brookhaven National Lab., Shuchen Kate Feng \n");
/* Make sure certain elements e.g. descriptor lists are aligned.*/
softc_mem = rtems_bsdnet_malloc(sizeof(*sc) + SOFTC_ALIGN, M_FREE, M_NOWAIT);
@@ -310,7 +313,7 @@
unit-1,&b, &d, &f))
rtems_panic("i82544EI device ID not found\n");
-#if WM_DEBUG
+#ifdef WM_DEBUG
printk("82544EI:b%d, d%d, f%d\n", b, d,f);
#endif
@@ -318,13 +321,18 @@
if ( pci_mem_find(b,d,f,PCI_MAPREG_START, &sc->sc_membase, &sc->sc_memsize))
rtems_panic("i82544EI: unable to map memory space\n");
+#ifdef WM_DEBUG
+ printk("Memory base addr 0x%x\n", sc->sc_membase);
+#endif
+ BSP_1GHz_membase= sc->sc_membase;
+
#ifdef WM_DEBUG
printk("Memory base addr 0x%x\n", sc->sc_membase);
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));
#endif
- sc->sc_ctrl |=CSR_READ(sc,WMREG_CTRL);
+ sc->sc_ctrl=CSR_READ(sc,WMREG_CTRL);
/*
* Determine a few things about the bus we're connected to.
*/
@@ -362,11 +370,10 @@
enaddr[4] = myea[2] & 0xff;
enaddr[5] = myea[2] >> 8;
-
memcpy(sc->arpcom.ac_enaddr, enaddr, ETHER_ADDR_LEN);
#ifdef WM_DEBUG
printk("%s: Ethernet address %s\n", sc->dv_xname,
- ether_sprintf1(enaddr));
+ ether_sprintf(enaddr));
#endif
/*
@@ -397,13 +404,39 @@
CSR_WRITE(sc,WMREG_CTRL_EXT, sc->sc_ctrl_ext);
#endif
+ /*
+ * Determine if we're TBI or GMII mode, and initialize the
+ * media structures accordingly.
+ */
+ if ((CSR_READ(sc, WMREG_STATUS) & STATUS_TBIMODE) != 0) {
+ /* 1000BASE-X : fiber (TBI mode)
+ wm_tbi_mediainit(sc); */
+ } else { /* 1000BASE-T : copper (internal PHY mode), for the mvme5500 */
+ wm_gmii_mediainit(sc);
+ }
+
ifp = &sc->arpcom.ac_if;
/* set this interface's name and unit */
ifp->if_unit = unit;
ifp->if_name = name;
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+#ifdef RTEMS_ETHERMTU_JUMBO
+ sc->arpcom.ec_capabilities |= ETHERCAP_JUMBO_MTU;
+ ifp->if_mtu = config->mtu ? config->mtu : ETHERMTU_JUMBO;
+#else
ifp->if_mtu = config->mtu ? config->mtu : ETHERMTU;
+#endif
+#ifdef RTEMS_CKSUM_OFFLOAD
+ /* < skf> The following is really not related to jumbo frame
+ sc->arpcom.ec_capabilities |= ETHERCAP_VLAN_MTU;*/
+ ifp->if_capabilities |= IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
+ IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
+ IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx |
+ IFCAP_CSUM_TCPv6_Tx | IFCAP_CSUM_UDPv6_Tx |
+ IFCAP_TSOv4; /* TCP segmentation offload. */
+#endif
+
ifp->if_ioctl = wm_ioctl;
ifp->if_start = i82544EI_ifstart;
/* ifp->if_watchdog = wm_watchdog;*/
@@ -418,7 +451,8 @@
rtems_build_name('I','G','H','Z'),0,0,0,&sc->daemonSync))
rtems_panic("i82544EI: semaphore creation failed");
- sc->next_module = root_i82544EI_dev;
+ i82544IrqData.handle= (rtems_irq_hdl_param) sc;
+ /* sc->next_module = root_i82544EI_dev;*/
root_i82544EI_dev = sc;
/* Attach the interface. */
@@ -432,6 +466,39 @@
}
/*
+ * wm_reset:
+ *
+ * Reset the i82544 chip.
+ */
+static void wm_reset(struct wm_softc *sc)
+{
+ int i;
+
+ sc->sc_pba = sc->arpcom.ac_if.if_mtu > 8192 ? PBA_40K : PBA_48K;
+ CSR_WRITE(sc, WMREG_PBA, sc->sc_pba);
+
+ /* device reset */
+ CSR_WRITE(sc, WMREG_CTRL, CTRL_RST);
+ rtems_bsp_delay(10000);
+
+ for (i = 0; i < 1000; i++) {
+ if ((CSR_READ(sc, WMREG_CTRL) & CTRL_RST) == 0)
+ break;
+ rtems_bsp_delay(20);
+ }
+ if (CSR_READ(sc, WMREG_CTRL) & CTRL_RST)
+ printk("Intel 82544 1GHz reset failed to complete\n");
+
+ sc->sc_ctrl_ext = CSR_READ(sc,WMREG_CTRL_EXT);
+ sc->sc_ctrl_ext |= CTRL_EXT_EE_RST;
+ CSR_WRITE(sc, WMREG_CTRL_EXT, sc->sc_ctrl_ext);
+ CSR_READ(sc, WMREG_STATUS);
+ /* Wait for EEPROM reload */
+ rtems_bsp_delay(2000);
+ sc->sc_ctrl= CSR_READ(sc, WMREG_CTRL);
+}
+
+/*
* i82544EI_ifstart: [ifnet interface function]
*
* Start packet transmission on the interface.
@@ -463,27 +530,21 @@
{
struct ifnet *ifp = &sc->arpcom.ac_if;
- printf(" Rx Interrupts:%-8u\n", sc->stats.rxInterrupts);
+ printf(" Ghost Interrupts:%-8lu\n", sc->stats.ghostInterrupts);
+ printf(" Rx Interrupts:%-8lu\n", sc->stats.rxInterrupts);
printf(" Receive Packets:%-8u\n", CSR_READ(sc,WMREG_GPRC));
- printf(" Receive Overrun:%-8u\n", sc->stats.rxOvrRunInterrupts);
+ printf(" Receive Overrun:%-8lu\n", sc->stats.rxOvrRunInterrupts);
printf(" Receive errors:%-8u\n", CSR_READ(sc,WMREG_RXERRC));
- printf(" Rx sequence error:%-8u\n", sc->stats.rxSeqErr);
- printf(" Rx /C/ ordered:%-8u\n", sc->stats.rxC_ordered);
+ printf(" Rx sequence error:%-8lu\n", sc->stats.rxSeqErr);
+ printf(" Rx /C/ ordered:%-8lu\n", sc->stats.rxC_ordered);
printf(" Rx Length Errors:%-8u\n", CSR_READ(sc,WMREG_RLEC));
- printf(" Tx Interrupts:%-8u\n", sc->stats.txInterrupts);
-#if 0
- printf("Multi-BuffTx Packets:%-8u\n", sc->stats.txMultiBuffPacket);
- printf("Multi-BuffTx max len:%-8u\n", sc->stats.txMultiMaxLen);
- printf("SingleBuffTx max len:%-8u\n", sc->stats.txSinglMaxLen);
- printf("Multi-BuffTx maxloop:%-8u\n", sc->stats.txMultiMaxLoop);
- printf("Tx buffer max len :%-8u\n", sc->stats.txBuffMaxLen);
-#endif
+ printf(" Tx Interrupts:%-8lu\n", sc->stats.txInterrupts);
printf(" Transmitt Packets:%-8u\n", CSR_READ(sc,WMREG_GPTC));
- printf(" Transmitt errors:%-8u\n", ifp->if_oerrors);
- printf(" Active Txqs:%-8u\n", sc->txq_nactive);
+ printf(" Transmitt errors:%-8lu\n", ifp->if_oerrors);
+ printf(" Active Txqs:%-8lu\n", sc->txq_nactive);
printf(" collisions:%-8u\n", CSR_READ(sc,WMREG_COLC));
printf(" Crc Errors:%-8u\n", CSR_READ(sc,WMREG_CRCERRS));
- printf(" Link Status Change:%-8u\n", sc->stats.linkStatusChng);
+ printf(" Link Status Change:%-8lu\n", sc->stats.linkStatusChng);
}
/*
@@ -491,7 +552,7 @@
*
* Handle control requests from the operator.
*/
-static int wm_ioctl(struct ifnet *ifp, u_long cmd,uint32_t data)
+static int wm_ioctl(struct ifnet *ifp, ioctl_command_t cmd,caddr_t data)
{
struct wm_softc *sc = ifp->if_softc;
int error=0;
@@ -523,9 +584,9 @@
*
* Interrupt service routine.
*/
-static void i82544EI_isr()
+static void i82544EI_isr(rtems_irq_hdl_param handle)
{
- volatile struct wm_softc *sc = root_i82544EI_dev;
+ volatile struct wm_softc *sc = (struct wm_softc *) handle;
uint32_t icr;
rtems_event_set events=0;
@@ -549,8 +610,8 @@
events |= INIT_EVENT;
}
if (icr & ICR_RXSEQ) /* framing error */ {
- sc->intr_errsts[sc->intr_err_ptr2++]=icr;
- sc->intr_err_ptr2 %=INTR_ERR_SIZE; /* Till Straumann */
+ sc->if_errsts[sc->if_err_ptr2++]=icr;
+ if ( sc->if_err_ptr2 ==IF_ERR_BUFSZE) sc->if_err_ptr2=0;
events |= ERR_EVENT;
sc->stats.rxSeqErr++;
}
@@ -608,15 +669,12 @@
* The other way is effective for packets < 2K
*/
if ( ((y=(len+mtp->m_len)) > sizeof(union mcluster))) {
- printk(">2048, use next descriptor\n");
+ printk(" >%d, use next descriptor\n", sizeof(union mcluster));
break;
}
memcpy((void *)pt,(char *)mtp->m_data, mtp->m_len);
pt += mtp->m_len;
len += mtp->m_len;
-#if 0
- sc->stats.txSinglMaxLen= MAX(mtp->m_len, sc->stats.txSinglMaxLen);
-#endif
} /* end for loop */
mdest->m_len=len;
sc->txs_mbuf[sc->txq_next] = mdest;
@@ -630,15 +688,8 @@
sc->txq_free--;
else
rtems_panic("i8254EI : no more free descriptors");
-#if 0
- sc->stats.txMultiMaxLen= MAX(mdest->m_len, sc->stats.txMultiMaxLen);
- sc->stats.txMultiBuffPacket++;
-#endif
} /* end for while */
/* free old mbuf chain */
-#if 0
- sc->stats.txMultiMaxLoop=MAX(loop, sc->stats.txMultiMaxLoop);
-#endif
m_freem(m);
m=0;
} /* end multiple mbufs */
@@ -744,12 +795,11 @@
sc->dv_xname, i));
status = sc->sc_rxdescs[i].wrx_status;
+ if ((status & WRX_ST_DD) == 0) break; /* descriptor not done */
+
errors = sc->sc_rxdescs[i].wrx_errors;
len = le16toh(sc->sc_rxdescs[i].wrx_len);
m = sc->rxs_mbuf[i];
-
- if ((status & WRX_ST_DD) == 0) break; /* descriptor not done */
-
if (sc->sc_rxdiscard) {
printk("RX: discarding contents of descriptor %d\n", i);
wm_init_rxdesc(sc, i);
@@ -821,16 +871,46 @@
int i,error;
uint8_t cksumfields;
+#if 0
+ /* KATETODO : sc_align_tweak */
+ /*
+ * *_HDR_ALIGNED_P is constant 1 if __NO_STRICT_ALIGMENT is set.
+ * There is a small but measurable benefit to avoiding the adjusment
+ * of the descriptor so that the headers are aligned, for normal mtu,
+ * on such platforms. One possibility is that the DMA itself is
+ * slightly more efficient if the front of the entire packet (instead
+ * of the front of the headers) is aligned.
+ *
+ * Note we must always set align_tweak to 0 if we are using
+ * jumbo frames.
+ */
+#ifdef __NO_STRICT_ALIGNMENT
+ sc->sc_align_tweak = 0;
+#else
+ if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN) > (MCLBYTES - 2))
+ sc->sc_align_tweak = 0;
+ else
+ sc->sc_align_tweak = 2;
+#endif /* __NO_STRICT_ALIGNMENT */
+#endif
+
/* Cancel any pending I/O. */
wm_stop(ifp, 0);
+ /* update statistics before reset */
+ ifp->if_collisions += CSR_READ(sc, WMREG_COLC);
+ ifp->if_ierrors += CSR_READ(sc, WMREG_RXERRC);
+
+ /* Reset the chip to a known state. */
+ wm_reset(sc);
+
/* Initialize the error buffer ring */
- sc->intr_err_ptr1=0;
- sc->intr_err_ptr2=0;
- for (i=0; i< INTR_ERR_SIZE; i++) sc->intr_errsts[i]=0;
+ sc->if_err_ptr1=0;
+ sc->if_err_ptr2=0;
+ for (i=0; i< IF_ERR_BUFSZE; i++) sc->if_errsts[i]=0;
/* Initialize the transmit descriptor ring. */
- memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
+ memset( (void *) sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
sc->txq_free = NTXDESC;
sc->txq_next = 0;
sc->txs_lastdesc = 0;
@@ -849,8 +929,8 @@
CSR_WRITE(sc,WMREG_TDLEN, sizeof(sc->sc_txdescs));
CSR_WRITE(sc,WMREG_TDH, 0);
CSR_WRITE(sc,WMREG_TDT, 0);
- CSR_WRITE(sc,WMREG_TIDV, 64 );
- CSR_WRITE(sc,WMREG_TADV, 128);
+ CSR_WRITE(sc,WMREG_TIDV, 0 );
+ /* CSR_WRITE(sc,WMREG_TADV, 128); not for 82544 */
CSR_WRITE(sc,WMREG_TXDCTL, TXDCTL_PTHRESH(0) |
TXDCTL_HTHRESH(0) | TXDCTL_WTHRESH(0));
@@ -864,10 +944,11 @@
* Set up checksum offload parameters for
* this packet.
*/
-#ifdef CKSUM_OFFLOAD
- if (m0->m_pkthdr.csum_flags &
- (M_CSUM_IPv4|M_CSUM_TCPv4|M_CSUM_UDPv4)) {
- if (wm_tx_cksum(sc, txs, &TxDescCmd,&cksumfields) != 0) {
+#ifdef RTEMS_CKSUM_OFFLOAD
+ if (m0->m_pkthdr.csum_flags & (M_CSUM_TSOv4|M_CSUM_TSOv6|
+ M_CSUM_IPv4|M_CSUM_TCPv4|M_CSUM_UDPv4|
+ M_CSUM_TCPv6|M_CSUM_UDPv6)) {
+ if (wm_tx_offload(sc, txs, &TxDescCmd,&cksumfields) != 0) {
/* Error message already displayed. */
continue;
}
@@ -875,7 +956,7 @@
#endif
TxDescCmd = 0;
cksumfields = 0;
-#ifdef CKSUM_OFFLOAD
+#ifdef RTEMS_CKSUM_OFFLOAD
}
#endif
@@ -894,14 +975,14 @@
* Initialize the receive descriptor and receive job
* descriptor rings.
*/
- memset(sc->sc_rxdescs, 0, sizeof(sc->sc_rxdescs));
+ memset( (void *) sc->sc_rxdescs, 0, sizeof(sc->sc_rxdescs));
CSR_WRITE(sc,WMREG_RDBAH, 0);
CSR_WRITE(sc,WMREG_RDBAL, WM_CDRXADDR(sc));
CSR_WRITE(sc,WMREG_RDLEN, sizeof(sc->sc_rxdescs));
CSR_WRITE(sc,WMREG_RDH, 0);
CSR_WRITE(sc,WMREG_RDT, 0);
CSR_WRITE(sc,WMREG_RDTR, 0 |RDTR_FPD);
- CSR_WRITE(sc, WMREG_RADV, 256);
+ /* CSR_WRITE(sc, WMREG_RADV, 256); not for 82544. */
for (i = 0; i < NRXDESC; i++) {
if (sc->rxs_mbuf[i] == NULL) {
@@ -945,12 +1026,13 @@
CSR_WRITE(sc,WMREG_FCRTH, FCRTH_DFLT);
CSR_WRITE(sc,WMREG_FCRTL, sc->sc_fcrtl);
- CSR_WRITE(sc,WMREG_FCTTV, FCTTV_DFLT);
+ /*KATETO CSR_WRITE(sc,WMREG_FCTTV, FCTTV_DFLT);*/
+ CSR_WRITE(sc,WMREG_FCTTV, 0x100);
sc->sc_ctrl &= ~CTRL_VME;
- /*sc->sc_ctrl |= CTRL_TFCE | CTRL_RFCE;*/
- /* enable Big Endian Mode for the powerPC
- sc->sc_ctrl |= CTRL_BEM;*/
+ /* KATETODo : not here.
+ Configures flow control settings after link is established
+ sc->sc_ctrl |= CTRL_TFCE | CTRL_RFCE; */
/* Write the control registers. */
CSR_WRITE(sc,WMREG_CTRL, sc->sc_ctrl);
@@ -958,7 +1040,21 @@
CSR_WRITE(sc,WMREG_CTRL_EXT, sc->sc_ctrl_ext);
#endif
- /* MOTLoad : WMREG_RXCSUM (0x5000)= 0, no Rx checksum offloading */
+ /* MOTLoad : WMREG_RXCSUM (0x5000)= 0, no Rx checksum offloading */
+#ifdef RTEMS_CKSUM_OFFLOAD
+ /*
+ * Set up checksum offload parameters.
+ */
+ reg = CSR_READ(sc, WMREG_RXCSUM);
+ reg &= ~(RXCSUM_IPOFL | RXCSUM_IPV6OFL | RXCSUM_TUOFL);
+ if (ifp->if_capenable & IFCAP_CSUM_IPv4_Rx)
+ reg |= RXCSUM_IPOFL;
+ if (ifp->if_capenable & (IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx))
+ reg |= RXCSUM_IPOFL | RXCSUM_TUOFL;
+ if (ifp->if_capenable & (IFCAP_CSUM_TCPv6_Rx | IFCAP_CSUM_UDPv6_Rx))
+ reg |= RXCSUM_IPV6OFL | RXCSUM_TUOFL;
+ CSR_WRITE(sc, WMREG_RXCSUM, reg);
+#endif
/*
* Set up the interrupt registers.
@@ -987,7 +1083,8 @@
* we resolve the media type.
*/
sc->sc_tctl = TCTL_EN | TCTL_PSP | TCTL_CT(TX_COLLISION_THRESHOLD) |
- TCTL_COLD(TX_COLLISION_DISTANCE_FDX) | TCTL_RTLC; /*transmitter enable*/
+ TCTL_COLD(TX_COLLISION_DISTANCE_FDX) |
+ TCTL_RTLC /* transmit on late collision */;
/*
* Set up the receive control register; we actually program
@@ -995,14 +1092,31 @@
* address offset type 0.
*
* Only the i82544 has the ability to strip the incoming
- * CRC, so we don't enable that feature. (TODO)
+ * CRC, so we don't enable that feature. (TODO: |RCTL_SECRC)
*/
sc->sc_mchash_type = 0;
sc->sc_rctl = RCTL_EN | RCTL_LBM_NONE | RCTL_RDMTS_1_2 | RCTL_LPE |
- RCTL_DPF | RCTL_MO(sc->sc_mchash_type);
+ RCTL_DPF | RCTL_MO(sc->sc_mchash_type)|RCTL_SECRC;
- /* (MCLBYTES == 2048) */
- sc->sc_rctl |= RCTL_2k;
+ if (MCLBYTES == 2048) {
+ sc->sc_rctl |= RCTL_2k;
+ } else {
+ switch(MCLBYTES) {
+ case 4096:
+ sc->sc_rctl |= RCTL_BSEX | RCTL_BSEX_4k;
+ break;
+ case 8192:
+ sc->sc_rctl |= RCTL_BSEX | RCTL_BSEX_8k;
+ break;
+ case 16384:
+ sc->sc_rctl |= RCTL_BSEX | RCTL_BSEX_16k;
+ break;
+ default:
+ rtems_panic("wm_init: MCLBYTES %d unsupported",
+ MCLBYTES);
+ break;
+ }
+ }
#ifdef WM_DEBUG
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,6 +1134,24 @@
return(0);
}
+void BSP_rdTIDV()
+{
+ printf("Reg TIDV: 0x%x\n", in_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_TIDV)));
+}
+void BSP_rdRDTR()
+{
+ printf("Reg RDTR: 0x%x\n", in_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_RDTR)));
+}
+
+void BSP_setTIDV(int val)
+{
+ out_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_TIDV), val);
+}
+
+void BSP_setRDTR(int val)
+{
+ out_le32((volatile unsigned *) (BSP_1GHz_membase+WMREG_RDTR), val);
+}
/*
* i82544EI_ifinit: [ifnet interface function]
*
@@ -1235,6 +1367,7 @@
return (0);
}
+#if 0
/*
* wm_acquire_eeprom:
*
@@ -1266,6 +1399,7 @@
return (0);
}
+#endif
/*
* wm_read_eeprom:
@@ -1370,7 +1504,7 @@
mta_reg = WMREG_CORDOVA_MTA;
sc->sc_rctl &= ~(RCTL_BAM | RCTL_UPE | RCTL_MPE);
- /* if (ifp->if_flags & IFF_BROADCAST)*/
+ if (ifp->if_flags & IFF_BROADCAST)
sc->sc_rctl |= RCTL_BAM;
if (ifp->if_flags & IFF_PROMISC) {
sc->sc_rctl |= RCTL_UPE;
@@ -1440,12 +1574,11 @@
static void i82544EI_error(struct wm_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ac_if;
- unsigned long intr_status= sc->intr_errsts[sc->intr_err_ptr1++];
+ unsigned long intr_status= sc->if_errsts[sc->if_err_ptr1];
/* read and reset the status; because this is written
* by the ISR, we must disable interrupts here
*/
- sc->intr_err_ptr1 %=INTR_ERR_SIZE; /* Till Straumann */
if (intr_status) {
printk("Error %s%d:", ifp->if_name, ifp->if_unit);
if (intr_status & ICR_RXSEQ) {
@@ -1455,6 +1588,8 @@
}
else
printk("%s%d: Ghost interrupt ?\n",ifp->if_name,ifp->if_unit);
+ sc->if_errsts[sc->if_err_ptr1]=0;
+ if ((++sc->if_err_ptr1)==IF_ERR_BUFSZE) sc->if_err_ptr1=0; /* Till Straumann */
}
void i82544EI_printStats()
@@ -1495,7 +1630,7 @@
&events);
if (KILL_EVENT & events) break;
- if (events & RX_EVENT) i82544EI_rx(sc);
+ if (events & RX_EVENT) i82544EI_rx(sc); /* in ISR instead */
/* clean up and try sending packets */
do {
@@ -1503,6 +1638,7 @@
while (sc->txq_free>0) {
if (sc->txq_free>TXQ_HiLmt_OFF) {
+ m=0;
IF_DEQUEUE(&ifp->if_snd,m);
if (m==0) break;
i82544EI_sendpacket(sc, m);
@@ -1511,7 +1647,6 @@
i82544EI_txq_done(sc);
break;
}
- if (events & RX_EVENT) i82544EI_rx(sc);
}
/* we leave this loop
* - either because there's no free buffer
@@ -1519,7 +1654,7 @@
* - or there's nothing to send (IF_DEQUEUE
* returned 0
*/
- } while (m && sc->txq_free);
+ } while (m);
ifp->if_flags &= ~IFF_OACTIVE;
@@ -1556,3 +1691,65 @@
*/
rtems_task_delete(RTEMS_SELF);
}
+
+/*
+ * wm_gmii_reset:
+ *
+ * Reset the PHY.
+ */
+static void wm_gmii_reset(struct wm_softc *sc)
+{
+
+ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl | CTRL_PHY_RESET);
+ rtems_bsp_delay(20000);
+
+ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
+ rtems_bsp_delay(20000);
+
+}
+
+/*
+ * wm_gmii_mediainit:
+ *
+ * Initialize media for use on 1000BASE-T devices.
+ */
+static void wm_gmii_mediainit(struct wm_softc *sc)
+{
+ /* struct ifnet *ifp = &sc->arpcom.ac_if;*/
+
+ /* We have MII. */
+ sc->sc_flags |= WM_F_HAS_MII;
+
+ sc->sc_tipg = TIPG_1000T_DFLT; /* 0x602008 */
+
+ /*
+ * Let the chip set speed/duplex on its own based on
+ * signals from the PHY.
+ * XXXbouyer - I'm not sure this is right for the 80003,
+ * the em driver only sets CTRL_SLU here - but it seems to work.
+ */
+ sc->sc_ctrl |= CTRL_SLU;
+ CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
+
+ wm_gmii_reset(sc);
+
+#if 0
+ /* Initialize our media structures and probe the GMII. */
+ sc->sc_mii.mii_ifp = ifp;
+
+ sc->sc_mii.mii_readreg = wm_gmii_i82544_readreg;
+ sc->sc_mii.mii_writereg = wm_gmii_i82544_writereg;
+ sc->sc_mii.mii_statchg = wm_gmii_statchg;
+
+ ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, wm_gmii_mediachange,
+ wm_gmii_mediastatus);
+
+ mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
+ MII_OFFSET_ANY, MIIF_DOPAUSE);
+ if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
+ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
+ } else
+ ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
+#endif
+}
diff -Naur mvme5500.orig/network/if_1GHz/if_wmreg.h mvme5500/network/if_1GHz/if_wmreg.h
--- mvme5500.orig/network/if_1GHz/if_wmreg.h 2007-09-13 10:26:24.000000000 -0400
+++ mvme5500/network/if_1GHz/if_wmreg.h 2009-02-25 11:34:03.000000000 -0500
@@ -5,6 +5,9 @@
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ * Some are added by Shuchen Kate Feng <[email protected]>,
+ * NSLS, Brookhaven National Laboratory. All rights reserved.
+ * under the Deaprtment of Energy contract DE-AC02-98CH10886
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -56,7 +59,7 @@
* The receive descriptor ring must be aligned to a 4K boundary,
* and there must be an even multiple of 8 descriptors in the ring.
*/
-typedef struct wiseman_rxdesc {
+typedef volatile struct wiseman_rxdesc {
wiseman_addr_t wrx_addr; /* buffer address */
uint16_t wrx_len; /* buffer length */
@@ -103,7 +106,7 @@
uint8_t wtxu_options; /* options */
uint16_t wtxu_vlan; /* VLAN info */
} __attribute__((__packed__)) wiseman_txfields_t;
-typedef struct wiseman_txdesc {
+typedef volatile struct wiseman_txdesc {
wiseman_addr_t wtx_addr; /* buffer address */
uint32_t wtx_cmdlen; /* command and length */
wiseman_txfields_t wtx_fields; /* fields; see below */
diff -Naur mvme5500.orig/network/if_1GHz/pcireg.h mvme5500/network/if_1GHz/pcireg.h
--- mvme5500.orig/network/if_1GHz/pcireg.h 2007-09-13 10:26:24.000000000 -0400
+++ mvme5500/network/if_1GHz/pcireg.h 2009-02-25 11:48:45.000000000 -0500
@@ -4,6 +4,7 @@
* Copyright (c) 1995, 1996, 1999, 2000
* Christopher G. Demetriou. All rights reserved.
* Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved.
+ * Copyright (C) 2007 Brookhaven National Laboratory, Shuchen Kate Feng
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +31,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <bsp.h>
/*
* PCI Class and Revision Register; defines type and revision of device.
@@ -305,7 +307,7 @@
#define PCI_MAPREG_MEM64_ADDR_MASK 0xfffffffffffffff0ULL
#define PCI_MAPREG_IO_ADDR(mr) \
- ((mr) & PCI_MAPREG_IO_ADDR_MASK)
+ ((mr+PCI0_IO_BASE) & PCI_MAPREG_IO_ADDR_MASK)
#define PCI_MAPREG_IO_SIZE(mr) \
(PCI_MAPREG_IO_ADDR(mr) & -PCI_MAPREG_IO_ADDR(mr))
#define PCI_MAPREG_IO_ADDR_MASK 0xfffffffc
diff -Naur mvme5500.orig/network/if_1GHz/POSSIBLEBUG mvme5500/network/if_1GHz/POSSIBLEBUG
--- mvme5500.orig/network/if_1GHz/POSSIBLEBUG 2007-09-13 10:26:24.000000000 -0400
+++ mvme5500/network/if_1GHz/POSSIBLEBUG 1969-12-31 19:00:00.000000000 -0500
@@ -1,4 +0,0 @@
-S. Kate Feng <[email protected]>, Sept. 06, 2007
-
-This driver boots smoothly with the 1GHZ media.
-It might not boot with the 10/100MHZ media.
diff -Naur mvme5500.orig/pci/pci.c mvme5500/pci/pci.c
--- mvme5500.orig/pci/pci.c 2008-08-20 04:56:56.000000000 -0400
+++ mvme5500/pci/pci.c 2009-03-11 16:01:23.000000000 -0400
@@ -13,29 +13,31 @@
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/rtems/license.html.
*
- * Copyright 2004, Brookhaven National Laboratory and
- * Shuchen K. Feng, <[email protected]>, 2004
- * - modified and added support for MVME5500 board
- * - added 2nd PCI support for the mvme5500/GT64260 PCI bridge
- * - added bus support for the expansion of PMCSpan, thanks to
- * Peter Dufault ([email protected]) for inputs.
+ * pci.c,v 1.2 2002/05/14 17:10:16 joel Exp
*
- * $Id: pci.c,v 1.13 2008/08/20 08:56:56 ralf Exp $
+ * Copyright 2004, 2008 Brookhaven National Laboratory and
+ * Shuchen K. Feng, <[email protected]>
+ *
+ * - to be consistent with the original pci.c written by Eric Valette
+ * - added 2nd PCI support for discovery based PCI bridge (e.g. mvme5500/mvme6100)
+ * - added bus support for the expansion of PMCSpan as per request by Peter
*/
#define PCI_MAIN
#include <libcpu/io.h>
#include <rtems/bspIo.h> /* printk */
+#include <bsp/irq.h>
#include <bsp/pci.h>
#include <bsp/gtreg.h>
#include <bsp/gtpcireg.h>
+#include <bsp.h>
#include <stdio.h>
#include <string.h>
#define PCI_DEBUG 0
-#define PCI_PRINT 0
+#define PCI_PRINT 1
/* allow for overriding these definitions */
#ifndef PCI_CONFIG_ADDR
@@ -56,17 +58,31 @@
#define PCI_MULTI_FUNCTION 0x80
#define HOSTBRIDGET_ERROR 0xf0000000
-/* define a shortcut */
-#define pci BSP_pci_configuration
+#define GT64x60_PCI_CONFIG_ADDR GT64x60_REG_BASE + PCI_CONFIG_ADDR
+#define GT64x60_PCI_CONFIG_DATA GT64x60_REG_BASE + PCI_CONFIG_DATA
+
+#define GT64x60_PCI1_CONFIG_ADDR GT64x60_REG_BASE + PCI1_CONFIG_ADDR
+#define GT64x60_PCI1_CONFIG_DATA GT64x60_REG_BASE + PCI1_CONFIG_DATA
+
+static int numPCIDevs=0;
+static DiscoveryChipVersion BSP_sysControllerVersion = 0;
+static BSP_VMEchipTypes BSP_VMEinterface = 0;
+static pci_config BSP_pci[2]={
+ {(volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR),
+ (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA),
+ 0 /* defined at BSP_pci_configuration */},
+ {(volatile unsigned char*) (GT64x60_PCI1_CONFIG_ADDR),
+ (volatile unsigned char*) (GT64x60_PCI1_CONFIG_DATA),
+ 0 /* defined at BSP_pci_configuration */}
+};
-static int numPCIDevs=0;
extern void pci_interface(void);
/* Pack RegNum,FuncNum,DevNum,BusNum,and ConfigEnable for
* PCI Configuration Address Register
*/
#define pciConfigPack(bus,dev,func,offset)\
-(((func&7)<<8)|((dev&0x1f )<<11)|(( bus&0xff)<<16)|(offset&0xfc))|0x80000000
+((offset&~3)<<24)|(PCI_DEVFN(dev,func)<<16)|(bus<<8)|0x80
/*
* Bit encode for PCI_CONFIG_HEADER_TYPE register
@@ -75,44 +91,36 @@
/* Please note that PCI0 and PCI1 does not correlate with the busNum 0 and 1.
*/
-static int direct_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func,
+static int indirect_pci_read_config_byte(unsigned char bus,unsigned char dev,unsigned char func,
unsigned char offset,unsigned char *val)
{
- volatile unsigned char *config_addr, *config_data;
+ int n=0;
if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
bus-=BSP_MAX_PCI_BUS_ON_PCI0;
- config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
- config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
- }
- else {
- config_addr = pci.pci_config_addr;
- config_data = pci.pci_config_data;
+ n=1;
}
+
*val = 0xff;
if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER;
#if 0
- printk("addr %x, data %x, pack %x \n", config_addr,
- config_data,pciConfigPack(bus,dev,func,offset));
+ printk("addr %x, data %x, pack %x \n", BSP_pci[n].pci_config_addr),
+ BSP_pci[n].config_data,pciConfigPack(bus,dev,func,offset));
#endif
- outl(pciConfigPack(bus,dev,func,offset),config_addr);
- *val = inb(config_data + (offset&3));
+
+ out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
+ *val = in_8(BSP_pci[n].pci_config_data + (offset&3));
return PCIBIOS_SUCCESSFUL;
}
-static int direct_pci_read_config_word(unsigned char bus, unsigned char dev,
+static int indirect_pci_read_config_word(unsigned char bus, unsigned char dev,
unsigned char func, unsigned char offset, unsigned short *val)
{
- volatile unsigned char *config_addr, *config_data;
+ int n=0;
if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
bus-=BSP_MAX_PCI_BUS_ON_PCI0;
- config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
- config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
- }
- else {
- config_addr = (volatile unsigned char*) pci.pci_config_addr;
- config_data = (volatile unsigned char*) pci.pci_config_data;
+ n=1;
}
*val = 0xffff;
@@ -121,123 +129,101 @@
printk("addr %x, data %x, pack %x \n", config_addr,
config_data,pciConfigPack(bus,dev,func,offset));
#endif
- outl(pciConfigPack(bus,dev,func,offset),config_addr);
- *val = inw(config_data + (offset&2));
+ out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
+ *val = in_le16(BSP_pci[n].pci_config_data + (offset&2));
return PCIBIOS_SUCCESSFUL;
}
-static int direct_pci_read_config_dword(unsigned char bus, unsigned char dev,
+static int indirect_pci_read_config_dword(unsigned char bus, unsigned char dev,
unsigned char func, unsigned char offset, unsigned int *val)
{
- volatile unsigned char *config_addr, *config_data;
+ int n=0;
if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
bus-=BSP_MAX_PCI_BUS_ON_PCI0;
- config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
- config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
- }
- else {
- config_addr = (volatile unsigned char*) pci.pci_config_addr;
- config_data = (volatile unsigned char*) pci.pci_config_data;
+ n=1;
}
*val = 0xffffffff;
if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER;
-#if 0
- printk("addr %x, data %x, pack %x \n", config_addr,
- pci.pci_config_data,pciConfigPack(bus,dev,func,offset));
-#endif
- outl(pciConfigPack(bus,dev,func,offset),config_addr);
- *val = inl(config_data);
+
+ out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
+ *val = in_le32(BSP_pci[n].pci_config_data);
return PCIBIOS_SUCCESSFUL;
}
-static int direct_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val)
+static int indirect_pci_write_config_byte(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned char val)
{
- volatile unsigned char *config_addr, *config_data;
+ int n=0;
if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
bus-=BSP_MAX_PCI_BUS_ON_PCI0;
- config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
- config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
- }
- else {
- config_addr = pci.pci_config_addr;
- config_data = pci.pci_config_data;
+ n=1;
}
if (offset & ~0xff) return PCIBIOS_BAD_REGISTER_NUMBER;
-#if 0
- printk("addr %x, data %x, pack %x \n", config_addr,
- config_data,pciConfigPack(bus,dev,func,offset));
-#endif
- outl(pciConfigPack(bus,dev,func,offset), config_addr);
- outb(val, config_data + (offset&3));
+ out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
+ out_8(BSP_pci[n].pci_config_data + (offset&3), val);
return PCIBIOS_SUCCESSFUL;
}
-static int direct_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val)
+static int indirect_pci_write_config_word(unsigned char bus, unsigned char dev,unsigned char func, unsigned char offset, unsigned short val)
{
- volatile unsigned char *config_addr, *config_data;
+ int n=0;
if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
bus-=BSP_MAX_PCI_BUS_ON_PCI0;
- config_addr = (volatile unsigned char*) PCI1_CONFIG_ADDR;
- config_data = (volatile unsigned char*) PCI1_CONFIG_DATA;
- }
- else {
- config_addr = (volatile unsigned char*) pci.pci_config_addr;
- config_data = (volatile unsigned char*) pci.pci_config_data;
+ n=1;
}
if ((offset&1)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER;
-#if 0
- printk("addr %x, data %x, pack %x \n", config_addr,
- config_data,pciConfigPack(bus,dev,func,offset));
-#endif
- outl(pciConfigPack(bus,dev,func,offset),config_addr);
- outw(val, config_data + (offset&3));
+
+ out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
+ out_le16(BSP_pci[n].pci_config_data + (offset&3), val);
return PCIBIOS_SUCCESSFUL;
}
-static int direct_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val)
+static int indirect_pci_write_config_dword(unsigned char bus,unsigned char dev,unsigned char func, unsigned char offset, unsigned int val)
{
- volatile unsigned char *config_addr, *config_data;
+ int n=0;
if (bus>= BSP_MAX_PCI_BUS_ON_PCI0) {
bus-=BSP_MAX_PCI_BUS_ON_PCI0;
- config_addr = (volatile unsigned char *) PCI1_CONFIG_ADDR;
- config_data = (volatile unsigned char *) PCI1_CONFIG_DATA;
- }
- else {
- config_addr = (volatile unsigned char*) pci.pci_config_addr;
- config_data = (volatile unsigned char*) pci.pci_config_data;
+ n=1;
}
if ((offset&3)|| (offset & ~0xff)) return PCIBIOS_BAD_REGISTER_NUMBER;
-#if 0
- printk("addr %x, data %x, pack %x \n", config_addr,
- config_data,pciConfigPack(bus,dev,func,offset));
-#endif
- outl(pciConfigPack(bus,dev,func,offset),config_addr);
- outl(val,config_data);
+
+ out_be32(BSP_pci[n].pci_config_addr, pciConfigPack(bus,dev,func,offset));
+ out_le32(BSP_pci[n].pci_config_data, val);
return PCIBIOS_SUCCESSFUL;
}
-const pci_config_access_functions pci_direct_functions = {
- direct_pci_read_config_byte,
- direct_pci_read_config_word,
- direct_pci_read_config_dword,
- direct_pci_write_config_byte,
- direct_pci_write_config_word,
- direct_pci_write_config_dword
+const pci_config_access_functions pci_indirect_functions = {
+ indirect_pci_read_config_byte,
+ indirect_pci_read_config_word,
+ indirect_pci_read_config_dword,
+ indirect_pci_write_config_byte,
+ indirect_pci_write_config_word,
+ indirect_pci_write_config_dword
};
-pci_config BSP_pci_configuration = {(volatile unsigned char*) PCI_CONFIG_ADDR,
- (volatile unsigned char*)PCI_CONFIG_DATA,
- &pci_direct_functions};
+pci_config BSP_pci_configuration = {
+ (volatile unsigned char*) (GT64x60_PCI_CONFIG_ADDR),
+ (volatile unsigned char*) (GT64x60_PCI_CONFIG_DATA),
+ &pci_indirect_functions};
+
+DiscoveryChipVersion BSP_getDiscoveryChipVersion(void)
+{
+ return(BSP_sysControllerVersion);
+}
+
+BSP_VMEchipTypes BSP_getVMEchipType(void)
+{
+ return(BSP_VMEinterface);
+}
/*
* This routine determines the maximum bus number in the system.
@@ -248,12 +234,12 @@
int pci_initialize(void)
{
int deviceFound;
- unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs;
- unsigned int ulHeader;
- unsigned int pcidata, ulClass, ulDeviceID;
+ unsigned char ucBusNumber, ucSlotNumber, ucFnNumber, ucNumFuncs, data8;
+ uint32_t ulHeader, ulClass, ulDeviceID;
+#if PCI_DEBUG
+ uint32_t pcidata;
+#endif
- pci_interface();
-
/*
* Scan PCI0 and PCI1 buses
*/
@@ -279,38 +265,49 @@
if (!deviceFound) deviceFound=1;
switch(ulDeviceID) {
case (PCI_VENDOR_ID_MARVELL+(PCI_DEVICE_ID_MARVELL_GT6426xAB<<16)):
+ pci_read_config_byte(0,0,0,PCI_REVISION_ID, &data8);
+ switch(data8) {
+ case 0x10:
+ BSP_sysControllerVersion = GT64260A;
#if PCI_PRINT
- printk("Marvell GT6426xA/B hostbridge detected at bus%d slot%d\n",
+ printk("Marvell GT64260A (Discovery I) hostbridge detected at bus%d slot%d\n",
ucBusNumber,ucSlotNumber);
#endif
- break;
- case (PCI_VENDOR_ID_PLX2+(PCI_DEVICE_ID_PLX2_PCI6154_HB2<<16)):
+ break;
+ case 0x20:
+ BSP_sysControllerVersion = GT64260B;
#if PCI_PRINT
- printk("PLX PCI6154 PCI-PCI bridge detected at bus%d slot%d\n",
+ printk("Marvell GT64260B (Discovery I) hostbridge detected at bus%d slot%d\n",
ucBusNumber,ucSlotNumber);
#endif
- break;
+ break;
+ default:
+ printk("Undefined revsion of GT64260 chip\n");
+ break;
+ }
+ break;
case PCI_VENDOR_ID_TUNDRA:
#if PCI_PRINT
printk("TUNDRA PCI-VME bridge detected at bus%d slot%d\n",
ucBusNumber,ucSlotNumber);
#endif
break;
- case (PCI_VENDOR_ID_INTEL+(PCI_DEVICE_INTEL_82544EI_COPPER<<16)):
-#if PCI_PRINT
- printk("INTEL 82544EI COPPER network controller detected at bus%d slot%d\n",
- ucBusNumber,ucSlotNumber);
-#endif
- break;
case (PCI_VENDOR_ID_DEC+(PCI_DEVICE_ID_DEC_21150<<16)):
- #if PCI_PRINT
+#if PCI_PRINT
printk("DEC21150 PCI-PCI bridge detected at bus%d slot%d\n",
ucBusNumber,ucSlotNumber);
#endif
break;
default :
+#if PCI_PRINT
printk("BSP unlisted vendor, Bus%d Slot%d DeviceID 0x%x \n",
ucBusNumber,ucSlotNumber, ulDeviceID);
+#endif
+ /* Kate Feng : device not supported by BSP needs to remap the IRQ line on mvme5500/mvme6100 */
+ pci_read_config_byte(ucBusNumber,ucSlotNumber,0,PCI_INTERRUPT_LINE,&data8);
+ if (data8 < BSP_GPP_IRQ_LOWEST_OFFSET) pci_write_config_byte(ucBusNumber,
+ ucSlotNumber,0,PCI_INTERRUPT_LINE,BSP_GPP_IRQ_LOWEST_OFFSET+data8);
+
break;
}
@@ -403,34 +400,6 @@
#endif
}
-
- pci_read_config_dword(ucBusNumber,
- ucSlotNumber,
- 0,
- PCI_COMMAND,
- &pcidata);
-#if PCI_DEBUG
- printk("MOTLoad command staus 0x%x, ", pcidata);
-#endif
- /* Clear the error on the host bridge */
- if ( (ucBusNumber==0) && (ucSlotNumber==0))
- pcidata |= PCI_STATUS_CLRERR_MASK;
- /* Enable bus,I/O and memory master access. */
- pcidata |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY);
- pci_write_config_dword(ucBusNumber,
- ucSlotNumber,
- 0,
- PCI_COMMAND,
- pcidata);
-
- pci_read_config_dword(ucBusNumber,
- ucSlotNumber,
- 0,
- PCI_COMMAND,
- &pcidata);
-#if PCI_DEBUG
- printk("Now command/staus 0x%x\n", pcidata);
-#endif
}
if (deviceFound) ucMaxPCIBus++;
} /* for (ucBusNumber=0; ucBusNumber<BSP_MAX_PCI_BUS; ... */
@@ -438,6 +407,7 @@
printk("number of PCI buses: %d, numPCIDevs %d\n",
pci_bus_count(), numPCIDevs);
#endif
+ pci_interface();
return(0);
}
diff -Naur mvme5500.orig/pci/pci_interface.c mvme5500/pci/pci_interface.c
--- mvme5500.orig/pci/pci_interface.c 2008-08-20 04:56:56.000000000 -0400
+++ mvme5500/pci/pci_interface.c 2009-03-17 14:58:19.000000000 -0400
@@ -7,10 +7,14 @@
* found in the file LICENSE in this distribution.
*
* 8/17/2006 : S. Kate Feng
- * uses in_le32()/out_le32(), instead of inl()/outl() so that
- * it is easier to be ported.
+ * uses in_le32()/out_le32(), instead of inl()/outl() for compatibility.
*
+ * 11/2008 : Enable "PCI Read Agressive Prefetch",
+ * "PCI Read Line Agressive Prefetch", and
+ * "PCI Read Multiple Agressive Prefetch" to improve the
+ * performance of the PCI based applications (e.g. 1GHz NIC).
*/
+
#include <libcpu/io.h>
#include <rtems/bspIo.h> /* printk */
@@ -19,55 +23,29 @@
#include <bsp/gtreg.h>
#include <bsp/gtpcireg.h>
-#define REG32_READ(reg) in_le32((volatile unsigned int *)(GT64260_REG_BASE+reg))
-#define REG32_WRITE(data, reg) out_le32((volatile unsigned int *)(GT64260_REG_BASE+reg), data)
-
#define PCI_DEBUG 0
-/* Please reference the GT64260B datasheet, for the PCI interface,
- * Synchronization Barriers and PCI ordering.
- *
- * Some PCI devices require Synchronization Barriers or PCI ordering
- * for synchronization (only one mechanism allowed. See section 11.1.2).
- * To use the former mechanism(default), one needs to call
- * CPU0_PciEnhanceSync() or CPU1_PciEnhanceSync() to perform software
- * synchronization between the CPU and PCI activities.
- *
- * To use the PCI-ordering, one can call pciToCpuSync() to trigger
- * the PCI-to-CPU sync barrier after the out_xx(). In this mode,
- * PCI configuration reads suffer sync barrier latency. Please reference
- * the datasheet to explore other options.
- *
- * Note : If PCI_ORDERING is needed for the PCI0, while disabling the
- * deadlock for the PCI0, one should keep the CommDLEn bit enabled
- * for the deadlock mechanism so that the 10/100 MB ethernet will
- * function correctly.
- *
- */
-/*#define PCI_ORDERING*/
-
-#define EN_SYN_BAR /* take MOTLoad default for enhanced SYN Barrier mode */
-
-/*#define PCI_DEADLOCK*/
+#if 0
+#define CPU2PCI_ORDER
+#define PCI2CPU_ORDER
+#endif
-#ifdef PCI_ORDERING
-#define PCI_ACCCTLBASEL_VALUE 0x01009000
+/* PCI Read Agressive Prefetch Enable (1<<16 ),
+ * PCI Read Line Agressive Prefetch Enable( 1<<17),
+ * PCI Read Multiple Agressive Prefetch Enable (1<<18).
+ */
+#ifdef PCI2CPU_ORDER
+#define PCI_ACCCTLBASEL_VALUE 0x01079000
#else
-#define PCI_ACCCTLBASEL_VALUE 0x01001000
+#define PCI_ACCCTLBASEL_VALUE 0x01071000
#endif
+
#define ConfSBDis 0x10000000 /* 1: disable, 0: enable */
#define IOSBDis 0x20000000 /* 1: disable, 0: enable */
#define ConfIOSBDis 0x30000000
#define CpuPipeline 0x00002000 /* optional, 1:enable, 0:disable */
-#define CPU0_SYNC_TRIGGER 0xD0 /* CPU0 Sync Barrier trigger */
-#define CPU0_SYNC_VIRTUAL 0xC0 /* CPU0 Sync Barrier Virtual */
-
-#define CPU1_SYNC_TRIGGER 0xD8 /* CPU1 Sync Barrier trigger */
-#define CPU1_SYNC_VIRTUAL 0xC8 /* CPU1 Sync Barrier Virtual */
-
-
/* CPU to PCI ordering register */
#define DLOCK_ORDER_REG 0x2D0 /* Deadlock and Ordering register */
#define PCI0OrEn 0x00000001
@@ -91,69 +69,30 @@
void pci_interface(void)
{
-#ifdef PCI_DEADLOCK
- REG32_WRITE(0x07fff600, CNT_SYNC_REG);
+#ifdef CPU2PCI_ORDER
+ /* MOTLOad deafult : 0x07ff8600 */
+ out_le32((volatile unsigned int *)(GT64x60_REG_BASE+CNT_SYNC_REG), 0x07fff600);
#endif
-#ifdef PCI_ORDERING
- /* Let's leave this to be MOTLOad deafult : 0x80070000
- REG32_WRITE(0xc0070000, DLOCK_ORDER_REG);*/
- /* Leave the CNT_SYNC_REG b/c MOTload default had the SyncBarMode set to 1 */
-#endif
-
- /* asserts SERR upon various detection */
- REG32_WRITE(0x3fffff, 0xc28);
-
- pciAccessInit();
+ /* asserts SERR upon various detection */
+ out_le32((volatile unsigned int *)(GT64x60_REG_BASE+0xc28), 0x3fffff);
+ pciAccessInit();
}
-/* Use MOTLoad default for Writeback Priority and Buffer Depth
- */
+
void pciAccessInit(void)
{
unsigned int PciLocal, data;
for (PciLocal=0; PciLocal < 2; PciLocal++) {
- /* MOTLoad combines the two banks of SDRAM into
- * one PCI access control because the top = 0x1ff
- */
- data = REG32_READ(GT_SCS0_Low_Decode) & 0xfff;
+ data = in_le32((volatile unsigned int *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)));
+#if 0
+ printk("PCI%d_ACCESS_CNTL_BASE0_LOW was 0x%x\n",PciLocal,data);
+#endif
data |= PCI_ACCCTLBASEL_VALUE;
data &= ~0x300000;
- REG32_WRITE(data, PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80));
-#if PCI_DEBUG
- printk("PCI%d_ACCESS_CNTL_BASE0_LOW 0x%x\n",PciLocal,REG32_READ(PCI_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)));
+ out_le32((volatile unsigned int *)(GT64x60_REG_BASE+PCI0_ACCESS_CNTL_BASE0_LOW+(PciLocal * 0x80)), data);
+#if 0
+ 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))));
#endif
-
}
}
-/* Sync Barrier Trigger. A write to the CPU_SYNC_TRIGGER register triggers
- * the sync barrier process. The three bits, define which buffers should
- * be flushed.
- * Bit 0 = PCI0 slave write buffer.
- * Bit 1 = PCI1 slave write buffer.
- * Bit 2 = SDRAM snoop queue.
- */
-void CPU0_PciEnhanceSync(unsigned int syncVal)
-{
- REG32_WRITE(syncVal,CPU0_SYNC_TRIGGER);
- while (REG32_READ(CPU0_SYNC_VIRTUAL));
-}
-
-void CPU1_PciEnhanceSync(unsigned int syncVal)
-{
- REG32_WRITE(syncVal,CPU1_SYNC_TRIGGER);
- while (REG32_READ(CPU1_SYNC_VIRTUAL));
-}
-
-/* Currently, if PCI_ordering is used for synchronization, configuration
- * reads is programmed to be the PCI slave "synchronization barrier"
- * cycles.
- */
-void pciToCpuSync(int pci_num)
-{
- unsigned char data;
- unsigned char bus=0;
-
- if (pci_num) bus += BSP_MAX_PCI_BUS_ON_PCI0;
- pci_read_config_byte(bus,0,0,4, &data);
-}
diff -Naur mvme5500.orig/README mvme5500/README
--- mvme5500.orig/README 2007-09-19 10:47:02.000000000 -0400
+++ mvme5500/README 2009-03-17 10:22:43.000000000 -0400
@@ -1,5 +1,5 @@
#
-# $Id: README,v 1.3.1 Shuchen Kate Feng, NSLS, BNL (08/27/07)
+# $Id: README,v 1.4.1 Shuchen Kate Feng, NSLS, BNL (03/16/2009)
#
Please reference README.booting for the boot/load process.
@@ -7,7 +7,10 @@
For the priority setting of the Interrupt Requests (IRQs), please
reference README.irq
-The BSP is built and tested on the 4.7.1 and 4.7.99.2 CVS RTEMS release.
+The BSP is built and tested on the RTEMS 4.9.1 release. The
+PR1385 patch for c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S
+is not needed for the mvme5500 BSP because the PowerPC BSPs
+use the shared exception framework in the RTEMS 4.9 release.
I believe in valuable real-time programming, where technical neatness,
performance and truth are. I hope I still believe. Any suggestion,
diff -Naur mvme5500.orig/README.booting mvme5500/README.booting
--- mvme5500.orig/README.booting 2007-09-13 10:26:24.000000000 -0400
+++ mvme5500/README.booting 2009-03-17 10:12:18.000000000 -0400
@@ -1,8 +1,9 @@
-README.booting: written by S. Kate Feng <[email protected]>, Aug. 28, 2007
+README.booting: written by S. Kate Feng <[email protected]>, March 16, 2009
-The bootloader is adapted from Till Straumann's Generic Mini-loader,
-which he wrote originally for the SVGM powerpc board.
-The BSP is built and tested on the 4.7 CVS RTEMS release.
+The BSP is built and tested on the RTEMS 4.9.1 release. The
+PR1385 patch for c/src/lib/libbsp/powerpc/shared/irq/irq_asm.S
+is not needed for the mvme5500 BSP because the PowerPC BSPs
+use the shared exception framework in the RTEMS 4.9 release.
Booting requirement :
-------------------------
@@ -11,12 +12,7 @@
or /etc/dhcpd.conf (DHCP) properly to boot the system.
(Note : EPICS needs a NTP server).
-2) Please copy the prebuilt RTEMS binary (e.g. misc/rtems5500-cexp.bin)
- and perhaps others (e.g. misc/st.sys) to the /tftpboot/epics/hostname/bin/
- directory or the TFTPBOOT one you specified in the 'tftpGet'
- command of the boot script (as shown in the following example).
-
-3) Example of the boot script setup carried out on the MOTLoad
+2) Example of the boot script setup carried out on the MOTLoad
command line :
MVME5500> gevEdit mot-script-boot
@@ -32,23 +28,14 @@
Note : (cxx.xx.xx.xx is the client IP address and
sxx.xx.xx.xx is the server IP address)
-4) Other reference web sites for mvme5500 BSP:
-http://lansce.lanl.gov/EPICS/presentations/KateFeng%20RTEMS-mvme55001.ppt
+3) Other reference web sites for mvme5500 BSP:
http://www.nsls.bnl.gov/facility/expsys/software/EPICS/
-http://www.nsls.bnl.gov/facility/expsys/software/EPICS/FAQ.txt
-5) When generating code (especially C++) for this system, one should
- use at least gcc-3.2 (preferrably a copy downloaded from the RTEMS
- site [snapshot area] )
-6) To reboot the RTEMS-MVME5500 (board reset), one can invoke the
+4) To reboot the RTEMS-MVME5500 (board reset), one can invoke the
rtemsReboot() command at Cexp> prompt.
-7) Please reference http://www.slac.stanford.edu/~strauman/rtems
-for the source code and installation guidance of cexp, GeSys and
-other useful utilities such as telnet, nfs, and so on.
-
-8) To get started with RTEMS/EPICS and to build development
+5) To get started with RTEMS/EPICS and to build development
tools and BSP, I would recommend one to reference
http://www.aps.anl.gov/epics/base/RTEMS/tutorial/
in additional to the RTEMS document.
diff -Naur mvme5500.orig/startup/bspclean.c mvme5500/startup/bspclean.c
--- mvme5500.orig/startup/bspclean.c 2008-10-23 09:45:55.000000000 -0400
+++ mvme5500/startup/bspclean.c 2009-02-11 16:08:45.000000000 -0500
@@ -1,3 +1,6 @@
+/* Copyright 2003, Shuchen Kate Feng <[email protected]>,
+ * NSLS,Brookhaven National Laboratory
+ */
#include <bsp.h>
#include <rtems/bspIo.h>
#include <libcpu/stackTrace.h>
diff -Naur mvme5500.orig/startup/bspstart.c mvme5500/startup/bspstart.c
--- mvme5500.orig/startup/bspstart.c 2008-08-20 04:56:56.000000000 -0400
+++ mvme5500/startup/bspstart.c 2009-04-01 11:51:21.000000000 -0400
@@ -24,8 +24,6 @@
* $Id: bspstart.c,v 1.23 2008/08/20 08:56:56 ralf Exp $
*/
-#warning The interrupt disable mask is now stored in SPRG0, please verify that this is compatible to this BSP (see also bootcard.c).
-
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
@@ -52,12 +50,12 @@
#undef __RTEMS_APPLICATION__
#endif
-/*
-#define SHOW_MORE_INIT_SETTINGS
+
+/*#define SHOW_MORE_INIT_SETTINGS
+#define CONF_VPD
#define SHOW_LCR1_REGISTER
#define SHOW_LCR2_REGISTER
#define SHOW_LCR3_REGISTER
-#define CONF_VPD
*/
/* there is no public Workspace_Free() variant :-( */
@@ -73,6 +71,7 @@
extern void BSP_pgtbl_activate(Triv121PgTbl);
extern int I2Cread_eeprom(unsigned char I2cBusAddr, uint32_t devA2A1A0, uint32_t AddrBytes, unsigned char *pBuff, uint32_t numBytes);
extern void BSP_vme_config(void);
+extern uint32_t probeMemoryEnd();
uint32_t bsp_clicks_per_usec;
@@ -267,12 +266,10 @@
setdbat(2, PCI0_MEM_BASE, PCI0_MEM_BASE, 0x10000000, IO_PAGE);
/* Till Straumann: 2004
- * map the PCI 0, 1 Domain I/O space, GT64260B registers
- * and the reserved area so that the size is the power of 2.
- *
+ * map the PCI 0, 1 Domain I/O space, GT64260B registers,
+ * Flash Bank 0 and Flash Bank 2.
*/
- setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x2000000, IO_PAGE);
-
+ setdbat(3,PCI0_IO_BASE, PCI0_IO_BASE, 0x10000000, IO_PAGE);
/*
* Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
@@ -327,29 +324,7 @@
printk("Welcome to %s on MVME5500-0163\n", _RTEMS_version );
printk("-----------------------------------------\n");
-#ifdef TEST_RETURN_TO_PPCBUG
- printk("Hit <Enter> to return to PPCBUG monitor\n");
- printk("When Finished hit GO. It should print <Back from monitor>\n");
- debug_getc();
- _return_to_ppcbug();
- printk("Back from monitor\n");
- _return_to_ppcbug();
-#endif /* TEST_RETURN_TO_PPCBUG */
-
-#ifdef TEST_RAW_EXCEPTION_CODE
- printk("Testing exception handling Part 1\n");
- /*
- * Cause a software exception
- */
- __asm__ __volatile ("sc");
- /*
- * Check we can still catch exceptions and returned coorectly.
- */
- printk("Testing exception handling Part 2\n");
- __asm__ __volatile ("sc");
-#endif
-
- BSP_mem_size = _512M;
+ BSP_mem_size = probeMemoryEnd();
/* TODO: calculate the BSP_bus_frequency using the REF_CLK bit
* of System Status register
*/
@@ -421,6 +396,19 @@
#endif
BSP_pgtbl_activate(pt);
}
+ /* Read Configuration Vital Product Data (VPD) */
+ if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
+ printk("I2Cread_eeprom() error \n");
+ else {
+#ifdef CONF_VPD
+ printk("\n");
+ for (i=0; i<150; i++) {
+ printk("%2x ", ConfVPD_buff[i]);
+ if ((i % 20)==0 ) printk("\n");
+ }
+ printk("\n");
+#endif
+ }
/*
* PCI 1 domain memory space
@@ -444,20 +432,6 @@
*/
_BSP_clear_hostbridge_errors(0, 1 /*quiet*/);
- /* Read Configuration Vital Product Data (VPD) */
- if ( I2Cread_eeprom(0xa8, 4,2, &ConfVPD_buff[0], 150))
- printk("I2Cread_eeprom() error \n");
- else {
-#ifdef CONF_VPD
- printk("\n");
- for (i=0; i<150; i++) {
- printk("%2x ", ConfVPD_buff[i]);
- if ((i % 20)==0 ) printk("\n");
- }
- printk("\n");
-#endif
- }
-
#ifdef SHOW_MORE_INIT_SETTINGS
printk("MSR %x \n", _read_MSR());
printk("Exit from bspstart\n");
diff -Naur mvme5500.orig/startup/reboot.c mvme5500/startup/reboot.c
--- mvme5500.orig/startup/reboot.c 2008-10-23 09:45:55.000000000 -0400
+++ mvme5500/startup/reboot.c 2009-02-25 15:39:41.000000000 -0500
@@ -1,3 +1,10 @@
+/* Copyright 2003, Shuchen Kate Feng <[email protected]>,
+ * NSLS,Brookhaven National Laboratory
+ *
+ * Ported it from powerpc/shared/console/reboot.c for mvme5500
+ *
+ */
+
#include <rtems.h>
#include <bsp.h>
#include <rtems/bspIo.h>
@@ -12,5 +19,5 @@
printk("RTEMS terminated; Rebooting ...\n");
/* Mvme5500 board reset : 2004 S. Kate Feng <[email protected]> */
- out_8((volatile unsigned char*) (GT64260_DEV1_BASE +2), 0x80);
+ out_8((volatile unsigned char*) (GT64x60_DEV1_BASE +2), 0x80);
}
diff -Naur mvme5500.orig/vectors/exceptionhandler.c mvme5500/vectors/exceptionhandler.c
--- mvme5500.orig/vectors/exceptionhandler.c 2008-10-23 09:45:55.000000000 -0400
+++ mvme5500/vectors/exceptionhandler.c 2009-02-26 09:46:11.000000000 -0500
@@ -134,6 +134,8 @@
/* register dump */
printk("\t Next PC or Address of fault = %x, ", excPtr->EXC_SRR0);
printk("Mvme5500 Saved MSR = %x\n", excPtr->EXC_SRR1);
+ printk("The Interrupt mask (e.g. MSR_EE) stored in SPRG0= 0x%x\n",
+ ppc_interrupt_get_disable_mask());
printk("\t R0 = %08x", excPtr->GPR0);
printk(" R1 = %08x", excPtr->GPR1);
printk(" R2 = %08x", excPtr->GPR2);
- References:
- Failing EPICS Test Harness on RTEMS-mvme5500 Ralph Lange
- Navigate by Date:
- Prev:
Failing EPICS Test Harness on RTEMS-mvme5500 Ralph Lange
- Next:
Re: Failing EPICS Test Harness on RTEMS-mvme5500 Kate Feng
- Index:
2002
2003
2004
2005
2006
2007
2008
<2009>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Failing EPICS Test Harness on RTEMS-mvme5500 Ralph Lange
- Next:
Re: Failing EPICS Test Harness on RTEMS-mvme5500 Kate Feng
- Index:
2002
2003
2004
2005
2006
2007
2008
<2009>
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|