1 |
27 |
unneback |
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
|
32 |
|
|
|
33 |
|
|
PCI Library
|
34 |
|
|
|
35 |
|
|
The eCos PCI Library
|
36 |
|
|
The PCI library is an optional part of eCos, and is only
|
37 |
|
|
applicable to some platforms.
|
38 |
|
|
|
39 |
|
|
PCI Library
|
40 |
|
|
The eCos PCI library provides the following functionality:
|
41 |
|
|
|
42 |
|
|
Scan the PCI bus for specific devices or devices of a certain
|
43 |
|
|
class.
|
44 |
|
|
Read and change generic PCI information.
|
45 |
|
|
Read and change device-specific PCI information.
|
46 |
|
|
Allocate PCI memory and IO space to devices.
|
47 |
|
|
Translate a device's PCI interrupts to equivalent HAL
|
48 |
|
|
vectors.
|
49 |
|
|
|
50 |
|
|
Example code fragments are from the pci1 test (see io/pci/<release>/tests/pci1.c).
|
51 |
|
|
All of the functions described below are declared in the header
|
52 |
|
|
file <cyg/io/pci.h> which all
|
53 |
|
|
clients of the PCI library should include.
|
54 |
|
|
|
55 |
|
|
PCI Overview
|
56 |
|
|
The PCI bus supports several address spaces: memory, IO, and configuration. All PCI
|
57 |
|
|
devices must support mandatory configuration space registers. Some devices may also present
|
58 |
|
|
IO mapped and/or memory mapped resources. Before devices on the bus can be used, they must
|
59 |
|
|
be configured. Basically, configuration will assign PCI IO and/or memory address ranges to
|
60 |
|
|
each device and then enable that device. All PCI devices have a unique address in
|
61 |
|
|
configuration space. This address is comprised of a bus number, a device number, and a
|
62 |
|
|
function number. Special devices called bridges are used to connect two PCI busses together.
|
63 |
|
|
The PCI standard supports up to 255 busses with each bus having up to 32 devices and each
|
64 |
|
|
device having up to 8 functions.
|
65 |
|
|
|
66 |
|
|
The environment in which a platform operates will dictate if and how eCos should
|
67 |
|
|
configure devices on the PCI bus. If the platform acts as a host on a single PCI bus,
|
68 |
|
|
then devices may be configured individually from the relevant device driver. If the
|
69 |
|
|
platform is not the primary host, such as a PCI card plugged into a PC, configuration
|
70 |
|
|
of PCI devices may be left to the PC BIOS. If PCI-PCI bridges are involved, configuration
|
71 |
|
|
of all devices is best done all at once early in the boot process. This is because all
|
72 |
|
|
devices on the secondary side of a bridge must be evaluated for their IO and memory space
|
73 |
|
|
requirements before the bridge can be configured.
|
74 |
|
|
|
75 |
|
|
|
76 |
|
|
|
77 |
|
|
Initializing the bus
|
78 |
|
|
The PCI bus needs to be initialized before it can be used.
|
79 |
|
|
This only needs to be done once - some HALs may do it as part of
|
80 |
|
|
the platform initialization procedure, other HALs may leave it to
|
81 |
|
|
the application or device drivers to do it. The following function
|
82 |
|
|
will do the initialization only once, so it's safe to call from
|
83 |
|
|
multiple drivers:
|
84 |
|
|
void cyg_pci_init( void );
|
85 |
|
|
|
86 |
|
|
|
87 |
|
|
Scanning for devices
|
88 |
|
|
After the bus has been initialized, it is possible to scan
|
89 |
|
|
it for devices. This is done using the function:
|
90 |
|
|
cyg_bool cyg_pci_find_next( cyg_pci_device_id cur_devid,
|
91 |
|
|
cyg_pci_device_id *next_devid );
|
92 |
|
|
|
93 |
|
|
It will scan the bus for devices starting at cur_devid
|
94 |
|
|
. If a device is found, its devid is stored in
|
95 |
|
|
next_devid and the function returns true.
|
96 |
|
|
|
97 |
|
|
The pci1 test's outer loop looks like:
|
98 |
|
|
|
99 |
|
|
cyg_pci_init();
|
100 |
|
|
if (cyg_pci_find_next(CYG_PCI_NULL_DEVID, &devid)) {
|
101 |
|
|
do {
|
102 |
|
|
<use devid>
|
103 |
|
|
} while (cyg_pci_find_next(devid, &devid));
|
104 |
|
|
}
|
105 |
|
|
What happens is that the bus gets initialized and a scan is
|
106 |
|
|
started. CYG_PCI_NULL_DEVID causes
|
107 |
|
|
cyg_pci_find_next() to restart its scan. If the bus does not
|
108 |
|
|
contain any devices, the first call to cyg_pci_find_next()
|
109 |
|
|
will return false.
|
110 |
|
|
If the call returns true, a loop is entered where
|
111 |
|
|
the found devid is used. After devid processing has completed, the next device
|
112 |
|
|
on the bus is searched for; cyg_pci_find_next()
|
113 |
|
|
continues its scan from the current devid. The loop terminates when
|
114 |
|
|
no more devices are found on the bus.
|
115 |
|
|
This is the generic way of scanning the bus, enumerating all
|
116 |
|
|
the devices on the bus. But if the application is looking for a
|
117 |
|
|
device of a given device class (e.g., a SCSI controller), or a specific
|
118 |
|
|
vendor device, these functions simplify the task a bit:
|
119 |
|
|
|
120 |
|
|
cyg_bool cyg_pci_find_class( cyg_uint32 dev_class,
|
121 |
|
|
cyg_pci_device_id *devid );
|
122 |
|
|
cyg_bool cyg_pci_find_device( cyg_uint16 vendor, cyg_uint16 device,
|
123 |
|
|
cyg_pci_device_id *devid );
|
124 |
|
|
They work just like cyg_pci_find_next(),
|
125 |
|
|
but only return true when the dev_class or vendor/device
|
126 |
|
|
qualifiers match those of a device on the bus. The devid serves
|
127 |
|
|
as both an input and an output operand: the scan starts at the given
|
128 |
|
|
device, and if a device is found devid is updated with the value
|
129 |
|
|
for the found device.
|
130 |
|
|
The <cyg/io/pci_cfg.h> header
|
131 |
|
|
file (included by pci.h) contains definitions for PCI
|
132 |
|
|
class, vendor and device codes which can be used as arguments to the find
|
133 |
|
|
functions.
|
134 |
|
|
The list of vendor and device codes is not complete: add new codes
|
135 |
|
|
as necessary. If possible also register the codes at the PCI Code
|
136 |
|
|
List (http://www.yourvote.com/pci)
|
137 |
|
|
which is where the eCos definitions are generated from.
|
138 |
|
|
|
139 |
|
|
|
140 |
|
|
Generic config information
|
141 |
|
|
When a valid device ID (devid) is found using one of the above
|
142 |
|
|
functions, the associated device can be queried and controlled using
|
143 |
|
|
the functions:
|
144 |
|
|
|
145 |
|
|
void cyg_pci_get_device_info ( cyg_pci_device_id devid,
|
146 |
|
|
cyg_pci_device *dev_info );
|
147 |
|
|
void cyg_pci_set_device_info ( cyg_pci_device_id devid,
|
148 |
|
|
cyg_pci_device *dev_info );
|
149 |
|
|
The cyg_pci_device structure (defined in
|
150 |
|
|
pci.h) primarily holds information as described by the PCI
|
151 |
|
|
specification [1].
|
152 |
|
|
The pci1 test prints out some of this information:
|
153 |
|
|
// Get device info
|
154 |
|
|
cyg_pci_get_device_info(devid, &dev_info);
|
155 |
|
|
diag_printf("\n Command 0x%04x, Status 0x%04x\n",
|
156 |
|
|
dev_info.command, dev_info.status);
|
157 |
|
|
The command register can also be written to, controlling (among
|
158 |
|
|
other things) whether the device responds to IO and memory access
|
159 |
|
|
from the bus.
|
160 |
|
|
|
161 |
|
|
|
162 |
|
|
Specific config information
|
163 |
|
|
The above functions only allow access to generic PCI config
|
164 |
|
|
registers. A device can have extra config registers not specified
|
165 |
|
|
by the PCI specification. These can be accessed with these functions:
|
166 |
|
|
|
167 |
|
|
void cyg_pci_read_config_uint8( cyg_pci_device_id devid,
|
168 |
|
|
cyg_uint8 offset, cyg_uint8 *val);
|
169 |
|
|
void cyg_pci_read_config_uint16( cyg_pci_device_id devid,
|
170 |
|
|
cyg_uint8 offset, cyg_uint16 *val);
|
171 |
|
|
void cyg_pci_read_config_uint32( cyg_pci_device_id devid,
|
172 |
|
|
cyg_uint8 offset, cyg_uint32 *val);
|
173 |
|
|
void cyg_pci_write_config_uint8( cyg_pci_device_id devid,
|
174 |
|
|
cyg_uint8 offset, cyg_uint8 val);
|
175 |
|
|
void cyg_pci_write_config_uint16( cyg_pci_device_id devid,
|
176 |
|
|
cyg_uint8 offset, cyg_uint16 val);
|
177 |
|
|
void cyg_pci_write_config_uint32( cyg_pci_device_id devid,
|
178 |
|
|
cyg_uint8 offset, cyg_uint32 val);
|
179 |
|
|
|
180 |
|
|
The write functions should only be used for device-specific
|
181 |
|
|
config registers since using them on generic registers may invalidate
|
182 |
|
|
the contents of a previously fetched cyg_pci_device
|
183 |
|
|
structure.
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
Allocating memory
|
187 |
|
|
A PCI device ignores all IO and memory access from the PCI
|
188 |
|
|
bus until it has been activated. Activation cannot happen until
|
189 |
|
|
after device configuration. Configuration means telling the device
|
190 |
|
|
where it should map its IO and memory resources. This is done with
|
191 |
|
|
one of the following functions::
|
192 |
|
|
cyg_bool cyg_pci_configure_device( cyg_pci_device *dev_info );
|
193 |
|
|
cyg_bool cyg_pci_configure_bus( cyg_uint8 bus, cyg_uint8 *next_bus );
|
194 |
|
|
|
195 |
|
|
The cyg_pci_configure_device handles all IO
|
196 |
|
|
and memory regions that need configuration on non-bridge devices. On
|
197 |
|
|
platforms with multiple busses connected by bridges, the
|
198 |
|
|
cyg_pci_configure_bus function should be used. It will recursively
|
199 |
|
|
configure all devices on the given bus and all
|
200 |
|
|
subordinate busses. cyg_pci_configure_bus will
|
201 |
|
|
use cyg_pci_configure_device to configure
|
202 |
|
|
individual non-bridge devices.
|
203 |
|
|
|
204 |
|
|
Each region is represented in the PCI device's config space by BARs
|
205 |
|
|
(Base Address Registers) and is handled individually according to type
|
206 |
|
|
using these functions:
|
207 |
|
|
cyg_bool cyg_pci_allocate_memory( cyg_pci_device *dev_info,
|
208 |
|
|
cyg_uint32 bar,
|
209 |
|
|
CYG_PCI_ADDRESS64 *base );
|
210 |
|
|
cyg_bool cyg_pci_allocate_io( cyg_pci_device *dev_info,
|
211 |
|
|
cyg_uint32 bar,
|
212 |
|
|
CYG_PCI_ADDRESS32 *base );
|
213 |
|
|
The memory bases (in two distinct address spaces) are increased
|
214 |
|
|
as memory regions are allocated to devices. Allocation will fail
|
215 |
|
|
(the function returns false) if the base exceeds the limits of the
|
216 |
|
|
address space (IO is 1MB, memory is 2^32 or 2^64 bytes).
|
217 |
|
|
These functions can also be called directly by the application/driver
|
218 |
|
|
if necessary, but this should not be necessary.
|
219 |
|
|
The bases are initialized with default values provided by
|
220 |
|
|
the HAL. It is possible for an application to override these using
|
221 |
|
|
the following functions:
|
222 |
|
|
void cyg_pci_set_memory_base( CYG_PCI_ADDRESS64 base );
|
223 |
|
|
void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );
|
224 |
|
|
When a device has been configured, the cyg_pci_device
|
225 |
|
|
structure will contain the physical address in the CPU's
|
226 |
|
|
address space where the device's memory regions can be
|
227 |
|
|
accessed.
|
228 |
|
|
This information is provided in base_map[] -
|
229 |
|
|
there is a 32 bit word for each of the device's BARs. For
|
230 |
|
|
32 bit PCI memory regions, each 32 bit word will be an actual pointer
|
231 |
|
|
that can be used immediately by the driver: the memory space will normally
|
232 |
|
|
be linearly addressable by the CPU.
|
233 |
|
|
However, for 64 bit PCI memory regions, some (or all) of the
|
234 |
|
|
region may be outside of the CPUs address space. In this case the
|
235 |
|
|
driver will need to know how to access the region in segments. This
|
236 |
|
|
functionality may be adopted by the eCos HAL if deemed useful in
|
237 |
|
|
the future. The 2GB available on many systems should suffice though.
|
238 |
|
|
|
239 |
|
|
|
240 |
|
|
Interrupts
|
241 |
|
|
A device may generate interrupts. The HAL vector associated
|
242 |
|
|
with a given device on the bus is platform specific. This function
|
243 |
|
|
allows a driver to find the actual interrupt vector for a given
|
244 |
|
|
device:
|
245 |
|
|
cyg_bool cyg_pci_translate_interrupt( cyg_pci_device *dev_info,
|
246 |
|
|
CYG_ADDRWORD *vec );
|
247 |
|
|
If the function returns false, no interrupts will be generated
|
248 |
|
|
by the device. If it returns true, the CYG_ADDRWORD pointed
|
249 |
|
|
to by vec is updated with the HAL interrupt vector the device will
|
250 |
|
|
be using. This is how the function is used in the pci1
|
251 |
|
|
test:
|
252 |
|
|
if (cyg_pci_translate_interrupt(&dev_info, &irq))
|
253 |
|
|
diag_printf(" Wired to HAL vector %d\n", irq);
|
254 |
|
|
else
|
255 |
|
|
diag_printf(" Does not generate interrupts.\n");
|
256 |
|
|
The application/drive should attach an interrupt
|
257 |
|
|
handler to a device's interrupt before activating the device.
|
258 |
|
|
|
259 |
|
|
|
260 |
|
|
Activating a device
|
261 |
|
|
When the device has been allocated memory space it can be
|
262 |
|
|
activated. This is not done by the library since a driver may have
|
263 |
|
|
to initialize more state on the device before it can be safely activated.
|
264 |
|
|
Activating the device is done by enabling flags in its command
|
265 |
|
|
word. As an example, see the pci1 test which can be
|
266 |
|
|
configured to enable the devices it finds. This allows these to be accessed from
|
267 |
|
|
GDB (if a breakpoint is set on cyg_test_exit):
|
268 |
|
|
#ifdef ENABLE_PCI_DEVICES
|
269 |
|
|
{
|
270 |
|
|
cyg_uint16 cmd;
|
271 |
|
|
|
272 |
|
|
// Don't use cyg_pci_set_device_info since it clears
|
273 |
|
|
// some of the fields we want to print out below.
|
274 |
|
|
cyg_pci_read_config_uint16(dev_info.devid,
|
275 |
|
|
CYG_PCI_CFG_COMMAND, &cmd);
|
276 |
|
|
cmd |= CYG_PCI_CFG_COMMAND_IO|CYG_PCI_CFG_COMMAND_MEMORY;
|
277 |
|
|
cyg_pci_write_config_uint16(dev_info.devid,
|
278 |
|
|
CYG_PCI_CFG_COMMAND, cmd);
|
279 |
|
|
}
|
280 |
|
|
diag_printf(" **** Device IO and MEM access enabled\n");
|
281 |
|
|
#endif
|
282 |
|
|
NoteThe best way to activate a device is actually
|
283 |
|
|
through cyg_pci_set_device_info(),
|
284 |
|
|
but in this particular case the cyg_pci_device
|
285 |
|
|
structure contents from before the activation is required for printout
|
286 |
|
|
further down in the code.
|
287 |
|
|
|
288 |
|
|
|
289 |
|
|
Links
|
290 |
|
|
See these links for more information about PCI:
|
291 |
|
|
|
292 |
|
|
|
293 |
|
|
http://www.pcisig.com/ - information on the PCI specifications
|
294 |
|
|
|
295 |
|
|
|
296 |
|
|
http://www.yourvote.com/pci/
|
297 |
|
|
- list of vendor and device IDs
|
298 |
|
|
|
299 |
|
|
|
300 |
|
|
http://www.picmg.org/
|
301 |
|
|
- PCI Industrial Computer Manufacturers Group
|
302 |
|
|
|
303 |
|
|
|
304 |
|
|
|
305 |
|
|
|
306 |
|
|
|
307 |
|
|
PCI Library reference
|
308 |
|
|
This document defines the PCI Support Library for eCos.
|
309 |
|
|
The PCI support library provides a set of routines for accessing
|
310 |
|
|
the PCI bus configuration space in a portable manner. This is provided
|
311 |
|
|
by two APIs. The high level API is used by device drivers, or other
|
312 |
|
|
code, to access the PCI configuration space portably. The low level
|
313 |
|
|
API is used by the PCI library itself to access the hardware in
|
314 |
|
|
a platform-specific manner, and may also be used by device drivers
|
315 |
|
|
to access the PCI configuration space directly.
|
316 |
|
|
Underlying the low-level API is HAL support for the basic
|
317 |
|
|
configuration space operations. These should not generally be used
|
318 |
|
|
by any code other than the PCI library, and are present in the HAL
|
319 |
|
|
to allow low level initialization of the PCI bus and devices to
|
320 |
|
|
take place if necessary.
|
321 |
|
|
|
322 |
|
|
PCI Library API
|
323 |
|
|
The PCI library provides the following routines and types
|
324 |
|
|
for accessing the PCI configuration space.
|
325 |
|
|
The API for the PCI library is found in the header file
|
326 |
|
|
.
|
327 |
|
|
|
328 |
|
|
|
329 |
|
|
Definitions
|
330 |
|
|
The header file contains definitions for the common configuration
|
331 |
|
|
structure offsets and specimen values for device, vendor and class
|
332 |
|
|
code.
|
333 |
|
|
|
334 |
|
|
|
335 |
|
|
Types and data structures
|
336 |
|
|
The following types are defined:
|
337 |
|
|
typedef CYG_WORD32 cyg_pci_device_id;
|
338 |
|
|
This is comprised of the bus number, device number and functional
|
339 |
|
|
unit numbers packed into a single word. The macro CYG_PCI_DEV_MAKE_ID()
|
340 |
|
|
, in conjunction with the CYG_PCI_DEV_MAKE_DEVFN()
|
341 |
|
|
macro, may be used to construct a device id from the bus, device and functional
|
342 |
|
|
unit numbers. Similarly the macros CYG_PCI_DEV_GET_BUS(),
|
343 |
|
|
CYG_PCI_DEV_GET_DEVFN(),
|
344 |
|
|
CYG_PCI_DEV_GET_DEV(), and
|
345 |
|
|
CYG_PCI_DEV_GET_FN() may be used to extract the
|
346 |
|
|
constituent parts of a device id. It should not be necessary to use these
|
347 |
|
|
macros under normal circumstances. The following code fragment demonstrates
|
348 |
|
|
how these macros may be used:
|
349 |
|
|
|
350 |
|
|
// Create a packed representation of device 1, function 0
|
351 |
|
|
cyg_uint8 devfn = CYG_PCI_DEV_MAKE_DEVFN(1,0);
|
352 |
|
|
|
353 |
|
|
// Create a packed devid for that device on bus 2
|
354 |
|
|
cyg_pci_device_id devid = CYG_PCI_DEV_MAKE_ID(2, devfn);
|
355 |
|
|
|
356 |
|
|
diag_printf("bus %d, dev %d, func %d\n",
|
357 |
|
|
CYG_PCI_DEV_GET_BUS(devid),
|
358 |
|
|
CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
|
359 |
|
|
CYG_PCI_DEV_GET_FN(CYG_PCI_DEV_GET_DEVFN(devid));
|
360 |
|
|
|
361 |
|
|
typedef struct cyg_pci_device;
|
362 |
|
|
This structure is used to contain data read from a PCI device's
|
363 |
|
|
configuration header by cyg_pci_get_device_info().
|
364 |
|
|
It is also used to record the resource allocations made to the device.
|
365 |
|
|
typedef CYG_WORD64 CYG_PCI_ADDRESS64;
|
366 |
|
|
typedef CYG_WORD32 CYG_PCI_ADDRESS32;
|
367 |
|
|
Pointers in the PCI address space are 32 bit (IO space) or
|
368 |
|
|
32/64 bit (memory space). In most platform and device configurations
|
369 |
|
|
all of PCI memory will be linearly addressable using only 32 bit
|
370 |
|
|
pointers as read from base_map[].
|
371 |
|
|
The 64 bit type is used to allow handling 64 bit devices in
|
372 |
|
|
the future, should it be necessary, without changing the library's
|
373 |
|
|
API.
|
374 |
|
|
|
375 |
|
|
|
376 |
|
|
Functions
|
377 |
|
|
void cyg_pci_init(void);
|
378 |
|
|
Initialize the PCI library and establish contact with the
|
379 |
|
|
hardware. This function is idempotent and can be called either by
|
380 |
|
|
all drivers in the system, or just from an application initialization
|
381 |
|
|
function.
|
382 |
|
|
cyg_bool cyg_pci_find_device( cyg_uint16 vendor,
|
383 |
|
|
cyg_uint16 device,
|
384 |
|
|
cyg_pci_device_id *devid );
|
385 |
|
|
Searches the PCI bus configuration space for a device with
|
386 |
|
|
the given vendor and device
|
387 |
|
|
ids. The search starts at the device pointed to by devid,
|
388 |
|
|
or at the first slot if it contains CYG_PCI_NULL_DEVID.
|
389 |
|
|
*devid will be updated with the ID of the next device
|
390 |
|
|
found. Returns true if one is found and false
|
391 |
|
|
if not.
|
392 |
|
|
cyg_bool cyg_pci_find_class( cyg_uint32 dev_class,
|
393 |
|
|
cyg_pci_device_id *devid );
|
394 |
|
|
Searches the PCI bus configuration space for a device with
|
395 |
|
|
the given dev_class class code. The search starts at the
|
396 |
|
|
device pointed to by devid, or at the first slot if it
|
397 |
|
|
contains CYG_PCI_NULL_DEVID.
|
398 |
|
|
*devid will be updated with the ID of the next
|
399 |
|
|
device found. Returns true if one is found and
|
400 |
|
|
false if not.
|
401 |
|
|
cyg_bool cyg_pci_find_next( cyg_pci_device_id cur_devid,
|
402 |
|
|
cyg_pci_device_id *next_devid );
|
403 |
|
|
Searches the PCI configuration space for the next valid device
|
404 |
|
|
after cur_devid. If cur_devid
|
405 |
|
|
is given the value CYG_PCI_NULL_DEVID, then the search starts
|
406 |
|
|
at the first slot. It is permitted for next_devid to
|
407 |
|
|
point to cur_devid. Returns true
|
408 |
|
|
if another device is found and false if not.
|
409 |
|
|
|
410 |
|
|
cyg_bool cyg_pci_find_matching( cyg_pci_match_func *matchp,
|
411 |
|
|
void * match_callback_data,
|
412 |
|
|
cyg_pci_device_id *devid );
|
413 |
|
|
|
414 |
|
|
Searches the PCI bus configuration space for a device whose properties
|
415 |
|
|
match those required by the caller supplied cyg_pci_match_func.
|
416 |
|
|
The search starts at the device pointed to by devid, or
|
417 |
|
|
at the first slot if it contains CYG_PCI_NULL_DEVID. The
|
418 |
|
|
devid will be updated with the ID of the next device found.
|
419 |
|
|
This function returns true if a matching device is found
|
420 |
|
|
and false if not.
|
421 |
|
|
|
422 |
|
|
The match_func has a type declared as:
|
423 |
|
|
|
424 |
|
|
typedef cyg_bool (cyg_pci_match_func)( cyg_uint16 vendor,
|
425 |
|
|
cyg_uint16 device,
|
426 |
|
|
cyg_uint32 class,
|
427 |
|
|
void * user_data);
|
428 |
|
|
|
429 |
|
|
The vendor, device, and
|
430 |
|
|
class are from the device configuration space. The
|
431 |
|
|
user_data is the callback data passed to
|
432 |
|
|
cyg_pci_find_matching.
|
433 |
|
|
|
434 |
|
|
void cyg_pci_get_device_info ( cyg_pci_device_id devid,
|
435 |
|
|
cyg_pci_device *dev_info );
|
436 |
|
|
This function gets the PCI configuration information for the
|
437 |
|
|
device indicated in devid. The common fields of the
|
438 |
|
|
cyg_pci_device structure, and the appropriate fields
|
439 |
|
|
of the relevant header union member are filled in from the device's
|
440 |
|
|
configuration space.
|
441 |
|
|
If the device has not been enabled, then this function will also fetch
|
442 |
|
|
the size and type information from the base address registers and
|
443 |
|
|
place it in the base_size[] array.
|
444 |
|
|
void cyg_pci_set_device_info ( cyg_pci_device_id devid,
|
445 |
|
|
cyg_pci_device *dev_info );
|
446 |
|
|
This function sets the PCI configuration information for the
|
447 |
|
|
device indicated in devid. Only the configuration space
|
448 |
|
|
registers that are writable are actually written. Once all the fields have
|
449 |
|
|
been written, the device info will be read back into *dev_info
|
450 |
|
|
, so that it reflects the true state of the hardware.
|
451 |
|
|
|
452 |
|
|
void cyg_pci_read_config_uint8( cyg_pci_device_id devid,
|
453 |
|
|
cyg_uint8 offset, cyg_uint8 *val );
|
454 |
|
|
void cyg_pci_read_config_uint16( cyg_pci_device_id devid,
|
455 |
|
|
cyg_uint8 offset, cyg_uint16 *val );
|
456 |
|
|
void cyg_pci_read_config_uint32( cyg_pci_device_id devid,
|
457 |
|
|
cyg_uint8 offset, cyg_uint32 *val );
|
458 |
|
|
|
459 |
|
|
These functions read registers of the appropriate size from
|
460 |
|
|
the configuration space of the given device. They should mainly
|
461 |
|
|
be used to access registers that are device specific. General PCI
|
462 |
|
|
registers are best accessed through cyg_pci_get_device_info()
|
463 |
|
|
.
|
464 |
|
|
|
465 |
|
|
void cyg_pci_write_config_uint8( cyg_pci_device_id devid,
|
466 |
|
|
cyg_uint8 offset, cyg_uint8 val );
|
467 |
|
|
void cyg_pci_write_config_uint16( cyg_pci_device_id devid,
|
468 |
|
|
cyg_uint8 offset, cyg_uint16 val );
|
469 |
|
|
void cyg_pci_write_config_uint32( cyg_pci_device_id devid,
|
470 |
|
|
cyg_uint8 offset, cyg_uint32 val );
|
471 |
|
|
|
472 |
|
|
These functions write registers of the appropriate size to
|
473 |
|
|
the configuration space of the given device. They should mainly
|
474 |
|
|
be used to access registers that are device specific. General PCI
|
475 |
|
|
registers are best accessed through cyg_pci_get_device_info()
|
476 |
|
|
. Writing the general registers this way may render the contents of
|
477 |
|
|
a cyg_pci_device structure invalid.
|
478 |
|
|
|
479 |
|
|
|
480 |
|
|
Resource allocation
|
481 |
|
|
These routines allocate memory and I/O space to PCI devices.
|
482 |
|
|
cyg_bool cyg_pci_configure_device( cyg_pci_device *dev_info )
|
483 |
|
|
Allocate memory and IO space to all base address registers
|
484 |
|
|
using the current memory and IO base addresses in the library. The
|
485 |
|
|
allocated base addresses, translated into directly usable values,
|
486 |
|
|
will be put into the matching base_map[] entries
|
487 |
|
|
in *dev_info. If *dev_info does
|
488 |
|
|
not contain valid base_size[] entries, then the result is
|
489 |
|
|
false. This function will also call
|
490 |
|
|
cyg_pci_translate_interrupt() to put the interrupt vector into the
|
491 |
|
|
HAL vector entry.
|
492 |
|
|
cyg_bool cyg_pci_configure_bus( cyg_uint8 bus, cyg_uint8 *next_bus )
|
493 |
|
|
|
494 |
|
|
Allocate memory and IO space to all base address registers on all devices
|
495 |
|
|
on the given bus and all subordinate busses. If a PCI-PCI bridge is found on
|
496 |
|
|
bus, this function will call itself recursively in order
|
497 |
|
|
to configure the bus on the other side of the bridge. Because of the nature of
|
498 |
|
|
bridge devices, all devices on the secondary side of a bridge must be allocated
|
499 |
|
|
memory and IO space before the memory and IO windows on the bridge device can be
|
500 |
|
|
properly configured. The next_bus argument points to the
|
501 |
|
|
bus number to assign to the next subordinate bus found. The number will be
|
502 |
|
|
incremented as new busses are discovered. If successful, true
|
503 |
|
|
is returned. Otherwise, false is returned.
|
504 |
|
|
|
505 |
|
|
|
506 |
|
|
cyg_bool cyg_pci_translate_interrupt( cyg_pci_device *dev_info,
|
507 |
|
|
CYG_ADDRWORD *vec );
|
508 |
|
|
|
509 |
|
|
Translate the device's PCI interrupt (INTA#-INTD#)
|
510 |
|
|
to the associated HAL vector. This may also depend on which slot
|
511 |
|
|
the device occupies. If the device may generate interrupts, the
|
512 |
|
|
translated vector number will be stored in vec and the
|
513 |
|
|
result is true. Otherwise the result is false
|
514 |
|
|
.
|
515 |
|
|
|
516 |
|
|
cyg_bool cyg_pci_allocate_memory( cyg_pci_device *dev_info,
|
517 |
|
|
cyg_uint32 bar,
|
518 |
|
|
CYG_PCI_ADDRESS64 *base );
|
519 |
|
|
cyg_bool cyg_pci_allocate_io( cyg_pci_device *dev_info,
|
520 |
|
|
cyg_uint32 bar,
|
521 |
|
|
CYG_PCI_ADDRESS32 *base );
|
522 |
|
|
|
523 |
|
|
These routines allocate memory or I/O space to the base address
|
524 |
|
|
register indicated by bar. The base address in
|
525 |
|
|
*base will be correctly aligned and the address of the
|
526 |
|
|
next free location will be written back into it if the allocation succeeds. If
|
527 |
|
|
the base address register is of the wrong type for this allocation, or
|
528 |
|
|
dev_info does not contain valid base_size[]
|
529 |
|
|
entries, the result is false. These functions
|
530 |
|
|
allow a device driver to set up its own mappings if it wants. Most devices
|
531 |
|
|
should probably use cyg_pci_configure_device().
|
532 |
|
|
void cyg_pci_set_memory_base( CYG_PCI_ADDRESS64 base );
|
533 |
|
|
void cyg_pci_set_io_base( CYG_PCI_ADDRESS32 base );
|
534 |
|
|
These routines set the base addresses for memory and I/O mappings
|
535 |
|
|
to be used by the memory allocation routines. Normally these base
|
536 |
|
|
addresses will be set to default values based on the platform. These
|
537 |
|
|
routines allow these to be changed by application code if necessary.
|
538 |
|
|
|
539 |
|
|
|
540 |
|
|
PCI Library Hardware API
|
541 |
|
|
This API is used by the PCI library to access the PCI bus
|
542 |
|
|
configuration space. Although it should not normally be necessary,
|
543 |
|
|
this API may also be used by device driver or application code to
|
544 |
|
|
perform PCI bus operations not supported by the PCI library.
|
545 |
|
|
void cyg_pcihw_init(void);
|
546 |
|
|
Initialize the PCI hardware so that the configuration space
|
547 |
|
|
may be accessed.
|
548 |
|
|
|
549 |
|
|
void cyg_pcihw_read_config_uint8( cyg_uint8 bus,
|
550 |
|
|
cyg_uint8 devfn, cyg_uint8 offset, cyg_uint8 *val);
|
551 |
|
|
void cyg_pcihw_read_config_uint16( cyg_uint8 bus,
|
552 |
|
|
cyg_uint8 devfn, cyg_uint8 offset, cyg_uint16 *val);
|
553 |
|
|
void cyg_pcihw_read_config_uint32( cyg_uint8 bus,
|
554 |
|
|
cyg_uint8 devfn, cyg_uint8 offset, cyg_uint32 *val);
|
555 |
|
|
|
556 |
|
|
These functions read a register of the appropriate size from
|
557 |
|
|
the PCI configuration space at an address composed from the bus
|
558 |
|
|
, devfn and offset
|
559 |
|
|
arguments.
|
560 |
|
|
|
561 |
|
|
void cyg_pcihw_write_config_uint8( cyg_uint8 bus,
|
562 |
|
|
cyg_uint8 devfn, cyg_uint8 offset, cyg_uint8 val);
|
563 |
|
|
void cyg_pcihw_write_config_uint16( cyg_uint8 bus,
|
564 |
|
|
cyg_uint8 devfn, cyg_uint8 offset, cyg_uint16 val);
|
565 |
|
|
void cyg_pcihw_write_config_uint32( cyg_uint8 bus,
|
566 |
|
|
cyg_uint8 devfn, cyg_uint8 offset, cyg_uint32 val);
|
567 |
|
|
|
568 |
|
|
These functions write a register of the appropriate size to
|
569 |
|
|
the PCI configuration space at an address composed from the
|
570 |
|
|
bus, devfn and
|
571 |
|
|
offset arguments.
|
572 |
|
|
|
573 |
|
|
cyg_bool cyg_pcihw_translate_interrupt( cyg_uint8 bus,
|
574 |
|
|
cyg_uint8 devfn,
|
575 |
|
|
CYG_ADDRWORD *vec);
|
576 |
|
|
|
577 |
|
|
This function interrogates the device and determines which
|
578 |
|
|
HAL interrupt vector it is connected to.
|
579 |
|
|
|
580 |
|
|
|
581 |
|
|
HAL PCI support
|
582 |
|
|
HAL support consists of a set of C macros that provide the
|
583 |
|
|
implementation of the low level PCI API.
|
584 |
|
|
HAL_PCI_INIT()
|
585 |
|
|
Initialize the PCI bus.
|
586 |
|
|
HAL_PCI_READ_UINT8( bus, devfn, offset, val )
|
587 |
|
|
HAL_PCI_READ_UINT16( bus, devfn, offset, val )
|
588 |
|
|
HAL_PCI_READ_UINT32( bus, devfn, offset, val )
|
589 |
|
|
Read a value from the PCI configuration space of the appropriate
|
590 |
|
|
size at an address composed from the bus,
|
591 |
|
|
devfn and offset.
|
592 |
|
|
HAL_PCI_WRITE_UINT8( bus, devfn, offset, val )
|
593 |
|
|
HAL_PCI_WRITE_UINT16( bus, devfn, offset, val )
|
594 |
|
|
HAL_PCI_WRITE_UINT32( bus, devfn, offset, val )
|
595 |
|
|
Write a value to the PCI configuration space of the appropriate
|
596 |
|
|
size at an address composed from the bus,
|
597 |
|
|
devfn and offset.
|
598 |
|
|
HAL_PCI_TRANSLATE_INTERRUPT( bus, devfn, *vec, valid )
|
599 |
|
|
Translate the device's interrupt line into a HAL
|
600 |
|
|
interrupt vector.
|
601 |
|
|
HAL_PCI_ALLOC_BASE_MEMORY
|
602 |
|
|
HAL_PCI_ALLOC_BASE_IO
|
603 |
|
|
These macros define the default base addresses used to initialize
|
604 |
|
|
the memory and I/O allocation pointers.
|
605 |
|
|
HAL_PCI_PHYSICAL_MEMORY_BASE
|
606 |
|
|
HAL_PCI_PHYSICAL_IO_BASE
|
607 |
|
|
PCI memory and IO range do not always correspond directly
|
608 |
|
|
to physical memory or IO addresses. Frequently the PCI address spaces
|
609 |
|
|
are windowed into the processor's address range at some
|
610 |
|
|
offset. These macros define offsets to be added to the PCI base
|
611 |
|
|
addresses to translate PCI bus addresses into physical memory addresses
|
612 |
|
|
that can be used to access the allocated memory or IO space.
|
613 |
|
|
|
614 |
|
|
The chunk of PCI memory space directly addressable though
|
615 |
|
|
the window by the CPU may be smaller than the amount of PCI memory
|
616 |
|
|
actually provided. In that case drivers will have to access PCI
|
617 |
|
|
memory space in segments. Doing this will be platform specific and
|
618 |
|
|
is currently beyond the scope of the HAL.
|
619 |
|
|
|
620 |
|
|
HAL_PCI_IGNORE_DEVICE( bus, dev, fn )
|
621 |
|
|
This macro, if defined, may be used to limit the devices which are
|
622 |
|
|
found by the bus scanning functions. This is sometimes necessary for
|
623 |
|
|
devices which need special handling. If this macro evaluates to true
|
624 |
|
|
, the given device will not be found by cyg_pci_find_next
|
625 |
|
|
or other bus scanning functions.
|
626 |
|
|
|
627 |
|
|
|
628 |
|
|
|
629 |
|
|
|
630 |
|
|
|