RTEMS: cpukit/include/pci/access.h Source File

| RTEMS 5.4-rc2

Loading...
Searching...
No Matches
access.h
1/* Routines to access PCI memory/configuration space and other PCI related
2 * functions the PCI Library provides.
3 *
4 * COPYRIGHT (c) 2010 Cobham Gaisler AB.
5 *
6 * The license and distribution terms for this file may be
7 * found in the file LICENSE in this distribution or at
8 * http://www.rtems.org/license/LICENSE.
9 */
10
11
12#ifndef __PCI_ACCESS_H__
13#define __PCI_ACCESS_H__
14
15#include <stdint.h>
16#include <libcpu/byteorder.h>
17#include <rtems/score/basedefs.h>
18#include <pci.h>
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* Identification of a PCI configuration space device (16-bit) */
25typedef uint16_t pci_dev_t;
26/* Create a PCI Configuration Space ID */
27#define PCI_DEV(bus, slot, func) (((bus)<<8) | ((slot)<<3) | (func))
28/* Get Bus of a PCI Configuration Space ID */
29#define PCI_DEV_BUS(dev) (((dev) >> 8) & 0xff)
30/* Get Slot/Device of a PCI Configuration Space ID */
31#define PCI_DEV_SLOT(dev) (((dev) >> 3) & 0x1f)
32/* Get Function of a PCI Configuration Space ID */
33#define PCI_DEV_FUNC(dev) ((dev) & 0x7)
34/* Get Device and Function of a PCI Configuration Space ID */
35#define PCI_DEV_DEVFUNC(dev) ((dev) & 0xff)
36/* Expand Device into argument lists */
37#define PCI_DEV_EXPAND(dev) PCI_DEV_BUS((dev)), PCI_DEV_SLOT((dev)), PCI_DEV_FUNC((dev))
38
39/* Configuration Space Read/Write Operations */
40 struct pci_cfg_ops {
41 /* Configuration Space Access and Setup Routines */
42 int (*read8)(pci_dev_t dev, int ofs, uint8_t *data);
43 int (*read16)(pci_dev_t dev, int ofs, uint16_t *data);
44 int (*read32)(pci_dev_t dev, int ofs, uint32_t *data);
45 int (*write8)(pci_dev_t dev, int ofs, uint8_t data);
46 int (*write16)(pci_dev_t dev, int ofs, uint16_t data);
47 int (*write32)(pci_dev_t dev, int ofs, uint32_t data);
48};
49
50/* Read a register over PCI I/O Space, and swap it if necessary (due to
51 * PCI endianness)
52 */
53 struct pci_io_ops {
54 uint8_t (*read8)(uint8_t *adr);
55 uint16_t(*read16)(uint16_t *adr);
56 uint32_t (*read32)(uint32_t *adr);
57 void (*write8)(uint8_t *adr, uint8_t data);
58 void (*write16)(uint16_t *adr, uint16_t data);
59 void (*write32)(uint32_t *adr, uint32_t data);
60};
61
62/* Read a register over PCI Memory Space (non-prefetchable memory), and
63 * swap it if necessary (due to PCI endianness)
64 */
65 struct pci_memreg_ops {
66 uint8_t (*ld8)(uint8_t *adr);
67 void (*st8)(uint8_t *adr, uint8_t data);
68
69 uint16_t(*ld_le16)(uint16_t *adr);
70 void (*st_le16)(uint16_t *adr, uint16_t data);
71 uint16_t(*ld_be16)(uint16_t *adr);
72 void (*st_be16)(uint16_t *adr, uint16_t data);
73
74 uint32_t (*ld_le32)(uint32_t *adr);
75 void (*st_le32)(uint32_t *adr, uint32_t data);
76 uint32_t (*ld_be32)(uint32_t *adr);
77 void (*st_be32)(uint32_t *adr, uint32_t data);
78};
79
80typedef uint8_t (*pci_ld8_t)(uint8_t *adr);
81typedef void (*pci_st8_t)(uint8_t *adr, uint8_t data);
82typedef uint16_t(pci_ld16_t)(uint16_t *adr);
83typedef void (*pci_st16_t)(uint16_t *adr, uint16_t data);
84typedef uint32_t (*pci_ld32_t)(uint32_t *adr);
85typedef void (*pci_st32_t)(uint32_t *adr, uint32_t data);
86
87 struct pci_access_drv {
88 /* Configuration */
89 struct pci_cfg_ops cfg;
90
91 /* I/O Access operations */
92 struct pci_io_ops io;
93
94 /* Registers over Memory Access operations. Note that these funcs
95 * are only for code that need to be compatible with both Big-Endian
96 * and Little-Endian PCI bus or for some other reason need function
97 * pointers to access functions. Normally drivers use the inline
98 * functions for Registers-over-Memory access to avoid extra function
99 * call.
100 */
101 struct pci_memreg_ops *memreg;
102
103 /* Translate from PCI address to CPU address (dir=0). Translate
104 * CPU address to PCI address (dir!=0). The address will can be
105 * used to perform I/O access or memory access by CPU or PCI DMA
106 * peripheral.
107 *
108 * address In/Out. CPU address or PCI address.
109 * type Access type. 1=I/O, 2=MEMIO, 3=MEM
110 * dir Translate direction. 0=PCI-to-CPU, 0!=CPU-to-PCI,
111 *
112 * Return Value
113 * 0 = Success
114 * -1 = Requested Address not mapped into other address space
115 * i.e. not accessible
116 */
117 int (*translate)(uint32_t *address, int type, int dir);
118};
119
120/* Access Routines valid after a PCI-Access-Driver has registered */
121extern struct pci_access_drv pci_access_ops;
122
123/* Register PCI Access Driver */
124extern int pci_access_drv_register(struct pci_access_drv *drv);
125
126/* Set/unset bits in command and status register of a PCI device */
127extern void pci_modify_cmdsts(pci_dev_t dev, uint32_t mask, uint32_t val);
128
129/* Enable Memory in command register */
130 RTEMS_INLINE_ROUTINE void pci_mem_enable(pci_dev_t dev)
131{
132 pci_modify_cmdsts(dev, PCIM_CMD_MEMEN, PCIM_CMD_MEMEN);
133}
134
135 RTEMS_INLINE_ROUTINE void pci_mem_disable(pci_dev_t dev)
136{
137 pci_modify_cmdsts(dev, PCIM_CMD_MEMEN, 0);
138}
139
140 RTEMS_INLINE_ROUTINE void pci_io_enable(pci_dev_t dev)
141{
142 pci_modify_cmdsts(dev, PCIM_CMD_PORTEN, PCIM_CMD_PORTEN);
143}
144
145 RTEMS_INLINE_ROUTINE void pci_io_disable(pci_dev_t dev)
146{
147 pci_modify_cmdsts(dev, PCIM_CMD_PORTEN, 0);
148}
149
150 RTEMS_INLINE_ROUTINE void pci_master_enable(pci_dev_t dev)
151{
152 pci_modify_cmdsts(dev, PCIM_CMD_BUSMASTEREN, PCIM_CMD_BUSMASTEREN);
153}
154
155 RTEMS_INLINE_ROUTINE void pci_master_disable(pci_dev_t dev)
156{
157 pci_modify_cmdsts(dev, PCIM_CMD_BUSMASTEREN, 0);
158}
159
160/* Configuration Space Access Read Routines */
161extern int pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *data);
162extern int pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *data);
163extern int pci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *data);
164
165/* Configuration Space Access Write Routines */
166extern int pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t data);
167extern int pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t data);
168extern int pci_cfg_w32(pci_dev_t dev, int ofs, uint32_t data);
169
170/* Read a register over PCI I/O Space */
171extern uint8_t pci_io_r8(uint32_t adr);
172extern uint16_t pci_io_r16(uint32_t adr);
173extern uint32_t pci_io_r32(uint32_t adr);
174
175/* Write a register over PCI I/O Space */
176extern void pci_io_w8(uint32_t adr, uint8_t data);
177extern void pci_io_w16(uint32_t adr, uint16_t data);
178extern void pci_io_w32(uint32_t adr, uint32_t data);
179
180/* Translate PCI address into CPU accessible address */
181 RTEMS_INLINE_ROUTINE int pci_pci2cpu(uint32_t *address, int type)
182{
183 return pci_access_ops.translate(address, type, 0);
184}
185
186/* Translate CPU accessible address into PCI address (for DMA) */
187 RTEMS_INLINE_ROUTINE int pci_cpu2pci(uint32_t *address, int type)
188{
189 return pci_access_ops.translate(address, type, 1);
190}
191
192/*** Read/Write a register over PCI Memory Space ***/
193
194 RTEMS_INLINE_ROUTINE uint8_t pci_ld8(volatile uint8_t *addr)
195{
196 return *addr;
197}
198
199 RTEMS_INLINE_ROUTINE void pci_st8(volatile uint8_t *addr, uint8_t val)
200{
201 *addr = val;
202}
203
204/* Registers-over-Memory Space access routines. The routines are not inlined
205 * so it is possible during run-time to select which function implemention
206 * to use. The use of these functions are not recommended since it will have a
207 * performance penalty.
208 *
209 * 8-bit accesses are the same for Little and Big endian PCI buses.
210 */
211uint8_t pci_mem_ld8(uint8_t *adr);
212void pci_mem_st8(uint8_t *adr, uint8_t data);
213/* Registers-over-Memory Space - Generic Big endian PCI bus definitions */
214uint16_t pci_mem_be_ld_le16(uint16_t *adr);
215uint16_t pci_mem_be_ld_be16(uint16_t *adr);
216uint32_t pci_mem_be_ld_le32(uint32_t *adr);
217uint32_t pci_mem_be_ld_be32(uint32_t *adr);
218void pci_mem_be_st_le16(uint16_t *adr, uint16_t data);
219void pci_mem_be_st_be16(uint16_t *adr, uint16_t data);
220void pci_mem_be_st_le32(uint32_t *adr, uint32_t data);
221void pci_mem_be_st_be32(uint32_t *adr, uint32_t data);
222/* Registers-over-Memory Space - Generic Little endian PCI bus definitions */
223uint16_t pci_mem_le_ld_le16(uint16_t *adr);
224uint16_t pci_mem_le_ld_be16(uint16_t *adr);
225uint32_t pci_mem_le_ld_le32(uint32_t *adr);
226uint32_t pci_mem_le_ld_be32(uint32_t *adr);
227void pci_mem_le_st_le16(uint16_t *adr, uint16_t data);
228void pci_mem_le_st_be16(uint16_t *adr, uint16_t data);
229void pci_mem_le_st_le32(uint32_t *adr, uint32_t data);
230void pci_mem_le_st_be32(uint32_t *adr, uint32_t data);
231
232/* Get Read/Write function for accessing a register over PCI Memory Space
233 * (non-inline functions).
234 *
235 * Arguments
236 * wr 0(Read), 1(Write)
237 * size 1(Byte), 2(Word), 4(Double Word)
238 * func Where function pointer will be stored
239 * endian PCI_LITTLE_ENDIAN or PCI_BIG_ENDIAN
240 * type 1(I/O), 3(REG over MEM), 4(CFG)
241 *
242 * Return
243 * 0 Found function
244 * others No such function defined by host driver or BSP
245 */
246extern int pci_access_func(int wr, int size, void **func, int endian, int type);
247
248/* Predefined functions for Host drivers or BSPs that define the
249 * register-over-memory space functions operations.
250 */
251extern struct pci_memreg_ops pci_mem_le_ops; /* For Little-Endian PCI bus */
252extern struct pci_memreg_ops pci_mem_be_ops; /* For Big-Endian PCI bus */
253
254#ifdef __cplusplus
255}
256#endif
257
258#endif /* !__PCI_ACCESS_H__ */
basedefs.h
Basic Definitions.
RTEMS_INLINE_ROUTINE
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66
pci_access_drv
Definition: access.h:87
pci_cfg_ops
Definition: access.h:40
pci_io_ops
Definition: access.h:53
pci_memreg_ops
Definition: access.h:65