Files
epics-base/modules/libcom/src/osi/devLibVME.h
Dirk Zimoch 36a8b51d8e CleanupWhitespace
removed spaces at end of line

replaced tabs with spaces
2020-05-20 14:48:09 -07:00

431 lines
16 KiB
C

/*************************************************************************\
* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/**
* \file devLibVME.h
* \author Marty Kraimer, Jeff Hill
* \brief API for accessing hardware devices, mosty over VMEbus.
*
* API for accessing hardware devices. The original APIs here were for
* written for use with VMEbus but additional routines were added for
* ISA-bus (but not fully implemented inside EPICS Base and may never
* have been actually used).
*
* If all VMEbus drivers register with these routines then addressing
* conflicts caused by multiple device/drivers trying to use the same
* VME addresses will be detected. This API also makes it easy for a
* single driver to be written that works on both VxWorks and RTEMS.
*/
#ifndef INCdevLibh
#define INCdevLibh 1
#include "dbDefs.h"
#include "osdVME.h"
#include "errMdef.h"
#include "libComAPI.h"
#include "devLib.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \brief The available bus address types */
typedef enum {
atVMEA16, /**< \brief VME short I/O. */
atVMEA24, /**< \brief VME standard I/O. */
atVMEA32, /**< \brief VME extended I/O. */
atISA, /**< \brief Memory mapped ISA access. */
atVMECSR, /**< \brief VME-64 CR/CSR address space. */
atLast /**< \brief Invalid, must be the last entry. */
} epicsAddressType;
/** \brief A string representation of each of the bus address types */
LIBCOM_API extern const char *epicsAddressTypeName[];
#ifdef __cplusplus
}
#endif
/*
* To retain compatibility include everything by default
*/
#ifndef NO_DEVLIB_COMPAT
# include "devLibVMEImpl.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** \brief Print a map of registered bus addresses.
*
* Display a table of registsred bus address ranges, including the owner of
* each registered address.
* \return 0, or an error status value
*/
LIBCOM_API long devAddressMap(void);
/** \brief Translate a bus address to a pointer the CPU can use.
*
* Given a bus address, returns a pointer to that location in the CPU's
* memory map, or an error if direct access isn't currently possible.
* \param addrType The bus address type.
* \param busAddr Bus address to be translated.
* \param *ppLocalAddr Where to put the CPU pointer.
* \return 0, or an error status value.
*/
LIBCOM_API long devBusToLocalAddr (
epicsAddressType addrType,
size_t busAddr,
volatile void **ppLocalAddr);
/** \brief Probe the bus for reading from a specific address.
*
* Performs a bus-error-safe \c wordSize atomic read from a specific
* address and returns an error if this caused a bus error.
* \param wordSize The word size to read: 1, 2, 4 or 8 bytes.
* \param ptr Pointer to the location in the CPU's memory map to read.
* \param pValueRead Where to put the value read.
* \return 0, or an error status value if the location could not be
* accessed or the read caused a bus error.
*/
LIBCOM_API long devReadProbe (
unsigned wordSize, volatile const void *ptr, void *pValueRead);
/** \brief Read-probe a range of bus addresses, looking for empty space.
*
* Verifies that no device responds at any naturally aligned addresses
* within the given range. Tries to read every aligned address at every
* word size between char and long over the entire range, returning
* success only if none of the reads succeed.
* \warning This routine may be slow and have a very bad effect on a busy
* VMEbus. Every read probe of an unused address will hold onto the VMEbus
* for the global bus timeout period.
* \param addrType The bus address type.
* \param base First address base to probe.
* \param size Range of bus addresses to test, in bytes.
* \return 0 if no devices respond, or an error status value.
*/
LIBCOM_API long devNoResponseProbe(
epicsAddressType addrType,
size_t base,
size_t size
);
/** \brief Probe the bus for writing to a specific address.
*
* Performs a bus-error-safe \c wordSize atomic write to a specific
* address and returns an error if this caused a bus error.
* \param wordSize The word size to write: 1, 2, 4 or 8 bytes.
* \param ptr Pointer to the location in the CPU's memory map to write to.
* \param pValueWritten The value to write.
* \return 0, or an error status value if the location could not be
* accessed or the write caused a bus error.
*/
LIBCOM_API long devWriteProbe (
unsigned wordSize, volatile void *ptr, const void *pValueWritten);
/** \brief Register a bus address range with a name.
*
* The devLib code keeps a list of all bus address ranges registered with
* this routine and returns an error if a later call attempts to register
* any addresses that overlap with a range already registered. The call to
* registering a range also converts the given base address into a pointer
* in the CPU address space for the driver to use (see devBusToLocalAddr()).
* \param pOwnerName Name of a driver that will own this range.
* \param addrType The bus address type.
* \param logicalBaseAddress The bus start address.
* \param size Number of bytes to reserve.
* \param pPhysicalAddress Where to put the converted CPU pointer.
* \return 0, or an error status.
*/
LIBCOM_API long devRegisterAddress(
const char *pOwnerName,
epicsAddressType addrType,
size_t logicalBaseAddress,
size_t size,
volatile void **pPhysicalAddress);
/** \brief Release a bus address range previously registered.
*
* Release an address range that was previously registered by a call to
* devRegisterAddress() or devAllocAddress().
* \param addrType The bus address type.
* \param logicalBaseAddress The bus start address.
* \param pOwnerName The name of the driver that owns this range.
* \return 0, or an error status.
*/
LIBCOM_API long devUnregisterAddress(
epicsAddressType addrType,
size_t logicalBaseAddress,
const char *pOwnerName);
/** \brief Allocate and register an unoccupied address block.
*
* Asks devLib to allocate an address block of a particular address type.
* This is useful for devices that appear in more than one address space
* and can program the base address of one window using registers found
* in another window. As with devRegisterAddress() this call also converts
* the new base address into a pointer in the CPU address space for the
* driver to use (see devBusToLocalAddr()).
* \note This routine calls devNoResponseProbe() to find an unoccupied
* block in the bus address space, so using it may have a bad effect on a
* busy VMEbus at allocation time; see the warning above.
* \param pOwnerName Name of a driver that will own this range.
* \param addrType The bus address type.
* \param size Number of bytes to be allocated.
* \param alignment How many low bits in the address must all be zero.
* \param pLocalAddress Where to put the CPU pointer.
* \return 0, or an error status value.
*/
LIBCOM_API long devAllocAddress(
const char *pOwnerName,
epicsAddressType addrType,
size_t size,
unsigned alignment, /*n ls bits zero in addr*/
volatile void **pLocalAddress);
/** \name VME Interrupt Management
* Routines to manage VME interrupts.
* @{
*/
/** \brief Connect an ISR up to a VME interrupt vector.
*
* Interrupt Service Routines (ISRs) are normally written in C, and get
* passed a context parameter given with them to this connection routine.
*
* There are many restrictions on the routines that an ISR may call; see
* epicsEvent.h, epicsInterrupt.h, epicsMessageQueue.h, epicsRingBytes.h,
* epicsRingPointer.h and epicsTime.h for some APIs known to be suitable.
* It is safest just to trigger a high-priority task to handle any
* complex work that must happen as a result of the interrupt.
* \param vectorNumber VME interrupt vector number.
* \param pFunction The ISR to be called.
* \param parameter Context parameter for the ISR.
* \return 0, or an error status value.
*/
LIBCOM_API long devConnectInterruptVME(
unsigned vectorNumber,
void (*pFunction)(void *),
void *parameter);
/** \brief Disconnect an ISR from its VME interrupt vector.
*
* Device drivers may disconnect an ISR they connected earlier using this
* routine. In addition to taking the \c vectorNumber the ISR itself is
* required and used as a check to prevent a driver from inadvertently
* removing an interrupt handler that it didn't install.
*
* On a PowerPC target running VxWorks, this routine will always return
* with an error status.
* \param vectorNumber VME interrupt vector number.
* \param pFunction The ISR to be disconnected.
* \return 0, or an error status value.
*/
LIBCOM_API long devDisconnectInterruptVME(
unsigned vectorNumber,
void (*pFunction)(void *));
/** \brief Determine if a VME interrupt vector is in use.
*
* On a PowerPC target running VxWorks this routine will always return
* false, indicating that a vector is unused.
* \param vectorNumber Interrupt vector number.
* \return True if vector has an ISR attached, otherwise false.
*/
LIBCOM_API int devInterruptInUseVME (unsigned vectorNumber);
/** \brief Enable a VME interrupt level onto the CPU.
*
* The VMEbus allows multiple CPU boards to be installed in the same
* backplane. When this is done, the differente VME interrupt levels
* must be assigned to the CPUs since they cannot be shared. This
* routine tells the VME interface that it should connect interrupts
* from the indicated interrupt level to a CPU interrupt line.
* \param level VMEbus interrupt level to enable, 1-7.
* \return 0, or an error status value.
*/
LIBCOM_API long devEnableInterruptLevelVME (unsigned level);
/** \brief Disable a VME interrupt level.
*
* This routine is the reverse of devEnableInterruptLevelVME().
* \note This routine should not normally be used, even by a
* driver that enabled the interrupt level. Disabling a VME
* interrupt level should only be done by software that knows
* for certain that no other interrupting device is also using
* that VME interrupt level.
* \param level VMEbus interrupt level to disable, 1-7.
* \return 0, or an error status value.
*/
LIBCOM_API long devDisableInterruptLevelVME (unsigned level);
/** @} */
/** \name Memory for VME DMA Operations
* These routines manage memory that can be directly accessed
* from the VMEbus in the A24 address space by another bus master
* such as a DMA controller.
* @{
*/
/** \brief malloc() for VME drivers that support DMA.
*
* Allocate memory of a given size from a region that can be
* accessed from the VMEbus in the A24 address space.
* \param size How many bytes to allocate
* \return A pointer to the memory allocated, or NULL.
*/
LIBCOM_API void *devLibA24Malloc(size_t size);
/** \brief calloc() for VME drivers that support DMA.
*
* Allocate and zero-fill a block of memory of a given size from
* a region that can be accessed from the VMEbus in the A24
* address space.
* \param size How many bytes to allocate and zero.
* \return A pointer to the memory allocated, or NULL.
*/
LIBCOM_API void *devLibA24Calloc(size_t size);
/** \brief free() for VME drivers that support DMA.
*
* Free a block of memory that was allocated using either
* devLibA24Malloc() or devLibA24Calloc().
* \param pBlock Block to be released.
*/
LIBCOM_API void devLibA24Free(void *pBlock);
/** @} */
/** \name ISA Interrupt Management
* Routines to manage ISAbus interrupts.
* \note These routines may not have been used for a very long time;
* some appear to have never been implemented at all. They may vanish
* with no notice from future versions of EPICS Base. Nobody is using
* the PC's ISA-bus any more are they?
* @{
*/
/**
* Connect ISR to a ISA interrupt.
* \warning Not implemented!
* \param interruptLevel Bus interrupt level to connect to.
* \param pFunction C function pointer to connect to.
* \param parameter Parameter to the called function.
* \return Returns success or error.
*/
LIBCOM_API long devConnectInterruptISA(
unsigned interruptLevel,
void (*pFunction)(void *),
void *parameter);
/**
* Disconnect ISR from a ISA interrupt level.
* \warning Not implemented!
* \param interruptLevel Interrupt level.
* \param pFunction C function pointer that was connected.
* \return returns success or error.
*/
LIBCOM_API long devDisconnectInterruptISA(
unsigned interruptLevel,
void (*pFunction)(void *));
/**
* Determine if an ISA interrupt level is in use
* \warning Not implemented!
* \param interruptLevel Interrupt level.
* \return Returns True/False.
*/
LIBCOM_API int devInterruptLevelInUseISA (unsigned interruptLevel);
/**
* Enable ISA interrupt level
* \param level Interrupt level.
* \return Returns True/False.
*/
LIBCOM_API long devEnableInterruptLevelISA (unsigned level);
/**
* Disable ISA interrupt level
* \param level Interrupt level.
* \return Returns True/False.
*/
LIBCOM_API long devDisableInterruptLevelISA (unsigned level);
/** @} */
#ifndef NO_DEVLIB_OLD_INTERFACE
/**
* \name Deprecated Interfaces
* @{
*/
typedef enum {intVME, intVXI, intISA} epicsInterruptType;
/**
* \note This routine has been deprecated. It exists
* for backwards compatibility purposes only.
* Please use one of devConnectInterruptVME(), devConnectInterruptPCI(),
* devConnectInterruptISA() instead. devConnectInterrupt() will be removed
* in a future release.
*/
LIBCOM_API long devConnectInterrupt(
epicsInterruptType intType,
unsigned vectorNumber,
void (*pFunction)(void *),
void *parameter);
/**
* \note This routine has been deprecated. It exists
* for backwards compatibility purposes only.
* Please use one of devDisconnectInterruptVME(), devDisconnectInterruptPCI(),
* devDisconnectInterruptISA() instead. devDisconnectInterrupt() will
* be removed in a future release.
*/
LIBCOM_API long devDisconnectInterrupt(
epicsInterruptType intType,
unsigned vectorNumber,
void (*pFunction)(void *));
/**
* \note This routine has been deprecated. It exists
* for backwards compatibility purposes only.
* Please use one of devEnableInterruptLevelVME(), devEnableInterruptLevelPCI(),
* devEnableInterruptLevelISA() instead. devEnableInterruptLevel() will
* be removed in a future release.
*/
LIBCOM_API long devEnableInterruptLevel(
epicsInterruptType intType, unsigned level);
/**
* \note This routine has been deprecated. It exists
* for backwards compatibility purposes only.
* Please use one of devDisableInterruptLevelVME(), devDisableInterruptLevelISA(),
* devDisableInterruptLevelPCI() instead. devDisableInterruptLevel() will
* be removed in a future release.
*/
LIBCOM_API long devDisableInterruptLevel (
epicsInterruptType intType, unsigned level);
/**
* \note This routine has been deprecated. It exists
* for backwards compatibility purposes only.
* Please use devNoResponseProbe() instead. locationProbe() will be removed
* in a future release.
*/
LIBCOM_API long locationProbe (epicsAddressType addrType, char *pLocation);
/** @} */
#endif /* NO_DEVLIB_OLD_INTERFACE */
#ifdef __cplusplus
}
#endif
#endif /* INCdevLibh.h*/