]>
git.saurik.com Git - apple/boot.git/blob - i386/libsaio/pci.c
7fd0542fa205735d24f9838b35afadface850ea0
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 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 1.1 (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
35 #include <mach/mach_types.h>
36 // #include "legacy/KernDevice.h"
37 #include "legacy/PCI.h"
39 #include "kernBootStruct.h"
41 #include "io_inline.h"
44 static BOOL
testMethod1(void);
45 static BOOL
testMethod2(void);
46 typedef unsigned long (*_pci_bus_method_t
)(
52 static unsigned long getMethod1(
58 static unsigned long getMethod2(
68 _pci_bus_method_t method
,
69 _pci_slot_info_t
*slot_array
72 _pci_slot_info_t
*PCISlotInfo
;
76 PCI_bus_info_t
*info
/* pass in the PCI boot info struct */
80 unsigned int maxBusNum
= 0, maxDevNum
= 0, useMethod
= 0;
81 _pci_bus_method_t method
= NULL
;
82 _pci_slot_info_t
*slot_array
;
85 maxBusNum
= info
->maxBusNum
;
86 if (info
->BIOSPresent
) {
87 if (info
->u_bus
.s
.configMethod1
) {
91 else if (info
->u_bus
.s
.configMethod2
) {
101 else if (testMethod2()) {
110 else if (useMethod
== 2)
115 nslots
= scanBus(maxBusNum
, maxDevNum
, method
, NULL
);
116 slot_array
= (_pci_slot_info_t
*)
117 malloc(sizeof(_pci_slot_info_t
) * nslots
+1);
118 (void)scanBus(maxBusNum
, maxDevNum
, method
, slot_array
);
119 slot_array
[nslots
].pid
= 0x00;
120 slot_array
[nslots
].sid
= 0x00;
121 PCISlotInfo
= slot_array
;
129 _pci_bus_method_t method
,
130 _pci_slot_info_t
*slot_array
133 unsigned int bus
, dev
, func
;
134 unsigned int pid
=0, sid
=0;
137 for (bus
=0; bus
<=maxBusNum
; bus
++) {
138 for (dev
=0; dev
<=maxDevNum
; dev
++) {
139 for (func
=0; func
<8; func
++) {
140 pid
= (*method
)(0x00, dev
, func
, bus
);
141 if ( ((pid
&0xffff) != 0xffff) &&
142 ((pid
&0xffff) != 0x0000) ) {
144 /* device found, do whatever here */
147 sid
= (*method
)(0x2c, dev
, func
, bus
);
148 slot_array
->pid
= pid
;
149 slot_array
->sid
= sid
;
150 slot_array
->dev
= dev
;
151 slot_array
->func
= func
;
152 slot_array
->bus
= bus
;
155 printf ("{\"0x%08x:%08x\" = {\"Location\" = \"Dev:%d Func:%d Bus:%d\"; }\n",
156 pid
, sid
, dev
, func
, bus
);
160 /* skip 1..7 if not multi-func device */
161 pid
= (*method
)(12, dev
, func
, bus
);
162 if ((pid
& 0x00800000)==0) break;
170 /* defines for Configuration Method #1 (PCI 2.0 Spec, sec 3.6.4.1.1) */
171 #define PCI_CONFIG_ADDRESS 0x0cf8
172 #define PCI_CONFIG_DATA 0x0cfc
177 unsigned long address
, data
;
179 for (address
= 0x80000000; address
< 0x80010000; address
+= 0x800) {
180 outl (PCI_CONFIG_ADDRESS
, address
);
181 if (inl (PCI_CONFIG_ADDRESS
) != address
) {
184 data
= inl(PCI_CONFIG_DATA
);
185 if ((data
!= PCI_DEFAULT_DATA
) && (data
!= 0x00)) {
186 outl (PCI_CONFIG_ADDRESS
, 0);
191 outl (PCI_CONFIG_ADDRESS
, 0);
203 unsigned long ret
=PCI_DEFAULT_DATA
;
208 unsigned long addr
:8;
209 unsigned long func
:3;
216 address
.d
= 0x00000000;
222 outl (PCI_CONFIG_ADDRESS
, address
.d
);
224 if (inl (PCI_CONFIG_ADDRESS
) == address
.d
)
225 ret
= inl(PCI_CONFIG_DATA
);
227 outl (PCI_CONFIG_ADDRESS
, 0);
232 /* defines for Configuration Method #2 (PCI 2.0 Spec, sec 3.6.4.1.3) */
233 #define PCI_CSE_REGISTER 0x0cf8
234 #define PCI_BUS_FORWARD 0x0cfa
239 unsigned long address
, data
;
241 /* Enable configuration space at I/O ports Cxxx. */
243 outb (PCI_CSE_REGISTER
, 0xF0);
244 if (inb (PCI_CSE_REGISTER
) != 0xF0) {
248 outb (PCI_BUS_FORWARD
, 0x00);
249 if (inb (PCI_BUS_FORWARD
) != 0x00) {
252 /* Search all devices on the bus. */
253 for (address
= 0xc000; address
<= 0xcfff; address
+= 0x100) {
255 if ((data
!= PCI_DEFAULT_DATA
) && (data
!= 0x00)) {
256 outb (PCI_CSE_REGISTER
, 0);
261 outb (PCI_CSE_REGISTER
, 0);
273 unsigned long ret
=PCI_DEFAULT_DATA
;
274 unsigned short address
;
277 cse
= 0xf0 | (func
<<1);
278 outb(PCI_CSE_REGISTER
, cse
);
279 if (inb(PCI_CSE_REGISTER
) == cse
) {
280 outb(PCI_BUS_FORWARD
, bus
);
281 if (inb(PCI_BUS_FORWARD
) == bus
) {
282 address
= 0xc000 | (addr
&0xfc) | ((dev
&0x0f)<<8);
285 outb(PCI_BUS_FORWARD
, 0x00);
287 outb(PCI_CSE_REGISTER
, 0x00);