![]() |
|
|||
File indexing completed on 2025-05-11 08:23:53
0001 /** 0002 * @file 0003 * 0004 * @ingroup shared_vmetsi148 0005 * 0006 * @brief Driver for the Tundra Tsi148 pci-vme bridge 0007 */ 0008 0009 #ifndef VME_TSI148_DRIVER_H 0010 #define VME_TSI148_DRIVER_H 0011 0012 /* 0013 * Authorship 0014 * ---------- 0015 * This software was created by 0016 * Till Straumann <strauman@slac.stanford.edu>, 2005-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 #include <stdint.h> 0058 #include <bsp/vme_am_defs.h> 0059 0060 0061 /** 0062 * @defgroup shared_vmetsi148 VMETSI148 Support 0063 * 0064 * @ingroup shared_vmeuniverse 0065 * 0066 * @brief VMETSI148 Support Package 0067 */ 0068 0069 /* NOTE: A64 currently not implemented */ 0070 0071 /* These can be ored with the AM */ 0072 0073 /* NOTE: unlike the universe, the tsi148 doesn't allow for disabling posted writes ! */ 0074 0075 #define VME_MODE_PREFETCH_ENABLE VME_AM_IS_MEMORY 0076 #define _LD_VME_MODE_PREFETCHSZ 24 0077 #define VME_MODE_PREFETCH_SIZE(x) (((x)&3)<<_LD_VME_MODE_PREFETCHSZ) 0078 0079 /* These bits can be or'ed with the address-modifier when calling 0080 * the 'XlateAddr' routine below to further qualify the 0081 * search criteria. 0082 */ 0083 #define VME_MODE_MATCH_MASK (3<<30) 0084 #define VME_MODE_EXACT_MATCH (2<<30) /* all bits must match */ 0085 #define VME_MODE_AS_MATCH (1<<30) /* only A16/24/32 must match */ 0086 0087 #ifdef __cplusplus 0088 extern "C" { 0089 #endif 0090 0091 typedef volatile uint32_t BERegister; /* emphasize contents are big endian */ 0092 0093 /* 0094 * Scan the PCI busses for the Nth (N=='instance') Tsi148 VME bridge. 0095 * 0096 * RETURNS: 0097 * contents of the IRQ_LINE PCI config register on Success, 0098 * the base address of the Tsi148 register block is stored in 0099 * *pbase. 0100 * -1 on error (no Tsi found, error accessing PCI config space). 0101 * 0102 * SIDE_EFFECTS: PCI busmaster and response to memory addresses is enabled. 0103 */ 0104 int 0105 vmeTsi148FindPciBase(int instance, BERegister **pbase); 0106 0107 /* Initialize driver for Nth Tsi148 device found. 0108 * This routine does not change any registers but 0109 * just scans the PCI bus for Tsi bridges and initializes 0110 * a driver slot. 0111 * 0112 * RETURNS: 0 on success, nonzero on error (or if no Tsi148 0113 * device is found). 0114 */ 0115 int 0116 vmeTsi148InitInstance(unsigned instance); 0117 0118 /* Initialize driver with 1st Tsi148 bridge found 0119 * RETURNS: (see vmeTsi148InitInstance()). 0120 */ 0121 int 0122 vmeTsi148Init(void); 0123 0124 /* Setup the tsi148 chip, i.e. disable most of its 0125 * mappings, reset interrupts etc. 0126 */ 0127 void 0128 vmeTsi148ResetXX(BERegister *base); 0129 0130 /* Setup the tsi148 connected to the first driver slot */ 0131 void 0132 vmeTsi148Reset(void); 0133 0134 /* Pull VME SYSRESET line */ 0135 void 0136 vmeTsi148ResetBusXX(BERegister *base); 0137 0138 /* Pull VME SYSRESET line of the 1st controller */ 0139 void 0140 vmeTsi148ResetBus(void); 0141 0142 /* NOTE: all non-'XX' versions of driver entry points which 0143 * have an associated 'XX' entry point operate on the 0144 * device connected to the 1st driver slot. 0145 */ 0146 0147 /* configure a outbound port 0148 * 0149 * port: port number 0..7 0150 * 0151 * address_space: vxWorks compliant addressing mode identifier 0152 * (see vme.h). The most important are: 0153 * 0x0d - A32, Sup, Data 0154 * 0x3d - A24, Sup, Data 0155 * 0x2d - A16, Sup, Data 0156 * additionally, the value 0 is accepted; it will 0157 * disable this port. 0158 * vme_address: address on the vme_bus of this port. 0159 * local_address: address on the pci_bus of this port. 0160 * length: size of this port. 0161 * 0162 * NOTE: the addresses and length parameters must meet certain alignment 0163 * requirements (see Tsi148 documentation). 0164 * 0165 * RETURNS: 0 on success, -1 on failure. Error messages printed to stderr. 0166 */ 0167 0168 int 0169 vmeTsi148OutboundPortCfgXX( 0170 BERegister *base, 0171 unsigned long port, 0172 unsigned long address_space, 0173 unsigned long vme_address, 0174 unsigned long pci_address, 0175 unsigned long length); 0176 0177 int 0178 vmeTsi148OutboundPortCfg( 0179 unsigned long port, 0180 unsigned long address_space, 0181 unsigned long vme_address, 0182 unsigned long pci_address, 0183 unsigned long length); 0184 0185 0186 /* configure a VME inbound (PCI master) port */ 0187 int 0188 vmeTsi148InboundPortCfgXX( 0189 BERegister *base, 0190 unsigned long port, 0191 unsigned long address_space, 0192 unsigned long vme_address, 0193 unsigned long pci_address, 0194 unsigned long length); 0195 0196 int 0197 vmeTsi148InboundPortCfg( 0198 unsigned long port, 0199 unsigned long address_space, 0200 unsigned long vme_address, 0201 unsigned long pci_address, 0202 unsigned long length); 0203 0204 /* Translate an address through the bridge 0205 * 0206 * vmeTsi248XlateAddr(0,0,as,addr,&result) 0207 * yields a VME a address that reflects 0208 * a local memory location as seen from the VME bus through the 0209 * tsi148 VME inbound port. 0210 * 0211 * Likewise does vmeTsi148XlateAddr(1,0,as,addr,&result) 0212 * translate a VME bus addr (backwards, through the VME outbound 0213 * port) to the PCI side of the bridge. 0214 * 0215 * A valid address space modifier must be specified. 0216 * If VME_MODE_EXACT_MATCH is set, all the mode bits must 0217 * match the requested mode. If VME_MODE_EXACT_MATCH is not 0218 * set in the mode word, only the basic mode (address-space, 0219 * sup/usr and pgm/data) is compared. 0220 * 0221 * The 'reverse' parameter may be used to find a reverse 0222 * mapping, i.e. the pci address in a outbound window can be 0223 * found if the respective vme address is known etc. 0224 * 0225 * RETURNS: translated address in *pbusAdrs / *plocalAdrs 0226 * 0227 * 0: success 0228 * -1: address/modifier not found in any bridge port 0229 * -2: invalid modifier 0230 */ 0231 0232 int 0233 vmeTsi148XlateAddrXX( 0234 BERegister *base, /* TSI 148 base address */ 0235 int outbound, /* look in the outbound windows */ 0236 int reverse, /* reverse mapping; for outbound ports: map local to VME */ 0237 unsigned long as, /* address space */ 0238 unsigned long aIn, /* address to look up */ 0239 unsigned long *paOut/* where to put result */ 0240 ); 0241 0242 int 0243 vmeTsi148XlateAddr( 0244 int outbound, /* look in the outbound windows */ 0245 int reverse, /* reverse mapping; for outbound: map local to VME */ 0246 unsigned long as, /* address space */ 0247 unsigned long aIn, /* address to look up */ 0248 unsigned long *paOut/* where to put result */ 0249 ); 0250 0251 0252 /* avoid pulling stdio.h into this header. 0253 * Applications that want a declaration of the 0254 * following routines should 0255 * #include <stdio.h> 0256 * #define _VME_TSI148_DECLARE_SHOW_ROUTINES 0257 * #include <vmeTsi148.h> 0258 */ 0259 #ifdef _VME_TSI148_DECLARE_SHOW_ROUTINES 0260 0261 /* Print the current configuration of all outbound ports to 0262 * f (stdout if NULL) 0263 */ 0264 0265 void 0266 vmeTsi148OutboundPortsShowXX(BERegister *base, FILE *f); 0267 0268 void 0269 vmeTsi148OutboundPortsShow(FILE *f); 0270 0271 /* Print the current configuration of all inbound ports to 0272 * f (stdout if NULL) 0273 */ 0274 0275 void 0276 vmeTsi148InboundPortsShowXX(BERegister *base, FILE *f); 0277 0278 void 0279 vmeTsi148InboundPortsShow(FILE *f); 0280 0281 #endif 0282 0283 0284 /* Disable all in- or out-bound ports, respectively */ 0285 void 0286 vmeTsi148DisableAllInboundPortsXX(BERegister *base); 0287 0288 void 0289 vmeTsi148DisableAllInboundPorts(void); 0290 0291 void 0292 vmeTsi148DisableAllOutboundPortsXX(BERegister *base); 0293 0294 void 0295 vmeTsi148DisableAllOutboundPorts(void); 0296 0297 # define TSI_VEAT_VES (1<<31) 0298 # define TSI_VEAT_VEOF (1<<30) 0299 # define TSI_VEAT_VESCL (1<<29) 0300 # define TSI_VEAT_2eOT (1<<21) 0301 # define TSI_VEAT_2eST (1<<20) 0302 # define TSI_VEAT_BERR (1<<19) 0303 # define TSI_VEAT_LWORD (1<<18) 0304 # define TSI_VEAT_WRITE (1<<17) 0305 # define TSI_VEAT_IACK (1<<16) 0306 # define TSI_VEAT_DS1 (1<<15) 0307 # define TSI_VEAT_DS0 (1<<14) 0308 # define TSI_VEAT_AM(v) (((v)>>8)&63) 0309 # define TSI_VEAT_XAM(v) ((v)&255) 0310 0311 /* Check and clear the error (AKA 'exception') register. 0312 * Note that the Tsi148 does *not* propagate VME bus errors of any kind to 0313 * the PCI status register and hence this routine (or registering an ISR 0314 * to the TSI_VERR_INT_VEC) is the only means for detecting a bus error. 0315 * 0316 * RETURNS: 0317 * 0 if no error has occurred since this routine was last called. 0318 * Contents of the 'VEAT' register (bit definitions as above) 0319 * otherwise. 0320 * If a non-NULL 'paddr' argument is provided then the lower 32-bit 0321 * of the error address is stored in *paddr (only if return value is 0322 * non-zero). 0323 * 0324 * SIDE EFFECTS: this routine clears the error attribute register, allowing 0325 * for future errors to be latched. 0326 */ 0327 unsigned long 0328 vmeTsi148ClearVMEBusErrorsXX(BERegister *base, uint32_t *paddr); 0329 0330 unsigned long 0331 vmeTsi148ClearVMEBusErrors(uint32_t *paddr); 0332 0333 /* Map internal register block to VME. 0334 * 0335 * This routine is intended for BSP implementors. The registers must be 0336 * accessible from VME so that the interrupt handler can flush the 0337 * bridge FIFO (see below). 0338 * 0339 * vme_base: VME address where the TSI registers (4k) can be mapped. 0340 * This VME address must fall into a range covered by 0341 * any pre-configured outbound window. 0342 * address_space: The desired VME address space. 0343 * (all of SUP/USR/PGM/DATA are always accepted). 0344 * 0345 * See NOTES [vmeTsi148InstallIrqMgrAlt()] below for further information. 0346 * 0347 * RETURNS: 0 on success, nonzero on error. It is not possible (and results 0348 * in a non-zero return code) to change the CRG VME address after 0349 * initializing the interrupt manager as it uses the CRG. 0350 */ 0351 int 0352 vmeTsi148MapCRGXX(BERegister *base, uint32_t vme_base, uint32_t address_space); 0353 0354 int 0355 vmeTsi148MapCRG(uint32_t vme_base, uint32_t address_space); 0356 0357 0358 /* VME Interrupt Handler functionality */ 0359 0360 /* we dont use the current RTEMS/BSP interrupt API for the 0361 * following reasons: 0362 * 0363 * - RTEMS/BSP API does not pass an argument to the ISR :-( :-( 0364 * - no separate vector space for VME vectors. Some vectors would 0365 * have to overlap with existing PCI/ISA vectors. 0366 * - RTEMS/BSP API allocates a structure for every possible vector 0367 * - the irq_on(), irq_off() functions add more bloat than helping. 0368 * They are (currently) only used by the framework to disable 0369 * interrupts at the device level before removing a handler 0370 * and to enable interrupts after installing a handler. 0371 * These operations may as well be done by the driver itself. 0372 * 0373 * Hence, we maintain our own (VME) handler table and hook our PCI 0374 * handler into the standard RTEMS/BSP environment. Our handler then 0375 * dispatches VME interrupts. 0376 */ 0377 0378 typedef void (*VmeTsi148ISR) (void *usrArg, unsigned long vector); 0379 0380 /* install a handler for a VME vector 0381 * RETURNS 0 on success, nonzero on failure. 0382 */ 0383 int 0384 vmeTsi148InstallISR(unsigned long vector, VmeTsi148ISR handler, void *usrArg); 0385 0386 /* remove a handler for a VME vector. The vector and usrArg parameters 0387 * must match the respective parameters used when installing the handler. 0388 * RETURNS 0 on success, nonzero on failure. 0389 */ 0390 int 0391 vmeTsi148RemoveISR(unsigned long vector, VmeTsi148ISR handler, void *usrArg); 0392 0393 /* query for the currently installed ISR and usr parameter at a given vector 0394 * RETURNS: ISR or 0 (vector too big or no ISR installed) 0395 */ 0396 VmeTsi148ISR 0397 vmeTsi148ISRGet(unsigned long vector, void **parg); 0398 0399 /* utility routines to enable/disable a VME IRQ level 0400 * 0401 * To enable/disable the internal interrupt sources (special vectors above) 0402 * pass a vector argument > 255. 0403 * 0404 * RETURNS 0 on success, nonzero on failure 0405 */ 0406 int 0407 vmeTsi148IntEnable(unsigned int level); 0408 0409 int 0410 vmeTsi148IntDisable(unsigned int level); 0411 0412 /* Check if an interrupt level or internal source is enabled: 0413 * 0414 * 'level': VME level 1..7 or internal special vector > 255 0415 * 0416 * RETURNS: value > 0 if interrupt is currently enabled, 0417 * zero if interrupt is currently disabled, 0418 * -1 on error (invalid argument). 0419 */ 0420 0421 int 0422 vmeTsi148IntIsEnabled(unsigned int level); 0423 0424 /* Set IACK width (1,2, or 4 bytes) for a given interrupt level. 0425 * 0426 * 'width' arg may be 0,1,2 or 4. If zero, the currently active 0427 * value is returned but not modified. 0428 * 0429 * RETURNS: old width or -1 if invalid argument. 0430 */ 0431 0432 int 0433 vmeTsi148SetIackWidth(int level, int width); 0434 0435 /* Change the routing of IRQ 'level' to 'pin'. 0436 * If the BSP connects more than one of the four 0437 * physical interrupt lines from the tsi148 to 0438 * the board's PIC then you may change the physical 0439 * line a given 'level' is using. By default, 0440 * all 7 VME levels use the first wire (pin==0) and 0441 * all internal sources use the (optional) second 0442 * wire (pin==1) [The driver doesn't support more than 0443 * four wires]. 0444 * This feature is useful if you want to make use of 0445 * different hardware priorities of the PIC. Let's 0446 * say you want to give IRQ level 7 the highest priority. 0447 * You could then give 'pin 0' a higher priority (at the 0448 * PIC) and 'pin 1' a lower priority and issue. 0449 * 0450 * for ( i=1; i<7; i++ ) vmeTsi148IntRoute(i, 1); 0451 * 0452 * PARAMETERS: 0453 * 'level' : VME interrupt level '1..7' or one of 0454 * the internal sources. Pass the internal 0455 * source's vector number (>=256). 0456 * 'pin' : a value of 0 routes the requested IRQ to 0457 * the first line registered with the manager, 0458 * a value of 1 routes it to the second wire 0459 * etc. 0460 * 0461 * RETURNS: 0 on success, nonzero on error (invalid arguments) 0462 * 0463 * NOTES: - DONT change the tsi148 'map' registers 0464 * directly. The driver caches routing internally. 0465 * - support for the extra wires (beyond wire #0) is 0466 * board dependent. If the board only provides 0467 * a single physical wire from the tsi148 to 0468 * the PIC then the feature might not be available. 0469 */ 0470 int 0471 vmeTsi148IntRoute(unsigned int level, unsigned int pin); 0472 0473 /* Raise a VME Interrupt at 'level' and respond with 'vector' to a 0474 * handler on the VME bus. (The handler could be a different board 0475 * or the tsi148 itself. 0476 * 0477 * Note that you could install a interrupt handler at TSI_VME_SW_IACK_INT_VEC 0478 * to be notified of an IACK cycle having completed. 0479 * 0480 * This routine is mainly FOR TESTING. 0481 * 0482 * NOTES: 0483 * - the VICR register is modified. 0484 * - NO MUTUAL EXCLUSION PROTECTION (reads VICR, modifies then writes back). 0485 * If several users need access to VICR it is their responsibility to serialize access. 0486 * 0487 * Arguments: 0488 * 'level': interrupt level, 1..7 0489 * 'vector': vector number (0..255) that the tsi148 puts on the bus in response to 0490 * an IACK cycle. 0491 * 0492 * RETURNS: 0493 * 0: Success 0494 * -1: Invalid argument (level not 1..7, vector >= 256) 0495 * -2: Interrupt 'level' already asserted (maybe nobody handles it). 0496 * You can manually clear it be setting the IRQC bit in 0497 * VICR. Make sure really nobody responds to avoid spurious 0498 * interrupts (consult tsi148 docs). 0499 */ 0500 0501 int 0502 vmeTsi148IntRaiseXX(BERegister *base, int level, unsigned vector); 0503 0504 int 0505 vmeTsi148IntRaise(int level, unsigned vector); 0506 0507 /* Loopback test of the VME interrupt subsystem. 0508 * - installs ISRs on 'vector' and on TSI_VME_SW_IACK_INT_VEC 0509 * - asserts VME interrupt 'level' 0510 * - waits for both interrupts: 'ordinary' VME interrupt of 'level' and 0511 * IACK completion interrupt ('special' vector TSI_VME_SW_IACK_INT_VEC). 0512 * 0513 * NOTES: 0514 * - make sure no other handler responds to 'level'. 0515 * - make sure no ISR is installed on both vectors yet. 0516 * - ISRs installed by this routine are removed after completion. 0517 * - no concurrent access protection of all involved resources 0518 * (levels, vectors and registers [see vmeTsi148IntRaise()]) 0519 * is implemented. 0520 * - this routine is intended for TESTING (when implementing new BSPs etc.). 0521 * - one RTEMS message queue is temporarily used (created/deleted). 0522 * 0523 * RETURNS: 0524 * 0: Success. 0525 * -1: Invalid arguments. 0526 * 1: Test failed (outstanding interrupts). 0527 * rtems_status_code: Failed RTEMS directive. 0528 */ 0529 0530 int 0531 vmeTsi148IntLoopbackTst(int level, unsigned vector); 0532 0533 /* use these special vectors to connect a handler to the 0534 * tsi148 specific interrupts (such as "DMA done", SW or 0535 * error irqs etc.) 0536 * NOTE: The wrapper clears all status LINT bits (except 0537 * for regular VME irqs). Also note that it is the user's 0538 * responsibility to enable the necessary interrupts in 0539 * LINT_EN 0540 * 0541 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 0542 * DO NOT CHANGE THE ORDER OF THESE VECTORS - THE DRIVER 0543 * DEPENDS ON IT 0544 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 0545 * 0546 * Deliberately, these vectors match the universe driver's 0547 */ 0548 /* 256 no VOWN interrupt */ 0549 #define TSI_DMA_INT_VEC 257 0550 #define TSI_LERR_INT_VEC 258 0551 #define TSI_VERR_INT_VEC 259 0552 /* 260 is reserved */ 0553 #define TSI_VME_SW_IACK_INT_VEC 261 0554 /* 262 no PCI SW IRQ */ 0555 #define TSI_SYSFAIL_INT_VEC 263 0556 #define TSI_ACFAIL_INT_VEC 264 0557 #define TSI_MBOX0_INT_VEC 265 0558 #define TSI_MBOX1_INT_VEC 266 0559 #define TSI_MBOX2_INT_VEC 267 0560 #define TSI_MBOX3_INT_VEC 268 0561 #define TSI_LM0_INT_VEC 269 0562 #define TSI_LM1_INT_VEC 270 0563 #define TSI_LM2_INT_VEC 271 0564 #define TSI_LM3_INT_VEC 272 0565 0566 /* New vectors; only on TSI148 */ 0567 #define TSI_VIES_INT_VEC 273 0568 #define TSI_DMA1_INT_VEC 274 0569 0570 #define TSI_NUM_INT_VECS 275 0571 0572 #ifdef __INSIDE_RTEMS_BSP__ 0573 0574 #include <stdarg.h> 0575 0576 /* the tsi148 interrupt handler is capable of routing all sorts of 0577 * (VME) interrupts to 4 different lines (some of) which may be hooked up 0578 * in a (board specific) way to a PIC. 0579 * 0580 * This driver initially supports at most two lines (i.e., if the user 0581 * doesn't re-route anything). By default, it routes the 0582 * 7 VME interrupts to the main line and optionally, it routes the 'special' 0583 * interrupts generated by the tsi148 itself (DMA done, SW irq etc.) 0584 * to a second line. If no second line is available, all IRQs are routed 0585 * to the main line. 0586 * 0587 * The routing of interrupts to the two lines can be modified (using 0588 * the vmeTsi148IntRoute() call - see above - i.e., to make use of 0589 * different hardware priorities and/or more physically available lines. 0590 * 0591 * Because the driver has no way to figure out which lines are actually 0592 * wired to the PIC, this information has to be provided when installing 0593 * the manager. 0594 * 0595 * Hence the manager sets up routing VME interrupts to 1 or 2 tsi148 0596 * OUTPUTS. However, it must also be told to which PIC INPUTS they 0597 * are wired. 0598 * Optionally, the first PIC input line can be read from PCI config space 0599 * but the second must be passed to this routine. Note that the info read 0600 * from PCI config space is wrong for some boards! 0601 * 0602 * PARAMETERS: 0603 * flags: VMETSI148_IRQ_MGR_FLAG_SHARED: 0604 * use the BSP_install_rtems_shared_irq_handler() instead 0605 * of BSP_install_rtems_irq_handler(). Use this if the PIC 0606 * line is used by other devices, too. 0607 * CAVEAT: shared interrupts need RTEMS workspace, i.e., the 0608 * VME interrupt manager can only be installed 0609 * *after workspace is initialized* if 'shared' is nonzero 0610 * (i.e., *not* from bspstart()). 0611 * 0612 * tsi_pin_0: to which output pin (of the tsi148) should the 7 0613 * VME irq levels be routed. 0614 * 0615 * pic_pin_0: specifies to which PIC input the 'main' output is 0616 * wired on your board. If passed a value < 0, the driver 0617 * reads this information from PCI config space ("IRQ line"). 0618 * ... : up to three additional tsi_pin/pic_pin pairs can be 0619 * specified if your board provides more physical wires. 0620 * In any case must the varargs list be terminated by '-1'. 0621 * 0622 * RETURNS: 0 on success, -1 on failure. 0623 * 0624 * NOTES: The Tsi148 always does 'posted' writes through a FIFO buffer. 0625 * This effectively makes VME write operations asynchronous 0626 * which can have undesired side-effects. 0627 * In particular, consider the case of an ISR clearing the 0628 * interrupt condition by writing to a CSR. The write operation 0629 * doesn't really do anything but goes into the FIFO and 0630 * the user ISR returns. At this point, the interrupt manager 0631 * may find the IRQ still pending, trying another IACK 0632 * cycle. Because it is probable that at this time the FIFO 0633 * has been flushed and the CSR-write operation been effective, 0634 * the IACK then times out. 0635 * Note that this phenomenon becomes more obvious as CPUs 0636 * become faster. 0637 * 0638 * To avoid this race condition and many VME drivers having 0639 * to be re-written, a VME read (having the desired side-effect 0640 * of flushing the write FIFO) must be issued between the 0641 * user ISR returning and the interrupt manager checking for 0642 * more pending interrupts. 0643 * 0644 * Therefore, the BSP needs to map the Tsi148 register 0645 * block to VME so that a read over VME can be effectuated. 0646 * (In addition to being mapped to VME, the mapped address 0647 * range must be accessible through an outbound window.) 0648 */ 0649 0650 #define VMETSI148_IRQ_MGR_FLAG_SHARED 1 0651 int 0652 vmeTsi148InstallIrqMgrAlt(int shared, int tsi_pin0, int pic_pin0, ...); 0653 0654 int 0655 vmeTsi148InstallIrqMgrVa(int shared, int tsi_pin0, int pic_pin0, va_list ap); 0656 #endif 0657 0658 #ifdef __cplusplus 0659 } 0660 #endif 0661 0662 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |