Files
rtems/cpukit/include/pci/access.h
T
Sebastian Huber b4d322971c cpukit: Group the last ungrouped files
Seventy-three files had a Doxygen block but no @ingroup line.  Doxygen
documented them, but no group page listed them.  The PCI headers, the
driver manager headers and 46 headers under include/rtems were affected.

Give each file the group of the component it belongs to.  The seven
default file system files follow the table they fill.  A file which
provides an entry of rtems_filesystem_operations_table joins LibIOFSOps.
A file which provides an entry of rtems_filesystem_file_handlers_r joins
LibIOFSHandler.

Every file in cpukit with a Doxygen block names a group.  The files
malloc.h, todimpl.h and printk_plugin.c name two groups.  The other
files name one.

Updates #5717.

Assisted-by: Claude:claude-opus-5 claude-code
Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
2026-09-01 20:17:20 +00:00

294 lines
10 KiB
C

/* SPDX-License-Identifier: BSD-2-Clause */
/**
* @file
*
* @ingroup RTEMSImplPCI
*
* @brief PCI Access Methods
*
* Routines to access PCI memory/configuration space and other PCI related
* functions the PCI Library provides.
*/
/*
* COPYRIGHT (c) 2010 Cobham Gaisler AB.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __PCI_ACCESS_H__
#define __PCI_ACCESS_H__
#include <stdint.h>
#include <libcpu/byteorder.h>
#include <rtems/score/basedefs.h>
#include <pci.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Identification of a PCI configuration space device (16-bit) */
typedef uint16_t pci_dev_t;
/* Create a PCI Configuration Space ID */
#define PCI_DEV( bus, slot, func ) \
( ( ( bus ) << 8 ) | ( ( slot ) << 3 ) | ( func ) )
/* Get Bus of a PCI Configuration Space ID */
#define PCI_DEV_BUS( dev ) ( ( ( dev ) >> 8 ) & 0xff )
/* Get Slot/Device of a PCI Configuration Space ID */
#define PCI_DEV_SLOT( dev ) ( ( ( dev ) >> 3 ) & 0x1f )
/* Get Function of a PCI Configuration Space ID */
#define PCI_DEV_FUNC( dev ) ( ( dev ) & 0x7 )
/* Get Device and Function of a PCI Configuration Space ID */
#define PCI_DEV_DEVFUNC( dev ) ( ( dev ) & 0xff )
/* Expand Device into argument lists */
#define PCI_DEV_EXPAND( dev ) \
PCI_DEV_BUS(( dev )), PCI_DEV_SLOT(( dev )), PCI_DEV_FUNC(( dev ))
/* Configuration Space Read/Write Operations */
struct pci_cfg_ops {
/* Configuration Space Access and Setup Routines */
int ( *read8 )( pci_dev_t dev, int ofs, uint8_t *data );
int ( *read16 )( pci_dev_t dev, int ofs, uint16_t *data );
int ( *read32 )( pci_dev_t dev, int ofs, uint32_t *data );
int ( *write8 )( pci_dev_t dev, int ofs, uint8_t data );
int ( *write16 )( pci_dev_t dev, int ofs, uint16_t data );
int ( *write32 )( pci_dev_t dev, int ofs, uint32_t data );
};
/* Read a register over PCI I/O Space, and swap it if necessary (due to
* PCI endianness)
*/
struct pci_io_ops {
uint8_t ( *read8 )( uint8_t *adr );
uint16_t ( *read16 )( uint16_t *adr );
uint32_t ( *read32 )( uint32_t *adr );
void ( *write8 )( uint8_t *adr, uint8_t data );
void ( *write16 )( uint16_t *adr, uint16_t data );
void ( *write32 )( uint32_t *adr, uint32_t data );
};
/* Read a register over PCI Memory Space (non-prefetchable memory), and
* swap it if necessary (due to PCI endianness)
*/
struct pci_memreg_ops {
uint8_t ( *ld8 )( uint8_t *adr );
void ( *st8 )( uint8_t *adr, uint8_t data );
uint16_t ( *ld_le16 )( uint16_t *adr );
void ( *st_le16 )( uint16_t *adr, uint16_t data );
uint16_t ( *ld_be16 )( uint16_t *adr );
void ( *st_be16 )( uint16_t *adr, uint16_t data );
uint32_t ( *ld_le32 )( uint32_t *adr );
void ( *st_le32 )( uint32_t *adr, uint32_t data );
uint32_t ( *ld_be32 )( uint32_t *adr );
void ( *st_be32 )( uint32_t *adr, uint32_t data );
};
typedef uint8_t ( *pci_ld8_t )( uint8_t *adr );
typedef void ( *pci_st8_t )( uint8_t *adr, uint8_t data );
typedef uint16_t( pci_ld16_t )( uint16_t *adr );
typedef void ( *pci_st16_t )( uint16_t *adr, uint16_t data );
typedef uint32_t ( *pci_ld32_t )( uint32_t *adr );
typedef void ( *pci_st32_t )( uint32_t *adr, uint32_t data );
struct pci_access_drv {
/* Configuration */
struct pci_cfg_ops cfg;
/* I/O Access operations */
struct pci_io_ops io;
/* Registers over Memory Access operations. Note that these funcs
* are only for code that need to be compatible with both Big-Endian
* and Little-Endian PCI bus or for some other reason need function
* pointers to access functions. Normally drivers use the inline
* functions for Registers-over-Memory access to avoid extra function
* call.
*/
struct pci_memreg_ops *memreg;
/* Translate from PCI address to CPU address (dir=0). Translate
* CPU address to PCI address (dir!=0). The address will can be
* used to perform I/O access or memory access by CPU or PCI DMA
* peripheral.
*
* address In/Out. CPU address or PCI address.
* type Access type. 1=I/O, 2=MEMIO, 3=MEM
* dir Translate direction. 0=PCI-to-CPU, 0!=CPU-to-PCI,
*
* Return Value
* 0 = Success
* -1 = Requested Address not mapped into other address space
* i.e. not accessible
*/
int ( *translate )( uint32_t *address, int type, int dir );
};
/* Access Routines valid after a PCI-Access-Driver has registered */
extern struct pci_access_drv pci_access_ops;
/* Register PCI Access Driver */
extern int pci_access_drv_register( struct pci_access_drv *drv );
/* Set/unset bits in command and status register of a PCI device */
extern void pci_modify_cmdsts( pci_dev_t dev, uint32_t mask, uint32_t val );
/* Enable Memory in command register */
static inline void pci_mem_enable( pci_dev_t dev )
{
pci_modify_cmdsts( dev, PCIM_CMD_MEMEN, PCIM_CMD_MEMEN );
}
static inline void pci_mem_disable( pci_dev_t dev )
{
pci_modify_cmdsts( dev, PCIM_CMD_MEMEN, 0 );
}
static inline void pci_io_enable( pci_dev_t dev )
{
pci_modify_cmdsts( dev, PCIM_CMD_PORTEN, PCIM_CMD_PORTEN );
}
static inline void pci_io_disable( pci_dev_t dev )
{
pci_modify_cmdsts( dev, PCIM_CMD_PORTEN, 0 );
}
static inline void pci_master_enable( pci_dev_t dev )
{
pci_modify_cmdsts( dev, PCIM_CMD_BUSMASTEREN, PCIM_CMD_BUSMASTEREN );
}
static inline void pci_master_disable( pci_dev_t dev )
{
pci_modify_cmdsts( dev, PCIM_CMD_BUSMASTEREN, 0 );
}
/* Configuration Space Access Read Routines */
extern int pci_cfg_r8( pci_dev_t dev, int ofs, uint8_t *data );
extern int pci_cfg_r16( pci_dev_t dev, int ofs, uint16_t *data );
extern int pci_cfg_r32( pci_dev_t dev, int ofs, uint32_t *data );
/* Configuration Space Access Write Routines */
extern int pci_cfg_w8( pci_dev_t dev, int ofs, uint8_t data );
extern int pci_cfg_w16( pci_dev_t dev, int ofs, uint16_t data );
extern int pci_cfg_w32( pci_dev_t dev, int ofs, uint32_t data );
/* Read a register over PCI I/O Space */
extern uint8_t pci_io_r8( uint32_t adr );
extern uint16_t pci_io_r16( uint32_t adr );
extern uint32_t pci_io_r32( uint32_t adr );
/* Write a register over PCI I/O Space */
extern void pci_io_w8( uint32_t adr, uint8_t data );
extern void pci_io_w16( uint32_t adr, uint16_t data );
extern void pci_io_w32( uint32_t adr, uint32_t data );
/* Translate PCI address into CPU accessible address */
static inline int pci_pci2cpu( uint32_t *address, int type )
{
return pci_access_ops.translate( address, type, 0 );
}
/* Translate CPU accessible address into PCI address (for DMA) */
static inline int pci_cpu2pci( uint32_t *address, int type )
{
return pci_access_ops.translate( address, type, 1 );
}
/*** Read/Write a register over PCI Memory Space ***/
static inline uint8_t pci_ld8( volatile uint8_t *addr )
{
return *addr;
}
static inline void pci_st8( volatile uint8_t *addr, uint8_t val )
{
*addr = val;
}
/* Registers-over-Memory Space access routines. The routines are not inlined
* so it is possible during run-time to select which function implemention
* to use. The use of these functions are not recommended since it will have a
* performance penalty.
*
* 8-bit accesses are the same for Little and Big endian PCI buses.
*/
uint8_t pci_mem_ld8( uint8_t *adr );
void pci_mem_st8( uint8_t *adr, uint8_t data );
/* Registers-over-Memory Space - Generic Big endian PCI bus definitions */
uint16_t pci_mem_be_ld_le16( uint16_t *adr );
uint16_t pci_mem_be_ld_be16( uint16_t *adr );
uint32_t pci_mem_be_ld_le32( uint32_t *adr );
uint32_t pci_mem_be_ld_be32( uint32_t *adr );
void pci_mem_be_st_le16( uint16_t *adr, uint16_t data );
void pci_mem_be_st_be16( uint16_t *adr, uint16_t data );
void pci_mem_be_st_le32( uint32_t *adr, uint32_t data );
void pci_mem_be_st_be32( uint32_t *adr, uint32_t data );
/* Registers-over-Memory Space - Generic Little endian PCI bus definitions */
uint16_t pci_mem_le_ld_le16( uint16_t *adr );
uint16_t pci_mem_le_ld_be16( uint16_t *adr );
uint32_t pci_mem_le_ld_le32( uint32_t *adr );
uint32_t pci_mem_le_ld_be32( uint32_t *adr );
void pci_mem_le_st_le16( uint16_t *adr, uint16_t data );
void pci_mem_le_st_be16( uint16_t *adr, uint16_t data );
void pci_mem_le_st_le32( uint32_t *adr, uint32_t data );
void pci_mem_le_st_be32( uint32_t *adr, uint32_t data );
/* Get Read/Write function for accessing a register over PCI Memory Space
* (non-inline functions).
*
* Arguments
* wr 0(Read), 1(Write)
* size 1(Byte), 2(Word), 4(Double Word)
* func Where function pointer will be stored
* endian PCI_LITTLE_ENDIAN or PCI_BIG_ENDIAN
* type 1(I/O), 3(REG over MEM), 4(CFG)
*
* Return
* 0 Found function
* others No such function defined by host driver or BSP
*/
extern int pci_access_func(
int wr,
int size,
void **func,
int endian,
int type
);
/* Predefined functions for Host drivers or BSPs that define the
* register-over-memory space functions operations.
*/
extern struct pci_memreg_ops pci_mem_le_ops; /* For Little-Endian PCI bus */
extern struct pci_memreg_ops pci_mem_be_ops; /* For Big-Endian PCI bus */
#ifdef __cplusplus
}
#endif
#endif /* !__PCI_ACCESS_H__ */