source: rtems/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c @ c0a36429

4.104.114.84.95
Last change on this file since c0a36429 was 0c04c377, checked in by Joel Sherrill <joel.sherrill@…>, on Feb 18, 1999 at 4:48:14 PM

./clock/Makefile.in,v
./clock/clock.c,v
./console/Makefile.in,v
./console/config.c,v
./console/console.c,v
./console/console.h,v
./console/debugio.c,v
./console/i8042.c,v
./console/i8042_p.h,v
./console/i8042vga.c,v
./console/i8042vga.h,v
./console/ns16550.c,v
./console/ns16550.h,v
./console/ns16550_p.h,v
./console/ns16550cfg.c,v
./console/ns16550cfg.h,v
./console/vga.c,v
./console/vga_p.h,v
./console/z85c30.c,v
./console/z85c30.h,v
./console/z85c30_p.h,v
./console/z85c30cfg.c,v
./console/z85c30cfg.h,v
./include/Makefile.in,v
./include/bsp.h,v
./include/chain.h,v
./include/coverhd.h,v
./include/extisrdrv.h,v
./include/nvram.h,v
./include/pci.h,v
./include/tod.h,v
./network/Makefile.in,v
./network/amd79c970.c,v
./network/amd79c970.h,v
./nvram/Makefile.in,v
./nvram/ds1385.h,v
./nvram/mk48t18.h,v
./nvram/nvram.c,v
./nvram/prepnvr.h,v
./nvram/stk11c68.h,v
./pci/Makefile.in,v
./pci/pci.c,v
./start/Makefile.in,v
./start/start.s,v
./startup/Makefile.in,v
./startup/bspclean.c,v
./startup/bspstart.c,v
./startup/bsptrap.s,v
./startup/device-tree,v
./startup/genpvec.c,v
./startup/linkcmds,v
./startup/rtems-ctor.cc,v
./startup/sbrk.c,v
./startup/setvec.c,v
./startup/spurious.c,v
./startup/swap.c,v
./timer/Makefile.in,v
./timer/timer.c,v
./tod/Makefile.in,v
./tod/cmos.h,v
./tod/tod.c,v
./universe/Makefile.in,v
./universe/universe.c,v
./vectors/Makefile.in,v
./vectors/README,v
./vectors/align_h.s,v
./vectors/vectors.s,v
./wrapup/Makefile.in,v
./Makefile.in,v
./README,v
./STATUS,v
./bsp_specs,v

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/*
2 *  COPYRIGHT (c) 1998 by Radstone Technology
3 *
4 *
5 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
6 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
7 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
8 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
9 *
10 * You are hereby granted permission to use, copy, modify, and distribute
11 * this file, provided that this notice, plus the above copyright notice
12 * and disclaimer, appears in all copies. Radstone Technology will provide
13 * no support for this code.
14 *
15 */
16#include <bsp.h>
17#include <pci.h>
18
19/* SCE 97/4/9
20 *
21 * Use PCI configuration space access mechanism 1
22 *
23 * This is the preferred access mechanism and must be used when accessing
24 * bridged PCI busses.
25 *
26 * The address to be written to the PCI_CONFIG_ADDRESS port is constructed
27 * thus (the representation below is little endian):
28 *
29 *  31  30   24 23        16 15        11 10        8 7          2 1   0
30 *  ----------------------------------------------------------------------
31 * | 1 | Resvd | Bus Number | Dev Number | Fn Number | Reg Number | 0 | 0 |
32 *  ----------------------------------------------------------------------
33 *
34 * On bus 0, the first 'real' device is at Device number 11, the Eagle being
35 * device 0. On all other busses, device numbering starts at 0.
36 */
37/*
38 * Normal PCI device numbering on busses other than 0 is such that
39 * that the first device (0) is attached to AD16, second (1) to AD17 etc.
40 */
41#define CONFIG_ADDRESS(Bus, Device, Function, Offset) \
42    (0x80000000 | (Bus<<16) | \
43    ((Device+(((Bus==0)&&(Device>0)) ? 10 : 0))<<11) | \
44    (Function<<8) | \
45    (Offset&~0x03))
46#define BYTE_LANE_OFFSET(Offset) ((Offset)&0x3)
47
48/*
49 * Private data
50 */
51static unsigned8 ucMaxPCIBus;
52
53/*
54 * Public routines
55 */
56rtems_status_code PCIConfigWrite8(
57        unsigned8 ucBusNumber,
58        unsigned8 ucSlotNumber,
59        unsigned8 ucFunctionNumber,
60        unsigned8 ucOffset,
61        unsigned8 ucValue
62)
63{
64        ISR_Level Irql;
65
66        /*
67         * Ensure that accesses to the addr/data ports are indivisible
68         */
69        _ISR_Disable(Irql);
70
71        /*
72         * Write to the configuration space address register
73         */
74        outport_32(PCI_CONFIG_ADDR,
75                   CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
76                                  ucFunctionNumber, ucOffset));
77        /*
78         * Write to the configuration space data register with the appropriate
79         * offset
80         */
81        outport_byte(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), ucValue);
82
83         _ISR_Enable(Irql);
84
85        return(RTEMS_SUCCESSFUL);
86}
87
88rtems_status_code PCIConfigWrite16(
89        unsigned8 ucBusNumber,
90        unsigned8 ucSlotNumber,
91        unsigned8 ucFunctionNumber,
92        unsigned8 ucOffset,
93        unsigned16 usValue
94)
95{
96        ISR_Level Irql;
97
98        /*
99         * Ensure that accesses to the addr/data ports are indivisible
100         */
101        _ISR_Disable(Irql);
102
103        /*
104         * Write to the configuration space address register
105         */
106        outport_32(PCI_CONFIG_ADDR,
107                   CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
108                                  ucFunctionNumber, ucOffset));
109        /*
110         * Write to the configuration space data register with the appropriate
111         * offset
112         */
113        outport_16(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), usValue);
114
115        _ISR_Enable(Irql);
116
117        return(RTEMS_SUCCESSFUL);
118}
119
120rtems_status_code PCIConfigWrite32(
121        unsigned8 ucBusNumber,
122        unsigned8 ucSlotNumber,
123        unsigned8 ucFunctionNumber,
124        unsigned8 ucOffset,
125        unsigned32 ulValue
126)
127{
128        ISR_Level Irql;
129
130        /*
131         * Ensure that accesses to the addr/data ports are indivisible
132         */
133        _ISR_Disable(Irql);
134
135        /*
136         * Write to the configuration space address register
137         */
138        outport_32(PCI_CONFIG_ADDR,
139                   CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
140                                  ucFunctionNumber, ucOffset));
141        /*
142         * Write to the configuration space data register with the appropriate
143         * offset
144         */
145        outport_32(PCI_CONFIG_DATA, ulValue);
146
147        _ISR_Enable(Irql);
148
149        return(RTEMS_SUCCESSFUL);
150}
151
152rtems_status_code PCIConfigRead8(
153        unsigned8 ucBusNumber,
154        unsigned8 ucSlotNumber,
155        unsigned8 ucFunctionNumber,
156        unsigned8 ucOffset,
157        unsigned8 *pucValue
158)
159{
160        ISR_Level Irql;
161
162        /*
163         * Ensure that accesses to the addr/data ports are indivisible
164         */
165        _ISR_Disable(Irql);
166
167        /*
168         * Write to the configuration space address register
169         */
170        outport_32(PCI_CONFIG_ADDR,
171                   CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
172                                  ucFunctionNumber, ucOffset));
173        /*
174         * Read from the configuration space data register with the appropriate
175         * offset
176         */
177        inport_byte(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), *pucValue);
178
179        _ISR_Enable(Irql);
180
181        return(RTEMS_SUCCESSFUL);
182}
183
184rtems_status_code PCIConfigRead16(
185        unsigned8 ucBusNumber,
186        unsigned8 ucSlotNumber,
187        unsigned8 ucFunctionNumber,
188        unsigned8 ucOffset,
189        unsigned16 *pusValue
190)
191{
192        ISR_Level Irql;
193
194        /*
195         * Ensure that accesses to the addr/data ports are indivisible
196         */
197        _ISR_Disable(Irql);
198
199        /*
200         * Write to the configuration space address register
201         */
202        outport_32(PCI_CONFIG_ADDR,
203                   CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
204                                  ucFunctionNumber, ucOffset));
205        /*
206         * Read from the configuration space data register with the appropriate
207         * offset
208         */
209        inport_16(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), *pusValue);
210
211        _ISR_Enable(Irql);
212
213        return(RTEMS_SUCCESSFUL);
214}
215
216rtems_status_code PCIConfigRead32(
217        unsigned8 ucBusNumber,
218        unsigned8 ucSlotNumber,
219        unsigned8 ucFunctionNumber,
220        unsigned8 ucOffset,
221        unsigned32 *pulValue
222)
223{
224        ISR_Level Irql;
225
226        /*
227         * Ensure that accesses to the addr/data ports are indivisible
228         */
229        _ISR_Disable(Irql);
230
231        /*
232         * Write to the configuration space address register
233         */
234        outport_32(PCI_CONFIG_ADDR,
235                   CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
236                                  ucFunctionNumber, ucOffset));
237        /*
238         * Read from the configuration space data register with the appropriate
239         * offset
240         */
241        inport_32(PCI_CONFIG_DATA, *pulValue);
242
243        _ISR_Enable(Irql);
244
245        return(RTEMS_SUCCESSFUL);
246}
247
248/*
249 * This routine determines the maximum bus number in the system
250 */
251void InitializePCI()
252{
253        unsigned8 ucSlotNumber, ucFnNumber, ucNumFuncs;
254        unsigned8 ucHeader;
255        unsigned8 ucBaseClass, ucSubClass, ucMaxSubordinate;
256        unsigned32 ulDeviceID;
257
258        /*
259         * Scan PCI bus 0 looking for PCI-PCI bridges
260         */
261        for(ucSlotNumber=0;ucSlotNumber<PCI_MAX_DEVICES;ucSlotNumber++)
262        {
263                (void)PCIConfigRead32(0,
264                                      ucSlotNumber,
265                                      0,
266                                      PCI_CONFIG_VENDOR_LOW,
267                                      &ulDeviceID);
268                if(ulDeviceID==PCI_INVALID_VENDORDEVICEID)
269                {
270                        /*
271                         * This slot is empty
272                         */
273                        continue;
274                }
275                (void)PCIConfigRead8(0,
276                                     ucSlotNumber,
277                                     0,
278                                     PCI_CONFIG_HEADER_TYPE,
279                                     &ucHeader);
280                if(ucHeader&PCI_MULTI_FUNCTION)
281                {
282                        ucNumFuncs=PCI_MAX_FUNCTIONS;
283                }
284                else
285                {
286                        ucNumFuncs=1;
287                }
288                for(ucFnNumber=0;ucFnNumber<ucNumFuncs;ucFnNumber++)
289                {
290                        (void)PCIConfigRead32(0,
291                                              ucSlotNumber,
292                                              ucFnNumber,
293                                              PCI_CONFIG_VENDOR_LOW,
294                                              &ulDeviceID);
295                        if(ulDeviceID==PCI_INVALID_VENDORDEVICEID)
296                        {
297                                /*
298                                 * This slot/function is empty
299                                 */
300                                continue;
301                        }
302
303                        /*
304                         * This slot/function has a device fitted.
305                         */
306                        (void)PCIConfigRead8(0,
307                                             ucSlotNumber,
308                                             ucFnNumber,
309                                             PCI_CONFIG_CLASS_CODE_U,
310                                             &ucBaseClass);
311                        (void)PCIConfigRead8(0,
312                                             ucSlotNumber,
313                                             ucFnNumber,
314                                             PCI_CONFIG_CLASS_CODE_M,
315                                             &ucSubClass);
316                        if((ucBaseClass==PCI_BASE_CLASS_BRIDGE) &&
317                           (ucSubClass==PCI_SUB_CLASS_BRIDGE_PCI))
318                        {
319                                /*
320                                 * We have found a PCI-PCI bridge
321                                 */
322                                (void)PCIConfigRead8(0,
323                                                     ucSlotNumber,
324                                                     ucFnNumber,
325                                                     PCI_BRIDGE_SUBORDINATE_BUS,
326                                                     &ucMaxSubordinate);
327                                if(ucMaxSubordinate>ucMaxPCIBus)
328                                {
329                                        ucMaxPCIBus=ucMaxSubordinate;
330                                }
331                        }
332                }
333        }
334}
335
336/*
337 * Return the number of PCI busses in the system
338 */
339unsigned8 BusCountPCI()
340{
341        return(ucMaxPCIBus+1);
342}
Note: See TracBrowser for help on using the repository browser.