3 ** Copyright 1999 Brian J. Swetland. All rights reserved.
4 ** Distributed under the terms of the OpenBLT License
25 uint32
pci_read(int bus
, int dev
, int func
, int reg
, int bytes
)
43 base
= 0xCFC + (reg
& 0x03);
46 case 1: return inb(base
);
47 case 2: return inw(base
);
48 case 4: return inl(base
);
53 void pci_write(int bus
, int dev
, int func
, int reg
, uint32 v
, int bytes
)
69 base
= 0xCFC + (reg
& 0x03);
72 case 1: outb(v
,base
); break;
73 case 2: outw(v
,base
); break;
74 case 4: outl(v
,base
); break;
79 int pci_probe(int bus
, int dev
, int func
, pci_cfg
*cfg
)
81 uint32
*word
= (uint32
*) cfg
;
85 word
[i
] = pci_read(bus
,dev
,func
,4*i
,4);
87 if(cfg
->vendor_id
== 0xffff) return 1;
93 printf("Device Info: /bus/pci/%d/%d/%d\n",bus
,dev
,func
);
94 printf(" * Vendor: %S Device: %S Class/SubClass/Interface %X/%X/%X\n",
95 cfg
->vendor_id
,cfg
->device_id
,cfg
->base_class
,cfg
->sub_class
,cfg
->interface
);
96 printf(" * Status: %S Command: %S BIST/Type/Lat/CLS: %X/%X/%X/%X\n",
97 cfg
->status
, cfg
->command
, cfg
->bist
, cfg
->header_type
,
98 cfg
->latency_timer
, cfg
->cache_line_size
);
101 switch(cfg
->header_type
& 0x7F){
102 case 0: /* normal device */
104 v
= pci_read(bus
,dev
,func
,i
*4 + 0x10, 4);
107 pci_write(bus
,dev
,func
,i
*4 + 0x10, 0xffffffff, 4);
108 v2
= pci_read(bus
,dev
,func
,i
*4+0x10, 4) & 0xfffffff0;
109 pci_write(bus
,dev
,func
,i
*4 + 0x10, v
, 4);
112 // printf(" * Base Register %d IO: %x (%x)\n",i,v&0xfff0,v2&0xffff);
113 cfg
->base
[i
] = v
& 0xffff;
114 cfg
->size
[i
] = v2
& 0xffff;
116 // printf(" * Base Register %d MM: %x (%x)\n",i,v&0xfffffff0,v2);
126 v
= pci_read(bus
,dev
,func
,0x3c,1);
127 // if((v != 0xff) && (v != 0)) printf(" * Interrupt Line: %X\n",v);
130 // printf(" * PCI <-> PCI Bridge\n");
133 // printf(" * Unknown Header Type\n");
139 int pci_find(pci_cfg
*cfg
, uint16 vendor_id
, uint16 device_id
)
143 for(bus
=0;bus
<255;bus
++){
144 for(dev
=0;dev
<32;dev
++) {
145 if(pci_probe(bus
,dev
,0,cfg
)) continue;
146 if((cfg
->vendor_id
== vendor_id
) &&
147 (cfg
->device_id
== device_id
)) return 0;
148 if(cfg
->header_type
& 0x80){
149 for(func
=1;func
<8;func
++){
150 if(!pci_probe(bus
,dev
,func
,cfg
) &&
151 (cfg
->vendor_id
== vendor_id
) &&
152 (cfg
->device_id
== device_id
)) return 0;