]>
git.saurik.com Git - apple/boot.git/blob - i386/libsaio/pci.c
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 2.0 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1994 NeXT Computer, Inc.
31 * 03 May 1994 Dean Reece at NeXT
38 static BOOL
testMethod1(void);
39 static BOOL
testMethod2(void);
40 typedef unsigned long (*_pci_bus_method_t
)(
46 static unsigned long getMethod1(
52 static unsigned long getMethod2(
62 _pci_bus_method_t method
,
63 _pci_slot_info_t
*slot_array
66 _pci_slot_info_t
*PCISlotInfo
;
70 PCI_bus_info_t
*info
/* pass in the PCI boot info struct */
73 unsigned int maxBusNum
= 0, maxDevNum
= 0, useMethod
= 0;
74 _pci_bus_method_t method
= NULL
;
75 _pci_slot_info_t
*slot_array
;
78 maxBusNum
= info
->maxBusNum
;
79 if (info
->BIOSPresent
) {
80 if (info
->u_bus
.s
.configMethod1
) {
84 else if (info
->u_bus
.s
.configMethod2
) {
94 else if (testMethod2()) {
102 else if (useMethod
== 2)
107 nslots
= scanBus(maxBusNum
, maxDevNum
, method
, NULL
);
108 slot_array
= (_pci_slot_info_t
*)
109 malloc(sizeof(_pci_slot_info_t
) * nslots
+1);
110 (void)scanBus(maxBusNum
, maxDevNum
, method
, slot_array
);
111 slot_array
[nslots
].pid
= 0x00;
112 slot_array
[nslots
].sid
= 0x00;
113 PCISlotInfo
= slot_array
;
121 _pci_bus_method_t method
,
122 _pci_slot_info_t
*slot_array
125 unsigned int bus
, dev
, func
;
126 unsigned int pid
=0, sid
=0;
129 for (bus
=0; bus
<=maxBusNum
; bus
++) {
130 for (dev
=0; dev
<=maxDevNum
; dev
++) {
131 for (func
=0; func
<8; func
++) {
132 pid
= (*method
)(0x00, dev
, func
, bus
);
133 if ( ((pid
&0xffff) != 0xffff) &&
134 ((pid
&0xffff) != 0x0000) ) {
136 /* device found, do whatever here */
139 sid
= (*method
)(0x2c, dev
, func
, bus
);
140 slot_array
->pid
= pid
;
141 slot_array
->sid
= sid
;
142 slot_array
->dev
= dev
;
143 slot_array
->func
= func
;
144 slot_array
->bus
= bus
;
147 printf ("{\"0x%08x:%08x\" = {\"Location\" = \"Dev:%d Func:%d Bus:%d\"; }\n",
148 pid
, sid
, dev
, func
, bus
);
152 /* skip 1..7 if not multi-func device */
153 pid
= (*method
)(12, dev
, func
, bus
);
154 if ((pid
& 0x00800000)==0) break;
162 /* defines for Configuration Method #1 (PCI 2.0 Spec, sec 3.6.4.1.1) */
163 #define PCI_CONFIG_ADDRESS 0x0cf8
164 #define PCI_CONFIG_DATA 0x0cfc
169 unsigned long address
, data
;
171 for (address
= 0x80000000; address
< 0x80010000; address
+= 0x800) {
172 outl (PCI_CONFIG_ADDRESS
, address
);
173 if (inl (PCI_CONFIG_ADDRESS
) != address
) {
176 data
= inl(PCI_CONFIG_DATA
);
177 if ((data
!= PCI_DEFAULT_DATA
) && (data
!= 0x00)) {
178 outl (PCI_CONFIG_ADDRESS
, 0);
183 outl (PCI_CONFIG_ADDRESS
, 0);
195 unsigned long ret
=PCI_DEFAULT_DATA
;
200 unsigned long addr
:8;
201 unsigned long func
:3;
208 address
.d
= 0x00000000;
214 outl (PCI_CONFIG_ADDRESS
, address
.d
);
216 if (inl (PCI_CONFIG_ADDRESS
) == address
.d
)
217 ret
= inl(PCI_CONFIG_DATA
);
219 outl (PCI_CONFIG_ADDRESS
, 0);
224 /* defines for Configuration Method #2 (PCI 2.0 Spec, sec 3.6.4.1.3) */
225 #define PCI_CSE_REGISTER 0x0cf8
226 #define PCI_BUS_FORWARD 0x0cfa
231 unsigned long address
, data
;
233 /* Enable configuration space at I/O ports Cxxx. */
235 outb (PCI_CSE_REGISTER
, 0xF0);
236 if (inb (PCI_CSE_REGISTER
) != 0xF0) {
240 outb (PCI_BUS_FORWARD
, 0x00);
241 if (inb (PCI_BUS_FORWARD
) != 0x00) {
244 /* Search all devices on the bus. */
245 for (address
= 0xc000; address
<= 0xcfff; address
+= 0x100) {
247 if ((data
!= PCI_DEFAULT_DATA
) && (data
!= 0x00)) {
248 outb (PCI_CSE_REGISTER
, 0);
253 outb (PCI_CSE_REGISTER
, 0);
265 unsigned long ret
=PCI_DEFAULT_DATA
;
266 unsigned short address
;
269 cse
= 0xf0 | (func
<<1);
270 outb(PCI_CSE_REGISTER
, cse
);
271 if (inb(PCI_CSE_REGISTER
) == cse
) {
272 outb(PCI_BUS_FORWARD
, bus
);
273 if (inb(PCI_BUS_FORWARD
) == bus
) {
274 address
= 0xc000 | (addr
&0xfc) | ((dev
&0x0f)<<8);
277 outb(PCI_BUS_FORWARD
, 0x00);
279 outb(PCI_CSE_REGISTER
, 0x00);