Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /**
0002  *  @file
0003  *
0004  *  @ingroup shared_vmeuniverse
0005  *
0006  *  @brief Driver for the Tundra Universe II pci-vme bridge
0007  */
0008 
0009 #ifndef VME_UNIVERSE_UTIL_H
0010 #define VME_UNIVERSE_UTIL_H
0011 
0012 /*
0013  * Authorship
0014  * ----------
0015  * This software was created by
0016  *     Till Straumann <strauman@slac.stanford.edu>, 2000-2007,
0017  *     Stanford Linear Accelerator Center, Stanford University.
0018  *
0019  * Acknowledgement of sponsorship
0020  * ------------------------------
0021  * This software was produced by
0022  *     the Stanford Linear Accelerator Center, Stanford University,
0023  *     under Contract DE-AC03-76SFO0515 with the Department of Energy.
0024  *
0025  * Government disclaimer of liability
0026  * ----------------------------------
0027  * Neither the United States nor the United States Department of Energy,
0028  * nor any of their employees, makes any warranty, express or implied, or
0029  * assumes any legal liability or responsibility for the accuracy,
0030  * completeness, or usefulness of any data, apparatus, product, or process
0031  * disclosed, or represents that its use would not infringe privately owned
0032  * rights.
0033  *
0034  * Stanford disclaimer of liability
0035  * --------------------------------
0036  * Stanford University makes no representations or warranties, express or
0037  * implied, nor assumes any liability for the use of this software.
0038  *
0039  * Stanford disclaimer of copyright
0040  * --------------------------------
0041  * Stanford University, owner of the copyright, hereby disclaims its
0042  * copyright and all other rights in this software.  Hence, anyone may
0043  * freely use it for any purpose without restriction.
0044  *
0045  * Maintenance of notices
0046  * ----------------------
0047  * In the interest of clarity regarding the origin and status of this
0048  * SLAC software, this and all the preceding Stanford University notices
0049  * are to remain affixed to any copy or derivative of this software made
0050  * or distributed by the recipient and are to be affixed to any copy of
0051  * software made or distributed by the recipient that contains a copy or
0052  * derivative of this software.
0053  *
0054  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
0055  */
0056 
0057 /**
0058  *  @defgroup shared_vmeuniverse_reg Register definitions
0059  *
0060  *  @ingroup shared_vmeuniverse
0061  *
0062  *  @brief all registers contents in PCI space are LITTLE ENDIAN
0063  */
0064 
0065 #ifdef __vxworks
0066 #include <vme.h>
0067 #else
0068 
0069 #include <bsp/vme_am_defs.h>
0070 
0071 #endif
0072 
0073 /* These bits can be or'ed with the address-modifier when calling
0074  * the 'XlateAddr' routine below to further qualify the
0075  * search criteria.
0076  */
0077 #define VME_MODE_MATCH_MASK                 (3<<30)
0078 #define VME_MODE_EXACT_MATCH                (2<<30) /* all bits must match */
0079 #define VME_MODE_AS_MATCH                   (1<<30) /* only A16/24/32 must match */
0080 
0081 
0082 typedef unsigned long LERegister; /* emphasize contents are little endian */
0083 
0084 /****** NOTE: USE OF VmeUniverseDMAPacket IS DEPRECATED *********
0085  ******       USE API IN VMEDMA.h INSTEAD               *********/
0086 
0087 /* NOTE: DMA packet descriptors MUST be 32 byte aligned */
0088 typedef struct VmeUniverseDMAPacketRec_ {
0089     LERegister  dctl    __attribute__((aligned(32)));
0090     LERegister  dtbc    __attribute__((packed));
0091     LERegister  dla     __attribute__((packed));
0092     LERegister  dummy1  __attribute__((packed));
0093     LERegister  dva     __attribute__((packed));
0094     LERegister  dummy2  __attribute__((packed));
0095     LERegister  dcpp    __attribute__((packed));
0096     LERegister  dummy3  __attribute__((packed));
0097 } VmeUniverseDMAPacketRec, *VmeUniverseDMAPacket; /* DEPRECATED */
0098 
0099 /* PCI CSR register */
0100 #define     UNIV_REGOFF_PCI_CSR     0x4
0101 # define    UNIV_PCI_CSR_D_PE       (1<<31) /* detected parity error; write 1 to clear */
0102 # define    UNIV_PCI_CSR_S_SERR     (1<<30) /* SERR (signalled error) asserted; write 1 to clear */
0103 # define    UNIV_PCI_CSR_R_MA       (1<<29) /* received master abort; write 1 to clear */
0104 # define    UNIV_PCI_CSR_R_TA       (1<<28) /* received target abort; write 1 to clear */
0105 # define    UNIV_PCI_CSR_S_TA       (1<<27) /* signalled target abort; write 1 to clear */
0106 # define    UNIV_PCI_CSR_DEVSEL_MASK (3<<25)    /* device select timing (RO) */
0107 # define    UNIV_PCI_CSR_DP_D       (1<<24) /* data parity error detected; write 1 to clear */
0108 # define    UNIV_PCI_CSR_TFBBC      (1<<23) /* target fast back to back capable (RO) */
0109 # define    UNIV_PCI_CSR_MFBBC      (1<<9)  /* master fast back to back capable (RO) */
0110 # define    UNIV_PCI_CSR_SERR_EN    (1<<8)  /* enable SERR driver */
0111 # define    UNIV_PCI_CSR_WAIT       (1<<7)  /* wait cycle control (RO) */
0112 # define    UNIV_PCI_CSR_PERESP     (1<<6)  /* parity error response enable */
0113 # define    UNIV_PCI_CSR_VGAPS      (1<<5)  /* VGA palette snoop (RO) */
0114 # define    UNIV_PCI_CSR_MWI_EN     (1<<4)  /* Memory write and invalidate enable (RO) */
0115 # define    UNIV_PCI_CSR_SC         (1<<3)  /* special cycles (RO) */
0116 # define    UNIV_PCI_CSR_BM         (1<<2)  /* master enable (MUST SET TO ENABLE VME SLAVES) */
0117 # define    UNIV_PCI_CSR_MS         (1<<1)  /* target memory enable */
0118 # define    UNIV_PCI_CSR_IOS        (1<<0)  /* target IO enable */
0119 
0120 /* Special cycle (ADOH, RMW) control register */
0121 #define     UNIV_REGOFF_SCYC_CTL    0x170   /* write 0 to disable */
0122 # define    UNIV_SCYC_CTL_LAS_IO    (1<<2)  /* PCI address space (1: IO, 0: mem) */
0123 # define    UNIV_SCYC_CTL_SCYC_RMW  (1<<0)  /* do a RMW cycle when reading  PCI address */
0124 # define    UNIV_SCYC_CTL_SCYC_ADOH (2<<0)  /* do a ADOH cycle when reading/writing  PCI address */
0125 
0126 /* Special cycle address register */
0127 #define     UNIV_REGOFF_SCYC_ADDR   0x174   /* PCI address (must be long word aligned) */
0128 
0129 /* Special cycle Swap/Compare/Enable */
0130 #define     UNIV_REGOFF_SCYC_EN 0x178   /* mask determining the bits involved in the compare and swap operations for VME RMW cycles */
0131 
0132 /* Special cycle compare data register */
0133 #define     UNIV_REGOFF_SCYC_CMP    0x17c   /* data to compare with word returned from VME RMW read */
0134 
0135 /* Special cycle swap data register */
0136 #define     UNIV_REGOFF_SCYC_SWP    0x180   /* If enabled bits of CMP match, corresponding SWP bits are written back to VME (under control of EN) */
0137 
0138 /* PCI miscellaneous register */
0139 #define     UNIV_REGOFF_LMISC   0x184
0140 # define    UNIV_LMISC_CRT_MASK (7<<28) /* Univ. I only, not used on II */
0141 # define    UNIV_LMISC_CRT_INF  (0<<28) /* Coupled Request Timeout */
0142 # define    UNIV_LMISC_CRT_128_US   (1<<28) /* Coupled Request Timeout */
0143 # define    UNIV_LMISC_CRT_256_US   (2<<28) /* Coupled Request Timeout */
0144 # define    UNIV_LMISC_CRT_512_US   (3<<28) /* Coupled Request Timeout */
0145 # define    UNIV_LMISC_CRT_1024_US  (4<<28) /* Coupled Request Timeout */
0146 # define    UNIV_LMISC_CRT_2048_US  (5<<28) /* Coupled Request Timeout */
0147 # define    UNIV_LMISC_CRT_4096_US  (6<<28) /* Coupled Request Timeout */
0148 
0149 # define    UNIV_LMISC_CWT_MASK (7<<24) /* coupled window timer */
0150 # define    UNIV_LMISC_CWT_DISABLE  0   /* disabled (release VME after 1 coupled xaction) */
0151 # define    UNIV_LMISC_CWT_16   (1<<24) /* 16 PCI clock cycles */
0152 # define    UNIV_LMISC_CWT_32   (2<<24) /* 32 PCI clock cycles */
0153 # define    UNIV_LMISC_CWT_64   (3<<24) /* 64 PCI clock cycles */
0154 # define    UNIV_LMISC_CWT_128  (4<<24) /* 128 PCI clock cycles */
0155 # define    UNIV_LMISC_CWT_256  (5<<24) /* 256 PCI clock cycles */
0156 # define    UNIV_LMISC_CWT_512  (6<<24) /* 512 PCI clock cycles */
0157 
0158 /* PCI Command Error Log Register */
0159 #define     UNIV_REGOFF_L_CMDERR    0x18c
0160 # define    UNIV_L_CMDERR_CMDERR(reg) (((reg)>>28)&0xf) /* extract PCI cmd error log */
0161 # define    UNIV_L_CMDERR_M_ERR (1<<27) /* multiple errors have occurred */
0162 # define    UNIV_L_CMDERR_L_STAT    (1<<23) /* PCI error log status valid (write 1 to clear and enable logging) */
0163 
0164 /* PCI Address Error Log */
0165 #define     UNIV_REGOFF_LAERR   0x190   /* PCI fault address (if L_CMDERR_L_STAT valid) */
0166 /* DMA Xfer Control Register */
0167 #define     UNIV_REGOFF_DCTL    0x200
0168 # define    UNIV_DCTL_L2V       (1<<31) /* PCI->VME if set */
0169 # define    UNIV_DCTL_VDW_MSK   (3<<22) /* VME max. width mask 0x00c00000 */
0170 # define    UNIV_DCTL_VDW_8     (0<<22) /* VME max. width 8 */
0171 # define    UNIV_DCTL_VDW_16    (1<<22) /* VME max. width 16 */
0172 # define    UNIV_DCTL_VDW_32    (2<<22) /* VME max. width 32 */
0173 # define    UNIV_DCTL_VDW_64    (3<<22) /* VME max. width 64 */
0174 # define    UNIV_DCTL_VAS_MSK   (7<<16) /* VME AS mask 0x00070000 */
0175 # define    UNIV_DCTL_VAS_A16   (0<<16) /* VME A16 */
0176 # define    UNIV_DCTL_VAS_A24   (1<<16) /* VME A24 */
0177 # define    UNIV_DCTL_VAS_A32   (2<<16) /* VME A32 */
0178 # define    UNIV_DCTL_PGM_MSK   (3<<14) /* VME PGM/DATA mask 0x0000c000 */
0179 # define    UNIV_DCTL_PGM       (1<<14) /* VME PGM(1)/DATA(0) */
0180 # define    UNIV_DCTL_SUPER_MSK (3<<12) /* VME SUPER/USR mask 0x00003000 */
0181 # define    UNIV_DCTL_SUPER     (1<<12) /* VME SUPER(1)/USR(0) */
0182 # define    UNIV_DCTL_NO_VINC   (1<<9)  /* VME no VME address increment [Universe IIa/b ONLY */
0183 # define    UNIV_DCTL_VCT       (1<<8)  /* VME enable BLT */
0184 # define    UNIV_DCTL_LD64EN    (1<<7)  /* PCI 64 enable  */
0185 
0186 /* DMA Xfer byte count register (is updated by DMA) */
0187 #define     UNIV_REGOFF_DTBC    0x204
0188 /* DMA Xfer local (PCI) address (direction is  set in DCTL) */
0189 #define     UNIV_REGOFF_DLA     0x208
0190 /* DMA Xfer VME address (direction is  set in DCTL)
0191  * NOTE: (*UNIV_DVA) & ~7 == (*UNIV_DLA) & ~7 MUST HOLD
0192  */
0193 #define     UNIV_REGOFF_DVA     0x210
0194 
0195 /* DMA Xfer VME command packet pointer
0196  * NOTE: The address stored here MUST be 32-byte aligned
0197  */
0198 #define     UNIV_REGOFF_DCPP    0x218
0199 /* these bits are only used in linked lists */
0200 # define    UNIV_DCPP_IMG_NULL  (1<<0)  /* last packet in list */
0201 # define    UNIV_DCPP_IMG_PROCESSED (1<<1)  /* packet processed */
0202 
0203 /* DMA Xfer General Control/Status register */
0204 #define     UNIV_REGOFF_DGCS    0x220
0205 # define    UNIV_DGCS_GO        (1<<31) /* start xfer */
0206 # define    UNIV_DGCS_STOP_REQ  (1<<30) /* stop xfer (immediate abort) */
0207 # define    UNIV_DGCS_HALT_REQ  (1<<29) /* halt xfer (abort after current packet) */
0208 # define    UNIV_DGCS_CHAIN     (1<<27) /* enable linked list mode */
0209 # define    UNIV_DGCS_VON_MSK   (7<<20) /* VON mask */
0210 # define    UNIV_DGCS_VON_DONE  (0<<20) /* VON counter disabled (do until done) */
0211 # define    UNIV_DGCS_VON_256   (1<<20) /* VON yield bus after 256 bytes */
0212 # define    UNIV_DGCS_VON_512   (2<<20) /* VON yield bus after 512 bytes */
0213 # define    UNIV_DGCS_VON_1024  (3<<20) /* VON yield bus after 1024 bytes */
0214 # define    UNIV_DGCS_VON_2048  (4<<20) /* VON yield bus after 2048 bytes */
0215 # define    UNIV_DGCS_VON_4096  (5<<20) /* VON yield bus after 4096 bytes */
0216 # define    UNIV_DGCS_VON_8192  (6<<20) /* VON yield bus after 8192 bytes */
0217 # define    UNIV_DGCS_VON_16384 (7<<20) /* VON yield bus after 16384 bytes */
0218 # define    UNIV_DGCS_VOFF_MSK  (15<<16) /* VOFF mask */
0219 # define    UNIV_DGCS_VOFF_0_US (0<<16) /* re-request VME master after 0 us */
0220 # define    UNIV_DGCS_VOFF_2_US (8<<16) /* re-request VME master after 2 us */
0221 # define    UNIV_DGCS_VOFF_4_US (9<<16) /* re-request VME master after 4 us */
0222 # define    UNIV_DGCS_VOFF_8_US (10<<16)/* re-request VME master after 8 us */
0223 # define    UNIV_DGCS_VOFF_16_US    (1<<16) /* re-request VME master after 16 us */
0224 # define    UNIV_DGCS_VOFF_32_US    (2<<16) /* re-request VME master after 32 us */
0225 # define    UNIV_DGCS_VOFF_64_US    (3<<16) /* re-request VME master after 64 us */
0226 # define    UNIV_DGCS_VOFF_128_US   (4<<16) /* re-request VME master after 128 us */
0227 # define    UNIV_DGCS_VOFF_256_US   (5<<16) /* re-request VME master after 256 us */
0228 # define    UNIV_DGCS_VOFF_512_US   (6<<16) /* re-request VME master after 512 us */
0229 # define    UNIV_DGCS_VOFF_1024_US  (7<<16) /* re-request VME master after 1024 us */
0230 /* Status Bits (write 1 to clear) */
0231 # define    UNIV_DGCS_ACT       (1<<15) /* DMA active */
0232 # define    UNIV_DGCS_STOP      (1<<14) /* DMA stopped */
0233 # define    UNIV_DGCS_HALT      (1<<13) /* DMA halted */
0234 # define    UNIV_DGCS_DONE      (1<<11) /* DMA done (OK) */
0235 # define    UNIV_DGCS_LERR      (1<<10) /* PCI bus error */
0236 # define    UNIV_DGCS_VERR      (1<<9)  /* VME bus error */
0237 # define    UNIV_DGCS_P_ERR     (1<<8)  /* programming protocol error (e.g. PCI master disabled) */
0238 # define    UNIV_DGCS_STATUS_CLEAR\
0239     (UNIV_DGCS_ACT|UNIV_DGCS_STOP|UNIV_DGCS_HALT|\
0240      UNIV_DGCS_DONE|UNIV_DGCS_LERR|UNIV_DGCS_VERR|UNIV_DGCS_P_ERR)
0241 # define    UNIV_DGCS_P_ERR     (1<<8)  /* programming protocol error (e.g. PCI master disabled) */
0242 /* Interrupt Mask Bits */
0243 # define    UNIV_DGCS_INT_STOP  (1<<6)  /* interrupt when stopped */
0244 # define    UNIV_DGCS_INT_HALT  (1<<5)  /* interrupt when halted */
0245 # define    UNIV_DGCS_INT_DONE  (1<<3)  /* interrupt when done */
0246 # define    UNIV_DGCS_INT_LERR  (1<<2)  /* interrupt on LERR */
0247 # define    UNIV_DGCS_INT_VERR  (1<<1)  /* interrupt on VERR */
0248 # define    UNIV_DGCS_INT_P_ERR (1<<0)  /* interrupt on P_ERR */
0249 # define    UNIV_DGCS_INT_MSK   (0x0000006f) /* interrupt mask */
0250 
0251 /* DMA Linked List Update Enable Register */
0252 #define     UNIV_REGOFF_D_LLUE  0x224
0253 # define    UNIV_D_LLUE_UPDATE  (1<<31)
0254 
0255 
0256 /* PCI (local) interrupt enable register */
0257 #define     UNIV_REGOFF_LINT_EN 0x300
0258 # define    UNIV_LINT_EN_LM3    (1<<23) /* location monitor 3 mask */
0259 # define    UNIV_LINT_EN_LM2    (1<<22) /* location monitor 2 mask */
0260 # define    UNIV_LINT_EN_LM1    (1<<21) /* location monitor 1 mask */
0261 # define    UNIV_LINT_EN_LM0    (1<<20) /* location monitor 0 mask */
0262 # define    UNIV_LINT_EN_MBOX3  (1<<19) /* mailbox 3 mask */
0263 # define    UNIV_LINT_EN_MBOX2  (1<<18) /* mailbox 2 mask */
0264 # define    UNIV_LINT_EN_MBOX1  (1<<17) /* mailbox 1 mask */
0265 # define    UNIV_LINT_EN_MBOX0  (1<<16) /* mailbox 0 mask */
0266 # define    UNIV_LINT_EN_ACFAIL (1<<15) /* ACFAIL irq mask */
0267 # define    UNIV_LINT_EN_SYSFAIL    (1<<14) /* SYSFAIL irq mask */
0268 # define    UNIV_LINT_EN_SW_INT (1<<13) /* PCI (local) software irq */
0269 # define    UNIV_LINT_EN_SW_IACK    (1<<12) /* VME software IACK mask */
0270 # define    UNIV_LINT_EN_VERR   (1<<10) /* PCI VERR irq mask */
0271 # define    UNIV_LINT_EN_LERR   (1<<9)  /* PCI LERR irq mask */
0272 # define    UNIV_LINT_EN_DMA    (1<<8)  /* PCI DMA irq mask */
0273 # define    UNIV_LINT_EN_VIRQ7  (1<<7)  /* VIRQ7 mask (universe does IACK automatically) */
0274 # define    UNIV_LINT_EN_VIRQ6  (1<<6)  /* VIRQ6 mask */
0275 # define    UNIV_LINT_EN_VIRQ5  (1<<5)  /* VIRQ5 mask */
0276 # define    UNIV_LINT_EN_VIRQ4  (1<<4)  /* VIRQ4 mask */
0277 # define    UNIV_LINT_EN_VIRQ3  (1<<3)  /* VIRQ3 mask */
0278 # define    UNIV_LINT_EN_VIRQ2  (1<<2)  /* VIRQ2 mask */
0279 # define    UNIV_LINT_EN_VIRQ1  (1<<1)  /* VIRQ1 mask */
0280 # define    UNIV_LINT_EN_VOWN   (1<<0)  /* VOWN mask */
0281 
0282 /* PCI (local) interrupt status register */
0283 #define     UNIV_REGOFF_LINT_STAT   0x304
0284 # define    UNIV_LINT_STAT_LM3  (1<<23) /* location monitor 3 status */
0285 # define    UNIV_LINT_STAT_LM2  (1<<22) /* location monitor 2 status */
0286 # define    UNIV_LINT_STAT_LM1  (1<<21) /* location monitor 1 status */
0287 # define    UNIV_LINT_STAT_LM0  (1<<20) /* location monitor 0 status */
0288 # define    UNIV_LINT_STAT_MBOX3    (1<<19) /* mailbox 3 status */
0289 # define    UNIV_LINT_STAT_MBOX2    (1<<18) /* mailbox 2 status */
0290 # define    UNIV_LINT_STAT_MBOX1    (1<<17) /* mailbox 1 status */
0291 # define    UNIV_LINT_STAT_MBOX0    (1<<16) /* mailbox 0 status */
0292 # define    UNIV_LINT_STAT_ACFAIL   (1<<15) /* ACFAIL irq status */
0293 # define    UNIV_LINT_STAT_SYSFAIL  (1<<14) /* SYSFAIL irq status */
0294 # define    UNIV_LINT_STAT_SW_INT   (1<<13) /* PCI (local) software irq */
0295 # define    UNIV_LINT_STAT_SW_IACK  (1<<12) /* VME software IACK status */
0296 # define    UNIV_LINT_STAT_VERR     (1<<10) /* PCI VERR irq status */
0297 # define    UNIV_LINT_STAT_LERR     (1<<9)  /* PCI LERR irq status */
0298 # define    UNIV_LINT_STAT_DMA      (1<<8)  /* PCI DMA irq status */
0299 # define    UNIV_LINT_STAT_VIRQ7    (1<<7)  /* VIRQ7 status */
0300 # define    UNIV_LINT_STAT_VIRQ6    (1<<6)  /* VIRQ6 status */
0301 # define    UNIV_LINT_STAT_VIRQ5    (1<<5)  /* VIRQ5 status */
0302 # define    UNIV_LINT_STAT_VIRQ4    (1<<4)  /* VIRQ4 status */
0303 # define    UNIV_LINT_STAT_VIRQ3    (1<<3)  /* VIRQ3 status */
0304 # define    UNIV_LINT_STAT_VIRQ2    (1<<2)  /* VIRQ2 status */
0305 # define    UNIV_LINT_STAT_VIRQ1    (1<<1)  /* VIRQ1 status */
0306 # define    UNIV_LINT_STAT_VOWN     (1<<0)  /* VOWN status */
0307 # define    UNIV_LINT_STAT_CLR      (0xfff7ff)/* Clear all status bits */
0308 
0309 /* PCI (local) interrupt map 0 register */
0310 #define     UNIV_REGOFF_LINT_MAP0   0x308   /* mapping of VME IRQ sources to PCI irqs */
0311 # define    UNIV_LINT_MAP0_VIRQ7(lint)  (((lint)&0x7)<<(7*4))
0312 # define    UNIV_LINT_MAP0_VIRQ6(lint)  (((lint)&0x7)<<(6*4))
0313 # define    UNIV_LINT_MAP0_VIRQ5(lint)  (((lint)&0x7)<<(5*4))
0314 # define    UNIV_LINT_MAP0_VIRQ4(lint)  (((lint)&0x7)<<(4*4))
0315 # define    UNIV_LINT_MAP0_VIRQ3(lint)  (((lint)&0x7)<<(3*4))
0316 # define    UNIV_LINT_MAP0_VIRQ2(lint)  (((lint)&0x7)<<(2*4))
0317 # define    UNIV_LINT_MAP0_VIRQ1(lint)  (((lint)&0x7)<<(1*4))
0318 # define    UNIV_LINT_MAP0_VOWN(lint)   (((lint)&0x7)<<(0*4))
0319 
0320 #define     UNIV_REGOFF_LINT_MAP1   0x30c   /* mapping of internal / VME IRQ sources to PCI irqs */
0321 # define    UNIV_LINT_MAP1_ACFAIL(lint) (((lint)&0x7)<<(7*4))
0322 # define    UNIV_LINT_MAP1_SYSFAIL(lint)    (((lint)&0x7)<<(6*4))
0323 # define    UNIV_LINT_MAP1_SW_INT(lint) (((lint)&0x7)<<(5*4))
0324 # define    UNIV_LINT_MAP1_SW_IACK(lint)    (((lint)&0x7)<<(4*4))
0325 # define    UNIV_LINT_MAP1_VERR(lint)   (((lint)&0x7)<<(2*4))
0326 # define    UNIV_LINT_MAP1_LERR(lint)   (((lint)&0x7)<<(1*4))
0327 # define    UNIV_LINT_MAP1_DMA(lint)    (((lint)&0x7)<<(0*4))
0328 
0329 /* enabling of generation of VME bus IRQs, TODO */
0330 #define     UNIV_REGOFF_VINT_EN     0x310
0331 # define    UNIV_VINT_EN_DISABLE_ALL    0
0332 # define    UNIV_VINT_EN_SWINT          (1<<12)
0333 # define    UNIV_VINT_EN_SWINT_LVL(l)   (1<<(((l)&7)+24))   /* universe II only */
0334 
0335 
0336 /* status of generation of VME bus IRQs */
0337 #define     UNIV_REGOFF_VINT_STAT   0x314
0338 # define    UNIV_VINT_STAT_LINT(lint)   (1<<((lint)&7))
0339 # define    UNIV_VINT_STAT_LINT_MASK    (0xff)
0340 # define    UNIV_VINT_STAT_CLR          (0xfe0f17ff)
0341 # define    UNIV_VINT_STAT_SWINT(l)     (1<<(((l)&7)+24))
0342 
0343 #define     UNIV_REGOFF_VINT_MAP0   0x318   /* VME destination of PCI IRQ source, TODO */
0344 
0345 #define     UNIV_REGOFF_VINT_MAP1   0x31c   /* VME destination of PCI IRQ source, TODO */
0346 # define    UNIV_VINT_MAP1_SWINT(level) (((level)&0x7)<<16)
0347 
0348 /* NOTE: The universe seems to always set LSB (which has a special purpose in
0349  *       the STATID register: enable raising a SW_INT on IACK) on the
0350  *       vector it puts out on the bus...
0351  */
0352 #define     UNIV_REGOFF_VINT_STATID 0x320   /* our status/id response to IACK, TODO */
0353 # define    UNIV_VINT_STATID(id)        ((id)<<24)
0354 
0355 #define     UNIV_REGOFF_VIRQ1_STATID 0x324  /* status/id of VME IRQ level 1 */
0356 #define     UNIV_REGOFF_VIRQ2_STATID 0x328  /* status/id of VME IRQ level 2 */
0357 #define     UNIV_REGOFF_VIRQ3_STATID 0x32c  /* status/id of VME IRQ level 3 */
0358 #define     UNIV_REGOFF_VIRQ4_STATID 0x330  /* status/id of VME IRQ level 4 */
0359 #define     UNIV_REGOFF_VIRQ5_STATID 0x334  /* status/id of VME IRQ level 5 */
0360 #define     UNIV_REGOFF_VIRQ6_STATID 0x338  /* status/id of VME IRQ level 6 */
0361 #define     UNIV_REGOFF_VIRQ7_STATID 0x33c  /* status/id of VME IRQ level 7 */
0362 # define    UNIV_VIRQ_ERR           (1<<8)  /* set if universe encountered a bus error when doing IACK */
0363 # define    UNIV_VIRQ_STATID_MASK       (0xff)
0364 
0365 #define     UNIV_REGOFF_LINT_MAP2   0x340   /* mapping of internal sources to PCI irqs */
0366 # define    UNIV_LINT_MAP2_LM3(lint)    (((lint)&0x7)<<7*4) /* location monitor 3 */
0367 # define    UNIV_LINT_MAP2_LM2(lint)    (((lint)&0x7)<<6*4) /* location monitor 2 */
0368 # define    UNIV_LINT_MAP2_LM1(lint)    (((lint)&0x7)<<5*4) /* location monitor 1 */
0369 # define    UNIV_LINT_MAP2_LM0(lint)    (((lint)&0x7)<<4*4) /* location monitor 0 */
0370 # define    UNIV_LINT_MAP2_MBOX3(lint)  (((lint)&0x7)<<3*4) /* mailbox 3 */
0371 # define    UNIV_LINT_MAP2_MBOX2(lint)  (((lint)&0x7)<<2*4) /* mailbox 2 */
0372 # define    UNIV_LINT_MAP2_MBOX1(lint)  (((lint)&0x7)<<1*4) /* mailbox 1 */
0373 # define    UNIV_LINT_MAP2_MBOX0(lint)  (((lint)&0x7)<<0*4) /* mailbox 0 */
0374 
0375 #define     UNIV_REGOFF_VINT_MAP2   0x344   /* mapping of internal sources to VME irqs */
0376 # define    UNIV_VINT_MAP2_MBOX3(vint)  (((vint)&0x7)<<3*4) /* mailbox 3 */
0377 # define    UNIV_VINT_MAP2_MBOX2(vint)  (((vint)&0x7)<<2*4) /* mailbox 2 */
0378 # define    UNIV_VINT_MAP2_MBOX1(vint)  (((vint)&0x7)<<1*4) /* mailbox 1 */
0379 # define    UNIV_VINT_MAP2_MBOX0(vint)  (((vint)&0x7)<<0*4) /* mailbox 0 */
0380 
0381 #define     UNIV_REGOFF_MBOX0   0x348   /* mailbox 0 */
0382 #define     UNIV_REGOFF_MBOX1   0x34c   /* mailbox 1 */
0383 #define     UNIV_REGOFF_MBOX2   0x350   /* mailbox 2 */
0384 #define     UNIV_REGOFF_MBOX3   0x354   /* mailbox 3 */
0385 
0386 #define     UNIV_REGOFF_SEMA0   0x358   /* semaphore 0 */
0387 #define     UNIV_REGOFF_SEMA1   0x35c   /* semaphore 0 */
0388 /* TODO define semaphore register bits */
0389 
0390 #define     UNIV_REGOFF_MAST_CTL    0x400   /* master control register */
0391 # define    UNIV_MAST_CTL_MAXRTRY(val)  (((val)&0xf)<<7*4)  /* max # of pci master retries */
0392 # define    UNIV_MAST_CTL_PWON(val)     (((val)&0xf)<<6*4)  /* posted write xfer count */
0393 # define    UNIV_MAST_CTL_VRL(val)      (((val)&0x3)<<22)   /* VME bus request level */
0394 # define    UNIV_MAST_CTL_VRM           (1<<21) /* bus request mode (demand = 0, fair = 1) */
0395 # define    UNIV_MAST_CTL_VREL          (1<<20) /* bus release mode (when done = 0, on request = 1) */
0396 # define    UNIV_MAST_CTL_VOWN          (1<<19) /* bus ownership (release = 0, acquire/hold = 1) */
0397 # define    UNIV_MAST_CTL_VOWN_ACK      (1<<18) /* bus ownership (not owned = 0, acquired/held = 1) */
0398 # define    UNIV_MAST_CTL_PABS(val)     (((val)&0x3)<<3*4)  /* PCI aligned burst size (32,64,128 byte / 0x3 is reserved) */
0399 # define    UNIV_MAST_CTL_BUS_NO(val)   (((val)&0xff)<<0*4) /* PCI bus number */
0400 
0401 #define     UNIV_REGOFF_MISC_CTL    0x404   /* misc control register */
0402 # define    UNIV_MISC_CTL_VBTO(val)     (((val)&0x7)<<7*4)  /* VME bus timeout (0=disable, 16*2^(val-1) us) */
0403 # define    UNIV_MISC_CTL_VARB          (1<<26) /* VME bus arbitration mode (0=round robin, 1= priority) */
0404 # define    UNIV_MISC_CTL_VARBTO(val)   (((val)&0x3)<<6*4)  /* arbitration time out: disable, 16us, 256us, reserved */
0405 # define    UNIV_MISC_CTL_SW_LRST       (1<<23) /* software PCI reset */
0406 # define    UNIV_MISC_CTL_SW_SYSRST     (1<<22) /* software VME reset */
0407 # define    UNIV_MISC_CTL_BI            (1<<20) /* BI mode */
0408 # define    UNIV_MISC_CTL_ENGBI         (1<<19) /* enable global BI mode initiator */
0409 # define    UNIV_MISC_CTL_SYSCON        (1<<17) /* (R/W) 1:universe is system controller */
0410 # define    UNIV_MISC_CTL_V64AUTO       (1<<16) /* (R/W) 1:initiate VME64 auto id slave participation */
0411 
0412 /* U2SPEC described in VGM manual */
0413 /* NOTE: the Joerger vtr10012_8 needs the timing to be tweaked!!!! READt27 must be _no_delay_
0414  */
0415 #define     UNIV_REGOFF_U2SPEC      0x4fc
0416 # define    UNIV_U2SPEC_DTKFLTR         (1<<12) /* DTAck filter: 0: slow, better filter; 1: fast, poorer filter */
0417 # define    UNIV_U2SPEC_MASt11          (1<<10) /* Master parameter t11 (DS hi time during BLT and MBLTs) */
0418 # define    UNIV_U2SPEC_READt27_DEFAULT (0<<8)  /* VME master parameter t27: (latch data after DTAck + 25ns) */
0419 # define    UNIV_U2SPEC_READt27_FAST    (1<<8)  /* VME master parameter t27: (latch data faster than 25ns)  */
0420 # define    UNIV_U2SPEC_READt27_NODELAY (2<<8)  /* VME master parameter t27: (latch data without any delay)  */
0421 # define    UNIV_U2SPEC_POSt28_FAST     (1<<2)  /* VME slave parameter t28: (faster time of DS to DTAck for posted write) */
0422 # define    UNIV_U2SPEC_PREt28_FAST     (1<<0)  /* VME slave parameter t28: (faster time of DS to DTAck for prefetch read) */
0423 
0424 /* Location Monitor control register */
0425 #define     UNIV_REGOFF_LM_CTL      0xf64
0426 # define    UNIV_LM_CTL_EN              (1<<31) /* image enable */
0427 # define    UNIV_LM_CTL_PGM             (1<<23) /* program AM */
0428 # define    UNIV_LM_CTL_DATA            (1<<22) /* data AM */
0429 # define    UNIV_LM_CTL_SUPER           (1<<21) /* supervisor AM */
0430 # define    UNIV_LM_CTL_USER            (1<<20) /* user AM */
0431 # define    UNIV_LM_CTL_VAS_A16         (0<<16) /* A16 */
0432 # define    UNIV_LM_CTL_VAS_A24         (1<<16) /* A16 */
0433 # define    UNIV_LM_CTL_VAS_A32         (2<<16) /* A16 */
0434 
0435 /* Location Monitor base address */
0436 #define     UNIV_REGOFF_LM_BS       0xf68
0437 
0438 /* VMEbus register access image control register */
0439 #define     UNIV_REGOFF_VRAI_CTL    0xf70
0440 # define    UNIV_VRAI_CTL_EN            (1<<31) /* image enable */
0441 # define    UNIV_VRAI_CTL_PGM           (1<<23) /* program AM */
0442 # define    UNIV_VRAI_CTL_DATA          (1<<22) /* data AM */
0443 # define    UNIV_VRAI_CTL_SUPER         (1<<21) /* supervisor AM */
0444 # define    UNIV_VRAI_CTL_USER          (1<<20) /* user AM */
0445 # define    UNIV_VRAI_CTL_VAS_A16       (0<<16) /* A16 */
0446 # define    UNIV_VRAI_CTL_VAS_A24       (1<<16) /* A14 */
0447 # define    UNIV_VRAI_CTL_VAS_A32       (2<<16) /* A32 */
0448 # define    UNIV_VRAI_CTL_VAS_MSK       (3<<16)
0449 
0450 /* VMEbus register acces image base address register */
0451 #define     UNIV_REGOFF_VRAI_BS     0xf74
0452 
0453 /* VMEbus CSR control register */
0454 #define     UNIV_REGOFF_VCSR_CTL    0xf80
0455 # define    UNIV_VCSR_CTL_EN            (1<<31) /* image enable */
0456 # define    UNIV_VCSR_CTL_LAS_PCI_MEM   (0<<0)  /* pci mem space */
0457 # define    UNIV_VCSR_CTL_LAS_PCI_IO    (1<<0)  /* pci IO space */
0458 # define    UNIV_VCSR_CTL_LAS_PCI_CFG   (2<<0)  /* pci config space */
0459 
0460 /* VMEbus CSR translation offset */
0461 #define     UNIV_REGOFF_VCSR_TO     0xf84
0462 
0463 /* VMEbus AM code error log */
0464 #define     UNIV_REGOFF_V_AMERR     0xf88
0465 # define    UNIV_V_AMERR_AMERR(reg)     (((reg)>>26)&0x3f)  /* extract error log code */
0466 # define    UNIV_V_AMERR_IACK           (1<<25) /* VMEbus IACK signal */
0467 # define    UNIV_V_AMERR_M_ERR          (1<<24) /* multiple errors occurred */
0468 # define    UNIV_V_AMERR_V_STAT         (1<<23) /* log status valid (write 1 to clear) */
0469 
0470 /* VMEbus address error log */
0471 #define     UNIV_REGOFF_VAERR       0xf8c       /* address of fault address (if MERR_V_STAT valid) */
0472 
0473 /* VMEbus CSR bit clear register */
0474 #define     UNIV_REGOFF_VCSR_CLR    0xff4
0475 # define    UNIV_VCSR_CLR_RESET         (1<<31) /* read/negate LRST (can only be written from VME bus */
0476 # define    UNIV_VCSR_CLR_SYSFAIL       (1<<30) /* read/negate SYSFAIL */
0477 # define    UNIV_VCSR_CLR_FAIL          (1<<29) /* read: board has failed */
0478 
0479 /* VMEbus CSR bit set register */
0480 #define     UNIV_REGOFF_VCSR_SET        (0xff8)
0481 # define    UNIV_VCSR_SET_RESET         (1<<31) /* read/assert LRST (can only be written from VME bus */
0482 # define    UNIV_VCSR_SET_SYSFAIL       (1<<30) /* read/assert SYSFAIL */
0483 # define    UNIV_VCSR_SET_FAIL          (1<<29) /* read: board has failed */
0484 
0485 /* VMEbus CSR base address register */
0486 #define     UNIV_REGOFF_VCSR_BS     0xffc
0487 #define     UNIV_VCSR_BS_MASK           (0xf8000000)
0488 
0489 /* offset of universe registers in VME-CSR slot */
0490 #define     UNIV_CSR_OFFSET             0x7f000
0491 
0492 #ifdef __cplusplus
0493 extern "C" {
0494 #endif
0495 
0496 /* base address and IRQ line of 1st universe bridge
0497  * NOTE: vmeUniverseInit() must be called before
0498  *       these may be used.
0499  */
0500 extern volatile LERegister *vmeUniverse0BaseAddr;
0501 extern int vmeUniverse0PciIrqLine;
0502 
0503 
0504 /* Initialize the driver */
0505 int
0506 vmeUniverseInit(void);
0507 
0508 /* setup the universe chip, i.e. disable most of its
0509  * mappings, reset interrupts etc.
0510  */
0511 void
0512 vmeUniverseReset(void);
0513 
0514 /* avoid pulling stdio.h into this header.
0515  * Applications that want a declaration of the
0516  * following routines should
0517  *  #include <stdio.h>
0518  *  #define _VME_UNIVERSE_DECLARE_SHOW_ROUTINES
0519  *  #include <vmeUniverse.h>
0520  */
0521 /* print the current configuration of all master ports to
0522  * f (stderr if NULL)
0523  */
0524 void
0525 vmeUniverseMasterPortsShow(FILE *f);
0526 
0527 /* print the current configuration of all slave ports to
0528  * f (stderr if NULL)
0529  */
0530 void
0531 vmeUniverseSlavePortsShow(FILE *f);
0532 
0533 /* disable all master or slave ports, respectively */
0534 void
0535 vmeUniverseDisableAllMasters(void);
0536 
0537 void
0538 vmeUniverseDisableAllSlaves(void);
0539 
0540 /* configure a master port
0541  *
0542  *   port:      port number 0..3  (0..7 for a UniverseII)
0543  *
0544  *   address_space: vxWorks compliant addressing mode identifier
0545  *                  (see vme.h). The most important are:
0546  *                    0x0d - A32, Sup, Data
0547  *                    0x3d - A24, Sup, Data
0548  *                    0x2d - A16, Sup, Data
0549  *                  additionally, the value 0 is accepted; it will
0550  *                  disable this port.
0551  *   vme_address:   address on the vme_bus of this port.
0552  *   local_address: address on the pci_bus of this port.
0553  *   length:        size of this port.
0554  *
0555  *   NOTE: the addresses and length parameters must be aligned on a
0556  *         2^16 byte (0x10000) boundary, except for port 4 (only available
0557  *         on a UniverseII), where the alignment can be 4k (4096).
0558  *
0559  *   RETURNS: 0 on success, -1 on failure. Error messages printed to stderr.
0560  */
0561 
0562 int
0563 vmeUniverseMasterPortCfg(
0564     unsigned long   port,
0565     unsigned long   address_space,
0566     unsigned long   vme_address,
0567     unsigned long   local_address,
0568     unsigned long   length);
0569 
0570 /* translate an address through the bridge
0571  *
0572  * vmeUniverseXlateAddr(0,0,as,addr,&result)
0573  * yields a VME a address that reflects
0574  * a local memory location as seen from the VME bus through the universe
0575  * VME slave.
0576  *
0577  * likewise does vmeUniverseXlateAddr(1,0,as,addr,&result)
0578  * translate a VME bus addr (through the VME master) to the
0579  * PCI side of the bridge.
0580  *
0581  * a valid address space modifier must be specified.
0582  *
0583  * The 'reverse' parameter may be used to find a reverse
0584  * mapping, i.e. the pci address in a master window can be
0585  * found if the respective vme address is known etc.
0586  *
0587  * RETURNS: translated address in *pbusAdrs / *plocalAdrs
0588  *
0589  *          0:  success
0590  *          -1: address/modifier not found in any bridge port
0591  *          -2: invalid modifier
0592  */
0593 int
0594 vmeUniverseXlateAddr(
0595     int master,         /* look in the master windows */
0596     int reverse,        /* reverse mapping; for masters: map local to VME */
0597     unsigned long as,   /* address space */
0598     unsigned long addr, /* address to look up */
0599     unsigned long *paOut/* where to put result */
0600     );
0601 
0602 /* configure a VME slave (PCI master) port */
0603 int
0604 vmeUniverseSlavePortCfg(
0605     unsigned long   port,
0606     unsigned long   address_space,
0607     unsigned long   vme_address,
0608     unsigned long   local_address,
0609     unsigned long   length);
0610 
0611 /****** NOTE: USE OF vmeUniverseStartDMA IS DEPRECATED      *********
0612  ******       USE API IN VMEDMA.h/vmeUniverseDMA.h INSTEAD  *********/
0613 
0614 /* start a (direct, not linked) DMA transfer
0615  *
0616  * NOTE:  DCTL and DGCS must be set up
0617  *        prior to calling this routine
0618  */
0619 int
0620 vmeUniverseStartDMA(
0621     unsigned long local_addr,
0622     unsigned long vme_addr,
0623     unsigned long count); /* DEPRECATED */
0624 
0625 int
0626 vmeUniverseStartDMAXX(
0627     volatile LERegister *ubase,
0628     unsigned long local_addr,
0629     unsigned long vme_addr,
0630     unsigned long count); /* DEPRECATED */
0631 
0632 
0633 /* read a register in PCI memory space
0634  * (offset being one of the declared constants)
0635  */
0636 unsigned long
0637 vmeUniverseReadReg(unsigned long offset);
0638 
0639 /* write a register in PCI memory space */
0640 void
0641 vmeUniverseWriteReg(unsigned long value, unsigned long offset);
0642 
0643 /* convert an array of unsigned long values to LE (as needed
0644  * when the universe reads e.g. DMA descriptors from PCI)
0645  */
0646 void
0647 vmeUniverseCvtToLE(unsigned long *ptr, unsigned long num);
0648 
0649 /* reset the VME bus */
0650 void
0651 vmeUniverseResetBus(void);
0652 
0653 /* The ...XX routines take the universe base address as an additional
0654  * argument - this allows for programming secondary devices.
0655  */
0656 
0657 unsigned long
0658 vmeUniverseReadRegXX(volatile LERegister *ubase, unsigned long offset);
0659 
0660 void
0661 vmeUniverseWriteRegXX(volatile LERegister *ubase, unsigned long value, unsigned long offset);
0662 
0663 int
0664 vmeUniverseXlateAddrXX(
0665     volatile LERegister *ubase,
0666     int master,
0667     int reverse,
0668     unsigned long as,
0669     unsigned long addr,
0670     unsigned long *paOut
0671     );
0672 
0673 int
0674 vmeUniverseMasterPortCfgXX(
0675     volatile LERegister *ubase,
0676     unsigned long   port,
0677     unsigned long   address_space,
0678     unsigned long   vme_address,
0679     unsigned long   local_address,
0680     unsigned long   length);
0681 
0682 int
0683 vmeUniverseSlavePortCfgXX(
0684     volatile LERegister *ubase,
0685     unsigned long   port,
0686     unsigned long   address_space,
0687     unsigned long   vme_address,
0688     unsigned long   local_address,
0689     unsigned long   length);
0690 
0691 void
0692 vmeUniverseDisableAllMastersXX(volatile LERegister *ubase);
0693 
0694 void
0695 vmeUniverseDisableAllSlavesXX(volatile LERegister *ubase);
0696 
0697 /* print the current configuration of all master ports to
0698  * f (stderr if NULL)
0699  */
0700 void
0701 vmeUniverseMasterPortsShowXX(
0702     volatile LERegister *ubase,FILE *f);
0703 
0704 /* print the current configuration of all slave ports to
0705  * f (stderr if NULL)
0706  */
0707 void
0708 vmeUniverseSlavePortsShowXX(
0709     volatile LERegister *ubase,FILE *f);
0710 
0711 /* Raise a VME Interrupt at 'level' and respond with 'vector' to a
0712  * handler on the VME bus. (The handler could be a different board
0713  * or the universe itself - [only works with universe II]).
0714  *
0715  * Note that you could install a interrupt handler at UNIV_VME_SW_IACK_INT_VEC
0716  * to be notified of an IACK cycle having completed.
0717  *
0718  * This routine is mainly FOR TESTING.
0719  *
0720  * NOTES:
0721  *   - several registers are modified: the vector is written to VINT_STATID
0722  *     and (universe 1 chip only) the level is written to the SW_INT bits
0723  *     int VINT_MAP1
0724  *   - NO MUTUAL EXCLUSION PROTECTION (reads VINT_EN, modifies then writes back).
0725  *     If several users need access to VINT_EN and/or VINT_STATID (and VINT_MAP1
0726  *     on the universe 1) it is their responsibility to serialize access.
0727  *
0728  * Arguments:
0729  *  'level':  interrupt level, 1..7
0730  *  'vector': vector number (0..254) that the universe puts on the bus in response to
0731  *            an IACK cycle. NOTE: the vector number *must be even* (hardware restriction
0732  *            of the universe -- it always clears the LSB when the interrupter is
0733  *            a software interrupt).
0734  *
0735  * RETURNS:
0736  *        0:  Success
0737  *       -1:  Invalid argument (level not 1..7, vector odd or >= 256)
0738  *       -2:  Interrupt 'level' already asserted (maybe nobody handles it).
0739  *            You can manually clear it be writing the respective bit in
0740  *            VINT_STAT. Make sure really nobody responds to avoid spurious
0741  *            interrupts (consult universe docs).
0742  */
0743 
0744 int
0745 vmeUniverseIntRaiseXX(volatile LERegister *base, int level, unsigned vector);
0746 
0747 int
0748 vmeUniverseIntRaise(int level, unsigned vector);
0749 
0750 /* Map internal register block to VME.
0751  *
0752  * This routine is intended for BSP implementors. The registers can be
0753  * made accessible from VME so that the interrupt handler can flush the
0754  * bridge FIFO (see below). The preferred method is by accessing VME CSR,
0755  * though, if these are mapped [and the BSP provides an outbound window].
0756  * On the universe we can also disable posted writes in the 'ordinary'
0757  * outbound windows.
0758  *
0759  *            vme_base: VME address where the universe registers (4k) can be mapped.
0760  *                      This VME address must fall into a range covered by
0761  *                      any pre-configured outbound window.
0762  *       address_space: The desired VME address space.
0763  *                      (all of SUP/USR/PGM/DATA are always accepted).
0764  *
0765  * See NOTES [vmeUniverseInstallIrqMgrAlt()] below for further information.
0766  *
0767  * RETURNS: 0 on success, nonzero on error. It is not possible (and results
0768  *          in a non-zero return code) to change the CRG VME address after
0769  *          initializing the interrupt manager as it uses the CRG.
0770  */
0771 int
0772 vmeUniverseMapCRGXX(volatile LERegister *base, unsigned long vme_base, unsigned long address_space);
0773 
0774 int
0775 vmeUniverseMapCRG(unsigned long vme_base, unsigned long address_space);
0776 
0777 
0778 #ifdef __rtems__
0779 
0780 /* VME Interrupt Handler functionality */
0781 
0782 /* we dont use the current RTEMS/BSP interrupt API for the
0783  * following reasons:
0784  *
0785  *    - RTEMS/BSP API does not pass an argument to the ISR :-( :-(
0786  *    - no separate vector space for VME vectors. Some vectors would
0787  *      have to overlap with existing PCI/ISA vectors.
0788  *    - RTEMS/BSP API allocates a structure for every possible vector
0789  *    - the irq_on(), irq_off() functions add more bloat than helping.
0790  *      They are (currently) only used by the framework to disable
0791  *      interrupts at the device level before removing a handler
0792  *      and to enable interrupts after installing a handler.
0793  *      These operations may as well be done by the driver itself.
0794  *
0795  * Hence, we maintain our own (VME) handler table and hook our PCI
0796  * handler into the standard RTEMS/BSP environment. Our handler then
0797  * dispatches VME interrupts.
0798  */
0799 
0800 typedef void (*VmeUniverseISR) (void *usrArg, unsigned long vector);
0801 
0802 /* use these special vectors to connect a handler to the
0803  * universe specific interrupts (such as "DMA done",
0804  * VOWN, error irqs etc.)
0805  * NOTE: The wrapper clears all status LINT bits (except
0806  * for regular VME irqs). Also note that it is the user's
0807  * responsibility to enable the necessary interrupts in
0808  * LINT_EN
0809  *
0810  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0811  * DO NOT CHANGE THE ORDER OF THESE VECTORS - THE DRIVER
0812  * DEPENDS ON IT
0813  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0814  *
0815  */
0816 #define UNIV_VOWN_INT_VEC           256
0817 #define UNIV_DMA_INT_VEC            257
0818 #define UNIV_LERR_INT_VEC           258
0819 #define UNIV_VERR_INT_VEC           259
0820 /* 260 is reserved */
0821 #define UNIV_VME_SW_IACK_INT_VEC    261
0822 #define UNIV_PCI_SW_INT_VEC         262
0823 #define UNIV_SYSFAIL_INT_VEC        263
0824 #define UNIV_ACFAIL_INT_VEC         264
0825 #define UNIV_MBOX0_INT_VEC          265
0826 #define UNIV_MBOX1_INT_VEC          266
0827 #define UNIV_MBOX2_INT_VEC          267
0828 #define UNIV_MBOX3_INT_VEC          268
0829 #define UNIV_LM0_INT_VEC            269
0830 #define UNIV_LM1_INT_VEC            270
0831 #define UNIV_LM2_INT_VEC            271
0832 #define UNIV_LM3_INT_VEC            272
0833 
0834 #define UNIV_NUM_INT_VECS           273
0835 
0836 
0837 /* install a handler for a VME vector
0838  * RETURNS 0 on success, nonzero on failure.
0839  */
0840 int
0841 vmeUniverseInstallISR(unsigned long vector, VmeUniverseISR handler, void *usrArg);
0842 
0843 /* remove a handler for a VME vector. The vector and usrArg parameters
0844  * must match the respective parameters used when installing the handler.
0845  * RETURNS 0 on success, nonzero on failure.
0846  */
0847 int
0848 vmeUniverseRemoveISR(unsigned long vector, VmeUniverseISR handler, void *usrArg);
0849 
0850 /* query for the currently installed ISR and usr parameter at a given vector
0851  * RETURNS: ISR or 0 (vector too big or no ISR installed)
0852  */
0853 VmeUniverseISR
0854 vmeUniverseISRGet(unsigned long vector, void **parg);
0855 
0856 /* utility routines to enable/disable a VME IRQ level.
0857  *
0858  * To enable/disable the internal interrupt sources (special vectors above)
0859  * pass a vector argument > 255.
0860  *
0861  * RETURNS 0 on success, nonzero on failure
0862  */
0863 int
0864 vmeUniverseIntEnable(unsigned int level);
0865 int
0866 vmeUniverseIntDisable(unsigned int level);
0867 
0868 /* Check if an interrupt level or internal source is enabled:
0869  *
0870  * 'level': VME level 1..7 or internal special vector > 255
0871  *
0872  * RETURNS: value > 0 if interrupt is currently enabled,
0873  *          zero      if interrupt is currently disabled,
0874  *          -1        on error (invalid argument).
0875  */
0876 int
0877 vmeUniverseIntIsEnabled(unsigned int level);
0878 
0879 
0880 /* Change the routing of IRQ 'level' to 'pin'.
0881  * If the BSP connects more than one of the eight
0882  * physical interrupt lines from the universe to
0883  * the board's PIC then you may change the physical
0884  * line a given 'level' is using. By default,
0885  * all 7 VME levels use the first wire (pin==0) and
0886  * all internal sources use the (optional) second
0887  * wire (pin==1).
0888  * This feature is useful if you want to make use of
0889  * different hardware priorities of the PIC. Let's
0890  * say you want to give IRQ level 7 the highest priority.
0891  * You could then give 'pin 0' a higher priority (at the
0892  * PIC) and 'pin 1' a lower priority and issue.
0893  *
0894  *   for ( i=1; i<7; i++ ) vmeUniverseIntRoute(i, 1);
0895  *
0896  * PARAMETERS:
0897  *    'level' : VME interrupt level '1..7' or one of
0898  *              the internal sources. Pass the internal
0899  *              source's vector number (>=256).
0900  *    'pin'   : a value of 0 routes the requested IRQ to
0901  *              the first line registered with the manager
0902  *              (vmeIrqUnivOut parameter), a value of 1
0903  *              routes it to the alternate wire
0904  *              (specialIrqUnivOut)
0905  * RETURNS: 0 on success, nonzero on error (invalid arguments)
0906  *
0907  * NOTES:   - DONT change the universe 'map' registers
0908  *            directly. The driver caches routing internally.
0909  *          - support for the 'specialIrqUnivOut' wire is
0910  *            board dependent. If the board only provides
0911  *            a single physical wire from the universe to
0912  *            the PIC then the feature might not be available.
0913  */
0914 int
0915 vmeUniverseIntRoute(unsigned int level, unsigned int pin);
0916 
0917 /* Loopback test of the VME interrupt subsystem.
0918  *  - installs ISRs on 'vector' and on UNIV_VME_SW_IACK_INT_VEC
0919  *  - asserts VME interrupt 'level'
0920  *  - waits for both interrupts: 'ordinary' VME interrupt of 'level' and
0921  *    IACK completion interrupt ('special' vector UNIV_VME_SW_IACK_INT_VEC).
0922  *
0923  * NOTES:
0924  *  - make sure no other handler responds to 'level'.
0925  *  - make sure no ISR is installed on both vectors yet.
0926  *  - ISRs installed by this routine are removed after completion.
0927  *  - no concurrent access protection of all involved resources
0928  *    (levels, vectors and registers  [see vmeUniverseIntRaise()])
0929  *    is implemented.
0930  *  - this routine is intended for TESTING (when implementing new BSPs etc.).
0931  *  - one RTEMS message queue is temporarily used (created/deleted).
0932  *  - the universe 1 always yields a zero vector (VIRQx_STATID) in response
0933  *    to a self-generated VME interrupt. As a workaround, the routine
0934  *    only accepts a zero vector when running on a universe 1.
0935  *
0936  * RETURNS:
0937  *                 0: Success.
0938  *                -1: Invalid arguments.
0939  *                 1: Test failed (outstanding interrupts).
0940  * rtems_status_code: Failed RTEMS directive.
0941  */
0942 int
0943 vmeUniverseIntLoopbackTst(int level, unsigned vector);
0944 
0945 
0946 /* the universe interrupt handler is capable of routing all sorts of
0947  * (VME) interrupts to 8 different lines (some of) which may be hooked up
0948  * in a (board specific) way to a PIC.
0949  *
0950  * This driver only supports at most two lines. By default, it routes the
0951  * 7 VME interrupts to the main line and optionally, it routes the 'special'
0952  * interrupts generated by the universe itself (DMA done, VOWN etc.)
0953  * to a second line. If no second line is available, all IRQs are routed
0954  * to the main line.
0955  *
0956  * The routing of interrupts to the two lines can be modified (using
0957  * the vmeUniverseIntRoute() call - see above - i.e., to make use of
0958  * different hardware priorities of the two pins.
0959  *
0960  * Because the driver has no way to figure out which lines are actually
0961  * wired to the PIC, this information has to be provided when installing
0962  * the manager.
0963  *
0964  * Hence the manager sets up routing VME interrupts to 1 or 2 universe
0965  * OUTPUTS. However, it must also be told to which PIC INPUTS they
0966  * are wired.
0967  * Optionally, the first PIC input line can be read from PCI config space
0968  * but the second must be passed to this routine. Note that the info read
0969  * from PCI config space is wrong for many boards!
0970  *
0971  * PARAMETERS:
0972  *       vmeIrqUnivOut: to which output pin (of the universe) should the 7
0973  *                      VME irq levels be routed.
0974  *       vmeIrqPicLine: specifies to which PIC input the 'main' output is
0975  *                      wired. If passed a value < 0, the driver reads this
0976  *                      information from PCI config space ("IRQ line").
0977  *   specialIrqUnivOut: to which output pin (of the universe) should the
0978  *                      internally irqs be routed. Use 'vmeIRQunivOut'
0979  *                      if < 0.
0980  *   specialIrqPicLine: specifies to which PIC input the 'special' output
0981  *                      pin is wired. The wiring of the 'vmeIRQunivOut' to
0982  *                      the PIC is determined by reading PCI config space.
0983  *
0984  * RETURNS: 0 on success, -1 on failure.
0985  *
0986  */
0987 
0988 /* This routine is outside of the __INSIDE_RTEMS_BSP__ test for bwrds compatibility ONLY */
0989 int
0990 vmeUniverseInstallIrqMgr(int vmeIrqUnivOut,
0991                          int vmeIrqPicLine,
0992                          int specialIrqUnivOut,
0993                          int specialIrqPicLine);
0994 
0995 
0996 #if defined(__INSIDE_RTEMS_BSP__)
0997 #include <stdarg.h>
0998 
0999 /* up to 4 universe outputs are now supported by this alternate
1000  * entry point.
1001  * Terminate the vararg list (uni_pin/pic_pin pairs) with a
1002  * '-1' uni_pin.
1003  * E.g., the old interface is now just a wrapper to
1004  *   vmeUniverseInstallIrqMgrAlt(0, vmeUnivOut, vmePicLint, specUnivOut, specPicLine, -1);
1005  *
1006  * The 'IRQ_MGR_SHARED' flag uses the BSP_install_rtems_shared_irq_handler()
1007  * API. CAVEAT: shared interrupts need RTEMS workspace, i.e., the
1008  * VME interrupt manager can only be installed *after workspace is initialized*
1009  * if 'shared' is nonzero (i.e., *not* from bspstart()).
1010  *
1011  * If 'PW_WORKAROUND' flag is set then the interrupt manager will try to
1012  * find a way to access the control registers from VME so that the universe's
1013  * posted write FIFO can be flushed after the user ISR returns:
1014  *
1015  * The installation routine looks first for CSR registers in CSR space (this
1016  * requires:
1017  *      - a VME64 crate with autoid or geographical addressing
1018  *      - the firmware or BSP to figure out the slot number and program the CSR base
1019  *        in the universe.
1020  *      - the BSP to open an outbound window to CSR space.
1021  *
1022  * If CSR registers cannot be found then the installation routine looks for CRG registers:
1023  *      - BSP must map CRG on VME
1024  *      - CRG must be visible in outbound window
1025  *      CAVEAT: multiple boards with same BSP on single backplane must not map their CRG
1026  *              to the same address!
1027  */
1028 
1029 #define VMEUNIVERSE_IRQ_MGR_FLAG_SHARED         1   /* use shared interrupts */
1030 #define VMEUNIVERSE_IRQ_MGR_FLAG_PW_WORKAROUND  2   /* use shared interrupts */
1031 
1032 int
1033 vmeUniverseInstallIrqMgrAlt(int flags, int uni_pin0, int pic_pin0, ...);
1034 
1035 int
1036 vmeUniverseInstallIrqMgrVa(int flags, int uni_pin0, int pic_pin0, va_list ap);
1037 
1038 #endif /* __INSIDE_RTEMS_BSP__ */
1039 #endif /* __rtems__ */
1040 
1041 #ifdef __cplusplus
1042 }
1043 #endif
1044 
1045 #endif