summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2003-02-20 21:35:57 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2003-02-20 21:35:57 +0000
commit20b349f15f4a52b87f86524f27a55db627f87cba (patch)
tree57442db14c37f1582bc09b32e7b7d94812be0132
parent2003-02-20 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-20b349f15f4a52b87f86524f27a55db627f87cba.tar.bz2
2003-02-20 Till Straumann <strauman@slac.stanford.edu>
PR 349/bsps * shared/README.universe, shared/vmeUniverse/README.porting shared/vmeUniverse/README.universe, shared/vmeUniverse/vmeUniverse.c, shared/vmeUniverse/vmeUniverse.h: Update of the VME universe driver.
-rw-r--r--c/src/lib/libbsp/shared/ChangeLog7
-rw-r--r--c/src/lib/libbsp/shared/vmeUniverse/README.porting88
-rw-r--r--c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.c231
-rw-r--r--c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.h92
4 files changed, 340 insertions, 78 deletions
diff --git a/c/src/lib/libbsp/shared/ChangeLog b/c/src/lib/libbsp/shared/ChangeLog
index da6b7f0a2a..d29d1e7c19 100644
--- a/c/src/lib/libbsp/shared/ChangeLog
+++ b/c/src/lib/libbsp/shared/ChangeLog
@@ -1,3 +1,10 @@
+2003-02-20 Till Straumann <strauman@slac.stanford.edu>
+
+ PR 349/bsps
+ * shared/README.universe, shared/vmeUniverse/README.porting
+ shared/vmeUniverse/README.universe, shared/vmeUniverse/vmeUniverse.c,
+ shared/vmeUniverse/vmeUniverse.h: Update of the VME universe driver.
+
2002-10-28 Eugeny S. Mints <Eugeny.Mints@oktet.ru>
* ide_ctrl.c: New file.
diff --git a/c/src/lib/libbsp/shared/vmeUniverse/README.porting b/c/src/lib/libbsp/shared/vmeUniverse/README.porting
new file mode 100644
index 0000000000..b72a673356
--- /dev/null
+++ b/c/src/lib/libbsp/shared/vmeUniverse/README.porting
@@ -0,0 +1,88 @@
+#
+# $Id$
+#
+
+The vmeUniverse driver needs some support from the BSP for
+
+a) PCI configuration space access
+b) PCI interrupt acknowledgement
+c) PCI interrupt handler installation
+
+The driver was developed using the powerpc/shared/ BSP
+(it also supports vxWorks) and by default uses that BSP's
+a) PCI access API
+b,c) irq handling API (AKA 'new' style BSP_install_rtems_irq_handler()
+ API).
+
+Some hooks exist in the driver to ease porting to other BSPs.
+The following information has been assembled when answering a
+question regarding a ppcn_60x BSP port:
+
+I looked through the ppcn_60x BSP. Here's what I found:
+
+ - this BSP does NOT adhere to neither the 'old' nor the 'new' API
+ but provides its own (startup/setvec.c: set_vector()).
+ - the BSP has a 'driver' for vmeUniverse although mine is far more
+ complete (including support for VME interrupts, DMA etc.).
+ - Porting my driver to your BSP should not be too hard:
+
+ 1) vmeUniverse needs PCI configuration space support from the
+ BSP:
+ a) a routine 'pciFindDevice' (need to be macro-aliased
+ to the proper routine/wrapper of your BSP) who scans
+ PCI config space for the universe bridge.
+ You could add 'libbsp/powerpc/shared/pci/pcifinddevice.c'
+ to your BSP substituting the pci_read_config_xxx calls
+ by the ones present on your BSP (see step 2))
+ b) routines to read PCI config registers (byte and longword)
+ [on your BSP these are PCIConfigRead32/PCIConfigRead8;
+ hence you could replace the macros on top with
+ #define pciConfigInLong PCIConfigRead32
+ 2) vmeUniverse needs to know how to acknowledge a PCI interrupt
+ In your case, nothing needs to be done
+ #define BSP_PIC_DO_EOI do {} while (0)
+ 3) Install the VME ISR dispatcher: replace the 'new' style
+ interrupt installer (BSP_install_rtems_irq_handler()) by
+ a proper call to 'set_vector()'
+ 4) I might have missed something...
+
+I attach the latest version of the vmeUniverse driver in case you want
+to try to do the port (should be easy).
+
+For the sake of ease of maintenance, I just added a few hooks making it
+possible to override some things without having to modify the driver code.
+
+ 1,2) PCI config space access macros may be overriden via CFLAGS
+ when compiling vmeUniverse.c, hence:
+ CFLAGS += -DBSP_PIC_DO_EOI=do{}while(0)
+ CFLAGS += -DBSP_PCI_CONFIG_IN_LONG=PCIConfigRead32
+ CFLAGS += -DBSP_PCI_CONFIG_IN_BYTE=PCIConfigRead8
+ (you still need to supply BSP_pciFindDevice)
+ 3) create your own version of vmeUniverseInstallIrqMgr():
+ copy to a separate file and replace
+ BSP_rtems_install_irq_handler() by a proper call to set_vector.
+
+ 4) Send me email :-)
+
+USAGE NOTE: To fully initialize the driver, the following steps can/must
+be performed:
+
+ vmeUniverseInit(); /* MANDATORY: Driver Initialization */
+ vmeUniverseReset(); /* OPTIONAL: Reset most registers to a known state;
+ * if this step is omitted, firmware setup is
+ * preserved
+ */
+ vmeUniverseMasterPortCfg(...); /* OPTIONAL: setup the master windows
+ * (current setup preserved if omitted)
+ */
+ vmeUniverseSlavePortCfg(...); /* OPTIONAL: setup the slave windows
+ * (current setup preserved if omitted)
+ */
+ vmeUniverseInstallIrqMgr(); /* NEEDED FOR VME INTERRUPT SUPPRORT
+ * initialize the interrupt manager.
+ * NOTE: you need to call your own
+ * version of this routine here
+ */
+
+For an example of init/setup, consult libbsp/powerpc/shared/vme/vmeconfig.c
+
diff --git a/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.c b/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.c
index 0fbd2840e8..0762f9ad01 100644
--- a/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.c
+++ b/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.c
@@ -6,7 +6,51 @@
*/
#if 0
+/*
* $Log$
+ * Revision 1.34 2003/02/10 23:20:05 till
+ * - added some macro magic to make porting easier (ppcn_60x BSP in mind)
+ * - made mgrInstalled public (vmeUniverseIrqMgrInstalled) so BSPs can
+ * supply their own versions of the mgrInstall() routine.
+ * - added READMEs to CVS
+ *
+ * Revision 1.33.2.1 2003/02/10 23:01:40 till
+ * - added some macro magic to make porting easier (ppcn_60x BSP in mind)
+ * - made mgrInstalled public (vmeUniverseIrqMgrInstalled) so BSPs can
+ * supply their own versions of the mgrInstall() routine.
+ *
+ * Revision 1.32 2002/09/05 02:50:41 till
+ * - use k_vsprintf(), not vsprintf() during early boot (RTEMS)
+ *
+ * Revision 1.31 2002/08/16 23:35:15 strauman
+ * - fixed typos
+ *
+ * Revision 1.30 2002/08/16 22:53:37 till
+ * - made address translation more generic; allow to look for reverse mappings
+ * also.
+ * - removed vmeUniverseLocalToBus() and vmeUniverseBusToLocal() and made
+ * vmeUniverseXlateAddr() public instead.
+ *
+ * Revision 1.29 2002/08/16 22:16:25 till
+ * - tweak U2SPEC (fix Joerger vtr10012_8 problem) the same
+ * way the synergy BSP does (rev 2 chips only)
+ *
+ * Revision 1.28 2002/08/15 23:16:01 till
+ * - bugfix: vmeUniverseISRGet() dereferenced a possibly NULL pointer
+ *
+ * Revision 1.25 2002/07/19 05:18:40 till
+ * - CVS log: again a problem. Cannot embed /_* *_/ comments in the log
+ * because the log has to be commented as a whole. I had tried
+ * #if 0 #endif - doesn't work because cpp expands char constants???
+ * WHAT A NUISANCE
+ *
+ * Revision 1.24 2002/07/19 02:44:14 till
+ * - added a new parameter to the IRQ manager install routine:
+ * the main interrupt's line can now also be specified (reading
+ * from PCI config does not always work - some boards don't
+ * have correct information there - PMC's will have a similar
+ * problem, though!)
+ *
* Revision 1.21 2002/04/11 06:54:48 till
* - silenced message about 'successfully configured a port'
*
@@ -32,14 +76,13 @@
*
* Revision 1.15 2002/01/23 06:15:30 till
* - changed master port data width to 64 bit.
- * /* NOTE: reading the CY961 (Echotek ECDR814) with VDW32
- * * generated bus errors when reading 32-bit words
- * * - very weird, because the registers are 16-bit
- * * AFAIK.
- * * - 32-bit accesses worked fine on vxWorks which
- * * has the port set to 64-bit.
- * * ????????
- * */
+ * NOTE: reading the CY961 (Echotek ECDR814) with VDW32
+ * generated bus errors when reading 32-bit words
+ * - very weird, because the registers are 16-bit
+ * AFAIK.
+ * - 32-bit accesses worked fine on vxWorks which
+ * has the port set to 64-bit.
+ * ????????
*
* Revision 1.14 2002/01/11 19:30:54 till
* - added more register defines to header
@@ -55,7 +98,7 @@
*
* Revision 1.11 2002/01/08 03:59:52 till
* - vxworks always defines _LITTLE_ENDIAN, fixed the conditionals
- * so it should work on __vxworks and on __rtems now.
+ * so it should work on __vxworks and on __rtems__ now.
* - rtems uprintf wrapper reverts to printk if stdio is not yet
* initialized (uses _impure_ptr->__sdidinit)
* - tested bus address translation utility routines
@@ -89,7 +132,7 @@
*
* Revision 1.1.1.1 2001/07/12 23:15:19 till
* - cvs import
- *
+ */
#endif
#include <stdio.h>
@@ -137,16 +180,23 @@
/* we rely on a vxWorks definition here */
#define VX_AM_SUP 4
-#ifdef __rtems
+#ifdef __rtems__
#include <stdlib.h>
#include <rtems/bspIo.h> /* printk */
#include <bsp/pci.h>
#include <bsp.h>
-#define pciFindDevice BSP_pciFindDevice
-#define pciConfigInLong pci_read_config_dword
-#define pciConfigInByte pci_read_config_byte
+/* allow the BSP to override the default routines */
+#ifndef BSP_PCI_FIND_DEVICE
+#define BSP_PCI_FIND_DEVICE BSP_pciFindDevice
+#endif
+#ifndef BSP_PCI_CONFIG_IN_LONG
+#define BSP_PCI_CONFIG_IN_LONG pci_read_config_dword
+#endif
+#ifndef BSP_PCI_CONFIG_IN_BYTE
+#define BSP_PCI_CONFIG_IN_BYTE pci_read_config_byte
+#endif
typedef unsigned int pci_ulong;
#define PCI_TO_LOCAL_ADDR(memaddr) ((pci_ulong)(memaddr) + PCI_MEM_BASE)
@@ -155,11 +205,16 @@ typedef unsigned int pci_ulong;
#elif defined(__vxworks)
typedef unsigned long pci_ulong;
#define PCI_TO_LOCAL_ADDR(memaddr) (memaddr)
-#define PCI_INTERRUPT_LINE 0x3c
+#define BSP_PCI_FIND_DEVICE pciFindDevice
+#define BSP_PCI_CONFIG_IN_LONG pciConfigInLong
+#define BSP_PCI_CONFIG_IN_BYTE pciConfigInByte
#else
#error "vmeUniverse not ported to this architecture yet"
#endif
+#ifndef PCI_INTERRUPT_LINE
+#define PCI_INTERRUPT_LINE 0x3c
+#endif
volatile LERegister *vmeUniverse0BaseAddr=0;
int vmeUniverse0PciIrqLine=-1;
@@ -192,7 +247,7 @@ WRITE_LE(
#elif (defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC)) && (__BIG_ENDIAN__ == 1)
/* offset is in bytes and MUST not end up in r0 */
__asm__ __volatile__("stwbrx %1, %0, %2" :: "b"(off),"r"(val),"r"(adrs));
-#elif defined(__rtems)
+#elif defined(__rtems__)
st_le32((volatile unsigned long*)(((unsigned long)adrs)+off), val);
#else
#error "little endian register writing not implemented"
@@ -221,7 +276,7 @@ READ_LE0(volatile LERegister *adrs)
register unsigned long rval;
__asm__ __volatile__("lwbrx %0, 0, %1":"=r"(rval):"r"(adrs));
return rval;
-#elif defined(__rtems)
+#elif defined(__rtems__)
return ld_le32((volatile unsigned long*)adrs);
#else
#error "little endian register reading not implemented"
@@ -254,17 +309,18 @@ return READ_LE0((volatile LERegister *)(((unsigned long)adrs)+off));
#define UNIV_REV(base) (READ_LE(base,2*sizeof(LERegister)) & 0xff)
-#ifdef __rtems
+#ifdef __rtems__
static int
uprintk(char *fmt, va_list ap)
{
int rval;
+extern int k_vsprintf(char *, char *, va_list);
/* during bsp init, there is no malloc and no stdio,
* hence we assemble the message on the stack and revert
* to printk
*/
char buf[200];
- rval = vsprintf(buf,fmt,ap);
+ rval = k_vsprintf(buf,fmt,ap);
if (rval > sizeof(buf))
BSP_panic("vmeUniverse/uprintk: buffer overrun");
printk(buf);
@@ -280,7 +336,7 @@ uprintf(FILE *f, char *fmt, ...)
va_list ap;
int rval;
va_start(ap, fmt);
-#ifdef __rtems
+#ifdef __rtems__
if (!f || !_impure_ptr->__sdidinit) {
/* Might be called at an early stage when
* stdio is not yet initialized.
@@ -307,7 +363,7 @@ int bus,dev,fun;
pci_ulong busaddr;
unsigned char irqline;
- if (pciFindDevice(
+ if (BSP_PCI_FIND_DEVICE(
PCI_VENDOR_TUNDRA,
PCI_DEVICE_UNIVERSEII,
instance,
@@ -315,17 +371,17 @@ unsigned char irqline;
&dev,
&fun))
return -1;
- if (pciConfigInLong(bus,dev,fun,PCI_UNIVERSE_BASE0,&busaddr))
+ if (BSP_PCI_CONFIG_IN_LONG(bus,dev,fun,PCI_UNIVERSE_BASE0,&busaddr))
return -1;
if ((unsigned long)(busaddr) & 1) {
/* it's IO space, try BASE1 */
- if (pciConfigInLong(bus,dev,fun,PCI_UNIVERSE_BASE1,&busaddr)
+ if (BSP_PCI_CONFIG_IN_LONG(bus,dev,fun,PCI_UNIVERSE_BASE1,&busaddr)
|| ((unsigned long)(busaddr) & 1))
return -1;
}
*pbase=(volatile LERegister*)PCI_TO_LOCAL_ADDR(busaddr);
- if (pciConfigInByte(bus,dev,fun,PCI_INTERRUPT_LINE,&irqline))
+ if (BSP_PCI_CONFIG_IN_BYTE(bus,dev,fun,PCI_INTERRUPT_LINE,&irqline))
return -1;
else
vmeUniverse0PciIrqLine = irqline;
@@ -608,6 +664,7 @@ showUniversePort(
typedef struct XlatRec_ {
unsigned long address;
unsigned long aspace;
+ unsigned reverse; /* find reverse mapping of this port */
} XlatRec, *Xlat;
/* try to translate an address through the bridge
@@ -653,12 +710,22 @@ unsigned long cntrl, start, bound, offst, mask, x;
offst = READ_LE0(preg++) & mask;
/* translate address to the other bus */
- x = l->address - offst;
+ if (l->reverse) {
+ /* reverse mapping, i.e. for master ports we map from
+ * VME to PCI, for slave ports we map from VME to PCI
+ */
+ if (l->address >= start && l->address < bound) {
+ l->address+=offst;
+ return 1;
+ }
+ } else {
+ x = l->address - offst;
- if (x >= start && x < bound) {
- /* valid address found */
- l->address = x;
- return 1;
+ if (x >= start && x < bound) {
+ /* valid address found */
+ l->address = x;
+ return 1;
+ }
}
return 0;
}
@@ -711,31 +778,26 @@ showUniversePorts(int ismaster, FILE *f)
mapOverAll(ismaster,showUniversePort,f);
}
-static int xlate(int ismaster, unsigned long as, unsigned long aIn, unsigned long *paOut)
+int
+vmeUniverseXlateAddr(
+ int master, /* look in the master windows */
+ int reverse, /* reverse mapping; for masters: map local to VME */
+ unsigned long as, /* address space */
+ unsigned long aIn, /* address to look up */
+ unsigned long *paOut/* where to put result */
+ )
{
int rval;
XlatRec l;
- l.aspace = as;
+ l.aspace = as;
l.address = aIn;
+ l.reverse = reverse;
/* map result -1/0/1 to -2/-1/0 with 0 on success */
- rval = mapOverAll(ismaster,xlatePort,(void*)&l) - 1;
+ rval = mapOverAll(master,xlatePort,(void*)&l) - 1;
*paOut = l.address;
return rval;
}
-/* public functions */
-int
-vmeUniverseLocalToBusAdrs(unsigned long as, unsigned long localAdrs, unsigned long *pbusAdrs)
-{
- return xlate(0,as,localAdrs,pbusAdrs);
-}
-
-int
-vmeUniverseBusToLocalAdrs(unsigned long as, unsigned long busAdrs, unsigned long *plocalAdrs)
-{
- return xlate(1,as,busAdrs,plocalAdrs);
-}
-
void
vmeUniverseReset(void)
{
@@ -765,6 +827,21 @@ vmeUniverseReset(void)
/* disable VME bus image of VME CSR */
vmeUniverseWriteReg(0, UNIV_REGOFF_VCSR_CTL);
+
+ /* I had problems with a Joerger vtr10012_8 card who would
+ * only be accessible after tweaking the U2SPEC register
+ * (the t27 parameter helped).
+ * I use the same settings here that are used by the
+ * Synergy VGM-powerpc BSP for vxWorks.
+ */
+ if (2==UNIV_REV(vmeUniverse0BaseAddr))
+ vmeUniverseWriteReg(UNIV_U2SPEC_DTKFLTR |
+ UNIV_U2SPEC_MASt11 |
+ UNIV_U2SPEC_READt27_NODELAY |
+ UNIV_U2SPEC_POSt28_FAST |
+ UNIV_U2SPEC_PREt28_FAST,
+ UNIV_REGOFF_U2SPEC);
+
/* disable interrupts, reset routing */
vmeUniverseWriteReg(0, UNIV_REGOFF_LINT_EN);
vmeUniverseWriteReg(0, UNIV_REGOFF_LINT_MAP0);
@@ -924,7 +1001,7 @@ register unsigned long *p=ptr+num;
"stwbrx 0, 0, %0\n"
: "=r"(p) : "r"(p) : "r0"
);
-#elif defined(__rtems)
+#elif defined(__rtems__)
p--; st_le32(p, *p);
#else
#error "vmeUniverse: endian conversion not implemented for this architecture"
@@ -935,7 +1012,7 @@ register unsigned long *p=ptr+num;
/* RTEMS interrupt subsystem */
-#ifdef __rtems
+#ifdef __rtems__
#include <bsp/irq.h>
typedef struct
@@ -944,16 +1021,18 @@ UniverseIRQEntryRec_ {
void *usrData;
} UniverseIRQEntryRec, *UniverseIRQEntry;
-static UniverseIRQEntry universeHdlTbl[257]={0};
+static UniverseIRQEntry universeHdlTbl[UNIV_NUM_INT_VECS]={0};
-static int mgrInstalled=0;
+int vmeUniverseIrqMgrInstalled=0;
static int vmeIrqUnivOut=-1;
static int specialIrqUnivOut=-1;
VmeUniverseISR
vmeUniverseISRGet(unsigned long vector, void **parg)
{
- if (vector>255) return 0;
+ if (vector>=UNIV_NUM_INT_VECS ||
+ ! universeHdlTbl[vector])
+ return 0;
if (parg)
*parg=universeHdlTbl[vector]->usrData;
return universeHdlTbl[vector]->isr;
@@ -962,10 +1041,29 @@ vmeUniverseISRGet(unsigned long vector, void **parg)
static void
universeSpecialISR(void)
{
-UniverseIRQEntry ip;
- /* try the special handler */
- if ((ip=universeHdlTbl[UNIV_SPECIAL_IRQ_VECTOR])) {
- ip->isr(ip->usrData, UNIV_SPECIAL_IRQ_VECTOR);
+register UniverseIRQEntry ip;
+register unsigned vec;
+register unsigned long status;
+
+ status=vmeUniverseReadReg(UNIV_REGOFF_LINT_STAT);
+
+ /* scan all LINT bits except for the 'normal' VME interrupts */
+
+ /* do VOWN first */
+ vec=UNIV_VOWN_INT_VEC;
+ if ( (status & UNIV_LINT_STAT_VOWN) && (ip=universeHdlTbl[vec]))
+ ip->isr(ip->usrData,vec);
+
+ /* now continue with DMA and scan through all bits;
+ * we assume the vectors are in the right order!
+ *
+ * The initial right shift brings the DMA bit into position 0;
+ * the loop is left early if there are no more bits set.
+ */
+ for (status>>=8; status; status>>=1) {
+ vec++;
+ if ((status&1) && (ip=universeHdlTbl[vec]))
+ ip->isr(ip->usrData,vec);
}
/* clear all special interrupts */
vmeUniverseWriteReg(
@@ -1092,16 +1190,25 @@ my_isOn(const rtems_irq_connect_data *arg)
}
int
-vmeUniverseInstallIrqMgr(int vmeOut, int specialOut, int specialIrqPicLine)
+vmeUniverseInstallIrqMgr(int vmeOut,
+ int vmeIrqPicLine,
+ int specialOut,
+ int specialIrqPicLine)
{
rtems_irq_connect_data aarrggh;
/* check parameters */
if ((vmeIrqUnivOut=vmeOut) < 0 || vmeIrqUnivOut > 7) return -1;
if ((specialIrqUnivOut=specialOut) > 7) return -2;
- if (specialIrqPicLine < 0) return -3;
+ if (specialOut >=0 && specialIrqPicLine < 0) return -3;
+ /* give them a chance to override buggy PCI info */
+ if (vmeIrqPicLine >= 0) {
+ uprintf(stderr,"Overriding main IRQ line PCI info with %i\n",
+ vmeIrqPicLine);
+ vmeUniverse0PciIrqLine=vmeIrqPicLine;
+ }
- if (mgrInstalled) return -4;
+ if (vmeUniverseIrqMgrInstalled) return -4;
aarrggh.on=my_no_op; /* at _least_ they could check for a 0 pointer */
aarrggh.off=my_no_op;
@@ -1142,7 +1249,7 @@ rtems_irq_connect_data aarrggh;
UNIV_LINT_MAP1_DMA(specialIrqUnivOut)
),
UNIV_REGOFF_LINT_MAP1);
- mgrInstalled=1;
+ vmeUniverseIrqMgrInstalled=1;
return 0;
}
@@ -1152,7 +1259,7 @@ vmeUniverseInstallISR(unsigned long vector, VmeUniverseISR hdl, void *arg)
{
UniverseIRQEntry ip;
- if (vector>sizeof(universeHdlTbl)/sizeof(universeHdlTbl[0]) || !mgrInstalled)
+ if (vector>sizeof(universeHdlTbl)/sizeof(universeHdlTbl[0]) || !vmeUniverseIrqMgrInstalled)
return -1;
ip=universeHdlTbl[vector];
@@ -1170,7 +1277,7 @@ vmeUniverseRemoveISR(unsigned long vector, VmeUniverseISR hdl, void *arg)
{
UniverseIRQEntry ip;
- if (vector>sizeof(universeHdlTbl)/sizeof(universeHdlTbl[0]) || !mgrInstalled)
+ if (vector>sizeof(universeHdlTbl)/sizeof(universeHdlTbl[0]) || !vmeUniverseIrqMgrInstalled)
return -1;
ip=universeHdlTbl[vector];
@@ -1185,7 +1292,7 @@ UniverseIRQEntry ip;
int
vmeUniverseIntEnable(unsigned int level)
{
- if (!mgrInstalled || level<1 || level>7)
+ if (!vmeUniverseIrqMgrInstalled || level<1 || level>7)
return -1;
vmeUniverseWriteReg(
(vmeUniverseReadReg(UNIV_REGOFF_LINT_EN) |
@@ -1198,7 +1305,7 @@ vmeUniverseIntEnable(unsigned int level)
int
vmeUniverseIntDisable(unsigned int level)
{
- if (!mgrInstalled || level<1 || level>7)
+ if (!vmeUniverseIrqMgrInstalled || level<1 || level>7)
return -1;
vmeUniverseWriteReg(
(vmeUniverseReadReg(UNIV_REGOFF_LINT_EN) &
diff --git a/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.h b/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.h
index 03f9032154..b37e8ed259 100644
--- a/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.h
+++ b/c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.h
@@ -14,16 +14,25 @@
#include <vme.h>
#else
/* vxworks compatible addressing modes */
+#define VME_AM_STD_SUP_ASCENDING 0x3f
#define VME_AM_STD_SUP_PGM 0x3e
+#define VME_AM_STD_USR_ASCENDING 0x3b
#define VME_AM_STD_USR_PGM 0x3a
#define VME_AM_STD_SUP_DATA 0x3d
#define VME_AM_STD_USR_DATA 0x39
+#define VME_AM_EXT_SUP_ASCENDING 0x0f
#define VME_AM_EXT_SUP_PGM 0x0e
+#define VME_AM_EXT_USR_ASCENDING 0x0b
#define VME_AM_EXT_USR_PGM 0x0a
#define VME_AM_EXT_SUP_DATA 0x0d
#define VME_AM_EXT_USR_DATA 0x09
#define VME_AM_SUP_SHORT_IO 0x2d
#define VME_AM_USR_SHORT_IO 0x29
+
+#define VME_AM_IS_SHORT(a) (((a) & 0xf0) == 0x20)
+#define VME_AM_IS_STD(a) (((a) & 0xf0) == 0x30)
+#define VME_AM_IS_EXT(a) (((a) & 0xf0) == 0x00)
+
#endif
typedef unsigned long LERegister; /* emphasize contents are little endian */
@@ -338,6 +347,18 @@ typedef struct VmeUniverseDMAPacketRec_ {
# define UNIV_MISC_CTL_SYSCON (1<<17) /* (R/W) 1:universe is system controller */
# define UNIV_MISC_CTL_V64AUTO (1<<16) /* (R/W) 1:initiate VME64 auto id slave participation */
+/* U2SPEC described in VGM manual */
+/* NOTE: the Joerger vtr10012_8 needs the timing to be tweaked!!!! READt27 must be _no_delay_
+ */
+#define UNIV_REGOFF_U2SPEC 0x4fc
+# define UNIV_U2SPEC_DTKFLTR (1<<12) /* DTAck filter: 0: slow, better filter; 1: fast, poorer filter */
+# define UNIV_U2SPEC_MASt11 (1<<10) /* Master parameter t11 (DS hi time during BLT and MBLTs) */
+# define UNIV_U2SPEC_READt27_DEFAULT (0<<8) /* VME master parameter t27: (latch data after DTAck + 25ns) */
+# define UNIV_U2SPEC_READt27_FAST (1<<8) /* VME master parameter t27: (latch data faster than 25ns) */
+# define UNIV_U2SPEC_READt27_NODELAY (2<<8) /* VME master parameter t27: (latch data without any delay) */
+# define UNIV_U2SPEC_POSt28_FAST (1<<2) /* VME slave parameter t28: (faster time of DS to DTAck for posted write) */
+# define UNIV_U2SPEC_PREt28_FAST (1<<0) /* VME slave parameter t28: (faster time of DS to DTAck for prefetch read) */
+
/* Location Monitor control register */
#define UNIV_REGOFF_LM_CTL 0xf64
# define UNIV_LM_CTL_EN (1<<31) /* image enable */
@@ -489,15 +510,21 @@ vmeUniverseMasterPortCfg(
/* translate an address through the bridge
*
- * vmeUniverseLocalToBusAdrs() yields a VME a address that reflects
+ * vmeUniverseXlateAddr(0,0,addr,as,&result)
+ * yields a VME a address that reflects
* a local memory location as seen from the VME bus through the universe
* VME slave.
*
- * likewise does vmeUniverseBusToLocalAdrs() translate a VME bus addr
- * (through the VME master) to the PCI side of the bridge.
+ * likewise does vmeUniverseXlateAddr(1,0,addr,as,&result)
+ * translate a VME bus addr (through the VME master) to the
+ * PCI side of the bridge.
*
* a valid address space modifier must be specified.
*
+ * The 'reverse' parameter may be used to find a reverse
+ * mapping, i.e. the pci address in a master window can be
+ * found if the respective vme address is known etc.
+ *
* RETURNS: translated address in *pbusAdrs / *plocalAdrs
*
* 0: success
@@ -505,11 +532,13 @@ vmeUniverseMasterPortCfg(
* -2: invalid modifier
*/
int
-vmeUniverseLocalToBusAdrs(unsigned long am, unsigned long localAdrs, unsigned long *pbusAdrs);
-
-int
-vmeUniverseBusToLocalAdrs(unsigned long am, unsigned long busAdrs, unsigned long *plocalAdrs);
-
+vmeUniverseXlateAddr(
+ int master, /* look in the master windows */
+ int reverse, /* reverse mapping; for masters: map local to VME */
+ unsigned long as, /* address space */
+ unsigned long addr, /* address to look up */
+ unsigned long *paOut/* where to put result */
+ );
/* configure a VME slave (PCI master) port */
int
@@ -556,7 +585,7 @@ vmeUniverseResetBus(void)
UNIV_REGOFF_MISC_CTL);
}
-#ifdef __rtems
+#ifdef __rtems__
/* VME Interrupt Handler functionality */
/* we dont use the current RTEMS/BSP interrupt API for the
@@ -608,15 +637,38 @@ int
vmeUniverseIntDisable(unsigned int level);
-/* use this special vector to connect a handler to the
+/* use these special vectors to connect a handler to the
* universe specific interrupts (such as "DMA done",
* VOWN, error irqs etc.)
* NOTE: The wrapper clears all status LINT bits (except
* for regular VME irqs). Also note that it is the user's
* responsibility to enable the necessary interrupts in
* LINT_EN
+ *
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * DO NOT CHANGE THE ORDER OF THESE VECTORS - THE DRIVER
+ * DEPENDS ON IT
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ *
*/
-#define UNIV_SPECIAL_IRQ_VECTOR 256
+#define UNIV_VOWN_INT_VEC 256
+#define UNIV_DMA_INT_VEC 257
+#define UNIV_LERR_INT_VEC 258
+#define UNIV_VERR_INT_VEC 259
+#define UNIV_VME_SW_IACK_INT_VEC 260
+#define UNIV_PCI_SW_INT_VEC 261
+#define UNIV_SYSFAIL_INT_VEC 262
+#define UNIV_ACFAIL_INT_VEC 263
+#define UNIV_MBOX0_INT_VEC 264
+#define UNIV_MBOX1_INT_VEC 265
+#define UNIV_MBOX2_INT_VEC 266
+#define UNIV_MBOX3_INT_VEC 267
+#define UNIV_LM0_INT_VEC 268
+#define UNIV_LM1_INT_VEC 269
+#define UNIV_LM2_INT_VEC 270
+#define UNIV_LM3_INT_VEC 271
+
+#define UNIV_NUM_INT_VECS 272
/* the universe interrupt handler is capable of routing all sorts of
* (VME) interrupts to 8 different lines (some of) which may be hooked up
@@ -634,13 +686,18 @@ vmeUniverseIntDisable(unsigned int level);
*
* Hence the manager sets up routing VME interrupts to 1 or 2 universe
* OUTPUTS. However, it must also be told to which PIC INPUTS they
- * are wired. The first PIC input line is read from PCI config space
- * but the second must be passed to this routine.
+ * are wired.
+ * Optionally, the first PIC input line can be read from PCI config space
+ * but the second must be passed to this routine. Note that the info read
+ * from PCI config space is wrong for many boards!
*
* PARAMETERS:
- * vmeIRQunivOut: to which output pin (of the universe) should the 7
+ * vmeIrqUnivOut: to which output pin (of the universe) should the 7
* VME irq levels be routed.
- * specialIRQunivOut: to which output pin (of the universe) should the
+ * vmeIrqPicLine: specifies to which PIC input the 'main' output is
+ * wired. If passed a value < 0, the driver reads this
+ * information from PCI config space ("IRQ line").
+ * specialIrqUnivOut: to which output pin (of the universe) should the
* internally irqs be routed. Use 'vmeIRQunivOut'
* if < 0.
* specialIrqPicLine: specifies to which PIC input the 'special' output
@@ -651,7 +708,10 @@ vmeUniverseIntDisable(unsigned int level);
*
*/
int
-vmeUniverseInstallIrqMgr(int vmeIrqUnivOut, int specialIrqUnivOut, int specialIrqPicLine);
+vmeUniverseInstallIrqMgr(int vmeIrqUnivOut,
+ int vmeIrqPicLine,
+ int specialIrqUnivOut,
+ int specialIrqPicLine);
#endif