setos

拙OS
Log | Files | Refs | LICENSE

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 }