source: rtems/c/src/lib/libbsp/shared/vmeUniverse/vmeTsi148.h @ adac8ab

4.104.114.84.95
Last change on this file since adac8ab was adac8ab, checked in by Till Straumann <strauman@…>, on 01/17/07 at 06:33:29

2007-01-16 Till Straumann <strauman@…>

  • vmeUniverse/vmeTsi148.c, vmeUniverse/vmeTsi148.h,
  • vmeUniverse/vmeUniverse.c, vmeUniverse/vmeUniverse.h,
  • vmeUniverse/vme_am_defs.h: Added SLAC/Stanford Authorship Note / Copyright + Liability Disclaimer.
  • Property mode set to 100644
File size: 21.8 KB
RevLine 
[784e792]1/* $Id$ */
2#ifndef VME_TSI148_DRIVER_H
3#define VME_TSI148_DRIVER_H
4
[adac8ab]5/* Driver for the Tundra Tsi148 pci-vme bridge */
6
7/*
8 * Authorship
9 * ----------
10 * This software was created by
11 *     Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
12 *         Stanford Linear Accelerator Center, Stanford University.
13 *
14 * Acknowledgement of sponsorship
15 * ------------------------------
16 * This software was produced by
17 *     the Stanford Linear Accelerator Center, Stanford University,
18 *         under Contract DE-AC03-76SFO0515 with the Department of Energy.
19 *
20 * Government disclaimer of liability
21 * ----------------------------------
22 * Neither the United States nor the United States Department of Energy,
23 * nor any of their employees, makes any warranty, express or implied, or
24 * assumes any legal liability or responsibility for the accuracy,
25 * completeness, or usefulness of any data, apparatus, product, or process
26 * disclosed, or represents that its use would not infringe privately owned
27 * rights.
28 *
29 * Stanford disclaimer of liability
30 * --------------------------------
31 * Stanford University makes no representations or warranties, express or
32 * implied, nor assumes any liability for the use of this software.
33 *
34 * Stanford disclaimer of copyright
35 * --------------------------------
36 * Stanford University, owner of the copyright, hereby disclaims its
37 * copyright and all other rights in this software.  Hence, anyone may
38 * freely use it for any purpose without restriction. 
39 *
40 * Maintenance of notices
41 * ----------------------
42 * In the interest of clarity regarding the origin and status of this
43 * SLAC software, this and all the preceding Stanford University notices
44 * are to remain affixed to any copy or derivative of this software made
45 * or distributed by the recipient and are to be affixed to any copy of
46 * software made or distributed by the recipient that contains a copy or
47 * derivative of this software.
48 *
49 * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
50 */
[784e792]51
[afd4c7b]52#include <stdint.h>
[784e792]53#include <bsp/vme_am_defs.h>
54
[afd4c7b]55
[784e792]56/* NOTE: A64 currently not implemented */
57
58/* These can be ored with the AM */
59
[afd4c7b]60/* NOTE: unlike the universe, the tsi148 doesn't allow for disabling posted writes ! */
[784e792]61
[afd4c7b]62#define VME_MODE_PREFETCH_ENABLE                        VME_AM_IS_MEMORY
63#define _LD_VME_MODE_PREFETCHSZ                         24
64#define VME_MODE_PREFETCH_SIZE(x)                       (((x)&3)<<_LD_VME_MODE_PREFETCHSZ)
[784e792]65
[afd4c7b]66/* These bits can be or'ed with the address-modifier when calling
67 * the 'XlateAddr' routine below to further qualify the
68 * search criteria.
[784e792]69 */
[afd4c7b]70#define VME_MODE_MATCH_MASK                                     (3<<30)
71#define VME_MODE_EXACT_MATCH                            (2<<30) /* all bits must match */
72#define VME_MODE_AS_MATCH                                       (1<<30) /* only A16/24/32 must match */
[784e792]73
74#ifdef __cplusplus
75extern "C" {
76#endif
77
[c2fc65b]78typedef volatile uint32_t BERegister; /* emphasize contents are big endian */
[784e792]79
80/*
81 * Scan the PCI busses for the Nth (N=='instance') Tsi148 VME bridge.
82 *
83 * RETURNS:
84 *    contents of the IRQ_LINE PCI config register on Success,
85 *    the base address of the Tsi148 register block is stored in
86 *    *pbase.
87 *    -1 on error (no Tsi found, error accessing PCI config space).
88 *
89 * SIDE_EFFECTS: PCI busmaster and response to memory addresses is enabled.
90 */
91int
92vmeTsi148FindPciBase(int instance, BERegister **pbase);
93
94/* Initialize driver for Nth Tsi148 device found.
95 * This routine does not change any registers but
96 * just scans the PCI bus for Tsi bridges and initializes
97 * a driver slot.
98 *
99 * RETURNS: 0 on success, nonzero on error (or if no Tsi148
100 *          device is found).
101 */
102int
103vmeTsi148InitInstance(unsigned instance);
104
105/* Initialize driver with 1st Tsi148 bridge found
106 * RETURNS: (see vmeTsi148InitInstance()).
107 */
108int
109vmeTsi148Init(void);
110
111/* setup the tsi148 chip, i.e. disable most of its
112 * mappings, reset interrupts etc.
113 */
114void
115vmeTsi148ResetXX(BERegister *base);
116
117/* setup the tsi148 connected to the first driver slot */
118void
119vmeTsi148Reset();
120
121/* NOTE: all non-'XX' versions of driver entry points which
122 *       have an associated 'XX' entry point operate on the
123 *       device connected to the 1st driver slot.
124 */
125
126/* configure a outbound port
127 *
128 *   port:          port number 0..7
129 *
130 *   address_space: vxWorks compliant addressing mode identifier
131 *                  (see vme.h). The most important are:
132 *                    0x0d - A32, Sup, Data
133 *                    0x3d - A24, Sup, Data
134 *                    0x2d - A16, Sup, Data
135 *                  additionally, the value 0 is accepted; it will
136 *                  disable this port.
137 *   vme_address:   address on the vme_bus of this port.
138 *   local_address: address on the pci_bus of this port.
139 *   length:        size of this port.
140 *
141 *   NOTE: the addresses and length parameters must meet certain alignment
142 *         requirements (see Tsi148 documentation).
143 *
144 *   RETURNS: 0 on success, -1 on failure. Error messages printed to stderr.
145 */
146
147int
148vmeTsi148OutboundPortCfgXX(
149        BERegister              *base,
150        unsigned long   port,
151        unsigned long   address_space,
152        unsigned long   vme_address,
153        unsigned long   pci_address,
154        unsigned long   length);
155
156int
157vmeTsi148OutboundPortCfg(
158        unsigned long   port,
159        unsigned long   address_space,
160        unsigned long   vme_address,
161        unsigned long   pci_address,
162        unsigned long   length);
163
164
165/* configure a VME inbound (PCI master) port */
166int
167vmeTsi148InboundPortCfgXX(
168        BERegister              *base,
169        unsigned long   port,
170        unsigned long   address_space,
171        unsigned long   vme_address,
172        unsigned long   pci_address,
173        unsigned long   length);
174
175int
176vmeTsi148InboundPortCfg(
177        unsigned long   port,
178        unsigned long   address_space,
179        unsigned long   vme_address,
180        unsigned long   pci_address,
181        unsigned long   length);
182
183/* Translate an address through the bridge
184 *
185 * vmeTsi248XlateAddr(0,0,as,addr,&result)
186 * yields a VME a address that reflects
187 * a local memory location as seen from the VME bus through the
188 * tsi148 VME inbound port.
189 *
190 * Likewise does vmeTsi148XlateAddr(1,0,as,addr,&result)
191 * translate a VME bus addr (backwards, through the VME outbound
192 * port) to the PCI side of the bridge.
193 *
194 * A valid address space modifier must be specified.
195 * If VME_MODE_EXACT_MATCH is set, all the mode bits must
196 * match the requested mode. If VME_MODE_EXACT_MATCH is not
197 * set in the mode word, only the basic mode (address-space,
198 * sup/usr and pgm/data) is compared.
199 *
200 * The 'reverse' parameter may be used to find a reverse
201 * mapping, i.e. the pci address in a outbound window can be
202 * found if the respective vme address is known etc.
203 *
204 * RETURNS: translated address in *pbusAdrs / *plocalAdrs
205 *
206 *          0:  success
207 *          -1: address/modifier not found in any bridge port
208 *          -2: invalid modifier
209 */
210
211int
212vmeTsi148XlateAddrXX(
213        BERegister *base,       /* TSI 148 base address */
214        int outbound,           /* look in the outbound windows */
215        int reverse,            /* reverse mapping; for outbound ports: map local to VME */
216        unsigned long as,       /* address space */
217        unsigned long aIn,      /* address to look up */
218        unsigned long *paOut/* where to put result */
219        );
220
221int
222vmeTsi148XlateAddr(
223        int outbound,           /* look in the outbound windows */
224        int reverse,            /* reverse mapping; for outbound: map local to VME */
225        unsigned long as,       /* address space */
226        unsigned long aIn,      /* address to look up */
227        unsigned long *paOut/* where to put result */
228        );
229
[43ea369]230
231/* avoid pulling stdio.h into this header.
232 * Applications that want a declaration of the
233 * following routines should
234 *  #include <stdio.h>
235 *  #define _VME_TSI148_DECLARE_SHOW_ROUTINES
236 *  #include <vmeTsi148.h>
237 */
238#ifdef _VME_TSI148_DECLARE_SHOW_ROUTINES
239
[784e792]240/* Print the current configuration of all outbound ports to
241 * f (stdout if NULL)
242 */
243
244void
245vmeTsi148OutboundPortsShowXX(BERegister *base, FILE *f);
246
247void
248vmeTsi148OutboundPortsShow(FILE *f);
249
250/* Print the current configuration of all inbound ports to
251 * f (stdout if NULL)
252 */
253
254void
255vmeTsi148InboundPortsShowXX(BERegister *base, FILE *f);
256
257void
258vmeTsi148InboundPortsShow(FILE *f);
259
[43ea369]260#endif
261
[784e792]262
263/* Disable all in- or out-bound ports, respectively */
264void
265vmeTsi148DisableAllInboundPortsXX(BERegister *base);
266
267void
268vmeTsi148DisableAllInboundPorts(void);
269
270void
271vmeTsi148DisableAllOutboundPortsXX(BERegister *base);
272
273void
274vmeTsi148DisableAllOutboundPorts(void);
275
276#       define TSI_VEAT_VES                     (1<<31)
277#       define TSI_VEAT_VEOF            (1<<30)
278#       define TSI_VEAT_VESCL           (1<<29)
279#       define TSI_VEAT_2eOT            (1<<21)
280#       define TSI_VEAT_2eST            (1<<20)
281#       define TSI_VEAT_BERR            (1<<19)
282#       define TSI_VEAT_LWORD           (1<<18)
283#       define TSI_VEAT_WRITE           (1<<17)
284#       define TSI_VEAT_IACK            (1<<16)
285#       define TSI_VEAT_DS1                     (1<<15)
286#       define TSI_VEAT_DS0                     (1<<14)
287#       define TSI_VEAT_AM(v)           (((v)>>8)&63)
288#       define TSI_VEAT_XAM(v)          ((v)&255)
289
290/* Check and clear the error (AKA 'exception') register.
291 * Note that the Tsi148 does *not* propagate VME bus errors of any kind to
292 * the PCI status register and hence this routine (or registering an ISR
293 * to the TSI_VERR_INT_VEC) is the only means for detecting a bus error.
294 *
295 * RETURNS:
296 *   0 if no error has occurred since this routine was last called.
297 *     Contents of the 'VEAT' register (bit definitions as above)
298 *     otherwise.
[afd4c7b]299 *   If a non-NULL 'paddr'  argument is provided then the lower 32-bit
300 *   of the error address is stored in *paddr (only if return value is
301 *   non-zero).
[784e792]302 *
303 * SIDE EFFECTS: this routine clears the error attribute register, allowing
304 *               for future errors to be latched.
305 */
306unsigned long
[afd4c7b]307vmeTsi148ClearVMEBusErrorsXX(BERegister *base, uint32_t *paddr);
[784e792]308
309unsigned long
[afd4c7b]310vmeTsi148ClearVMEBusErrors(uint32_t *paddr);
311
312/* Map internal register block to VME.
313 *
314 * This routine is intended for BSP implementors. The registers must be
315 * accessible from VME so that the interrupt handler can flush the
316 * bridge FIFO (see below).
317 *
318 *            vme_base: VME address where the TSI registers (4k) can be mapped.
319 *                      This VME address must fall into a range covered by
320 *                      any pre-configured outbound window.
321 *       address_space: The desired VME address space.
322 *                      (all of SUP/USR/PGM/DATA are always accepted).
323 *
324 * See NOTES [vmeTsi148InstallIrqMgrAlt()] below for further information.
325 *
326 * RETURNS: 0 on success, nonzero on error. It is not possible (and results
327 *          in a non-zero return code) to change the CRG VME address after
328 *          initializing the interrupt manager as it uses the CRG.
329 */
330int
331vmeTsi148MapCRGXX(BERegister *base, uint32_t vme_base, uint32_t address_space);
332
333int
334vmeTsi148MapCRG(uint32_t vme_base, uint32_t address_space);
335
[784e792]336
337/* VME Interrupt Handler functionality */
338
339/* we dont use the current RTEMS/BSP interrupt API for the
340 * following reasons:
341 *
342 *    - RTEMS/BSP API does not pass an argument to the ISR :-( :-(
343 *    - no separate vector space for VME vectors. Some vectors would
344 *      have to overlap with existing PCI/ISA vectors.
345 *    - RTEMS/BSP API allocates a structure for every possible vector
346 *    - the irq_on(), irq_off() functions add more bloat than helping.
347 *      They are (currently) only used by the framework to disable
348 *      interrupts at the device level before removing a handler
349 *      and to enable interrupts after installing a handler.
350 *      These operations may as well be done by the driver itself.
351 *
352 * Hence, we maintain our own (VME) handler table and hook our PCI
353 * handler into the standard RTEMS/BSP environment. Our handler then
354 * dispatches VME interrupts.
355 */
356
357typedef void (*VmeTsi148ISR) (void *usrArg, unsigned long vector);
358
359/* install a handler for a VME vector
360 * RETURNS 0 on success, nonzero on failure.
361 */
362int
363vmeTsi148InstallISR(unsigned long vector, VmeTsi148ISR handler, void *usrArg);
364
365/* remove a handler for a VME vector. The vector and usrArg parameters
366 * must match the respective parameters used when installing the handler.
367 * RETURNS 0 on success, nonzero on failure.
368 */
369int
370vmeTsi148RemoveISR(unsigned long vector, VmeTsi148ISR handler, void *usrArg);
371
372/* query for the currently installed ISR and usr parameter at a given vector
373 * RETURNS: ISR or 0 (vector too big or no ISR installed)
374 */
375VmeTsi148ISR
376vmeTsi148ISRGet(unsigned long vector, void **parg);
377
378/* utility routines to enable/disable a VME IRQ level
379 *
380 * To enable/disable the internal interrupt sources (special vectors above)
381 * pass a vector argument > 255.
382 *
383 * RETURNS 0 on success, nonzero on failure
384 */
385int
386vmeTsi148IntEnable(unsigned int level);
387
388int
389vmeTsi148IntDisable(unsigned int level);
390
391/* Check if an interrupt level or internal source is enabled:
392 *
393 * 'level': VME level 1..7 or internal special vector > 255
394 *
395 * RETURNS: value > 0 if interrupt is currently enabled,
396 *          zero      if interrupt is currently disabled,
397 *          -1        on error (invalid argument).
398 */
399
400int
401vmeTsi148IntIsEnabled(unsigned int level);
402
403/* Set IACK width (1,2, or 4 bytes) for a given interrupt level.
404 *
405 * 'width' arg may be 0,1,2 or 4. If zero, the currently active
406 * value is returned but not modified.
407 *
408 * RETURNS: old width or -1 if invalid argument.
409 */
410
411int
412vmeTsi148SetIackWidth(int level, int width);
413
414/* Change the routing of IRQ 'level' to 'pin'.
415 * If the BSP connects more than one of the four
416 * physical interrupt lines from the tsi148 to
417 * the board's PIC then you may change the physical
418 * line a given 'level' is using. By default,
419 * all 7 VME levels use the first wire (pin==0) and
420 * all internal sources use the (optional) second
421 * wire (pin==1) [The driver doesn't support more than
422 * four wires].
423 * This feature is useful if you want to make use of
424 * different hardware priorities of the PIC. Let's
425 * say you want to give IRQ level 7 the highest priority.
426 * You could then give 'pin 0' a higher priority (at the
427 * PIC) and 'pin 1' a lower priority and issue.
428 *
429 *   for ( i=1; i<7; i++ ) vmeTsi148IntRoute(i, 1);
430 *
431 * PARAMETERS:
432 *    'level' : VME interrupt level '1..7' or one of
433 *              the internal sources. Pass the internal
434 *              source's vector number (>=256).
435 *    'pin'   : a value of 0 routes the requested IRQ to
436 *              the first line registered with the manager,
437 *              a value of 1 routes it to the second wire
438 *              etc.
439 *
440 * RETURNS: 0 on success, nonzero on error (invalid arguments)
441 *
442 * NOTES:       - DONT change the tsi148 'map' registers
443 *            directly. The driver caches routing internally.
444 *          - support for the extra wires (beyond wire #0) is
445 *            board dependent. If the board only provides
446 *            a single physical wire from the tsi148 to
447 *            the PIC then the feature might not be available.
448 */
449int
450vmeTsi148IntRoute(unsigned int level, unsigned int pin);
451
452/* Raise a VME Interrupt at 'level' and respond with 'vector' to a
453 * handler on the VME bus. (The handler could be a different board
454 * or the tsi148 itself.
455 *
456 * Note that you could install a interrupt handler at TSI_VME_SW_IACK_INT_VEC
457 * to be notified of an IACK cycle having completed.
458 *
459 * This routine is mainly FOR TESTING.
460 *
461 * NOTES:
462 *   - the VICR register is modified.
463 *   - NO MUTUAL EXCLUSION PROTECTION (reads VICR, modifies then writes back).
464 *     If several users need access to VICR it is their responsibility to serialize access.
465 *
466 * Arguments:
467 *  'level':  interrupt level, 1..7
468 *  'vector': vector number (0..255) that the tsi148 puts on the bus in response to
469 *            an IACK cycle.
470 *
471 * RETURNS:
472 *        0:  Success
473 *       -1:  Invalid argument (level not 1..7, vector >= 256)
474 *       -2:  Interrupt 'level' already asserted (maybe nobody handles it).
475 *            You can manually clear it be setting the IRQC bit in
476 *            VICR. Make sure really nobody responds to avoid spurious
477 *            interrupts (consult tsi148 docs).
478 */
479
480int
481vmeTsi148IntRaiseXX(BERegister *base, int level, unsigned vector);
482
483int
484vmeTsi148IntRaise(int level, unsigned vector);
485
486/* Loopback test of the VME interrupt subsystem.
487 *  - installs ISRs on 'vector' and on TSI_VME_SW_IACK_INT_VEC
488 *  - asserts VME interrupt 'level'
489 *  - waits for both interrupts: 'ordinary' VME interrupt of 'level' and
490 *    IACK completion interrupt ('special' vector TSI_VME_SW_IACK_INT_VEC).
491 *
492 * NOTES:
493 *  - make sure no other handler responds to 'level'.
494 *  - make sure no ISR is installed on both vectors yet.
495 *  - ISRs installed by this routine are removed after completion.
496 *  - no concurrent access protection of all involved resources
497 *    (levels, vectors and registers  [see vmeTsi148IntRaise()])
498 *    is implemented.
499 *  - this routine is intended for TESTING (when implementing new BSPs etc.).
500 *  - one RTEMS message queue is temporarily used (created/deleted).
501 *
502 * RETURNS:
503 *                 0: Success.
504 *                -1: Invalid arguments.
505 *                 1: Test failed (outstanding interrupts).
506 * rtems_status_code: Failed RTEMS directive.
507 */
508
509int
510vmeTsi148IntLoopbackTst(int level, unsigned vector);
511
512/* use these special vectors to connect a handler to the
513 * tsi148 specific interrupts (such as "DMA done", SW or
514 * error irqs etc.)
515 * NOTE: The wrapper clears all status LINT bits (except
516 * for regular VME irqs). Also note that it is the user's
517 * responsibility to enable the necessary interrupts in
518 * LINT_EN
519 *
520 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
521 * DO NOT CHANGE THE ORDER OF THESE VECTORS - THE DRIVER
522 * DEPENDS ON IT
523 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
524 *
525 * Deliberately, these vectors match the universe driver's
526 */
527/* 256 no VOWN interrupt */
528#define TSI_DMA_INT_VEC                 257
529#define TSI_LERR_INT_VEC                258
530#define TSI_VERR_INT_VEC                259
531/* 260 is reserved       */
532#define TSI_VME_SW_IACK_INT_VEC 261
533/* 262 no PCI SW IRQ     */
534#define TSI_SYSFAIL_INT_VEC             263
535#define TSI_ACFAIL_INT_VEC              264
536#define TSI_MBOX0_INT_VEC               265
537#define TSI_MBOX1_INT_VEC               266
538#define TSI_MBOX2_INT_VEC               267
539#define TSI_MBOX3_INT_VEC               268
540#define TSI_LM0_INT_VEC                 269
541#define TSI_LM1_INT_VEC                 270
542#define TSI_LM2_INT_VEC                 271
543#define TSI_LM3_INT_VEC                 272
544
545/* New vectors; only on TSI148 */
546#define TSI_VIES_INT_VEC                273
547#define TSI_DMA1_INT_VEC                274
548
549#define TSI_NUM_INT_VECS                275
550
[afd4c7b]551#ifdef __INSIDE_RTEMS_BSP__
552
553#include <stdarg.h>
554
[784e792]555/* the tsi148 interrupt handler is capable of routing all sorts of
556 * (VME) interrupts to 4 different lines (some of) which may be hooked up
557 * in a (board specific) way to a PIC.
558 *
559 * This driver initially supports at most two lines (i.e., if the user
560 * doesn't re-route anything). By default, it routes the
561 * 7 VME interrupts to the main line and optionally, it routes the 'special'
562 * interrupts generated by the tsi148 itself (DMA done, SW irq etc.)
563 * to a second line. If no second line is available, all IRQs are routed
564 * to the main line.
565 *
566 * The routing of interrupts to the two lines can be modified (using
567 * the vmeTsi148IntRoute() call - see above - i.e., to make use of
568 * different hardware priorities and/or more physically available lines.
569 *
570 * Because the driver has no way to figure out which lines are actually
571 * wired to the PIC, this information has to be provided when installing
572 * the manager.
573 *
574 * Hence the manager sets up routing VME interrupts to 1 or 2 tsi148
575 * OUTPUTS. However, it must also be told to which PIC INPUTS they
576 * are wired.
577 * Optionally, the first PIC input line can be read from PCI config space
578 * but the second must be passed to this routine. Note that the info read
579 * from PCI config space is wrong for some boards!
580 *
581 * PARAMETERS:
[afd4c7b]582 *              flags:  VMETSI148_IRQ_MGR_FLAG_SHARED: 
583 *                      use the BSP_install_rtems_shared_irq_handler() instead
[784e792]584 *                      of BSP_install_rtems_irq_handler(). Use this if the PIC
585 *                      line is used by other devices, too.
586 *                      CAVEAT: shared interrupts need RTEMS workspace, i.e., the
587 *                      VME interrupt manager can only be installed
588 *                      *after workspace is initialized* if 'shared' is nonzero
589 *                      (i.e., *not* from bspstart()).
[afd4c7b]590 *
[784e792]591 *           tsi_pin_0: to which output pin (of the tsi148) should the 7
592 *                                      VME irq levels be routed.
[afd4c7b]593 *
[784e792]594 *           pic_pin_0: specifies to which PIC input the 'main' output is
595 *                      wired on your board. If passed a value < 0, the driver
596 *                      reads this information from PCI config space ("IRQ line").
597 *           ...      : up to three additional tsi_pin/pic_pin pairs can be
598 *                      specified if your board provides more physical wires.
599 *                      In any case must the varargs list be terminated by '-1'.
600 *
601 * RETURNS: 0 on success, -1 on failure.
[afd4c7b]602 *
603 * NOTES: The Tsi148 always does 'posted' writes through a FIFO buffer.
604 *        This effectively makes VME write operations asynchronous
605 *        which can have undesired side-effects.
606 *        In particular, consider the case of an ISR clearing the
607 *        interrupt condition by writing to a CSR. The write operation
608 *        doesn't really do anything but goes into the FIFO and
609 *        the user ISR returns. At this point, the interrupt manager
610 *        may find the IRQ still pending, trying another IACK
611 *        cycle. Because it is probable that at this time the FIFO
612 *        has been flushed and the CSR-write operation been effective,
613 *        the IACK then times out.
614 *        Note that this phenomenon becomes more obvious as CPUs
615 *        become faster.
616 *
617 *        To avoid this race condition and many VME drivers having
618 *        to be re-written, a VME read (having the desired side-effect
619 *        of flushing the write FIFO) must be issued between the
620 *        user ISR returning and the interrupt manager checking for
621 *        more pending interrupts.
622 *
623 *        Therefore, the BSP needs to map the Tsi148 register
624 *        block to VME so that a read over VME can be effectuated.
625 *        (In addition to being mapped to VME, the mapped address
626 *        range must be accessible through an outbound window.)
[784e792]627 */
[afd4c7b]628
629#define VMETSI148_IRQ_MGR_FLAG_SHARED   1
[784e792]630int
631vmeTsi148InstallIrqMgrAlt(int shared, int tsi_pin0, int pic_pin0, ...);
632
633int
634vmeTsi148InstallIrqMgrVa(int shared, int tsi_pin0, int pic_pin0, va_list ap);
[afd4c7b]635#endif
[784e792]636
637#ifdef __cplusplus
638}
639#endif
640
641#endif
Note: See TracBrowser for help on using the repository browser.