source: rtems/bsps/powerpc/include/bsp/vmeTsi148.h @ a2dad96

5
Last change on this file since a2dad96 was 814eccb4, checked in by Sebastian Huber <sebastian.huber@…>, on 04/03/18 at 14:41:16

bsps: Move VME support to bsps

The VME support is only used by powerpc BSPs.

This patch is a part of the BSP source reorganization.

Update #3285.

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