RTEMS 6.1-rc2
Loading...
Searching...
No Matches
access.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
12/*
13 * COPYRIGHT (c) 2010 Cobham Gaisler AB.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37
38#ifndef __PCI_ACCESS_H__
39#define __PCI_ACCESS_H__
40
41#include <stdint.h>
42#include <libcpu/byteorder.h>
44#include <pci.h>
45
46#ifdef __cplusplus
47extern "C" {
48#endif
49
50/* Identification of a PCI configuration space device (16-bit) */
51typedef uint16_t pci_dev_t;
52/* Create a PCI Configuration Space ID */
53#define PCI_DEV(bus, slot, func) (((bus)<<8) | ((slot)<<3) | (func))
54/* Get Bus of a PCI Configuration Space ID */
55#define PCI_DEV_BUS(dev) (((dev) >> 8) & 0xff)
56/* Get Slot/Device of a PCI Configuration Space ID */
57#define PCI_DEV_SLOT(dev) (((dev) >> 3) & 0x1f)
58/* Get Function of a PCI Configuration Space ID */
59#define PCI_DEV_FUNC(dev) ((dev) & 0x7)
60/* Get Device and Function of a PCI Configuration Space ID */
61#define PCI_DEV_DEVFUNC(dev) ((dev) & 0xff)
62/* Expand Device into argument lists */
63#define PCI_DEV_EXPAND(dev) PCI_DEV_BUS((dev)), PCI_DEV_SLOT((dev)), PCI_DEV_FUNC((dev))
64
65/* Configuration Space Read/Write Operations */
67 /* Configuration Space Access and Setup Routines */
68 int (*read8)(pci_dev_t dev, int ofs, uint8_t *data);
69 int (*read16)(pci_dev_t dev, int ofs, uint16_t *data);
70 int (*read32)(pci_dev_t dev, int ofs, uint32_t *data);
71 int (*write8)(pci_dev_t dev, int ofs, uint8_t data);
72 int (*write16)(pci_dev_t dev, int ofs, uint16_t data);
73 int (*write32)(pci_dev_t dev, int ofs, uint32_t data);
74};
75
76/* Read a register over PCI I/O Space, and swap it if necessary (due to
77 * PCI endianness)
78 */
79struct pci_io_ops {
80 uint8_t (*read8)(uint8_t *adr);
81 uint16_t(*read16)(uint16_t *adr);
82 uint32_t (*read32)(uint32_t *adr);
83 void (*write8)(uint8_t *adr, uint8_t data);
84 void (*write16)(uint16_t *adr, uint16_t data);
85 void (*write32)(uint32_t *adr, uint32_t data);
86};
87
88/* Read a register over PCI Memory Space (non-prefetchable memory), and
89 * swap it if necessary (due to PCI endianness)
90 */
92 uint8_t (*ld8)(uint8_t *adr);
93 void (*st8)(uint8_t *adr, uint8_t data);
94
95 uint16_t(*ld_le16)(uint16_t *adr);
96 void (*st_le16)(uint16_t *adr, uint16_t data);
97 uint16_t(*ld_be16)(uint16_t *adr);
98 void (*st_be16)(uint16_t *adr, uint16_t data);
99
100 uint32_t (*ld_le32)(uint32_t *adr);
101 void (*st_le32)(uint32_t *adr, uint32_t data);
102 uint32_t (*ld_be32)(uint32_t *adr);
103 void (*st_be32)(uint32_t *adr, uint32_t data);
104};
105
106typedef uint8_t (*pci_ld8_t)(uint8_t *adr);
107typedef void (*pci_st8_t)(uint8_t *adr, uint8_t data);
108typedef uint16_t(pci_ld16_t)(uint16_t *adr);
109typedef void (*pci_st16_t)(uint16_t *adr, uint16_t data);
110typedef uint32_t (*pci_ld32_t)(uint32_t *adr);
111typedef void (*pci_st32_t)(uint32_t *adr, uint32_t data);
112
114 /* Configuration */
115 struct pci_cfg_ops cfg;
116
117 /* I/O Access operations */
118 struct pci_io_ops io;
119
120 /* Registers over Memory Access operations. Note that these funcs
121 * are only for code that need to be compatible with both Big-Endian
122 * and Little-Endian PCI bus or for some other reason need function
123 * pointers to access functions. Normally drivers use the inline
124 * functions for Registers-over-Memory access to avoid extra function
125 * call.
126 */
127 struct pci_memreg_ops *memreg;
128
129 /* Translate from PCI address to CPU address (dir=0). Translate
130 * CPU address to PCI address (dir!=0). The address will can be
131 * used to perform I/O access or memory access by CPU or PCI DMA
132 * peripheral.
133 *
134 * address In/Out. CPU address or PCI address.
135 * type Access type. 1=I/O, 2=MEMIO, 3=MEM
136 * dir Translate direction. 0=PCI-to-CPU, 0!=CPU-to-PCI,
137 *
138 * Return Value
139 * 0 = Success
140 * -1 = Requested Address not mapped into other address space
141 * i.e. not accessible
142 */
143 int (*translate)(uint32_t *address, int type, int dir);
144};
145
146/* Access Routines valid after a PCI-Access-Driver has registered */
147extern struct pci_access_drv pci_access_ops;
148
149/* Register PCI Access Driver */
150extern int pci_access_drv_register(struct pci_access_drv *drv);
151
152/* Set/unset bits in command and status register of a PCI device */
153extern void pci_modify_cmdsts(pci_dev_t dev, uint32_t mask, uint32_t val);
154
155/* Enable Memory in command register */
156static inline void pci_mem_enable(pci_dev_t dev)
157{
158 pci_modify_cmdsts(dev, PCIM_CMD_MEMEN, PCIM_CMD_MEMEN);
159}
160
161static inline void pci_mem_disable(pci_dev_t dev)
162{
163 pci_modify_cmdsts(dev, PCIM_CMD_MEMEN, 0);
164}
165
166static inline void pci_io_enable(pci_dev_t dev)
167{
168 pci_modify_cmdsts(dev, PCIM_CMD_PORTEN, PCIM_CMD_PORTEN);
169}
170
171static inline void pci_io_disable(pci_dev_t dev)
172{
173 pci_modify_cmdsts(dev, PCIM_CMD_PORTEN, 0);
174}
175
176static inline void pci_master_enable(pci_dev_t dev)
177{
178 pci_modify_cmdsts(dev, PCIM_CMD_BUSMASTEREN, PCIM_CMD_BUSMASTEREN);
179}
180
181static inline void pci_master_disable(pci_dev_t dev)
182{
183 pci_modify_cmdsts(dev, PCIM_CMD_BUSMASTEREN, 0);
184}
185
186/* Configuration Space Access Read Routines */
187extern int pci_cfg_r8(pci_dev_t dev, int ofs, uint8_t *data);
188extern int pci_cfg_r16(pci_dev_t dev, int ofs, uint16_t *data);
189extern int pci_cfg_r32(pci_dev_t dev, int ofs, uint32_t *data);
190
191/* Configuration Space Access Write Routines */
192extern int pci_cfg_w8(pci_dev_t dev, int ofs, uint8_t data);
193extern int pci_cfg_w16(pci_dev_t dev, int ofs, uint16_t data);
194extern int pci_cfg_w32(pci_dev_t dev, int ofs, uint32_t data);
195
196/* Read a register over PCI I/O Space */
197extern uint8_t pci_io_r8(uint32_t adr);
198extern uint16_t pci_io_r16(uint32_t adr);
199extern uint32_t pci_io_r32(uint32_t adr);
200
201/* Write a register over PCI I/O Space */
202extern void pci_io_w8(uint32_t adr, uint8_t data);
203extern void pci_io_w16(uint32_t adr, uint16_t data);
204extern void pci_io_w32(uint32_t adr, uint32_t data);
205
206/* Translate PCI address into CPU accessible address */
207static inline int pci_pci2cpu(uint32_t *address, int type)
208{
209 return pci_access_ops.translate(address, type, 0);
210}
211
212/* Translate CPU accessible address into PCI address (for DMA) */
213static inline int pci_cpu2pci(uint32_t *address, int type)
214{
215 return pci_access_ops.translate(address, type, 1);
216}
217
218/*** Read/Write a register over PCI Memory Space ***/
219
220static inline uint8_t pci_ld8(volatile uint8_t *addr)
221{
222 return *addr;
223}
224
225static inline void pci_st8(volatile uint8_t *addr, uint8_t val)
226{
227 *addr = val;
228}
229
230/* Registers-over-Memory Space access routines. The routines are not inlined
231 * so it is possible during run-time to select which function implemention
232 * to use. The use of these functions are not recommended since it will have a
233 * performance penalty.
234 *
235 * 8-bit accesses are the same for Little and Big endian PCI buses.
236 */
237uint8_t pci_mem_ld8(uint8_t *adr);
238void pci_mem_st8(uint8_t *adr, uint8_t data);
239/* Registers-over-Memory Space - Generic Big endian PCI bus definitions */
240uint16_t pci_mem_be_ld_le16(uint16_t *adr);
241uint16_t pci_mem_be_ld_be16(uint16_t *adr);
242uint32_t pci_mem_be_ld_le32(uint32_t *adr);
243uint32_t pci_mem_be_ld_be32(uint32_t *adr);
244void pci_mem_be_st_le16(uint16_t *adr, uint16_t data);
245void pci_mem_be_st_be16(uint16_t *adr, uint16_t data);
246void pci_mem_be_st_le32(uint32_t *adr, uint32_t data);
247void pci_mem_be_st_be32(uint32_t *adr, uint32_t data);
248/* Registers-over-Memory Space - Generic Little endian PCI bus definitions */
249uint16_t pci_mem_le_ld_le16(uint16_t *adr);
250uint16_t pci_mem_le_ld_be16(uint16_t *adr);
251uint32_t pci_mem_le_ld_le32(uint32_t *adr);
252uint32_t pci_mem_le_ld_be32(uint32_t *adr);
253void pci_mem_le_st_le16(uint16_t *adr, uint16_t data);
254void pci_mem_le_st_be16(uint16_t *adr, uint16_t data);
255void pci_mem_le_st_le32(uint32_t *adr, uint32_t data);
256void pci_mem_le_st_be32(uint32_t *adr, uint32_t data);
257
258/* Get Read/Write function for accessing a register over PCI Memory Space
259 * (non-inline functions).
260 *
261 * Arguments
262 * wr 0(Read), 1(Write)
263 * size 1(Byte), 2(Word), 4(Double Word)
264 * func Where function pointer will be stored
265 * endian PCI_LITTLE_ENDIAN or PCI_BIG_ENDIAN
266 * type 1(I/O), 3(REG over MEM), 4(CFG)
267 *
268 * Return
269 * 0 Found function
270 * others No such function defined by host driver or BSP
271 */
272extern int pci_access_func(int wr, int size, void **func, int endian, int type);
273
274/* Predefined functions for Host drivers or BSPs that define the
275 * register-over-memory space functions operations.
276 */
277extern struct pci_memreg_ops pci_mem_le_ops; /* For Little-Endian PCI bus */
278extern struct pci_memreg_ops pci_mem_be_ops; /* For Big-Endian PCI bus */
279
280#ifdef __cplusplus
281}
282#endif
283
284#endif /* !__PCI_ACCESS_H__ */
This header file provides basic definitions used by the API and the implementation.
Definition: access.h:113
Definition: access.h:66
Definition: access.h:79
Definition: access.h:91