00001 #define USER_SPACE 1
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "../drivers.h"
00011 #define NDEBUG
00012 #include <assert.h>
00013 #include <ibm/pci.h>
00014 #include <sys/vm.h>
00015 #include <minix/com.h>
00016 #include <minix/syslib.h>
00017
00018 #include "pci.h"
00019 #include "pci_amd.h"
00020 #include "pci_intel.h"
00021 #include "pci_sis.h"
00022 #include "pci_via.h"
00023 #if __minix_vmd
00024 #include "config.h"
00025 #endif
00026
00027 #if !__minix_vmd
00028 #define irq_mode_pci(irq) ((void)0)
00029 #endif
00030
00031 #include <stdlib.h>
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <minix/sysutil.h>
00035
00036 #define NR_PCIBUS 10
00037 #define NR_PCIDEV 40
00038
00039 #define PBT_INTEL_HOST 1
00040 #define PBT_PCIBRIDGE 2
00041 #define PBT_CARDBUS 3
00042
00043 #define BAM_NR 6
00044
00045 PRIVATE int debug= 0;
00046
00047 PRIVATE struct pcibus
00048 {
00049 int pb_type;
00050 int pb_needinit;
00051 int pb_isabridge_dev;
00052 int pb_isabridge_type;
00053
00054 int pb_devind;
00055 int pb_busnr;
00056 u8_t (*pb_rreg8)(int busind, int devind, int port);
00057 u16_t (*pb_rreg16)(int busind, int devind, int port);
00058 u32_t (*pb_rreg32)(int busind, int devind, int port);
00059 void (*pb_wreg8)(int busind, int devind, int port, U8_t value);
00060 void (*pb_wreg16)(int busind, int devind, int port, U16_t value);
00061 void (*pb_wreg32)(int busind, int devind, int port, u32_t value);
00062 u16_t (*pb_rsts)(int busind);
00063 void (*pb_wsts)(int busind, U16_t value);
00064 } pcibus[NR_PCIBUS];
00065 PRIVATE int nr_pcibus= 0;
00066
00067 PRIVATE struct pcidev
00068 {
00069 u8_t pd_busnr;
00070 u8_t pd_dev;
00071 u8_t pd_func;
00072 u8_t pd_baseclass;
00073 u8_t pd_subclass;
00074 u8_t pd_infclass;
00075 u16_t pd_vid;
00076 u16_t pd_did;
00077 u8_t pd_ilr;
00078 u8_t pd_inuse;
00079
00080 struct bar
00081 {
00082 int pb_flags;
00083 int pb_nr;
00084 u32_t pb_base;
00085 u32_t pb_size;
00086 } pd_bar[BAM_NR];
00087 int pd_bar_nr;
00088
00089 char pd_name[M3_STRING];
00090 } pcidev[NR_PCIDEV];
00091
00092
00093 #define PBF_IO 1
00094 #define PBF_INCOMPLETE 2
00095
00096 PRIVATE int nr_pcidev= 0;
00097
00098
00099 PRIVATE int qemu_pci= 0;
00100
00101 FORWARD _PROTOTYPE( void pci_intel_init, (void) );
00102 FORWARD _PROTOTYPE( void probe_bus, (int busind) );
00103 FORWARD _PROTOTYPE( int is_duplicate, (U8_t busnr, U8_t dev, U8_t func) );
00104 FORWARD _PROTOTYPE( void record_irq, (int devind) );
00105 FORWARD _PROTOTYPE( void record_bars, (int devind) );
00106 FORWARD _PROTOTYPE( void record_bars_bridge, (int devind) );
00107 FORWARD _PROTOTYPE( void record_bars_cardbus, (int devind) );
00108 FORWARD _PROTOTYPE( void record_bar, (int devind, int bar_nr) );
00109 FORWARD _PROTOTYPE( void complete_bridges, (void) );
00110 FORWARD _PROTOTYPE( void complete_bars, (void) );
00111 FORWARD _PROTOTYPE( void update_bridge4dev_io, (int devind,
00112 u32_t io_base, u32_t io_size) );
00113 FORWARD _PROTOTYPE( int get_freebus, (void) );
00114 FORWARD _PROTOTYPE( int do_isabridge, (int busind) );
00115 FORWARD _PROTOTYPE( void do_pcibridge, (int busind) );
00116 FORWARD _PROTOTYPE( int get_busind, (int busnr) );
00117 FORWARD _PROTOTYPE( int do_piix, (int devind) );
00118 FORWARD _PROTOTYPE( int do_amd_isabr, (int devind) );
00119 FORWARD _PROTOTYPE( int do_sis_isabr, (int devind) );
00120 FORWARD _PROTOTYPE( int do_via_isabr, (int devind) );
00121 FORWARD _PROTOTYPE( void report_vga, (int devind) );
00122 FORWARD _PROTOTYPE( char *pci_vid_name, (U16_t vid) );
00123 FORWARD _PROTOTYPE( char *pci_baseclass_name, (U8_t baseclass) );
00124 FORWARD _PROTOTYPE( char *pci_subclass_name, (U8_t baseclass,
00125 U8_t subclass, U8_t infclass) );
00126 FORWARD _PROTOTYPE( void ntostr, (unsigned n, char **str, char *end) );
00127 FORWARD _PROTOTYPE( u16_t pci_attr_rsts, (int devind) );
00128 FORWARD _PROTOTYPE( void pci_attr_wsts, (int devind, U16_t value) );
00129 FORWARD _PROTOTYPE( u16_t pcibr_std_rsts, (int busind) );
00130 FORWARD _PROTOTYPE( void pcibr_std_wsts, (int busind, U16_t value) );
00131 FORWARD _PROTOTYPE( u16_t pcibr_cb_rsts, (int busind) );
00132 FORWARD _PROTOTYPE( void pcibr_cb_wsts, (int busind, U16_t value) );
00133 FORWARD _PROTOTYPE( u16_t pcibr_via_rsts, (int busind) );
00134 FORWARD _PROTOTYPE( void pcibr_via_wsts, (int busind, U16_t value) );
00135 FORWARD _PROTOTYPE( u8_t pcii_rreg8, (int busind, int devind, int port) );
00136 FORWARD _PROTOTYPE( u16_t pcii_rreg16, (int busind, int devind,
00137 int port) );
00138 FORWARD _PROTOTYPE( u32_t pcii_rreg32, (int busind, int devind,
00139 int port) );
00140 FORWARD _PROTOTYPE( void pcii_wreg8, (int busind, int devind, int port,
00141 U8_t value) );
00142 FORWARD _PROTOTYPE( void pcii_wreg16, (int busind, int devind, int port,
00143 U16_t value) );
00144 FORWARD _PROTOTYPE( void pcii_wreg32, (int busind, int devind, int port,
00145 u32_t value) );
00146 FORWARD _PROTOTYPE( u16_t pcii_rsts, (int busind) );
00147 FORWARD _PROTOTYPE( void pcii_wsts, (int busind, U16_t value) );
00148 FORWARD _PROTOTYPE( void print_capabilities, (int devind) );
00149
00150
00151
00152
00153 PUBLIC unsigned pci_inb(U16_t port) {
00154 u32_t value;
00155 int s;
00156 if ((s=sys_inb(port, &value)) !=OK)
00157 printf("PCI: warning, sys_inb failed: %d\n", s);
00158 return value;
00159 }
00160 PUBLIC unsigned pci_inw(U16_t port) {
00161 u32_t value;
00162 int s;
00163 if ((s=sys_inw(port, &value)) !=OK)
00164 printf("PCI: warning, sys_inw failed: %d\n", s);
00165 return value;
00166 }
00167 PUBLIC unsigned pci_inl(U16_t port) {
00168 U32_t value;
00169 int s;
00170 if ((s=sys_inl(port, &value)) !=OK)
00171 printf("PCI: warning, sys_inl failed: %d\n", s);
00172 return value;
00173 }
00174 PUBLIC void pci_outb(U16_t port, U8_t value) {
00175 int s;
00176 if ((s=sys_outb(port, value)) !=OK)
00177 printf("PCI: warning, sys_outb failed: %d\n", s);
00178 }
00179 PUBLIC void pci_outw(U16_t port, U16_t value) {
00180 int s;
00181 if ((s=sys_outw(port, value)) !=OK)
00182 printf("PCI: warning, sys_outw failed: %d\n", s);
00183 }
00184 PUBLIC void pci_outl(U16_t port, U32_t value) {
00185 int s;
00186 if ((s=sys_outl(port, value)) !=OK)
00187 printf("PCI: warning, sys_outl failed: %d\n", s);
00188 }
00189
00190
00191
00192
00193 PUBLIC void pci_init()
00194 {
00195 static int first_time= 1;
00196
00197 long v;
00198
00199 if (!first_time)
00200 return;
00201
00202 v= 0;
00203 env_parse("qemu_pci", "d", 0, &v, 0, 1);
00204 qemu_pci= v;
00205
00206 v= 0;
00207 env_parse("pci_debug", "d", 0, &v, 0, 1);
00208 debug= v;
00209
00210
00211 assert(first_time == 1);
00212 first_time= -1;
00213
00214
00215
00216
00217 pci_intel_init();
00218
00219 first_time= 0;
00220 }
00221
00222
00223
00224
00225 PUBLIC int pci_find_dev(bus, dev, func, devindp)
00226 u8_t bus;
00227 u8_t dev;
00228 u8_t func;
00229 int *devindp;
00230 {
00231 int devind;
00232
00233 for (devind= 0; devind < nr_pcidev; devind++)
00234 {
00235 if (pcidev[devind].pd_busnr == bus &&
00236 pcidev[devind].pd_dev == dev &&
00237 pcidev[devind].pd_func == func)
00238 {
00239 break;
00240 }
00241 }
00242 if (devind >= nr_pcidev)
00243 return 0;
00244 if (pcidev[devind].pd_inuse)
00245 return 0;
00246 *devindp= devind;
00247 return 1;
00248 }
00249
00250
00251
00252
00253 PUBLIC int pci_first_dev(devindp, vidp, didp)
00254 int *devindp;
00255 u16_t *vidp;
00256 u16_t *didp;
00257 {
00258 int devind;
00259
00260 for (devind= 0; devind < nr_pcidev; devind++)
00261 {
00262 if (!pcidev[devind].pd_inuse)
00263 break;
00264 }
00265 if (devind >= nr_pcidev)
00266 return 0;
00267 *devindp= devind;
00268 *vidp= pcidev[devind].pd_vid;
00269 *didp= pcidev[devind].pd_did;
00270 return 1;
00271 }
00272
00273
00274
00275
00276 PUBLIC int pci_next_dev(devindp, vidp, didp)
00277 int *devindp;
00278 u16_t *vidp;
00279 u16_t *didp;
00280 {
00281 int devind;
00282
00283 for (devind= *devindp+1; devind < nr_pcidev; devind++)
00284 {
00285 if (!pcidev[devind].pd_inuse)
00286 break;
00287 }
00288 if (devind >= nr_pcidev)
00289 return 0;
00290 *devindp= devind;
00291 *vidp= pcidev[devind].pd_vid;
00292 *didp= pcidev[devind].pd_did;
00293 return 1;
00294 }
00295
00296
00297
00298
00299 PUBLIC void pci_reserve3(devind, proc, name)
00300 int devind;
00301 int proc;
00302 char *name;
00303 {
00304 int i, r;
00305 u8_t ilr;
00306 struct io_range ior;
00307 struct mem_range mr;
00308
00309 assert(devind <= nr_pcidev);
00310 assert(!pcidev[devind].pd_inuse);
00311 pcidev[devind].pd_inuse= 1;
00312 strcpy(pcidev[devind].pd_name, name);
00313
00314 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
00315 {
00316 if (pcidev[devind].pd_bar[i].pb_flags & PBF_INCOMPLETE)
00317 {
00318 printf("pci_reserve3: BAR %d is incomplete\n", i);
00319 continue;
00320 }
00321 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
00322 {
00323 ior.ior_base= pcidev[devind].pd_bar[i].pb_base;
00324 ior.ior_limit= ior.ior_base +
00325 pcidev[devind].pd_bar[i].pb_size-1;
00326
00327 if(debug) {
00328 printf(
00329 "pci_reserve3: for proc %d, adding I/O range [0x%x..0x%x]\n",
00330 proc, ior.ior_base, ior.ior_limit);
00331 }
00332 r= sys_privctl(proc, SYS_PRIV_ADD_IO, 0, &ior);
00333 if (r != OK)
00334 {
00335 printf("sys_privctl failed for proc %d: %d\n",
00336 proc, r);
00337 }
00338 }
00339 else
00340 {
00341 mr.mr_base= pcidev[devind].pd_bar[i].pb_base;
00342 mr.mr_limit= mr.mr_base +
00343 pcidev[devind].pd_bar[i].pb_size-1;
00344
00345 if(debug) {
00346 printf(
00347 "pci_reserve3: for proc %d, should add memory range [0x%x..0x%x]\n",
00348 proc, mr.mr_base, mr.mr_limit);
00349 }
00350 r= sys_privctl(proc, SYS_PRIV_ADD_MEM, 0, &mr);
00351 if (r != OK)
00352 {
00353 printf("sys_privctl failed for proc %d: %d\n",
00354 proc, r);
00355 }
00356 }
00357 }
00358 ilr= pcidev[devind].pd_ilr;
00359 if (ilr != PCI_ILR_UNKNOWN)
00360 {
00361 if(debug) printf("pci_reserve3: adding IRQ %d\n", ilr);
00362 r= sys_privctl(proc, SYS_PRIV_ADD_IRQ, ilr, NULL);
00363 if (r != OK)
00364 {
00365 printf("sys_privctl failed for proc %d: %d\n",
00366 proc, r);
00367 }
00368 }
00369 }
00370
00371
00372
00373
00374 PUBLIC void pci_release(name)
00375 char *name;
00376 {
00377 int i;
00378
00379 for (i= 0; i<nr_pcidev; i++)
00380 {
00381 if (!pcidev[i].pd_inuse)
00382 continue;
00383 if (strcmp(pcidev[i].pd_name, name) != 0)
00384 continue;
00385 pcidev[i].pd_inuse= 0;
00386 }
00387 }
00388
00389
00390
00391
00392 PUBLIC void pci_ids(devind, vidp, didp)
00393 int devind;
00394 u16_t *vidp;
00395 u16_t *didp;
00396 {
00397 assert(devind <= nr_pcidev);
00398 *vidp= pcidev[devind].pd_vid;
00399 *didp= pcidev[devind].pd_did;
00400 }
00401
00402
00403
00404
00405 PUBLIC void pci_rescan_bus(busnr)
00406 u8_t busnr;
00407 {
00408 int busind;
00409
00410 busind= get_busind(busnr);
00411 probe_bus(busind);
00412
00413
00414 complete_bridges();
00415
00416
00417 complete_bars();
00418 }
00419
00420
00421
00422
00423 PUBLIC char *pci_slot_name(devind)
00424 int devind;
00425 {
00426 static char label[]= "ddd.ddd.ddd";
00427 char *end;
00428 char *p;
00429
00430 p= label;
00431 end= label+sizeof(label);
00432
00433 ntostr(pcidev[devind].pd_busnr, &p, end);
00434 *p++= '.';
00435
00436 ntostr(pcidev[devind].pd_dev, &p, end);
00437 *p++= '.';
00438
00439 ntostr(pcidev[devind].pd_func, &p, end);
00440
00441 return label;
00442 }
00443
00444
00445
00446
00447 PUBLIC char *pci_dev_name(vid, did)
00448 u16_t vid;
00449 u16_t did;
00450 {
00451 int i;
00452
00453 for (i= 0; pci_device_table[i].name; i++)
00454 {
00455 if (pci_device_table[i].vid == vid &&
00456 pci_device_table[i].did == did)
00457 {
00458 return pci_device_table[i].name;
00459 }
00460 }
00461 return NULL;
00462 }
00463
00464
00465
00466
00467 PUBLIC u8_t pci_attr_r8(devind, port)
00468 int devind;
00469 int port;
00470 {
00471 int busnr, busind;
00472
00473 busnr= pcidev[devind].pd_busnr;
00474 busind= get_busind(busnr);
00475 return pcibus[busind].pb_rreg8(busind, devind, port);
00476 }
00477
00478
00479
00480
00481 PUBLIC u16_t pci_attr_r16(devind, port)
00482 int devind;
00483 int port;
00484 {
00485 int busnr, busind;
00486
00487 busnr= pcidev[devind].pd_busnr;
00488 busind= get_busind(busnr);
00489 return pcibus[busind].pb_rreg16(busind, devind, port);
00490 }
00491
00492
00493
00494
00495 PUBLIC u32_t pci_attr_r32(devind, port)
00496 int devind;
00497 int port;
00498 {
00499 int busnr, busind;
00500
00501 busnr= pcidev[devind].pd_busnr;
00502 busind= get_busind(busnr);
00503 return pcibus[busind].pb_rreg32(busind, devind, port);
00504 }
00505
00506
00507
00508
00509 PUBLIC void pci_attr_w8(devind, port, value)
00510 int devind;
00511 int port;
00512 u16_t value;
00513 {
00514 int busnr, busind;
00515
00516 busnr= pcidev[devind].pd_busnr;
00517 busind= get_busind(busnr);
00518 pcibus[busind].pb_wreg8(busind, devind, port, value);
00519 }
00520
00521
00522
00523
00524 PUBLIC void pci_attr_w16(devind, port, value)
00525 int devind;
00526 int port;
00527 u16_t value;
00528 {
00529 int busnr, busind;
00530
00531 busnr= pcidev[devind].pd_busnr;
00532 busind= get_busind(busnr);
00533 pcibus[busind].pb_wreg16(busind, devind, port, value);
00534 }
00535
00536
00537
00538
00539 PUBLIC void pci_attr_w32(devind, port, value)
00540 int devind;
00541 int port;
00542 u32_t value;
00543 {
00544 int busnr, busind;
00545
00546 busnr= pcidev[devind].pd_busnr;
00547 busind= get_busind(busnr);
00548 pcibus[busind].pb_wreg32(busind, devind, port, value);
00549 }
00550
00551
00552
00553
00554 PRIVATE void pci_intel_init()
00555 {
00556
00557
00558
00559
00560
00561 u32_t bus, dev, func;
00562 u16_t vid, did;
00563 int s, i, r, busind, busnr;
00564 char *dstr;
00565
00566 bus= 0;
00567 dev= 0;
00568 func= 0;
00569
00570 vid= PCII_RREG16_(bus, dev, func, PCI_VID);
00571 did= PCII_RREG16_(bus, dev, func, PCI_DID);
00572 #if USER_SPACE
00573 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
00574 printf("PCI: warning, sys_outl failed: %d\n", s);
00575 #else
00576 outl(PCII_CONFADD, PCII_UNSEL);
00577 #endif
00578
00579 if (vid == 0xffff && did == 0xffff)
00580 return;
00581
00582 #if 0
00583 for (i= 0; pci_intel_ctrl[i].vid; i++)
00584 {
00585 if (pci_intel_ctrl[i].vid == vid &&
00586 pci_intel_ctrl[i].did == did)
00587 {
00588 break;
00589 }
00590 }
00591
00592 if (!pci_intel_ctrl[i].vid)
00593 {
00594 printf("pci_intel_init (warning): unknown PCI-controller:\n"
00595 "\tvendor %04X (%s), device %04X\n",
00596 vid, pci_vid_name(vid), did);
00597 }
00598 #endif
00599
00600 if (nr_pcibus >= NR_PCIBUS)
00601 panic("PCI","too many PCI busses", nr_pcibus);
00602 busind= nr_pcibus;
00603 nr_pcibus++;
00604 pcibus[busind].pb_type= PBT_INTEL_HOST;
00605 pcibus[busind].pb_needinit= 0;
00606 pcibus[busind].pb_isabridge_dev= -1;
00607 pcibus[busind].pb_isabridge_type= 0;
00608 pcibus[busind].pb_devind= -1;
00609 pcibus[busind].pb_busnr= 0;
00610 pcibus[busind].pb_rreg8= pcii_rreg8;
00611 pcibus[busind].pb_rreg16= pcii_rreg16;
00612 pcibus[busind].pb_rreg32= pcii_rreg32;
00613 pcibus[busind].pb_wreg8= pcii_wreg8;
00614 pcibus[busind].pb_wreg16= pcii_wreg16;
00615 pcibus[busind].pb_wreg32= pcii_wreg32;
00616 pcibus[busind].pb_rsts= pcii_rsts;
00617 pcibus[busind].pb_wsts= pcii_wsts;
00618
00619 dstr= pci_dev_name(vid, did);
00620 if (!dstr)
00621 dstr= "unknown device";
00622 if (debug)
00623 {
00624 printf("pci_intel_init: %s (%04X/%04X)\n",
00625 dstr, vid, did);
00626 }
00627
00628 probe_bus(busind);
00629
00630 r= do_isabridge(busind);
00631 if (r != OK)
00632 {
00633 busnr= pcibus[busind].pb_busnr;
00634
00635
00636 for (i= 0; i<nr_pcidev; i++)
00637 {
00638 if (pcidev[i].pd_busnr != busnr)
00639 continue;
00640 pcidev[i].pd_inuse= 1;
00641 }
00642 return;
00643 }
00644
00645
00646 do_pcibridge(busind);
00647
00648
00649 complete_bridges();
00650
00651
00652 complete_bars();
00653 }
00654
00655
00656
00657
00658 PRIVATE void probe_bus(busind)
00659 int busind;
00660 {
00661 u32_t dev, func, t3;
00662 u16_t vid, did, sts;
00663 u8_t headt;
00664 u8_t baseclass, subclass, infclass;
00665 int devind, busnr;
00666 char *s, *dstr;
00667
00668 #if DEBUG
00669 printf("probe_bus(%d)\n", busind);
00670 #endif
00671 if (nr_pcidev >= NR_PCIDEV)
00672 panic("PCI","too many PCI devices", nr_pcidev);
00673 devind= nr_pcidev;
00674
00675 busnr= pcibus[busind].pb_busnr;
00676 for (dev= 0; dev<32; dev++)
00677 {
00678
00679 for (func= 0; func < 8; func++)
00680 {
00681 pcidev[devind].pd_busnr= busnr;
00682 pcidev[devind].pd_dev= dev;
00683 pcidev[devind].pd_func= func;
00684
00685 pci_attr_wsts(devind,
00686 PSR_SSE|PSR_RMAS|PSR_RTAS);
00687 vid= pci_attr_r16(devind, PCI_VID);
00688 did= pci_attr_r16(devind, PCI_DID);
00689 headt= pci_attr_r8(devind, PCI_HEADT);
00690 sts= pci_attr_rsts(devind);
00691
00692 #if 0
00693 printf("vid 0x%x, did 0x%x, headt 0x%x, sts 0x%x\n",
00694 vid, did, headt, sts);
00695 #endif
00696
00697 if (vid == NO_VID)
00698 {
00699 if (func == 0)
00700 break;
00701
00702
00703
00704
00705 continue;
00706 }
00707
00708 if (sts & (PSR_SSE|PSR_RMAS|PSR_RTAS))
00709 {
00710 if (qemu_pci)
00711 {
00712 printf(
00713 "pci: ignoring bad value 0x%x in sts for QEMU\n",
00714 sts & (PSR_SSE|PSR_RMAS|PSR_RTAS));
00715 }
00716 else
00717 {
00718 if (func == 0)
00719 break;
00720
00721
00722
00723
00724 continue;
00725 }
00726 }
00727
00728 dstr= pci_dev_name(vid, did);
00729 if (debug)
00730 {
00731 if (dstr)
00732 {
00733 printf("%d.%lu.%lu: %s (%04X/%04X)\n",
00734 busind, (unsigned long)dev,
00735 (unsigned long)func, dstr,
00736 vid, did);
00737 }
00738 else
00739 {
00740 printf(
00741 "%d.%lu.%lu: Unknown device, vendor %04X (%s), device %04X\n",
00742 busind, (unsigned long)dev,
00743 (unsigned long)func, vid,
00744 pci_vid_name(vid), did);
00745 }
00746 printf("Device index: %d\n", devind);
00747 printf("Subsystem: Vid 0x%x, did 0x%x\n",
00748 pci_attr_r16(devind, PCI_SUBVID),
00749 pci_attr_r16(devind, PCI_SUBDID));
00750 }
00751
00752 baseclass= pci_attr_r8(devind, PCI_BCR);
00753 subclass= pci_attr_r8(devind, PCI_SCR);
00754 infclass= pci_attr_r8(devind, PCI_PIFR);
00755 s= pci_subclass_name(baseclass, subclass, infclass);
00756 if (!s)
00757 s= pci_baseclass_name(baseclass);
00758 {
00759 if (!s)
00760 s= "(unknown class)";
00761 }
00762 if (debug)
00763 {
00764 printf("\tclass %s (%X/%X/%X)\n", s,
00765 baseclass, subclass, infclass);
00766 }
00767
00768 if (is_duplicate(busnr, dev, func))
00769 {
00770 printf("\tduplicate!\n");
00771 if (func == 0 && !(headt & PHT_MULTIFUNC))
00772 break;
00773 continue;
00774 }
00775
00776 devind= nr_pcidev;
00777 nr_pcidev++;
00778 pcidev[devind].pd_baseclass= baseclass;
00779 pcidev[devind].pd_subclass= subclass;
00780 pcidev[devind].pd_infclass= infclass;
00781 pcidev[devind].pd_vid= vid;
00782 pcidev[devind].pd_did= did;
00783 pcidev[devind].pd_inuse= 0;
00784 pcidev[devind].pd_bar_nr= 0;
00785 record_irq(devind);
00786 switch(headt & PHT_MASK)
00787 {
00788 case PHT_NORMAL:
00789 record_bars(devind);
00790 break;
00791 case PHT_BRIDGE:
00792 record_bars_bridge(devind);
00793 break;
00794 case PHT_CARDBUS:
00795 record_bars_cardbus(devind);
00796 break;
00797 default:
00798 printf("\t%d.%d.%d: unknown header type %d\n",
00799 busind, dev, func,
00800 headt & PHT_MASK);
00801 break;
00802 }
00803 if (debug)
00804 print_capabilities(devind);
00805
00806 t3= ((baseclass << 16) | (subclass << 8) | infclass);
00807 if (t3 == PCI_T3_VGA || t3 == PCI_T3_VGA_OLD)
00808 report_vga(devind);
00809
00810 if (nr_pcidev >= NR_PCIDEV)
00811 panic("PCI","too many PCI devices", nr_pcidev);
00812 devind= nr_pcidev;
00813
00814 if (func == 0 && !(headt & PHT_MULTIFUNC))
00815 break;
00816 }
00817 }
00818 }
00819
00820
00821
00822
00823 PRIVATE int is_duplicate(busnr, dev, func)
00824 u8_t busnr;
00825 u8_t dev;
00826 u8_t func;
00827 {
00828 int i;
00829
00830 for (i= 0; i<nr_pcidev; i++)
00831 {
00832 if (pcidev[i].pd_busnr == busnr &&
00833 pcidev[i].pd_dev == dev &&
00834 pcidev[i].pd_func == func)
00835 {
00836 return 1;
00837 }
00838 }
00839 return 0;
00840 }
00841
00842
00843
00844
00845 PRIVATE void record_irq(devind)
00846 int devind;
00847 {
00848 int ilr, ipr, busnr, busind, cb_devind;
00849
00850 ilr= pci_attr_r8(devind, PCI_ILR);
00851 ipr= pci_attr_r8(devind, PCI_IPR);
00852 if (ilr == 0)
00853 {
00854 static int first= 1;
00855 if (ipr && first && debug)
00856 {
00857 first= 0;
00858 printf("PCI: strange, BIOS assigned IRQ0\n");
00859 }
00860 ilr= PCI_ILR_UNKNOWN;
00861 }
00862 pcidev[devind].pd_ilr= ilr;
00863 if (ilr == PCI_ILR_UNKNOWN && !ipr)
00864 {
00865 }
00866 else if (ilr != PCI_ILR_UNKNOWN && ipr)
00867 {
00868 if (debug)
00869 printf("\tIRQ %d for INT%c\n", ilr, 'A' + ipr-1);
00870 }
00871 else if (ilr != PCI_ILR_UNKNOWN)
00872 {
00873 printf(
00874 "PCI: IRQ %d is assigned, but device %d.%d.%d does not need it\n",
00875 ilr, pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
00876 pcidev[devind].pd_func);
00877 }
00878 else
00879 {
00880
00881 busnr= pcidev[devind].pd_busnr;
00882 busind= get_busind(busnr);
00883 if (pcibus[busind].pb_type == PBT_CARDBUS)
00884 {
00885 cb_devind= pcibus[busind].pb_devind;
00886 ilr= pcidev[cb_devind].pd_ilr;
00887 if (ilr != PCI_ILR_UNKNOWN)
00888 {
00889 if (debug)
00890 {
00891 printf(
00892 "assigning IRQ %d to Cardbus device\n",
00893 ilr);
00894 }
00895 pci_attr_w8(devind, PCI_ILR, ilr);
00896 pcidev[devind].pd_ilr= ilr;
00897 return;
00898 }
00899 }
00900 if(debug) {
00901 printf(
00902 "PCI: device %d.%d.%d uses INT%c but is not assigned any IRQ\n",
00903 pcidev[devind].pd_busnr, pcidev[devind].pd_dev,
00904 pcidev[devind].pd_func, 'A' + ipr-1);
00905 }
00906 }
00907 }
00908
00909
00910
00911
00912 PRIVATE void record_bars(devind)
00913 int devind;
00914 {
00915 int i, j, reg, prefetch, type, clear_01, clear_23, pb_nr;
00916 u32_t bar, bar2;
00917
00918 for (i= 0, reg= PCI_BAR; reg <= PCI_BAR_6; i++, reg += 4)
00919 {
00920 record_bar(devind, i);
00921 }
00922
00923
00924 if (pcidev[devind].pd_baseclass == PCI_BCR_MASS_STORAGE &&
00925 pcidev[devind].pd_subclass == PCI_MS_IDE)
00926 {
00927
00928 clear_01= 0;
00929 clear_23= 0;
00930 if (!(pcidev[devind].pd_infclass & PCI_IDE_PRI_NATIVE))
00931 {
00932 if (debug)
00933 {
00934 printf(
00935 "primary channel is not in native mode, clearing BARs 0 and 1\n");
00936 }
00937 clear_01= 1;
00938 }
00939 if (!(pcidev[devind].pd_infclass & PCI_IDE_SEC_NATIVE))
00940 {
00941 if (debug)
00942 {
00943 printf(
00944 "primary channel is not in native mode, clearing BARs 2 and 3\n");
00945 }
00946 clear_23= 1;
00947 }
00948
00949 j= 0;
00950 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
00951 {
00952 pb_nr= pcidev[devind].pd_bar[i].pb_nr;
00953 if ((pb_nr == 0 || pb_nr == 1) && clear_01)
00954 {
00955 if (debug) printf("skipping bar %d\n", pb_nr);
00956 continue;
00957 }
00958 if ((pb_nr == 2 || pb_nr == 3) && clear_23)
00959 {
00960 if (debug) printf("skipping bar %d\n", pb_nr);
00961 continue;
00962 }
00963 if (i == j)
00964 continue;
00965 pcidev[devind].pd_bar[j]=
00966 pcidev[devind].pd_bar[i];
00967 j++;
00968 }
00969 pcidev[devind].pd_bar_nr= j;
00970 }
00971 }
00972
00973
00974
00975
00976 PRIVATE void record_bars_bridge(devind)
00977 int devind;
00978 {
00979 u32_t base, limit, size;
00980
00981 record_bar(devind, 0);
00982 record_bar(devind, 1);
00983
00984 base= ((pci_attr_r8(devind, PPB_IOBASE) & PPB_IOB_MASK) << 8) |
00985 (pci_attr_r16(devind, PPB_IOBASEU16) << 16);
00986 limit= 0xff |
00987 ((pci_attr_r8(devind, PPB_IOLIMIT) & PPB_IOL_MASK) << 8) |
00988 ((~PPB_IOL_MASK & 0xff) << 8) |
00989 (pci_attr_r16(devind, PPB_IOLIMITU16) << 16);
00990 size= limit-base + 1;
00991 if (debug)
00992 {
00993 printf("\tI/O window: base 0x%x, limit 0x%x, size %d\n",
00994 base, limit, size);
00995 }
00996
00997 base= ((pci_attr_r16(devind, PPB_MEMBASE) & PPB_MEMB_MASK) << 16);
00998 limit= 0xffff |
00999 ((pci_attr_r16(devind, PPB_MEMLIMIT) & PPB_MEML_MASK) << 16) |
01000 ((~PPB_MEML_MASK & 0xffff) << 16);
01001 size= limit-base + 1;
01002 if (debug)
01003 {
01004 printf("\tMemory window: base 0x%x, limit 0x%x, size 0x%x\n",
01005 base, limit, size);
01006 }
01007
01008
01009 base= ((pci_attr_r16(devind, PPB_PFMEMBASE) & PPB_PFMEMB_MASK) << 16);
01010 limit= 0xffff |
01011 ((pci_attr_r16(devind, PPB_PFMEMLIMIT) &
01012 PPB_PFMEML_MASK) << 16) |
01013 ((~PPB_PFMEML_MASK & 0xffff) << 16);
01014 size= limit-base + 1;
01015 if (debug)
01016 {
01017 printf(
01018 "\tPrefetchable memory window: base 0x%x, limit 0x%x, size 0x%x\n",
01019 base, limit, size);
01020 }
01021 }
01022
01023
01024
01025
01026 PRIVATE void record_bars_cardbus(devind)
01027 int devind;
01028 {
01029 u32_t base, limit, size;
01030
01031 record_bar(devind, 0);
01032
01033 base= pci_attr_r32(devind, CBB_MEMBASE_0);
01034 limit= pci_attr_r32(devind, CBB_MEMLIMIT_0) |
01035 (~CBB_MEML_MASK & 0xffffffff);
01036 size= limit-base + 1;
01037 if (debug)
01038 {
01039 printf("\tMemory window 0: base 0x%x, limit 0x%x, size %d\n",
01040 base, limit, size);
01041 }
01042
01043 base= pci_attr_r32(devind, CBB_MEMBASE_1);
01044 limit= pci_attr_r32(devind, CBB_MEMLIMIT_1) |
01045 (~CBB_MEML_MASK & 0xffffffff);
01046 size= limit-base + 1;
01047 if (debug)
01048 {
01049 printf("\tMemory window 1: base 0x%x, limit 0x%x, size %d\n",
01050 base, limit, size);
01051 }
01052
01053 base= pci_attr_r32(devind, CBB_IOBASE_0);
01054 limit= pci_attr_r32(devind, CBB_IOLIMIT_0) |
01055 (~CBB_IOL_MASK & 0xffffffff);
01056 size= limit-base + 1;
01057 if (debug)
01058 {
01059 printf("\tI/O window 0: base 0x%x, limit 0x%x, size %d\n",
01060 base, limit, size);
01061 }
01062
01063 base= pci_attr_r32(devind, CBB_IOBASE_1);
01064 limit= pci_attr_r32(devind, CBB_IOLIMIT_1) |
01065 (~CBB_IOL_MASK & 0xffffffff);
01066 size= limit-base + 1;
01067 if (debug)
01068 {
01069 printf("\tI/O window 1: base 0x%x, limit 0x%x, size %d\n",
01070 base, limit, size);
01071 }
01072 }
01073
01074
01075
01076
01077 PRIVATE void record_bar(devind, bar_nr)
01078 int devind;
01079 int bar_nr;
01080 {
01081 int reg, prefetch, type, dev_bar_nr;
01082 u32_t bar, bar2;
01083
01084 reg= PCI_BAR+4*bar_nr;
01085
01086 bar= pci_attr_r32(devind, reg);
01087 if (bar & PCI_BAR_IO)
01088 {
01089
01090 pci_attr_w32(devind, reg, 0xffffffff);
01091 bar2= pci_attr_r32(devind, reg);
01092 pci_attr_w32(devind, reg, bar);
01093
01094 bar &= ~(u32_t)3;
01095 bar2 &= ~(u32_t)3;
01096 bar2= (~bar2 & 0xffff)+1;
01097 if (debug)
01098 {
01099 printf("\tbar_%d: %d bytes at 0x%x I/O\n",
01100 bar_nr, bar2, bar);
01101 }
01102
01103 dev_bar_nr= pcidev[devind].pd_bar_nr++;
01104 assert(dev_bar_nr < BAR_NR);
01105 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= PBF_IO;
01106 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
01107 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
01108 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
01109 if (bar == 0)
01110 {
01111 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
01112 PBF_INCOMPLETE;
01113 }
01114 }
01115 else
01116 {
01117
01118 pci_attr_w32(devind, reg, 0xffffffff);
01119 bar2= pci_attr_r32(devind, reg);
01120 pci_attr_w32(devind, reg, bar);
01121
01122 if (bar2 == 0)
01123 return;
01124
01125 prefetch= !!(bar & PCI_BAR_PREFETCH);
01126 type= (bar & PCI_BAR_TYPE);
01127 bar &= ~(u32_t)0xf;
01128 bar2 &= ~(u32_t)0xf;
01129 bar2= (~bar2)+1;
01130 if (debug)
01131 {
01132 printf("\tbar_%d: 0x%x bytes at 0x%x%s memory\n",
01133 bar_nr, bar2, bar,
01134 prefetch ? " prefetchable" : "");
01135 if (type != 0)
01136 printf("type = 0x%x\n", type);
01137 }
01138
01139 dev_bar_nr= pcidev[devind].pd_bar_nr++;
01140 assert(dev_bar_nr < BAR_NR);
01141 pcidev[devind].pd_bar[dev_bar_nr].pb_flags= 0;
01142 pcidev[devind].pd_bar[dev_bar_nr].pb_base= bar;
01143 pcidev[devind].pd_bar[dev_bar_nr].pb_size= bar2;
01144 pcidev[devind].pd_bar[dev_bar_nr].pb_nr= bar_nr;
01145 if (bar == 0)
01146 {
01147 pcidev[devind].pd_bar[dev_bar_nr].pb_flags |=
01148 PBF_INCOMPLETE;
01149 }
01150 }
01151 }
01152
01153
01154
01155
01156 PRIVATE void complete_bridges()
01157 {
01158 int i, freebus, devind, prim_busnr;
01159
01160 for (i= 0; i<nr_pcibus; i++)
01161 {
01162 if (!pcibus[i].pb_needinit)
01163 continue;
01164 printf("should allocate bus number for bus %d\n", i);
01165 freebus= get_freebus();
01166 printf("got bus number %d\n", freebus);
01167
01168 devind= pcibus[i].pb_devind;
01169
01170 prim_busnr= pcidev[devind].pd_busnr;
01171 if (prim_busnr != 0)
01172 {
01173 printf(
01174 "complete_bridge: updating subordinate bus number not implemented\n");
01175 }
01176
01177 pcibus[i].pb_needinit= 0;
01178 pcibus[i].pb_busnr= freebus;
01179
01180 printf("devind = %d\n", devind);
01181 printf("prim_busnr= %d\n", prim_busnr);
01182
01183 pci_attr_w8(devind, PPB_PRIMBN, prim_busnr);
01184 pci_attr_w8(devind, PPB_SECBN, freebus);
01185 pci_attr_w8(devind, PPB_SUBORDBN, freebus);
01186
01187 printf("CR = 0x%x\n", pci_attr_r16(devind, PCI_CR));
01188 printf("SECBLT = 0x%x\n", pci_attr_r8(devind, PPB_SECBLT));
01189 printf("BRIDGECTRL = 0x%x\n",
01190 pci_attr_r16(devind, PPB_BRIDGECTRL));
01191 }
01192 }
01193
01194
01195
01196
01197 PRIVATE void complete_bars()
01198 {
01199 int i, j, r, bar_nr, reg;
01200 u32_t memgap_low, memgap_high, iogap_low, iogap_high, io_high,
01201 base, size, v32, diff1, diff2;
01202 char *cp, *next;
01203 char memstr[256];
01204
01205 r= env_get_param("memory", memstr, sizeof(memstr));
01206 if (r != OK)
01207 panic("pci", "env_get_param failed", r);
01208
01209
01210 memgap_low= 0;
01211 cp= memstr;
01212 while (*cp != '\0')
01213 {
01214 base= strtoul(cp, &next, 16);
01215 if (next == cp || *next != ':')
01216 {
01217 printf("pci: bad memory environment string '%s'\n",
01218 memstr);
01219 panic(NULL, NULL, NO_NUM);
01220 }
01221 cp= next+1;
01222 size= strtoul(cp, &next, 16);
01223 if (next == cp || (*next != ',' && *next != '\0'))
01224 {
01225 printf("pci: bad memory environment string '%s'\n",
01226 memstr);
01227 panic(NULL, NULL, NO_NUM);
01228 }
01229 cp= next+1;
01230
01231 if (base+size > memgap_low)
01232 memgap_low= base+size;
01233 }
01234
01235 memgap_high= 0xfe000000;
01236
01237 if (debug)
01238 {
01239 printf("complete_bars: initial gap: [0x%x .. 0x%x>\n",
01240 memgap_low, memgap_high);
01241 }
01242
01243
01244 for (i= 0; i<nr_pcidev; i++)
01245 {
01246 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
01247 {
01248 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
01249 continue;
01250 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
01251 continue;
01252 base= pcidev[i].pd_bar[j].pb_base;
01253 size= pcidev[i].pd_bar[j].pb_size;
01254
01255 if (base >= memgap_high)
01256 continue;
01257 if (base+size <= memgap_low)
01258 continue;
01259
01260
01261 diff1= base+size-memgap_low;
01262 diff2= memgap_high-base;
01263
01264 if (diff1 < diff2)
01265 memgap_low= base+size;
01266 else
01267 memgap_high= base;
01268 }
01269 }
01270
01271 if (debug)
01272 {
01273 printf("complete_bars: intermediate gap: [0x%x .. 0x%x>\n",
01274 memgap_low, memgap_high);
01275 }
01276
01277
01278 if (memgap_high < memgap_low)
01279 {
01280 printf("pci: bad memory gap: [0x%x .. 0x%x>\n",
01281 memgap_low, memgap_high);
01282 panic(NULL, NULL, NO_NUM);
01283 }
01284
01285 iogap_high= 0x10000;
01286 iogap_low= 0x400;
01287
01288
01289 for (i= 0; i<nr_pcidev; i++)
01290 {
01291 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
01292 {
01293 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
01294 continue;
01295 if (pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE)
01296 continue;
01297 base= pcidev[i].pd_bar[j].pb_base;
01298 size= pcidev[i].pd_bar[j].pb_size;
01299 if (base >= iogap_high)
01300 continue;
01301 if (base+size <= iogap_low)
01302 continue;
01303 #if 0
01304 if (debug)
01305 {
01306 printf(
01307 "pci device %d (%04x/%04x), bar %d: base 0x%x, size 0x%x\n",
01308 i, pcidev[i].pd_vid, pcidev[i].pd_did,
01309 j, base, size);
01310 }
01311 #endif
01312 if (base+size-iogap_low < iogap_high-base)
01313 iogap_low= base+size;
01314 else
01315 iogap_high= base;
01316 }
01317 }
01318
01319 if (iogap_high < iogap_low)
01320 {
01321 if (debug)
01322 {
01323 printf("iogap_high too low, should panic\n");
01324 }
01325 else
01326 panic("pci", "iogap_high too low", iogap_high);
01327 }
01328 if (debug)
01329 printf("I/O range = [0x%x..0x%x>\n", iogap_low, iogap_high);
01330
01331 for (i= 0; i<nr_pcidev; i++)
01332 {
01333 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
01334 {
01335 if (pcidev[i].pd_bar[j].pb_flags & PBF_IO)
01336 continue;
01337 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
01338 continue;
01339 size= pcidev[i].pd_bar[j].pb_size;
01340 if (size < PAGE_SIZE)
01341 size= PAGE_SIZE;
01342 base= memgap_high-size;
01343 base &= ~(u32_t)(size-1);
01344 if (base < memgap_low)
01345 panic("pci", "memory base too low", base);
01346 memgap_high= base;
01347 bar_nr= pcidev[i].pd_bar[j].pb_nr;
01348 reg= PCI_BAR + 4*bar_nr;
01349 v32= pci_attr_r32(i, reg);
01350 pci_attr_w32(i, reg, v32 | base);
01351 if (debug)
01352 {
01353 printf(
01354 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
01355 base, size, pcidev[i].pd_busnr,
01356 pcidev[i].pd_dev, pcidev[i].pd_func,
01357 bar_nr);
01358 }
01359 pcidev[i].pd_bar[j].pb_base= base;
01360 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
01361 }
01362
01363 io_high= iogap_high;
01364 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
01365 {
01366 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_IO))
01367 continue;
01368 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
01369 continue;
01370 size= pcidev[i].pd_bar[j].pb_size;
01371 base= iogap_high-size;
01372 base &= ~(u32_t)(size-1);
01373
01374
01375
01376
01377 base &= 0xfcff;
01378
01379 if (base < iogap_low)
01380 panic("pci", "I/O base too low", base);
01381
01382 iogap_high= base;
01383 bar_nr= pcidev[i].pd_bar[j].pb_nr;
01384 reg= PCI_BAR + 4*bar_nr;
01385 v32= pci_attr_r32(i, reg);
01386 pci_attr_w32(i, reg, v32 | base);
01387 if (debug)
01388 {
01389 printf(
01390 "complete_bars: allocated 0x%x size %d to %d.%d.%d, bar_%d\n",
01391 base, size, pcidev[i].pd_busnr,
01392 pcidev[i].pd_dev, pcidev[i].pd_func,
01393 bar_nr);
01394 }
01395 pcidev[i].pd_bar[j].pb_base= base;
01396 pcidev[i].pd_bar[j].pb_flags &= ~PBF_INCOMPLETE;
01397
01398 }
01399 if (iogap_high != io_high)
01400 {
01401 update_bridge4dev_io(i, iogap_high,
01402 io_high-iogap_high);
01403 }
01404 }
01405
01406 for (i= 0; i<nr_pcidev; i++)
01407 {
01408 for (j= 0; j<pcidev[i].pd_bar_nr; j++)
01409 {
01410 if (!(pcidev[i].pd_bar[j].pb_flags & PBF_INCOMPLETE))
01411 continue;
01412 printf("should allocate resources for device %d\n", i);
01413 }
01414 }
01415 }
01416
01417
01418
01419
01420 PRIVATE void update_bridge4dev_io(devind, io_base, io_size)
01421 int devind;
01422 u32_t io_base;
01423 u32_t io_size;
01424 {
01425 int busnr, busind, type, br_devind;
01426 u16_t v16;
01427
01428 busnr= pcidev[devind].pd_busnr;
01429 busind= get_busind(busnr);
01430 type= pcibus[busind].pb_type;
01431 if (type == PBT_INTEL_HOST)
01432 return;
01433 if (type == PBT_PCIBRIDGE)
01434 {
01435 printf(
01436 "update_bridge4dev_io: not implemented for PCI bridges\n");
01437 return;
01438 }
01439 if (type != PBT_CARDBUS)
01440 panic("pci", "update_bridge4dev_io: strange bus type", type);
01441
01442 if (debug)
01443 {
01444 printf("update_bridge4dev_io: adding 0x%x at 0x%x\n",
01445 io_size, io_base);
01446 }
01447 br_devind= pcibus[busind].pb_devind;
01448 pci_attr_w32(br_devind, CBB_IOLIMIT_0, io_base+io_size-1);
01449 pci_attr_w32(br_devind, CBB_IOBASE_0, io_base);
01450
01451
01452 v16= pci_attr_r16(devind, PCI_CR);
01453 pci_attr_w16(devind, PCI_CR, v16 | PCI_CR_IO_EN | PCI_CR_MAST_EN);
01454 }
01455
01456
01457
01458
01459 PRIVATE int get_freebus()
01460 {
01461 int i, freebus;
01462
01463 freebus= 1;
01464 for (i= 0; i<nr_pcibus; i++)
01465 {
01466 if (pcibus[i].pb_needinit)
01467 continue;
01468 if (pcibus[i].pb_type == PBT_INTEL_HOST)
01469 continue;
01470 if (pcibus[i].pb_busnr <= freebus)
01471 freebus= pcibus[i].pb_busnr+1;
01472 printf("get_freebus: should check suboridinate bus number\n");
01473 }
01474 return freebus;
01475 }
01476
01477
01478
01479
01480 PRIVATE int do_isabridge(busind)
01481 int busind;
01482 {
01483 int i, j, r, type, busnr, unknown_bridge, bridge_dev;
01484 u16_t vid, did;
01485 u32_t t3;
01486 char *dstr;
01487
01488 unknown_bridge= -1;
01489 bridge_dev= -1;
01490 j= 0;
01491 vid= did= 0;
01492 busnr= pcibus[busind].pb_busnr;
01493 for (i= 0; i< nr_pcidev; i++)
01494 {
01495 if (pcidev[i].pd_busnr != busnr)
01496 continue;
01497 t3= ((pcidev[i].pd_baseclass << 16) |
01498 (pcidev[i].pd_subclass << 8) | pcidev[i].pd_infclass);
01499 if (t3 == PCI_T3_ISA)
01500 {
01501
01502
01503
01504 unknown_bridge= i;
01505 }
01506
01507 vid= pcidev[i].pd_vid;
01508 did= pcidev[i].pd_did;
01509 for (j= 0; pci_isabridge[j].vid != 0; j++)
01510 {
01511 if (pci_isabridge[j].vid != vid)
01512 continue;
01513 if (pci_isabridge[j].did != did)
01514 continue;
01515 if (pci_isabridge[j].checkclass &&
01516 unknown_bridge != i)
01517 {
01518
01519
01520
01521 continue;
01522 }
01523 break;
01524 }
01525 if (pci_isabridge[j].vid)
01526 {
01527 bridge_dev= i;
01528 break;
01529 }
01530 }
01531
01532 if (bridge_dev != -1)
01533 {
01534 dstr= pci_dev_name(vid, did);
01535 if (!dstr)
01536 dstr= "unknown device";
01537 if (debug)
01538 {
01539 printf("found ISA bridge (%04X/%04X) %s\n",
01540 vid, did, dstr);
01541 }
01542 pcibus[busind].pb_isabridge_dev= bridge_dev;
01543 type= pci_isabridge[j].type;
01544 pcibus[busind].pb_isabridge_type= type;
01545 switch(type)
01546 {
01547 case PCI_IB_PIIX:
01548 r= do_piix(bridge_dev);
01549 break;
01550 case PCI_IB_VIA:
01551 r= do_via_isabr(bridge_dev);
01552 break;
01553 case PCI_IB_AMD:
01554 r= do_amd_isabr(bridge_dev);
01555 break;
01556 case PCI_IB_SIS:
01557 r= do_sis_isabr(bridge_dev);
01558 break;
01559 default:
01560 panic("PCI","unknown ISA bridge type", type);
01561 }
01562 return r;
01563 }
01564
01565 if (unknown_bridge == -1)
01566 {
01567 if (debug)
01568 {
01569 printf("(warning) no ISA bridge found on bus %d\n",
01570 busind);
01571 }
01572 return 0;
01573 }
01574 if (debug)
01575 {
01576 printf(
01577 "(warning) unsupported ISA bridge %04X/%04X for bus %d\n",
01578 pcidev[unknown_bridge].pd_vid,
01579 pcidev[unknown_bridge].pd_did, busind);
01580 }
01581 return 0;
01582 }
01583
01584
01585
01586
01587 PRIVATE void do_pcibridge(busind)
01588 int busind;
01589 {
01590 int i, devind, busnr;
01591 int ind, type;
01592 u16_t vid, did;
01593 u8_t sbusn, baseclass, subclass, infclass, headt;
01594 u32_t t3;
01595
01596 vid= did= 0;
01597 busnr= pcibus[busind].pb_busnr;
01598 for (devind= 0; devind< nr_pcidev; devind++)
01599 {
01600 #if 0
01601 printf("do_pcibridge: trying %u.%u.%u\n",
01602 pcidev[devind].pd_busind, pcidev[devind].pd_dev,
01603 pcidev[devind].pd_func);
01604 #endif
01605
01606 if (pcidev[devind].pd_busnr != busnr)
01607 {
01608 #if 0
01609 printf("wrong bus\n");
01610 #endif
01611 continue;
01612 }
01613
01614 vid= pcidev[devind].pd_vid;
01615 did= pcidev[devind].pd_did;
01616 for (i= 0; pci_pcibridge[i].vid != 0; i++)
01617 {
01618 if (pci_pcibridge[i].vid != vid)
01619 continue;
01620 if (pci_pcibridge[i].did != did)
01621 continue;
01622 break;
01623 }
01624 type= pci_pcibridge[i].type;
01625 if (pci_pcibridge[i].vid == 0)
01626 {
01627 headt= pci_attr_r8(devind, PCI_HEADT);
01628 type= 0;
01629 if ((headt & PHT_MASK) == PHT_BRIDGE)
01630 type= PCI_PPB_STD;
01631 else if ((headt & PHT_MASK) == PHT_CARDBUS)
01632 type= PCI_PPB_CB;
01633 else
01634 {
01635 #if 0
01636 printf("not a bridge\n");
01637 #endif
01638 continue;
01639 }
01640
01641 baseclass= pci_attr_r8(devind, PCI_BCR);
01642 subclass= pci_attr_r8(devind, PCI_SCR);
01643 infclass= pci_attr_r8(devind, PCI_PIFR);
01644 t3= ((baseclass << 16) | (subclass << 8) | infclass);
01645 if (type == PCI_PPB_STD &&
01646 t3 != PCI_T3_PCI2PCI &&
01647 t3 != PCI_T3_PCI2PCI_SUBTR)
01648 {
01649 printf(
01650 "Unknown PCI class %02x:%02x:%02x for PCI-to-PCI bridge, device %04X/%04X\n",
01651 baseclass, subclass, infclass,
01652 vid, did);
01653 continue;
01654 }
01655 if (type == PCI_PPB_CB &&
01656 t3 != PCI_T3_CARDBUS)
01657 {
01658 printf(
01659 "Unknown PCI class %02x:%02x:%02x for Cardbus bridge, device %04X/%04X\n",
01660 baseclass, subclass, infclass,
01661 vid, did);
01662 continue;
01663 }
01664 }
01665
01666 if (debug)
01667 {
01668 printf("%u.%u.%u: PCI-to-PCI bridge: %04X/%04X\n",
01669 pcidev[devind].pd_busnr,
01670 pcidev[devind].pd_dev,
01671 pcidev[devind].pd_func, vid, did);
01672 }
01673
01674
01675
01676
01677 sbusn= pci_attr_r8(devind, PPB_SECBN);
01678 #if DEBUG
01679 printf("sbusn = %d\n", sbusn);
01680 printf("subordn = %d\n", pci_attr_r8(devind, PPB_SUBORDBN));
01681 #endif
01682
01683 if (nr_pcibus >= NR_PCIBUS)
01684 panic("PCI","too many PCI busses", nr_pcibus);
01685 ind= nr_pcibus;
01686 nr_pcibus++;
01687 pcibus[ind].pb_type= PBT_PCIBRIDGE;
01688 pcibus[ind].pb_needinit= 1;
01689 pcibus[ind].pb_isabridge_dev= -1;
01690 pcibus[ind].pb_isabridge_type= 0;
01691 pcibus[ind].pb_devind= devind;
01692 pcibus[ind].pb_busnr= sbusn;
01693 pcibus[ind].pb_rreg8= pcibus[busind].pb_rreg8;
01694 pcibus[ind].pb_rreg16= pcibus[busind].pb_rreg16;
01695 pcibus[ind].pb_rreg32= pcibus[busind].pb_rreg32;
01696 pcibus[ind].pb_wreg8= pcibus[busind].pb_wreg8;
01697 pcibus[ind].pb_wreg16= pcibus[busind].pb_wreg16;
01698 pcibus[ind].pb_wreg32= pcibus[busind].pb_wreg32;
01699 switch(type)
01700 {
01701 case PCI_PPB_STD:
01702 pcibus[ind].pb_rsts= pcibr_std_rsts;
01703 pcibus[ind].pb_wsts= pcibr_std_wsts;
01704 break;
01705 case PCI_PPB_CB:
01706 pcibus[ind].pb_type= PBT_CARDBUS;
01707 pcibus[ind].pb_rsts= pcibr_cb_rsts;
01708 pcibus[ind].pb_wsts= pcibr_cb_wsts;
01709 break;
01710 case PCI_AGPB_VIA:
01711 pcibus[ind].pb_rsts= pcibr_via_rsts;
01712 pcibus[ind].pb_wsts= pcibr_via_wsts;
01713 break;
01714 default:
01715 panic("PCI","unknown PCI-PCI bridge type", type);
01716 }
01717 if (sbusn == 0)
01718 {
01719 printf("Secondary bus number not initialized\n");
01720 continue;
01721 }
01722 pcibus[ind].pb_needinit= 0;
01723
01724 probe_bus(ind);
01725
01726
01727 do_pcibridge(ind);
01728 }
01729 }
01730
01731
01732
01733
01734 PRIVATE int get_busind(busnr)
01735 int busnr;
01736 {
01737 int i;
01738
01739 for (i= 0; i<nr_pcibus; i++)
01740 {
01741 if (pcibus[i].pb_busnr == busnr)
01742 return i;
01743 }
01744 panic("pci", "get_busind: can't find bus", busnr);
01745 }
01746
01747
01748
01749
01750 PRIVATE int do_piix(devind)
01751 int devind;
01752 {
01753 int i, s, dev, func, irqrc, irq;
01754 u32_t elcr1, elcr2, elcr;
01755
01756 #if DEBUG
01757 printf("in piix\n");
01758 #endif
01759 dev= pcidev[devind].pd_dev;
01760 func= pcidev[devind].pd_func;
01761 #if USER_SPACE
01762 if (OK != (s=sys_inb(PIIX_ELCR1, &elcr1)))
01763 printf("Warning, sys_inb failed: %d\n", s);
01764 if (OK != (s=sys_inb(PIIX_ELCR2, &elcr2)))
01765 printf("Warning, sys_inb failed: %d\n", s);
01766 #else
01767 elcr1= inb(PIIX_ELCR1);
01768 elcr2= inb(PIIX_ELCR2);
01769 #endif
01770 elcr= elcr1 | (elcr2 << 8);
01771 for (i= 0; i<4; i++)
01772 {
01773 irqrc= pci_attr_r8(devind, PIIX_PIRQRCA+i);
01774 if (irqrc & PIIX_IRQ_DI)
01775 {
01776 if (debug)
01777 printf("INT%c: disabled\n", 'A'+i);
01778 }
01779 else
01780 {
01781 irq= irqrc & PIIX_IRQ_MASK;
01782 if (debug)
01783 printf("INT%c: %d\n", 'A'+i, irq);
01784 if (!(elcr & (1 << irq)))
01785 {
01786 if (debug)
01787 {
01788 printf(
01789 "(warning) IRQ %d is not level triggered\n",
01790 irq);
01791 }
01792 }
01793 irq_mode_pci(irq);
01794 }
01795 }
01796 return 0;
01797 }
01798
01799
01800
01801
01802 PRIVATE int do_amd_isabr(devind)
01803 int devind;
01804 {
01805 int i, busnr, dev, func, xdevind, irq, edge;
01806 u8_t levmask;
01807 u16_t pciirq;
01808
01809
01810 func= AMD_ISABR_FUNC;
01811 busnr= pcidev[devind].pd_busnr;
01812 dev= pcidev[devind].pd_dev;
01813
01814
01815 if (nr_pcidev >= NR_PCIDEV)
01816 panic("PCI","too many PCI devices", nr_pcidev);
01817 xdevind= nr_pcidev;
01818 pcidev[xdevind].pd_busnr= busnr;
01819 pcidev[xdevind].pd_dev= dev;
01820 pcidev[xdevind].pd_func= func;
01821 pcidev[xdevind].pd_inuse= 1;
01822 nr_pcidev++;
01823
01824 levmask= pci_attr_r8(xdevind, AMD_ISABR_PCIIRQ_LEV);
01825 pciirq= pci_attr_r16(xdevind, AMD_ISABR_PCIIRQ_ROUTE);
01826 for (i= 0; i<4; i++)
01827 {
01828 edge= (levmask >> i) & 1;
01829 irq= (pciirq >> (4*i)) & 0xf;
01830 if (!irq)
01831 {
01832 if (debug)
01833 printf("INT%c: disabled\n", 'A'+i);
01834 }
01835 else
01836 {
01837 if (debug)
01838 printf("INT%c: %d\n", 'A'+i, irq);
01839 if (edge && debug)
01840 {
01841 printf(
01842 "(warning) IRQ %d is not level triggered\n",
01843 irq);
01844 }
01845 irq_mode_pci(irq);
01846 }
01847 }
01848 nr_pcidev--;
01849 return 0;
01850 }
01851
01852
01853
01854
01855 PRIVATE int do_sis_isabr(devind)
01856 int devind;
01857 {
01858 int i, dev, func, irq;
01859
01860 dev= pcidev[devind].pd_dev;
01861 func= pcidev[devind].pd_func;
01862 irq= 0;
01863 for (i= 0; i<4; i++)
01864 {
01865 irq= pci_attr_r8(devind, SIS_ISABR_IRQ_A+i);
01866 if (irq & SIS_IRQ_DISABLED)
01867 {
01868 if (debug)
01869 printf("INT%c: disabled\n", 'A'+i);
01870 }
01871 else
01872 {
01873 irq &= SIS_IRQ_MASK;
01874 if (debug)
01875 printf("INT%c: %d\n", 'A'+i, irq);
01876 irq_mode_pci(irq);
01877 }
01878 }
01879 return 0;
01880 }
01881
01882
01883
01884
01885 PRIVATE int do_via_isabr(devind)
01886 int devind;
01887 {
01888 int i, dev, func, irq, edge;
01889 u8_t levmask;
01890
01891 dev= pcidev[devind].pd_dev;
01892 func= pcidev[devind].pd_func;
01893 levmask= pci_attr_r8(devind, VIA_ISABR_EL);
01894 irq= 0;
01895 edge= 0;
01896 for (i= 0; i<4; i++)
01897 {
01898 switch(i)
01899 {
01900 case 0:
01901 edge= (levmask & VIA_ISABR_EL_INTA);
01902 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2) >> 4;
01903 break;
01904 case 1:
01905 edge= (levmask & VIA_ISABR_EL_INTB);
01906 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R2);
01907 break;
01908 case 2:
01909 edge= (levmask & VIA_ISABR_EL_INTC);
01910 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R3) >> 4;
01911 break;
01912 case 3:
01913 edge= (levmask & VIA_ISABR_EL_INTD);
01914 irq= pci_attr_r8(devind, VIA_ISABR_IRQ_R1) >> 4;
01915 break;
01916 default:
01917 assert(0);
01918 }
01919 irq &= 0xf;
01920 if (!irq)
01921 {
01922 if (debug)
01923 printf("INT%c: disabled\n", 'A'+i);
01924 }
01925 else
01926 {
01927 if (debug)
01928 printf("INT%c: %d\n", 'A'+i, irq);
01929 if (edge && debug)
01930 {
01931 printf(
01932 "(warning) IRQ %d is not level triggered\n",
01933 irq);
01934 }
01935 irq_mode_pci(irq);
01936 }
01937 }
01938 return 0;
01939 }
01940
01941
01942
01943
01944
01945 PRIVATE void report_vga(devind)
01946 int devind;
01947 {
01948
01949
01950
01951
01952 size_t amount, size;
01953 int i;
01954
01955 amount= 0;
01956 for (i= 0; i<pcidev[devind].pd_bar_nr; i++)
01957 {
01958 if (pcidev[devind].pd_bar[i].pb_flags & PBF_IO)
01959 continue;
01960 size= pcidev[devind].pd_bar[i].pb_size;
01961 if (size < amount)
01962 continue;
01963 amount= size;
01964 }
01965 if (size != 0)
01966 {
01967 printf("PCI: video memory for device at %d.%d.%d: %d bytes\n",
01968 pcidev[devind].pd_busnr,
01969 pcidev[devind].pd_dev,
01970 pcidev[devind].pd_func,
01971 amount);
01972 }
01973 }
01974
01975
01976
01977
01978
01979 PRIVATE char *pci_vid_name(vid)
01980 u16_t vid;
01981 {
01982 int i;
01983
01984 for (i= 0; pci_vendor_table[i].name; i++)
01985 {
01986 if (pci_vendor_table[i].vid == vid)
01987 return pci_vendor_table[i].name;
01988 }
01989 return "unknown";
01990 }
01991
01992
01993
01994
01995 PRIVATE char *pci_baseclass_name(baseclass)
01996 u8_t baseclass;
01997 {
01998 int i;
01999
02000 for (i= 0; pci_baseclass_table[i].name; i++)
02001 {
02002 if (pci_baseclass_table[i].baseclass == baseclass)
02003 return pci_baseclass_table[i].name;
02004 }
02005 return NULL;
02006 }
02007
02008
02009
02010
02011 PRIVATE char *pci_subclass_name(baseclass, subclass, infclass)
02012 u8_t baseclass;
02013 u8_t subclass;
02014 u8_t infclass;
02015 {
02016 int i;
02017
02018 for (i= 0; pci_subclass_table[i].name; i++)
02019 {
02020 if (pci_subclass_table[i].baseclass != baseclass)
02021 continue;
02022 if (pci_subclass_table[i].subclass != subclass)
02023 continue;
02024 if (pci_subclass_table[i].infclass != infclass &&
02025 pci_subclass_table[i].infclass != (u16_t)-1)
02026 {
02027 continue;
02028 }
02029 return pci_subclass_table[i].name;
02030 }
02031 return NULL;
02032 }
02033
02034
02035
02036
02037 PRIVATE void ntostr(n, str, end)
02038 unsigned n;
02039 char **str;
02040 char *end;
02041 {
02042 char tmpstr[20];
02043 int i;
02044
02045 if (n == 0)
02046 {
02047 tmpstr[0]= '0';
02048 i= 1;
02049 }
02050 else
02051 {
02052 for (i= 0; n; i++)
02053 {
02054 tmpstr[i]= '0' + (n%10);
02055 n /= 10;
02056 }
02057 }
02058 for (; i>0; i--)
02059 {
02060 if (*str == end)
02061 {
02062 break;
02063 }
02064 **str= tmpstr[i-1];
02065 (*str)++;
02066 }
02067 if (*str == end)
02068 end[-1]= '\0';
02069 else
02070 **str= '\0';
02071 }
02072
02073
02074
02075
02076 PRIVATE u16_t pci_attr_rsts(devind)
02077 int devind;
02078 {
02079 int busnr, busind;
02080
02081 busnr= pcidev[devind].pd_busnr;
02082 busind= get_busind(busnr);
02083 return pcibus[busind].pb_rsts(busind);
02084 }
02085
02086
02087
02088
02089
02090 PRIVATE u16_t pcibr_std_rsts(busind)
02091 int busind;
02092 {
02093 int devind;
02094
02095 devind= pcibus[busind].pb_devind;
02096 return pci_attr_r16(devind, PPB_SSTS);
02097 }
02098
02099
02100
02101
02102 PRIVATE void pcibr_std_wsts(busind, value)
02103 int busind;
02104 u16_t value;
02105 {
02106 int devind;
02107 devind= pcibus[busind].pb_devind;
02108
02109 #if 0
02110 printf("pcibr_std_wsts(%d, 0x%X), devind= %d\n",
02111 busind, value, devind);
02112 #endif
02113 pci_attr_w16(devind, PPB_SSTS, value);
02114 }
02115
02116
02117
02118
02119 PRIVATE u16_t pcibr_cb_rsts(busind)
02120 int busind;
02121 {
02122 int devind;
02123 devind= pcibus[busind].pb_devind;
02124
02125 return pci_attr_r16(devind, CBB_SSTS);
02126 }
02127
02128
02129
02130
02131 PRIVATE void pcibr_cb_wsts(busind, value)
02132 int busind;
02133 u16_t value;
02134 {
02135 int devind;
02136 devind= pcibus[busind].pb_devind;
02137
02138 #if 0
02139 printf("pcibr_cb_wsts(%d, 0x%X), devind= %d\n",
02140 busind, value, devind);
02141 #endif
02142 pci_attr_w16(devind, CBB_SSTS, value);
02143 }
02144
02145
02146
02147
02148 PRIVATE u16_t pcibr_via_rsts(busind)
02149 int busind;
02150 {
02151 int devind;
02152 devind= pcibus[busind].pb_devind;
02153
02154 return 0;
02155 }
02156
02157
02158
02159
02160 PRIVATE void pcibr_via_wsts(busind, value)
02161 int busind;
02162 u16_t value;
02163 {
02164 int devind;
02165 devind= pcibus[busind].pb_devind;
02166
02167 #if 0
02168 printf("pcibr_via_wsts(%d, 0x%X), devind= %d (not implemented)\n",
02169 busind, value, devind);
02170 #endif
02171 }
02172
02173
02174
02175
02176 PRIVATE void pci_attr_wsts(devind, value)
02177 int devind;
02178 u16_t value;
02179 {
02180 int busnr, busind;
02181
02182 busnr= pcidev[devind].pd_busnr;
02183 busind= get_busind(busnr);
02184 pcibus[busind].pb_wsts(busind, value);
02185 }
02186
02187
02188
02189
02190
02191 PRIVATE u8_t pcii_rreg8(busind, devind, port)
02192 int busind;
02193 int devind;
02194 int port;
02195 {
02196 u8_t v;
02197 int s;
02198
02199 v= PCII_RREG8_(pcibus[busind].pb_busnr,
02200 pcidev[devind].pd_dev, pcidev[devind].pd_func,
02201 port);
02202 #if USER_SPACE
02203 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02204 printf("PCI: warning, sys_outl failed: %d\n", s);
02205 #else
02206 outl(PCII_CONFADD, PCII_UNSEL);
02207 #endif
02208 #if 0
02209 printf("pcii_rreg8(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
02210 busind, devind, port,
02211 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
02212 pcidev[devind].pd_func, v);
02213 #endif
02214 return v;
02215 }
02216
02217
02218
02219
02220 PRIVATE u16_t pcii_rreg16(busind, devind, port)
02221 int busind;
02222 int devind;
02223 int port;
02224 {
02225 u16_t v;
02226 int s;
02227
02228 v= PCII_RREG16_(pcibus[busind].pb_busnr,
02229 pcidev[devind].pd_dev, pcidev[devind].pd_func,
02230 port);
02231 #if USER_SPACE
02232 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02233 printf("PCI: warning, sys_outl failed: %d\n");
02234 #else
02235 outl(PCII_CONFADD, PCII_UNSEL);
02236 #endif
02237 #if 0
02238 printf("pcii_rreg16(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
02239 busind, devind, port,
02240 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
02241 pcidev[devind].pd_func, v);
02242 #endif
02243 return v;
02244 }
02245
02246
02247
02248
02249 PRIVATE u32_t pcii_rreg32(busind, devind, port)
02250 int busind;
02251 int devind;
02252 int port;
02253 {
02254 u32_t v;
02255 int s;
02256
02257 v= PCII_RREG32_(pcibus[busind].pb_busnr,
02258 pcidev[devind].pd_dev, pcidev[devind].pd_func,
02259 port);
02260 #if USER_SPACE
02261 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02262 printf("PCI: warning, sys_outl failed: %d\n", s);
02263 #else
02264 outl(PCII_CONFADD, PCII_UNSEL);
02265 #endif
02266 #if 0
02267 printf("pcii_rreg32(%d, %d, 0x%X): %d.%d.%d= 0x%X\n",
02268 busind, devind, port,
02269 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
02270 pcidev[devind].pd_func, v);
02271 #endif
02272 return v;
02273 }
02274
02275
02276
02277
02278 PRIVATE void pcii_wreg8(busind, devind, port, value)
02279 int busind;
02280 int devind;
02281 int port;
02282 u8_t value;
02283 {
02284 int s;
02285 #if 0
02286 printf("pcii_wreg8(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
02287 busind, devind, port, value,
02288 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
02289 pcidev[devind].pd_func);
02290 #endif
02291 PCII_WREG8_(pcibus[busind].pb_busnr,
02292 pcidev[devind].pd_dev, pcidev[devind].pd_func,
02293 port, value);
02294 #if USER_SPACE
02295 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02296 printf("PCI: warning, sys_outl failed: %d\n", s);
02297 #else
02298 outl(PCII_CONFADD, PCII_UNSEL);
02299 #endif
02300 }
02301
02302
02303
02304
02305 PRIVATE void pcii_wreg16(busind, devind, port, value)
02306 int busind;
02307 int devind;
02308 int port;
02309 u16_t value;
02310 {
02311 int s;
02312 #if 0
02313 printf("pcii_wreg16(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
02314 busind, devind, port, value,
02315 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
02316 pcidev[devind].pd_func);
02317 #endif
02318 PCII_WREG16_(pcibus[busind].pb_busnr,
02319 pcidev[devind].pd_dev, pcidev[devind].pd_func,
02320 port, value);
02321 #if USER_SPACE
02322 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02323 printf("PCI: warning, sys_outl failed: %d\n", s);
02324 #else
02325 outl(PCII_CONFADD, PCII_UNSEL);
02326 #endif
02327 }
02328
02329
02330
02331
02332 PRIVATE void pcii_wreg32(busind, devind, port, value)
02333 int busind;
02334 int devind;
02335 int port;
02336 u32_t value;
02337 {
02338 int s;
02339 #if 0
02340 printf("pcii_wreg32(%d, %d, 0x%X, 0x%X): %d.%d.%d\n",
02341 busind, devind, port, value,
02342 pcibus[busind].pb_bus, pcidev[devind].pd_dev,
02343 pcidev[devind].pd_func);
02344 #endif
02345 PCII_WREG32_(pcibus[busind].pb_busnr,
02346 pcidev[devind].pd_dev, pcidev[devind].pd_func,
02347 port, value);
02348 #if USER_SPACE
02349 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02350 printf("PCI: warning, sys_outl failed: %d\n");
02351 #else
02352 outl(PCII_CONFADD, PCII_UNSEL);
02353 #endif
02354 }
02355
02356
02357
02358
02359 PRIVATE u16_t pcii_rsts(busind)
02360 int busind;
02361 {
02362 u16_t v;
02363 int s;
02364
02365 v= PCII_RREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR);
02366 #if USER_SPACE
02367 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02368 printf("PCI: warning, sys_outl failed: %d\n", s);
02369 #else
02370 outl(PCII_CONFADD, PCII_UNSEL);
02371 #endif
02372 return v;
02373 }
02374
02375
02376
02377
02378 PRIVATE void pcii_wsts(busind, value)
02379 int busind;
02380 u16_t value;
02381 {
02382 int s;
02383 PCII_WREG16_(pcibus[busind].pb_busnr, 0, 0, PCI_SR, value);
02384 #if USER_SPACE
02385 if (OK != (s=sys_outl(PCII_CONFADD, PCII_UNSEL)))
02386 printf("PCI: warning, sys_outl failed: %d\n", s);
02387 #else
02388 outl(PCII_CONFADD, PCII_UNSEL);
02389 #endif
02390 }
02391
02392
02393
02394
02395
02396 PRIVATE void print_capabilities(devind)
02397 int devind;
02398 {
02399 u8_t status, capptr, type, next;
02400 char *str;
02401
02402
02403 status= pci_attr_r16(devind, PCI_SR);
02404 if (!(status & PSR_CAPPTR))
02405 return;
02406
02407 capptr= (pci_attr_r8(devind, PCI_CAPPTR) & PCI_CP_MASK);
02408 while (capptr != 0)
02409 {
02410 type = pci_attr_r8(devind, capptr+CAP_TYPE);
02411 next= (pci_attr_r8(devind, capptr+CAP_NEXT) & PCI_CP_MASK);
02412 switch(type)
02413 {
02414 case 1: str= "PCI Power Management"; break;
02415 case 2: str= "AGP"; break;
02416 case 3: str= "Vital Product Data"; break;
02417 case 4: str= "Slot Identification"; break;
02418 case 5: str= "Message Signaled Interrupts"; break;
02419 case 6: str= "CompactPCI Hot Swap"; break;
02420 case 8: str= "AMD HyperTransport"; break;
02421 case 0xf: str= "AMD I/O MMU"; break;
02422 defuault: str= "(unknown type)"; break;
02423 }
02424
02425 printf(" @0x%x: capability type 0x%x: %s\n",
02426 capptr, type, str);
02427 capptr= next;
02428 }
02429 }
02430
02431
02432
02433