pci.c (1534B)
1 #include <libc.h> 2 #include <pci.h> 3 4 PCIDev pci_dev[MaxPCIDev]; 5 int num_pci_dev; 6 7 uint16 8 pci_config_read_vendor_id(uint8 bus, uint8 dev, uint8 func) 9 { 10 return pci_config_read16(bus, dev, func, 0x0); 11 } 12 13 int 14 pci_scan_all_bus(void) 15 { 16 int func; 17 num_pci_dev = 0; 18 for (func = 0; func < 8; func++) { 19 if (pci_config_read_vendor_id(0, 0, func) == 0xffff) { 20 continue; 21 } 22 if (pci_scan_bus(func) < 0) { 23 return -1; 24 } 25 } 26 return 0; 27 } 28 29 int 30 pci_scan_bus(uint8 bus) 31 { 32 int dev; 33 for (dev = 0; dev < 32; dev++) { 34 if (pci_config_read_vendor_id(bus, dev, 0) == 0xffff) { 35 continue; 36 } 37 if (pci_scan_dev(bus, dev) < 0) { 38 return -1; 39 } 40 } 41 return 0; 42 } 43 44 int 45 pci_scan_dev(uint8 bus, uint8 dev) 46 { 47 int func; 48 if (pci_config_read_vendor_id(bus, dev, 0) == 0xffff) { 49 return pci_scan_func(bus, dev, 0); 50 } 51 for (func = 1; func < 8; func++) { 52 if (pci_config_read_vendor_id(bus, dev, func) == 0xffff) { 53 continue; 54 } 55 if (pci_scan_func(bus, dev, func) < 0) { 56 return -1; 57 } 58 } 59 return 0; 60 } 61 62 int 63 pci_scan_func(uint8 bus, uint8 dev, uint8 func) 64 { 65 uint8 sub_bus; 66 int i; 67 if (num_pci_dev >= MaxPCIDev) { 68 return -1; 69 } 70 // populate the PCIDev struct. 71 for (i = 0; i < (sizeof(PCIDev) + 3) / 4; i++) { 72 ((uint32 *)&pci_dev[num_pci_dev])[i] = 73 pci_config_read32(bus, dev, func, i * 4); 74 } 75 num_pci_dev++; 76 77 // pci-pci bridge 78 if (pci_dev[num_pci_dev-1].base_class == 0x06 && 79 pci_dev[num_pci_dev-1].sub_class == 0x04) { 80 sub_bus = pci_config_read16(bus, dev, func, 0x18) >> 8; 81 return pci_scan_bus(sub_bus); 82 } 83 84 return 0; 85 }