From 20b349f15f4a52b87f86524f27a55db627f87cba Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 20 Feb 2003 21:35:57 +0000 Subject: 2003-02-20 Till Straumann 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. --- c/src/lib/libbsp/shared/ChangeLog | 7 + c/src/lib/libbsp/shared/vmeUniverse/README.porting | 88 ++++++++ c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.c | 231 +++++++++++++++------ c/src/lib/libbsp/shared/vmeUniverse/vmeUniverse.h | 92 ++++++-- 4 files changed, 340 insertions(+), 78 deletions(-) create mode 100644 c/src/lib/libbsp/shared/vmeUniverse/README.porting (limited to 'c/src') 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 + + 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 * 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 @@ -137,16 +180,23 @@ /* we rely on a vxWorks definition here */ #define VX_AM_SUP 4 -#ifdef __rtems +#ifdef __rtems__ #include #include /* printk */ #include #include -#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 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 #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 -- cgit v1.2.3