1 /* 2 * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2003, Marcus Overhagen. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include <device_manager.h> 10 #include <PCI.h> 11 #include <drivers/bus/FDT.h> 12 13 #include <string.h> 14 15 #include "pci_private.h" 16 #include "pci.h" 17 18 19 // name of PCI root module 20 #define PCI_ROOT_MODULE_NAME "bus_managers/pci/root/driver_v1" 21 22 23 device_node* gPCIRootNode = NULL; 24 25 26 static float 27 pci_root_supports_device(device_node* parent) 28 { 29 const char* bus; 30 if (gDeviceManager->get_attr_string(parent, B_DEVICE_BUS, &bus, false) < B_OK) 31 return -1.0f; 32 33 #ifdef __riscv 34 const char* compatible; 35 if (gDeviceManager->get_attr_string(parent, "fdt/compatible", &compatible, 36 false) < B_OK) 37 return -1.0f; 38 39 if (strcmp(bus, "fdt") != 0) 40 return 0.0f; 41 42 if (strcmp(compatible, "pci-host-ecam-generic") != 0 43 && strcmp(compatible, "sifive,fu740-pcie") != 0) { 44 return 0.0f; 45 } 46 #else 47 if (strcmp(bus, "root") != 0) 48 return 0.0f; 49 #endif 50 51 return 1.0; 52 } 53 54 55 static status_t 56 pci_root_register_device(device_node* parent) 57 { 58 dprintf("pci_root_register_device()\n"); 59 // XXX how do we handle this for PPC? 60 // I/O port for PCI config space address 61 #define PCI_CONFIG_ADDRESS 0xcf8 62 63 io_resource resources[2] = { 64 {B_IO_PORT, PCI_CONFIG_ADDRESS, 8}, 65 {} 66 }; 67 device_attr attrs[] = { 68 {B_DEVICE_PRETTY_NAME, B_STRING_TYPE, {string: "PCI"}}, 69 {B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_KEEP_DRIVER_LOADED}}, 70 {} 71 }; 72 73 return gDeviceManager->register_node(parent, PCI_ROOT_MODULE_NAME, attrs, 74 resources, NULL); 75 } 76 77 78 static status_t 79 pci_root_register_child_devices(void* cookie) 80 { 81 dprintf("pci_root_register_child_devices()\n"); 82 device_node* node = (device_node*)cookie; 83 84 pci_info info; 85 for (int32 i = 0; pci_get_nth_pci_info(i, &info) == B_OK; i++) { 86 uint8 domain; 87 uint8 bus; 88 if (gPCI->ResolveVirtualBus(info.bus, &domain, &bus) != B_OK) { 89 dprintf("ResolveVirtualBus(%u) failed\n", info.bus); 90 continue; 91 } 92 93 device_attr attrs[] = { 94 // info about device 95 {B_DEVICE_BUS, B_STRING_TYPE, {string: "pci"}}, 96 97 // location on PCI bus 98 {B_PCI_DEVICE_DOMAIN, B_UINT8_TYPE, {ui8: domain}}, 99 {B_PCI_DEVICE_BUS, B_UINT8_TYPE, {ui8: bus}}, 100 {B_PCI_DEVICE_DEVICE, B_UINT8_TYPE, {ui8: info.device}}, 101 {B_PCI_DEVICE_FUNCTION, B_UINT8_TYPE, {ui8: info.function}}, 102 103 // info about the device 104 {B_DEVICE_VENDOR_ID, B_UINT16_TYPE, { ui16: info.vendor_id }}, 105 {B_DEVICE_ID, B_UINT16_TYPE, { ui16: info.device_id }}, 106 107 {B_DEVICE_TYPE, B_UINT16_TYPE, { ui16: info.class_base }}, 108 {B_DEVICE_SUB_TYPE, B_UINT16_TYPE, { ui16: info.class_sub }}, 109 {B_DEVICE_INTERFACE, B_UINT16_TYPE, { ui16: info.class_api }}, 110 111 {B_DEVICE_FLAGS, B_UINT32_TYPE, {ui32: B_FIND_CHILD_ON_DEMAND}}, 112 {} 113 }; 114 115 gDeviceManager->register_node(node, PCI_DEVICE_MODULE_NAME, attrs, 116 NULL, NULL); 117 } 118 119 return B_OK; 120 } 121 122 123 static status_t 124 pci_root_init(device_node* node, void** _cookie) 125 { 126 dprintf("pci_root_init()\n"); 127 *_cookie = node; 128 129 gPCIRootNode = node; 130 131 module_info *module; 132 status_t res = get_module(B_PCI_MODULE_NAME, &module); 133 if (res < B_OK) 134 return res; 135 136 return B_OK; 137 } 138 139 140 static int32 141 pci_root_std_ops(int32 op, ...) 142 { 143 switch (op) { 144 case B_MODULE_INIT: 145 { 146 dprintf("+pci_root\n"); 147 /* 148 module_info *module; 149 return get_module(B_PCI_MODULE_NAME, &module); 150 // this serializes our module initialization 151 */ 152 return B_OK; 153 } 154 155 case B_MODULE_UNINIT: 156 dprintf("-pci_root\n"); 157 // return put_module(B_PCI_MODULE_NAME); 158 return B_OK; 159 } 160 161 return B_BAD_VALUE; 162 } 163 164 165 struct pci_root_module_info gPCIRootModule = { 166 { 167 { 168 PCI_ROOT_MODULE_NAME, 169 0, 170 pci_root_std_ops 171 }, 172 173 pci_root_supports_device, 174 pci_root_register_device, 175 pci_root_init, 176 NULL, // uninit 177 pci_root_register_child_devices, 178 NULL, // rescan devices 179 NULL, // device removed 180 }, 181 182 &pci_read_config, 183 &pci_write_config 184 }; 185