mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
2005-11-04 Till Straumann <strauman@slac.stanford.edu>
* shared/vmeUniverse/vmeTsi148.c, shared/vmeUniverse/vmeTsi148.h,
shared/vmeUniverse/vme_am_defs.h: New files.
* Makefile.am, shared/vmeUniverse/README.universe,
shared/vmeUniverse/vmeUniverse.c, shared/vmeUniverse/vmeUniverse.h:
Several VME related upgrades and fixes, hopefully addressing PR#835:
vmeUniverse driver now supports shared interrupts. vmeUniverse now
supports up to four wires between universe and PIC. A new irq mgr
installation routine has been added allowing to use the new features.
(old version is still present for bwd compatibility). Calls have been
added to change interrupt routing (e.g., if wires have different
priorities at the PIC this feature can be used to configure
priorites). Routine for testing VME interrupts has been added (useful
during BSP development). A new header defining standard VME address
modes has been added so that the VME API doesn't have to #include a
particular bridge driver header. For all driver entry points, a 'XX'
variant has been added which allows to pass the chip's base address
[in case a second universe is sitting on a VME card :-)]. Driver now
uses interrupt line as read from PCI config. space (without offset)
BSP needs to use PCI fixup if necessary. Added a driver for the
tundra tsi148 VME bridge.
This commit is contained in:
@@ -1,3 +1,26 @@
|
||||
2005-11-04 Till Straumann <strauman@slac.stanford.edu>
|
||||
|
||||
* shared/vmeUniverse/vmeTsi148.c, shared/vmeUniverse/vmeTsi148.h,
|
||||
shared/vmeUniverse/vme_am_defs.h: New files.
|
||||
* Makefile.am, shared/vmeUniverse/README.universe,
|
||||
shared/vmeUniverse/vmeUniverse.c, shared/vmeUniverse/vmeUniverse.h:
|
||||
Several VME related upgrades and fixes, hopefully addressing PR#835:
|
||||
vmeUniverse driver now supports shared interrupts. vmeUniverse now
|
||||
supports up to four wires between universe and PIC. A new irq mgr
|
||||
installation routine has been added allowing to use the new features.
|
||||
(old version is still present for bwd compatibility). Calls have been
|
||||
added to change interrupt routing (e.g., if wires have different
|
||||
priorities at the PIC this feature can be used to configure
|
||||
priorites). Routine for testing VME interrupts has been added (useful
|
||||
during BSP development). A new header defining standard VME address
|
||||
modes has been added so that the VME API doesn't have to #include a
|
||||
particular bridge driver header. For all driver entry points, a 'XX'
|
||||
variant has been added which allows to pass the chip's base address
|
||||
[in case a second universe is sitting on a VME card :-)]. Driver now
|
||||
uses interrupt line as read from PCI config. space (without offset)
|
||||
BSP needs to use PCI fixup if necessary. Added a driver for the
|
||||
tundra tsi148 VME bridge.
|
||||
|
||||
2004-02-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
||||
|
||||
* bsp.am: Remove everything but CPPASCOMPILE.
|
||||
|
||||
@@ -15,7 +15,13 @@ EXTRA_DIST += shared/bootcard.c shared/bspclean.c shared/bsplibc.c \
|
||||
shared/gnatinstallhandler.c shared/main.c shared/sbrk.c shared/tod.c \
|
||||
shared/tod.h
|
||||
EXTRA_DIST += shared/vmeUniverse/vmeUniverse.c \
|
||||
shared/vmeUniverse/vmeUniverse.h
|
||||
shared/vmeUniverse/vmeUniverse.h \
|
||||
shared/vmeUniverse/vmeTsi148.c \
|
||||
shared/vmeUniverse/vmeTsi148.h \
|
||||
shared/vmeUniverse/vme_am_defs.h \
|
||||
shared/vmeUniverse/README.porting \
|
||||
shared/vmeUniverse/README.universe
|
||||
|
||||
EXTRA_DIST += shared/include/coverhd.h
|
||||
EXTRA_DIST += shared/gdbstub/rtems-stub-glue.c
|
||||
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
The universe II driver is in a separate subdir
|
||||
because it is maintained at SSRL outside of the
|
||||
rtems CVS tree (it supports other OSes as well)
|
||||
The tundra drivers are in a separate subdir
|
||||
because they are maintained at SSRL outside of the
|
||||
rtems CVS tree. The directory is called 'vmeUniverse'
|
||||
for historic reasons. 'tundra' would be better
|
||||
since we now support the tundra tsi148 as well...
|
||||
|
||||
Till Straumann <strauman@slac.stanford.edu> 1/2002
|
||||
Till Straumann <strauman@slac.stanford.edu> 1/2002, 2005
|
||||
|
||||
NOTES:
|
||||
This driver is maintained _outside_ rtems.
|
||||
These driver are maintained _outside_ rtems.
|
||||
Please forward future modifications to me.
|
||||
|
||||
A BSP that wants to use the vmeUniverse driver
|
||||
A BSP that wants to use these drivers
|
||||
must implement the following headers / functionality:
|
||||
- <bsp/pci.h> offering an API like 'libbsp/powerpc/shared/pci'
|
||||
- <bsp/irq.h> offering the 'new style' RTEMS irq API
|
||||
(like 'libbsp/powerpc/shared/irq').
|
||||
|
||||
The BSP should then use "VPATH magic" (to use Joel's
|
||||
words :-) to reach the vmeUniverse.* files in the
|
||||
universe subdir.
|
||||
words :-) to reach the vmeUniverse.* / vmeTsi148.* files
|
||||
in this subdir.
|
||||
|
||||
1649
c/src/lib/libbsp/shared/vmeUniverse/vmeTsi148.c
Normal file
1649
c/src/lib/libbsp/shared/vmeUniverse/vmeTsi148.c
Normal file
File diff suppressed because it is too large
Load Diff
533
c/src/lib/libbsp/shared/vmeUniverse/vmeTsi148.h
Normal file
533
c/src/lib/libbsp/shared/vmeUniverse/vmeTsi148.h
Normal file
@@ -0,0 +1,533 @@
|
||||
/* $Id$ */
|
||||
#ifndef VME_TSI148_DRIVER_H
|
||||
#define VME_TSI148_DRIVER_H
|
||||
|
||||
/* Routines to configure and use the Tundra Tsi148 VME bridge
|
||||
* Author: Till Straumann <strauman@slac.stanford.edu>
|
||||
* Sept. 2005.
|
||||
*/
|
||||
|
||||
#include <bsp/vme_am_defs.h>
|
||||
|
||||
/* NOTE: A64 currently not implemented */
|
||||
|
||||
/* These can be ored with the AM */
|
||||
|
||||
#define VME_MODE_PREFETCH_ENABLE (4<<12)
|
||||
#define VME_MODE_PREFETCH_SIZE(x) (((x)&3)<<12)
|
||||
#define VME_MODE_2eSSTM(x) (((x)&7)<<16)
|
||||
|
||||
#define VME_MODE_DBW32_DISABLE (8<<12)
|
||||
|
||||
/* Transfer modes:
|
||||
*
|
||||
* On a outbound window, only the least significant
|
||||
* bit that is set is considered.
|
||||
* On a inbound window, the bitwise OR of modes
|
||||
* is accepted.
|
||||
*/
|
||||
#define VME_MODE_BLT (1<<20)
|
||||
#define VME_MODE_MBLT (1<<21)
|
||||
#define VME_MODE_2eVME (1<<22)
|
||||
#define VME_MODE_2eSST (1<<23)
|
||||
#define VME_MODE_2eSST_BCST (1<<24)
|
||||
#define VME_MODE_MASK (31<<20)
|
||||
|
||||
#define VME_MODE_EXACT_MATCH (1<<31)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef volatile unsigned32 BERegister; /* emphasize contents are big endian */
|
||||
|
||||
/*
|
||||
* Scan the PCI busses for the Nth (N=='instance') Tsi148 VME bridge.
|
||||
*
|
||||
* RETURNS:
|
||||
* contents of the IRQ_LINE PCI config register on Success,
|
||||
* the base address of the Tsi148 register block is stored in
|
||||
* *pbase.
|
||||
* -1 on error (no Tsi found, error accessing PCI config space).
|
||||
*
|
||||
* SIDE_EFFECTS: PCI busmaster and response to memory addresses is enabled.
|
||||
*/
|
||||
int
|
||||
vmeTsi148FindPciBase(int instance, BERegister **pbase);
|
||||
|
||||
/* Initialize driver for Nth Tsi148 device found.
|
||||
* This routine does not change any registers but
|
||||
* just scans the PCI bus for Tsi bridges and initializes
|
||||
* a driver slot.
|
||||
*
|
||||
* RETURNS: 0 on success, nonzero on error (or if no Tsi148
|
||||
* device is found).
|
||||
*/
|
||||
int
|
||||
vmeTsi148InitInstance(unsigned instance);
|
||||
|
||||
/* Initialize driver with 1st Tsi148 bridge found
|
||||
* RETURNS: (see vmeTsi148InitInstance()).
|
||||
*/
|
||||
int
|
||||
vmeTsi148Init(void);
|
||||
|
||||
/* setup the tsi148 chip, i.e. disable most of its
|
||||
* mappings, reset interrupts etc.
|
||||
*/
|
||||
void
|
||||
vmeTsi148ResetXX(BERegister *base);
|
||||
|
||||
/* setup the tsi148 connected to the first driver slot */
|
||||
void
|
||||
vmeTsi148Reset();
|
||||
|
||||
/* NOTE: all non-'XX' versions of driver entry points which
|
||||
* have an associated 'XX' entry point operate on the
|
||||
* device connected to the 1st driver slot.
|
||||
*/
|
||||
|
||||
/* configure a outbound port
|
||||
*
|
||||
* port: port number 0..7
|
||||
*
|
||||
* address_space: vxWorks compliant addressing mode identifier
|
||||
* (see vme.h). The most important are:
|
||||
* 0x0d - A32, Sup, Data
|
||||
* 0x3d - A24, Sup, Data
|
||||
* 0x2d - A16, Sup, Data
|
||||
* additionally, the value 0 is accepted; it will
|
||||
* disable this port.
|
||||
* vme_address: address on the vme_bus of this port.
|
||||
* local_address: address on the pci_bus of this port.
|
||||
* length: size of this port.
|
||||
*
|
||||
* NOTE: the addresses and length parameters must meet certain alignment
|
||||
* requirements (see Tsi148 documentation).
|
||||
*
|
||||
* RETURNS: 0 on success, -1 on failure. Error messages printed to stderr.
|
||||
*/
|
||||
|
||||
int
|
||||
vmeTsi148OutboundPortCfgXX(
|
||||
BERegister *base,
|
||||
unsigned long port,
|
||||
unsigned long address_space,
|
||||
unsigned long vme_address,
|
||||
unsigned long pci_address,
|
||||
unsigned long length);
|
||||
|
||||
int
|
||||
vmeTsi148OutboundPortCfg(
|
||||
unsigned long port,
|
||||
unsigned long address_space,
|
||||
unsigned long vme_address,
|
||||
unsigned long pci_address,
|
||||
unsigned long length);
|
||||
|
||||
|
||||
/* configure a VME inbound (PCI master) port */
|
||||
int
|
||||
vmeTsi148InboundPortCfgXX(
|
||||
BERegister *base,
|
||||
unsigned long port,
|
||||
unsigned long address_space,
|
||||
unsigned long vme_address,
|
||||
unsigned long pci_address,
|
||||
unsigned long length);
|
||||
|
||||
int
|
||||
vmeTsi148InboundPortCfg(
|
||||
unsigned long port,
|
||||
unsigned long address_space,
|
||||
unsigned long vme_address,
|
||||
unsigned long pci_address,
|
||||
unsigned long length);
|
||||
|
||||
/* Translate an address through the bridge
|
||||
*
|
||||
* vmeTsi248XlateAddr(0,0,as,addr,&result)
|
||||
* yields a VME a address that reflects
|
||||
* a local memory location as seen from the VME bus through the
|
||||
* tsi148 VME inbound port.
|
||||
*
|
||||
* Likewise does vmeTsi148XlateAddr(1,0,as,addr,&result)
|
||||
* translate a VME bus addr (backwards, through the VME outbound
|
||||
* port) to the PCI side of the bridge.
|
||||
*
|
||||
* A valid address space modifier must be specified.
|
||||
* If VME_MODE_EXACT_MATCH is set, all the mode bits must
|
||||
* match the requested mode. If VME_MODE_EXACT_MATCH is not
|
||||
* set in the mode word, only the basic mode (address-space,
|
||||
* sup/usr and pgm/data) is compared.
|
||||
*
|
||||
* The 'reverse' parameter may be used to find a reverse
|
||||
* mapping, i.e. the pci address in a outbound window can be
|
||||
* found if the respective vme address is known etc.
|
||||
*
|
||||
* RETURNS: translated address in *pbusAdrs / *plocalAdrs
|
||||
*
|
||||
* 0: success
|
||||
* -1: address/modifier not found in any bridge port
|
||||
* -2: invalid modifier
|
||||
*/
|
||||
|
||||
int
|
||||
vmeTsi148XlateAddrXX(
|
||||
BERegister *base, /* TSI 148 base address */
|
||||
int outbound, /* look in the outbound windows */
|
||||
int reverse, /* reverse mapping; for outbound ports: map local to VME */
|
||||
unsigned long as, /* address space */
|
||||
unsigned long aIn, /* address to look up */
|
||||
unsigned long *paOut/* where to put result */
|
||||
);
|
||||
|
||||
int
|
||||
vmeTsi148XlateAddr(
|
||||
int outbound, /* look in the outbound windows */
|
||||
int reverse, /* reverse mapping; for outbound: map local to VME */
|
||||
unsigned long as, /* address space */
|
||||
unsigned long aIn, /* address to look up */
|
||||
unsigned long *paOut/* where to put result */
|
||||
);
|
||||
|
||||
/* Print the current configuration of all outbound ports to
|
||||
* f (stdout if NULL)
|
||||
*/
|
||||
|
||||
void
|
||||
vmeTsi148OutboundPortsShowXX(BERegister *base, FILE *f);
|
||||
|
||||
void
|
||||
vmeTsi148OutboundPortsShow(FILE *f);
|
||||
|
||||
/* Print the current configuration of all inbound ports to
|
||||
* f (stdout if NULL)
|
||||
*/
|
||||
|
||||
void
|
||||
vmeTsi148InboundPortsShowXX(BERegister *base, FILE *f);
|
||||
|
||||
void
|
||||
vmeTsi148InboundPortsShow(FILE *f);
|
||||
|
||||
|
||||
/* Disable all in- or out-bound ports, respectively */
|
||||
void
|
||||
vmeTsi148DisableAllInboundPortsXX(BERegister *base);
|
||||
|
||||
void
|
||||
vmeTsi148DisableAllInboundPorts(void);
|
||||
|
||||
void
|
||||
vmeTsi148DisableAllOutboundPortsXX(BERegister *base);
|
||||
|
||||
void
|
||||
vmeTsi148DisableAllOutboundPorts(void);
|
||||
|
||||
# define TSI_VEAT_VES (1<<31)
|
||||
# define TSI_VEAT_VEOF (1<<30)
|
||||
# define TSI_VEAT_VESCL (1<<29)
|
||||
# define TSI_VEAT_2eOT (1<<21)
|
||||
# define TSI_VEAT_2eST (1<<20)
|
||||
# define TSI_VEAT_BERR (1<<19)
|
||||
# define TSI_VEAT_LWORD (1<<18)
|
||||
# define TSI_VEAT_WRITE (1<<17)
|
||||
# define TSI_VEAT_IACK (1<<16)
|
||||
# define TSI_VEAT_DS1 (1<<15)
|
||||
# define TSI_VEAT_DS0 (1<<14)
|
||||
# define TSI_VEAT_AM(v) (((v)>>8)&63)
|
||||
# define TSI_VEAT_XAM(v) ((v)&255)
|
||||
|
||||
/* Check and clear the error (AKA 'exception') register.
|
||||
* Note that the Tsi148 does *not* propagate VME bus errors of any kind to
|
||||
* the PCI status register and hence this routine (or registering an ISR
|
||||
* to the TSI_VERR_INT_VEC) is the only means for detecting a bus error.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0 if no error has occurred since this routine was last called.
|
||||
* Contents of the 'VEAT' register (bit definitions as above)
|
||||
* otherwise.
|
||||
* If a non-NULL 'paddr' argument is provided then the 64-bit error
|
||||
* address is stored in *paddr (only if return value is non-zero).
|
||||
*
|
||||
* SIDE EFFECTS: this routine clears the error attribute register, allowing
|
||||
* for future errors to be latched.
|
||||
*/
|
||||
unsigned long
|
||||
vmeTsi148ClearVMEBusErrorsXX(BERegister *base, unsigned long long *paddr);
|
||||
|
||||
unsigned long
|
||||
vmeTsi148ClearVMEBusErrors(unsigned long long *paddr);
|
||||
|
||||
/* VME Interrupt Handler functionality */
|
||||
|
||||
/* we dont use the current RTEMS/BSP interrupt API for the
|
||||
* following reasons:
|
||||
*
|
||||
* - RTEMS/BSP API does not pass an argument to the ISR :-( :-(
|
||||
* - no separate vector space for VME vectors. Some vectors would
|
||||
* have to overlap with existing PCI/ISA vectors.
|
||||
* - RTEMS/BSP API allocates a structure for every possible vector
|
||||
* - the irq_on(), irq_off() functions add more bloat than helping.
|
||||
* They are (currently) only used by the framework to disable
|
||||
* interrupts at the device level before removing a handler
|
||||
* and to enable interrupts after installing a handler.
|
||||
* These operations may as well be done by the driver itself.
|
||||
*
|
||||
* Hence, we maintain our own (VME) handler table and hook our PCI
|
||||
* handler into the standard RTEMS/BSP environment. Our handler then
|
||||
* dispatches VME interrupts.
|
||||
*/
|
||||
|
||||
typedef void (*VmeTsi148ISR) (void *usrArg, unsigned long vector);
|
||||
|
||||
/* install a handler for a VME vector
|
||||
* RETURNS 0 on success, nonzero on failure.
|
||||
*/
|
||||
int
|
||||
vmeTsi148InstallISR(unsigned long vector, VmeTsi148ISR handler, void *usrArg);
|
||||
|
||||
/* remove a handler for a VME vector. The vector and usrArg parameters
|
||||
* must match the respective parameters used when installing the handler.
|
||||
* RETURNS 0 on success, nonzero on failure.
|
||||
*/
|
||||
int
|
||||
vmeTsi148RemoveISR(unsigned long vector, VmeTsi148ISR handler, void *usrArg);
|
||||
|
||||
/* query for the currently installed ISR and usr parameter at a given vector
|
||||
* RETURNS: ISR or 0 (vector too big or no ISR installed)
|
||||
*/
|
||||
VmeTsi148ISR
|
||||
vmeTsi148ISRGet(unsigned long vector, void **parg);
|
||||
|
||||
/* utility routines to enable/disable a VME IRQ level
|
||||
*
|
||||
* To enable/disable the internal interrupt sources (special vectors above)
|
||||
* pass a vector argument > 255.
|
||||
*
|
||||
* RETURNS 0 on success, nonzero on failure
|
||||
*/
|
||||
int
|
||||
vmeTsi148IntEnable(unsigned int level);
|
||||
|
||||
int
|
||||
vmeTsi148IntDisable(unsigned int level);
|
||||
|
||||
/* Check if an interrupt level or internal source is enabled:
|
||||
*
|
||||
* 'level': VME level 1..7 or internal special vector > 255
|
||||
*
|
||||
* RETURNS: value > 0 if interrupt is currently enabled,
|
||||
* zero if interrupt is currently disabled,
|
||||
* -1 on error (invalid argument).
|
||||
*/
|
||||
|
||||
int
|
||||
vmeTsi148IntIsEnabled(unsigned int level);
|
||||
|
||||
/* Set IACK width (1,2, or 4 bytes) for a given interrupt level.
|
||||
*
|
||||
* 'width' arg may be 0,1,2 or 4. If zero, the currently active
|
||||
* value is returned but not modified.
|
||||
*
|
||||
* RETURNS: old width or -1 if invalid argument.
|
||||
*/
|
||||
|
||||
int
|
||||
vmeTsi148SetIackWidth(int level, int width);
|
||||
|
||||
/* Change the routing of IRQ 'level' to 'pin'.
|
||||
* If the BSP connects more than one of the four
|
||||
* physical interrupt lines from the tsi148 to
|
||||
* the board's PIC then you may change the physical
|
||||
* line a given 'level' is using. By default,
|
||||
* all 7 VME levels use the first wire (pin==0) and
|
||||
* all internal sources use the (optional) second
|
||||
* wire (pin==1) [The driver doesn't support more than
|
||||
* four wires].
|
||||
* This feature is useful if you want to make use of
|
||||
* different hardware priorities of the PIC. Let's
|
||||
* say you want to give IRQ level 7 the highest priority.
|
||||
* You could then give 'pin 0' a higher priority (at the
|
||||
* PIC) and 'pin 1' a lower priority and issue.
|
||||
*
|
||||
* for ( i=1; i<7; i++ ) vmeTsi148IntRoute(i, 1);
|
||||
*
|
||||
* PARAMETERS:
|
||||
* 'level' : VME interrupt level '1..7' or one of
|
||||
* the internal sources. Pass the internal
|
||||
* source's vector number (>=256).
|
||||
* 'pin' : a value of 0 routes the requested IRQ to
|
||||
* the first line registered with the manager,
|
||||
* a value of 1 routes it to the second wire
|
||||
* etc.
|
||||
*
|
||||
* RETURNS: 0 on success, nonzero on error (invalid arguments)
|
||||
*
|
||||
* NOTES: - DONT change the tsi148 'map' registers
|
||||
* directly. The driver caches routing internally.
|
||||
* - support for the extra wires (beyond wire #0) is
|
||||
* board dependent. If the board only provides
|
||||
* a single physical wire from the tsi148 to
|
||||
* the PIC then the feature might not be available.
|
||||
*/
|
||||
int
|
||||
vmeTsi148IntRoute(unsigned int level, unsigned int pin);
|
||||
|
||||
/* Raise a VME Interrupt at 'level' and respond with 'vector' to a
|
||||
* handler on the VME bus. (The handler could be a different board
|
||||
* or the tsi148 itself.
|
||||
*
|
||||
* Note that you could install a interrupt handler at TSI_VME_SW_IACK_INT_VEC
|
||||
* to be notified of an IACK cycle having completed.
|
||||
*
|
||||
* This routine is mainly FOR TESTING.
|
||||
*
|
||||
* NOTES:
|
||||
* - the VICR register is modified.
|
||||
* - NO MUTUAL EXCLUSION PROTECTION (reads VICR, modifies then writes back).
|
||||
* If several users need access to VICR it is their responsibility to serialize access.
|
||||
*
|
||||
* Arguments:
|
||||
* 'level': interrupt level, 1..7
|
||||
* 'vector': vector number (0..255) that the tsi148 puts on the bus in response to
|
||||
* an IACK cycle.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0: Success
|
||||
* -1: Invalid argument (level not 1..7, vector >= 256)
|
||||
* -2: Interrupt 'level' already asserted (maybe nobody handles it).
|
||||
* You can manually clear it be setting the IRQC bit in
|
||||
* VICR. Make sure really nobody responds to avoid spurious
|
||||
* interrupts (consult tsi148 docs).
|
||||
*/
|
||||
|
||||
int
|
||||
vmeTsi148IntRaiseXX(BERegister *base, int level, unsigned vector);
|
||||
|
||||
int
|
||||
vmeTsi148IntRaise(int level, unsigned vector);
|
||||
|
||||
/* Loopback test of the VME interrupt subsystem.
|
||||
* - installs ISRs on 'vector' and on TSI_VME_SW_IACK_INT_VEC
|
||||
* - asserts VME interrupt 'level'
|
||||
* - waits for both interrupts: 'ordinary' VME interrupt of 'level' and
|
||||
* IACK completion interrupt ('special' vector TSI_VME_SW_IACK_INT_VEC).
|
||||
*
|
||||
* NOTES:
|
||||
* - make sure no other handler responds to 'level'.
|
||||
* - make sure no ISR is installed on both vectors yet.
|
||||
* - ISRs installed by this routine are removed after completion.
|
||||
* - no concurrent access protection of all involved resources
|
||||
* (levels, vectors and registers [see vmeTsi148IntRaise()])
|
||||
* is implemented.
|
||||
* - this routine is intended for TESTING (when implementing new BSPs etc.).
|
||||
* - one RTEMS message queue is temporarily used (created/deleted).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0: Success.
|
||||
* -1: Invalid arguments.
|
||||
* 1: Test failed (outstanding interrupts).
|
||||
* rtems_status_code: Failed RTEMS directive.
|
||||
*/
|
||||
|
||||
int
|
||||
vmeTsi148IntLoopbackTst(int level, unsigned vector);
|
||||
|
||||
/* use these special vectors to connect a handler to the
|
||||
* tsi148 specific interrupts (such as "DMA done", SW or
|
||||
* error irqs etc.)
|
||||
* NOTE: The wrapper clears all status LINT bits (except
|
||||
* for regular VME irqs). Also note that it is the user's
|
||||
* responsibility to enable the necessary interrupts in
|
||||
* LINT_EN
|
||||
*
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
* DO NOT CHANGE THE ORDER OF THESE VECTORS - THE DRIVER
|
||||
* DEPENDS ON IT
|
||||
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
*
|
||||
* Deliberately, these vectors match the universe driver's
|
||||
*/
|
||||
/* 256 no VOWN interrupt */
|
||||
#define TSI_DMA_INT_VEC 257
|
||||
#define TSI_LERR_INT_VEC 258
|
||||
#define TSI_VERR_INT_VEC 259
|
||||
/* 260 is reserved */
|
||||
#define TSI_VME_SW_IACK_INT_VEC 261
|
||||
/* 262 no PCI SW IRQ */
|
||||
#define TSI_SYSFAIL_INT_VEC 263
|
||||
#define TSI_ACFAIL_INT_VEC 264
|
||||
#define TSI_MBOX0_INT_VEC 265
|
||||
#define TSI_MBOX1_INT_VEC 266
|
||||
#define TSI_MBOX2_INT_VEC 267
|
||||
#define TSI_MBOX3_INT_VEC 268
|
||||
#define TSI_LM0_INT_VEC 269
|
||||
#define TSI_LM1_INT_VEC 270
|
||||
#define TSI_LM2_INT_VEC 271
|
||||
#define TSI_LM3_INT_VEC 272
|
||||
|
||||
/* New vectors; only on TSI148 */
|
||||
#define TSI_VIES_INT_VEC 273
|
||||
#define TSI_DMA1_INT_VEC 274
|
||||
|
||||
#define TSI_NUM_INT_VECS 275
|
||||
|
||||
/* the tsi148 interrupt handler is capable of routing all sorts of
|
||||
* (VME) interrupts to 4 different lines (some of) which may be hooked up
|
||||
* in a (board specific) way to a PIC.
|
||||
*
|
||||
* This driver initially supports at most two lines (i.e., if the user
|
||||
* doesn't re-route anything). By default, it routes the
|
||||
* 7 VME interrupts to the main line and optionally, it routes the 'special'
|
||||
* interrupts generated by the tsi148 itself (DMA done, SW irq etc.)
|
||||
* to a second line. If no second line is available, all IRQs are routed
|
||||
* to the main line.
|
||||
*
|
||||
* The routing of interrupts to the two lines can be modified (using
|
||||
* the vmeTsi148IntRoute() call - see above - i.e., to make use of
|
||||
* different hardware priorities and/or more physically available lines.
|
||||
*
|
||||
* Because the driver has no way to figure out which lines are actually
|
||||
* wired to the PIC, this information has to be provided when installing
|
||||
* the manager.
|
||||
*
|
||||
* Hence the manager sets up routing VME interrupts to 1 or 2 tsi148
|
||||
* OUTPUTS. However, it must also be told to which PIC INPUTS they
|
||||
* are wired.
|
||||
* Optionally, the first PIC input line can be read from PCI config space
|
||||
* but the second must be passed to this routine. Note that the info read
|
||||
* from PCI config space is wrong for some boards!
|
||||
*
|
||||
* PARAMETERS:
|
||||
* shared: use the BSP_install_rtems_shared_irq_handler() instead
|
||||
* of BSP_install_rtems_irq_handler(). Use this if the PIC
|
||||
* line is used by other devices, too.
|
||||
* CAVEAT: shared interrupts need RTEMS workspace, i.e., the
|
||||
* VME interrupt manager can only be installed
|
||||
* *after workspace is initialized* if 'shared' is nonzero
|
||||
* (i.e., *not* from bspstart()).
|
||||
* tsi_pin_0: to which output pin (of the tsi148) should the 7
|
||||
* VME irq levels be routed.
|
||||
* pic_pin_0: specifies to which PIC input the 'main' output is
|
||||
* wired on your board. If passed a value < 0, the driver
|
||||
* reads this information from PCI config space ("IRQ line").
|
||||
* ... : up to three additional tsi_pin/pic_pin pairs can be
|
||||
* specified if your board provides more physical wires.
|
||||
* In any case must the varargs list be terminated by '-1'.
|
||||
*
|
||||
* RETURNS: 0 on success, -1 on failure.
|
||||
*
|
||||
*/
|
||||
int
|
||||
vmeTsi148InstallIrqMgrAlt(int shared, int tsi_pin0, int pic_pin0, ...);
|
||||
|
||||
int
|
||||
vmeTsi148InstallIrqMgrVa(int shared, int tsi_pin0, int pic_pin0, va_list ap);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,28 +13,71 @@
|
||||
#ifdef __vxworks
|
||||
#include <vme.h>
|
||||
#else
|
||||
/* vxworks compatible addressing modes */
|
||||
#define VME_AM_STD_SUP_ASCENDING 0x3f
|
||||
#define VME_AM_STD_SUP_PGM 0x3e
|
||||
#define VME_AM_STD_USR_ASCENDING 0x3b
|
||||
#define VME_AM_STD_USR_PGM 0x3a
|
||||
#define VME_AM_STD_SUP_DATA 0x3d
|
||||
#define VME_AM_STD_USR_DATA 0x39
|
||||
#define VME_AM_EXT_SUP_ASCENDING 0x0f
|
||||
#define VME_AM_EXT_SUP_PGM 0x0e
|
||||
#define VME_AM_EXT_USR_ASCENDING 0x0b
|
||||
#define VME_AM_EXT_USR_PGM 0x0a
|
||||
#define VME_AM_EXT_SUP_DATA 0x0d
|
||||
#define VME_AM_EXT_USR_DATA 0x09
|
||||
#define VME_AM_SUP_SHORT_IO 0x2d
|
||||
#define VME_AM_USR_SHORT_IO 0x29
|
||||
|
||||
#define VME_AM_IS_SHORT(a) (((a) & 0xf0) == 0x20)
|
||||
#define VME_AM_IS_STD(a) (((a) & 0xf0) == 0x30)
|
||||
#define VME_AM_IS_EXT(a) (((a) & 0xf0) == 0x00)
|
||||
/* vxworks compatible addressing modes */
|
||||
|
||||
#ifndef VME_AM_STD_SUP_ASCENDING
|
||||
#define VME_AM_STD_SUP_ASCENDING 0x3f
|
||||
#endif
|
||||
#ifndef VME_AM_STD_SUP_PGM
|
||||
#define VME_AM_STD_SUP_PGM 0x3e
|
||||
#endif
|
||||
#ifndef VME_AM_STD_USR_ASCENDING
|
||||
#define VME_AM_STD_USR_ASCENDING 0x3b
|
||||
#endif
|
||||
#ifndef VME_AM_STD_USR_PGM
|
||||
#define VME_AM_STD_USR_PGM 0x3a
|
||||
#endif
|
||||
#ifndef VME_AM_STD_SUP_DATA
|
||||
#define VME_AM_STD_SUP_DATA 0x3d
|
||||
#endif
|
||||
#ifndef VME_AM_STD_USR_DATA
|
||||
#define VME_AM_STD_USR_DATA 0x39
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_SUP_ASCENDING
|
||||
#define VME_AM_EXT_SUP_ASCENDING 0x0f
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_SUP_PGM
|
||||
#define VME_AM_EXT_SUP_PGM 0x0e
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_USR_ASCENDING
|
||||
#define VME_AM_EXT_USR_ASCENDING 0x0b
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_USR_PGM
|
||||
#define VME_AM_EXT_USR_PGM 0x0a
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_SUP_DATA
|
||||
#define VME_AM_EXT_SUP_DATA 0x0d
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_USR_DATA
|
||||
#define VME_AM_EXT_USR_DATA 0x09
|
||||
#endif
|
||||
#ifndef VME_AM_SUP_SHORT_IO
|
||||
#define VME_AM_SUP_SHORT_IO 0x2d
|
||||
#endif
|
||||
#ifndef VME_AM_USR_SHORT_IO
|
||||
#define VME_AM_USR_SHORT_IO 0x29
|
||||
#endif
|
||||
#ifndef VME_AM_IS_SHORT
|
||||
#define VME_AM_IS_SHORT(a) (((a) & 0xf0) == 0x20)
|
||||
#endif
|
||||
#ifndef VME_AM_IS_STD
|
||||
#define VME_AM_IS_STD(a) (((a) & 0xf0) == 0x30)
|
||||
#endif
|
||||
#ifndef VME_AM_IS_EXT
|
||||
#define VME_AM_IS_EXT(a) (((a) & 0xf0) == 0x00)
|
||||
#endif
|
||||
#ifndef VME_AM_IS_SUP
|
||||
#define VME_AM_IS_SUP(a) ((a) & 4)
|
||||
#endif
|
||||
#ifndef VME_AM_MASK
|
||||
#define VME_AM_MASK 0xff
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef unsigned long LERegister; /* emphasize contents are little endian */
|
||||
|
||||
/* NOTE: DMA packet descriptors MUST be 32 byte aligned */
|
||||
@@ -203,6 +246,7 @@ typedef struct VmeUniverseDMAPacketRec_ {
|
||||
#define UNIV_REGOFF_D_LLUE 0x224
|
||||
# define UNIV_D_LLUE_UPDATE (1<<31)
|
||||
|
||||
|
||||
/* PCI (local) interrupt enable register */
|
||||
#define UNIV_REGOFF_LINT_EN 0x300
|
||||
# define UNIV_LINT_EN_LM3 (1<<23) /* location monitor 3 mask */
|
||||
@@ -279,15 +323,28 @@ typedef struct VmeUniverseDMAPacketRec_ {
|
||||
/* enabling of generation of VME bus IRQs, TODO */
|
||||
#define UNIV_REGOFF_VINT_EN 0x310
|
||||
# define UNIV_VINT_EN_DISABLE_ALL 0
|
||||
# define UNIV_VINT_EN_SWINT (1<<12)
|
||||
# define UNIV_VINT_EN_SWINT_LVL(l) (1<<(((l)&7)+24)) /* universe II only */
|
||||
|
||||
/* status of generation of VME bus IRQs, TODO */
|
||||
|
||||
/* status of generation of VME bus IRQs */
|
||||
#define UNIV_REGOFF_VINT_STAT 0x314
|
||||
# define UNIV_VINT_STAT_LINT(lint) (1<<((lint)&7))
|
||||
# define UNIV_VINT_STAT_LINT_MASK (0xff)
|
||||
# define UNIV_VINT_STAT_CLR (0xfe0f17ff)
|
||||
# define UNIV_VINT_STAT_SWINT(l) (1<<(((l)&7)+24))
|
||||
|
||||
#define UNIV_REGOFF_VINT_MAP0 0x318 /* VME destination of PCI IRQ source, TODO */
|
||||
|
||||
#define UNIV_REGOFF_VINT_MAP1 0x31c /* VME destination of PCI IRQ source, TODO */
|
||||
# define UNIV_VINT_MAP1_SWINT(level) (((level)&0x7)<<16)
|
||||
|
||||
/* NOTE: The universe seems to always set LSB (which has a special purpose in
|
||||
* the STATID register: enable raising a SW_INT on IACK) on the
|
||||
* vector it puts out on the bus...
|
||||
*/
|
||||
#define UNIV_REGOFF_VINT_STATID 0x320 /* our status/id response to IACK, TODO */
|
||||
# define UNIV_VINT_STATID(id) ((id)<<24)
|
||||
|
||||
#define UNIV_REGOFF_VIRQ1_STATID 0x324 /* status/id of VME IRQ level 1 */
|
||||
#define UNIV_REGOFF_VIRQ2_STATID 0x328 /* status/id of VME IRQ level 2 */
|
||||
@@ -433,6 +490,7 @@ extern "C" {
|
||||
extern volatile LERegister *vmeUniverse0BaseAddr;
|
||||
extern int vmeUniverse0PciIrqLine;
|
||||
|
||||
|
||||
/* Initialize the driver */
|
||||
int
|
||||
vmeUniverseInit(void);
|
||||
@@ -508,12 +566,12 @@ vmeUniverseMasterPortCfg(
|
||||
|
||||
/* translate an address through the bridge
|
||||
*
|
||||
* vmeUniverseXlateAddr(0,0,addr,as,&result)
|
||||
* vmeUniverseXlateAddr(0,0,as,addr,&result)
|
||||
* yields a VME a address that reflects
|
||||
* a local memory location as seen from the VME bus through the universe
|
||||
* VME slave.
|
||||
*
|
||||
* likewise does vmeUniverseXlateAddr(1,0,addr,as,&result)
|
||||
* likewise does vmeUniverseXlateAddr(1,0,as,addr,&result)
|
||||
* translate a VME bus addr (through the VME master) to the
|
||||
* PCI side of the bridge.
|
||||
*
|
||||
@@ -575,13 +633,119 @@ void
|
||||
vmeUniverseCvtToLE(unsigned long *ptr, unsigned long num);
|
||||
|
||||
/* reset the VME bus */
|
||||
static inline void
|
||||
vmeUniverseResetBus(void)
|
||||
{
|
||||
vmeUniverseWriteReg(
|
||||
vmeUniverseReadReg(UNIV_REGOFF_MISC_CTL) | UNIV_MISC_CTL_SW_SYSRST,
|
||||
UNIV_REGOFF_MISC_CTL);
|
||||
}
|
||||
void
|
||||
vmeUniverseResetBus(void);
|
||||
|
||||
/* The ...XX routines take the universe base address as an additional
|
||||
* argument - this allows for programming secondary devices.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
vmeUniverseReadRegXX(volatile LERegister *ubase, unsigned long offset);
|
||||
|
||||
void
|
||||
vmeUniverseWriteRegXX(volatile LERegister *ubase, unsigned long value, unsigned long offset);
|
||||
|
||||
int
|
||||
vmeUniverseXlateAddrXX(
|
||||
volatile LERegister *ubase,
|
||||
int master,
|
||||
int reverse,
|
||||
unsigned long as,
|
||||
unsigned long addr,
|
||||
unsigned long *paOut
|
||||
);
|
||||
|
||||
int
|
||||
vmeUniverseMasterPortCfgXX(
|
||||
volatile LERegister *ubase,
|
||||
unsigned long port,
|
||||
unsigned long address_space,
|
||||
unsigned long vme_address,
|
||||
unsigned long local_address,
|
||||
unsigned long length);
|
||||
|
||||
int
|
||||
vmeUniverseSlavePortCfgXX(
|
||||
volatile LERegister *ubase,
|
||||
unsigned long port,
|
||||
unsigned long address_space,
|
||||
unsigned long vme_address,
|
||||
unsigned long local_address,
|
||||
unsigned long length);
|
||||
|
||||
void
|
||||
vmeUniverseDisableAllMastersXX(volatile LERegister *ubase);
|
||||
|
||||
void
|
||||
vmeUniverseDisableAllSlavesXX(volatile LERegister *ubase);
|
||||
|
||||
#ifdef _VME_UNIVERSE_DECLARE_SHOW_ROUTINES
|
||||
/* print the current configuration of all master ports to
|
||||
* f (stderr if NULL)
|
||||
*/
|
||||
void
|
||||
vmeUniverseMasterPortsShowXX(
|
||||
volatile LERegister *ubase,FILE *f);
|
||||
|
||||
/* print the current configuration of all slave ports to
|
||||
* f (stderr if NULL)
|
||||
*/
|
||||
void
|
||||
vmeUniverseSlavePortsShowXX(
|
||||
volatile LERegister *ubase,FILE *f);
|
||||
#else
|
||||
void
|
||||
vmeUniverseMasterPortsShowXX();
|
||||
void
|
||||
vmeUniverseSlavePortsShowXX();
|
||||
#endif
|
||||
|
||||
int
|
||||
vmeUniverseStartDMAXX(
|
||||
volatile LERegister *ubase,
|
||||
unsigned long local_addr,
|
||||
unsigned long vme_addr,
|
||||
unsigned long count);
|
||||
|
||||
/* Raise a VME Interrupt at 'level' and respond with 'vector' to a
|
||||
* handler on the VME bus. (The handler could be a different board
|
||||
* or the universe itself - [only works with universe II]).
|
||||
*
|
||||
* Note that you could install a interrupt handler at UNIV_VME_SW_IACK_INT_VEC
|
||||
* to be notified of an IACK cycle having completed.
|
||||
*
|
||||
* This routine is mainly FOR TESTING.
|
||||
*
|
||||
* NOTES:
|
||||
* - several registers are modified: the vector is written to VINT_STATID
|
||||
* and (universe 1 chip only) the level is written to the SW_INT bits
|
||||
* int VINT_MAP1
|
||||
* - NO MUTUAL EXCLUSION PROTECTION (reads VINT_EN, modifies then writes back).
|
||||
* If several users need access to VINT_EN and/or VINT_STATID (and VINT_MAP1
|
||||
* on the universe 1) it is their responsibility to serialize access.
|
||||
*
|
||||
* Arguments:
|
||||
* 'level': interrupt level, 1..7
|
||||
* 'vector': vector number (0..254) that the universe puts on the bus in response to
|
||||
* an IACK cycle. NOTE: the vector number *must be even* (hardware restriction
|
||||
* of the universe -- it always clears the LSB when the interrupter is
|
||||
* a software interrupt).
|
||||
*
|
||||
* RETURNS:
|
||||
* 0: Success
|
||||
* -1: Invalid argument (level not 1..7, vector odd or >= 256)
|
||||
* -2: Interrupt 'level' already asserted (maybe nobody handles it).
|
||||
* You can manually clear it be writing the respective bit in
|
||||
* VINT_STAT. Make sure really nobody responds to avoid spurious
|
||||
* interrupts (consult universe docs).
|
||||
*/
|
||||
|
||||
int
|
||||
vmeUniverseIntRaiseXX(volatile LERegister *base, int level, unsigned vector);
|
||||
|
||||
int
|
||||
vmeUniverseIntRaise(int level, unsigned vector);
|
||||
|
||||
#ifdef __rtems__
|
||||
/* VME Interrupt Handler functionality */
|
||||
@@ -625,7 +789,10 @@ vmeUniverseRemoveISR(unsigned long vector, VmeUniverseISR handler, void *usrArg)
|
||||
VmeUniverseISR
|
||||
vmeUniverseISRGet(unsigned long vector, void **parg);
|
||||
|
||||
/* utility routines to enable/disable a VME IRQ level
|
||||
/* utility routines to enable/disable a VME IRQ level.
|
||||
*
|
||||
* To enable/disable the internal interrupt sources (special vectors above)
|
||||
* pass a vector argument > 255.
|
||||
*
|
||||
* RETURNS 0 on success, nonzero on failure
|
||||
*/
|
||||
@@ -634,6 +801,56 @@ vmeUniverseIntEnable(unsigned int level);
|
||||
int
|
||||
vmeUniverseIntDisable(unsigned int level);
|
||||
|
||||
/* Check if an interrupt level or internal source is enabled:
|
||||
*
|
||||
* 'level': VME level 1..7 or internal special vector > 255
|
||||
*
|
||||
* RETURNS: value > 0 if interrupt is currently enabled,
|
||||
* zero if interrupt is currently disabled,
|
||||
* -1 on error (invalid argument).
|
||||
*/
|
||||
int
|
||||
vmeUniverseIntIsEnabled(unsigned int level);
|
||||
|
||||
|
||||
/* Change the routing of IRQ 'level' to 'pin'.
|
||||
* If the BSP connects more than one of the eight
|
||||
* physical interrupt lines from the universe to
|
||||
* the board's PIC then you may change the physical
|
||||
* line a given 'level' is using. By default,
|
||||
* all 7 VME levels use the first wire (pin==0) and
|
||||
* all internal sources use the (optional) second
|
||||
* wire (pin==1) [The driver doesn't support more than
|
||||
* to wires].
|
||||
* This feature is useful if you want to make use of
|
||||
* different hardware priorities of the PIC. Let's
|
||||
* say you want to give IRQ level 7 the highest priority.
|
||||
* You could then give 'pin 0' a higher priority (at the
|
||||
* PIC) and 'pin 1' a lower priority and issue.
|
||||
*
|
||||
* for ( i=1; i<7; i++ ) vmeUniverseIntRoute(i, 1);
|
||||
*
|
||||
* PARAMETERS:
|
||||
* 'level' : VME interrupt level '1..7' or one of
|
||||
* the internal sources. Pass the internal
|
||||
* source's vector number (>=256).
|
||||
* 'pin' : a value of 0 routes the requested IRQ to
|
||||
* the first line registered with the manager
|
||||
* (vmeIrqUnivOut parameter), a value of 1
|
||||
* routes it to the alternate wire
|
||||
* (specialIrqUnivOut)
|
||||
* RETURNS: 0 on success, nonzero on error (invalid arguments)
|
||||
*
|
||||
* NOTES: - DONT change the universe 'map' registers
|
||||
* directly. The driver caches routing internally.
|
||||
* - support for the 'specialIrqUnivOut' wire is
|
||||
* board dependent. If the board only provides
|
||||
* a single physical wire from the universe to
|
||||
* the PIC then the feature might not be available.
|
||||
*/
|
||||
int
|
||||
vmeUniverseIntRoute(unsigned int level, unsigned int pin);
|
||||
|
||||
/* use these special vectors to connect a handler to the
|
||||
* universe specific interrupts (such as "DMA done",
|
||||
* VOWN, error irqs etc.)
|
||||
@@ -652,31 +869,36 @@ vmeUniverseIntDisable(unsigned int level);
|
||||
#define UNIV_DMA_INT_VEC 257
|
||||
#define UNIV_LERR_INT_VEC 258
|
||||
#define UNIV_VERR_INT_VEC 259
|
||||
#define UNIV_VME_SW_IACK_INT_VEC 260
|
||||
#define UNIV_PCI_SW_INT_VEC 261
|
||||
#define UNIV_SYSFAIL_INT_VEC 262
|
||||
#define UNIV_ACFAIL_INT_VEC 263
|
||||
#define UNIV_MBOX0_INT_VEC 264
|
||||
#define UNIV_MBOX1_INT_VEC 265
|
||||
#define UNIV_MBOX2_INT_VEC 266
|
||||
#define UNIV_MBOX3_INT_VEC 267
|
||||
#define UNIV_LM0_INT_VEC 268
|
||||
#define UNIV_LM1_INT_VEC 269
|
||||
#define UNIV_LM2_INT_VEC 270
|
||||
#define UNIV_LM3_INT_VEC 271
|
||||
/* 260 is reserved */
|
||||
#define UNIV_VME_SW_IACK_INT_VEC 261
|
||||
#define UNIV_PCI_SW_INT_VEC 262
|
||||
#define UNIV_SYSFAIL_INT_VEC 263
|
||||
#define UNIV_ACFAIL_INT_VEC 264
|
||||
#define UNIV_MBOX0_INT_VEC 265
|
||||
#define UNIV_MBOX1_INT_VEC 266
|
||||
#define UNIV_MBOX2_INT_VEC 267
|
||||
#define UNIV_MBOX3_INT_VEC 268
|
||||
#define UNIV_LM0_INT_VEC 269
|
||||
#define UNIV_LM1_INT_VEC 270
|
||||
#define UNIV_LM2_INT_VEC 271
|
||||
#define UNIV_LM3_INT_VEC 272
|
||||
|
||||
#define UNIV_NUM_INT_VECS 272
|
||||
#define UNIV_NUM_INT_VECS 273
|
||||
|
||||
/* the universe interrupt handler is capable of routing all sorts of
|
||||
* (VME) interrupts to 8 different lines (some of) which may be hooked up
|
||||
* in a (board specific) way to a PIC.
|
||||
*
|
||||
* This driver only supports at most two lines. It routes the 7 VME
|
||||
* interrupts to the main line and optionally, it routes the 'special'
|
||||
* This driver only supports at most two lines. By default, it routes the
|
||||
* 7 VME interrupts to the main line and optionally, it routes the 'special'
|
||||
* interrupts generated by the universe itself (DMA done, VOWN etc.)
|
||||
* to a second line. If no second line is available, all IRQs are routed
|
||||
* to the main line.
|
||||
*
|
||||
* The routing of interrupts to the two lines can be modified (using
|
||||
* the vmeUniverseIntRoute() call - see above - i.e., to make use of
|
||||
* different hardware priorities of the two pins.
|
||||
*
|
||||
* Because the driver has no way to figure out which lines are actually
|
||||
* wired to the PIC, this information has to be provided when installing
|
||||
* the manager.
|
||||
@@ -710,6 +932,52 @@ vmeUniverseInstallIrqMgr(int vmeIrqUnivOut,
|
||||
int specialIrqUnivOut,
|
||||
int specialIrqPicLine);
|
||||
|
||||
/* up to 4 universe outputs are now supported by this alternate
|
||||
* entry point.
|
||||
* Terminate the vararg list (uni_pin/pic_pin pairs) with a
|
||||
* '-1' uni_pin.
|
||||
* E.g., the old interface is now just a wrapper to
|
||||
* vmeUniverseInstallIrqMgrAlt(0, vmeUnivOut, vmePicLint, specUnivOut, specPicLine, -1);
|
||||
*
|
||||
* The 'shared' argument uses the BSP_install_rtems_shared_irq_handler()
|
||||
* API. CAVEAT: shared interrupts need RTEMS workspace, i.e., the
|
||||
* VME interrupt manager can only be installed *after workspace is initialized*
|
||||
* if 'shared' is nonzero (i.e., *not* from bspstart()).
|
||||
*/
|
||||
int
|
||||
vmeUniverseInstallIrqMgrAlt(int shared, int uni_pin0, int pic_pin0, ...);
|
||||
|
||||
int
|
||||
vmeUniverseInstallIrqMgrVa(int shared, int uni_pin0, int pic_pin0, va_list ap);
|
||||
|
||||
/* Loopback test of the VME interrupt subsystem.
|
||||
* - installs ISRs on 'vector' and on UNIV_VME_SW_IACK_INT_VEC
|
||||
* - asserts VME interrupt 'level'
|
||||
* - waits for both interrupts: 'ordinary' VME interrupt of 'level' and
|
||||
* IACK completion interrupt ('special' vector UNIV_VME_SW_IACK_INT_VEC).
|
||||
*
|
||||
* NOTES:
|
||||
* - make sure no other handler responds to 'level'.
|
||||
* - make sure no ISR is installed on both vectors yet.
|
||||
* - ISRs installed by this routine are removed after completion.
|
||||
* - no concurrent access protection of all involved resources
|
||||
* (levels, vectors and registers [see vmeUniverseIntRaise()])
|
||||
* is implemented.
|
||||
* - this routine is intended for TESTING (when implementing new BSPs etc.).
|
||||
* - one RTEMS message queue is temporarily used (created/deleted).
|
||||
* - the universe 1 always yields a zero vector (VIRQx_STATID) in response
|
||||
* to a self-generated VME interrupt. As a workaround, the routine
|
||||
* only accepts a zero vector when running on a universe 1.
|
||||
*
|
||||
* RETURNS:
|
||||
* 0: Success.
|
||||
* -1: Invalid arguments.
|
||||
* 1: Test failed (outstanding interrupts).
|
||||
* rtems_status_code: Failed RTEMS directive.
|
||||
*/
|
||||
int
|
||||
vmeUniverseIntLoopbackTst(int level, unsigned vector);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
67
c/src/lib/libbsp/shared/vmeUniverse/vme_am_defs.h
Normal file
67
c/src/lib/libbsp/shared/vmeUniverse/vme_am_defs.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef VME_AM_DEFINITIONS_H
|
||||
#define VME_AM_DEFINITIONS_H
|
||||
|
||||
/* vxworks compatible addressing modes */
|
||||
|
||||
#ifndef VME_AM_STD_SUP_ASCENDING
|
||||
#define VME_AM_STD_SUP_ASCENDING 0x3f
|
||||
#endif
|
||||
#ifndef VME_AM_STD_SUP_PGM
|
||||
#define VME_AM_STD_SUP_PGM 0x3e
|
||||
#endif
|
||||
#ifndef VME_AM_STD_USR_ASCENDING
|
||||
#define VME_AM_STD_USR_ASCENDING 0x3b
|
||||
#endif
|
||||
#ifndef VME_AM_STD_USR_PGM
|
||||
#define VME_AM_STD_USR_PGM 0x3a
|
||||
#endif
|
||||
#ifndef VME_AM_STD_SUP_DATA
|
||||
#define VME_AM_STD_SUP_DATA 0x3d
|
||||
#endif
|
||||
#ifndef VME_AM_STD_USR_DATA
|
||||
#define VME_AM_STD_USR_DATA 0x39
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_SUP_ASCENDING
|
||||
#define VME_AM_EXT_SUP_ASCENDING 0x0f
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_SUP_PGM
|
||||
#define VME_AM_EXT_SUP_PGM 0x0e
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_USR_ASCENDING
|
||||
#define VME_AM_EXT_USR_ASCENDING 0x0b
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_USR_PGM
|
||||
#define VME_AM_EXT_USR_PGM 0x0a
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_SUP_DATA
|
||||
#define VME_AM_EXT_SUP_DATA 0x0d
|
||||
#endif
|
||||
#ifndef VME_AM_EXT_USR_DATA
|
||||
#define VME_AM_EXT_USR_DATA 0x09
|
||||
#endif
|
||||
#ifndef VME_AM_SUP_SHORT_IO
|
||||
#define VME_AM_SUP_SHORT_IO 0x2d
|
||||
#endif
|
||||
#ifndef VME_AM_USR_SHORT_IO
|
||||
#define VME_AM_USR_SHORT_IO 0x29
|
||||
#endif
|
||||
#ifndef VME_AM_IS_SHORT
|
||||
#define VME_AM_IS_SHORT(a) (((a) & 0xf0) == 0x20)
|
||||
#endif
|
||||
#ifndef VME_AM_IS_STD
|
||||
#define VME_AM_IS_STD(a) (((a) & 0xf0) == 0x30)
|
||||
#endif
|
||||
#ifndef VME_AM_IS_EXT
|
||||
#define VME_AM_IS_EXT(a) (((a) & 0xf0) == 0x00)
|
||||
#endif
|
||||
#ifndef VME_AM_IS_SUP
|
||||
#define VME_AM_IS_SUP(a) ((a) & 4)
|
||||
#endif
|
||||
|
||||
/* Higher order bits are driver specific */
|
||||
|
||||
#ifndef VME_AM_MASK
|
||||
#define VME_AM_MASK 0xff
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user