1 /* 2 * Copyright (C) 2013, Red Hat Inc, Michael S. Tsirkin <mst@redhat.com> 3 * 4 * This work is licensed under the terms of the GNU LGPL, version 2. 5 */ 6 #include <linux/pci_regs.h> 7 #include "pci.h" 8 #include "asm/pci.h" 9 10 typedef void (*pci_cap_handler)(struct pci_dev *dev, int cap_offset); 11 12 static void pci_cap_msi_handler(struct pci_dev *dev, int cap_offset) 13 { 14 printf("Detected MSI for device 0x%x offset 0x%x\n", 15 dev->bdf, cap_offset); 16 dev->msi_offset = cap_offset; 17 } 18 19 static pci_cap_handler cap_handlers[PCI_CAP_ID_MAX + 1] = { 20 [PCI_CAP_ID_MSI] = pci_cap_msi_handler, 21 }; 22 23 void pci_cap_walk(struct pci_dev *dev) 24 { 25 uint8_t cap_offset; 26 uint8_t cap_id; 27 int count = 0; 28 29 cap_offset = pci_config_readb(dev->bdf, PCI_CAPABILITY_LIST); 30 while (cap_offset) { 31 cap_id = pci_config_readb(dev->bdf, cap_offset); 32 printf("PCI detected cap 0x%x\n", cap_id); 33 assert(cap_id < PCI_CAP_ID_MAX + 1); 34 if (cap_handlers[cap_id]) 35 cap_handlers[cap_id](dev, cap_offset); 36 cap_offset = pci_config_readb(dev->bdf, cap_offset + 1); 37 /* Avoid dead loop during cap walk */ 38 assert(++count <= 255); 39 } 40 } 41 42 bool pci_setup_msi(struct pci_dev *dev, uint64_t msi_addr, uint32_t msi_data) 43 { 44 uint16_t msi_control; 45 uint16_t offset; 46 pcidevaddr_t addr; 47 48 assert(dev); 49 50 if (!dev->msi_offset) { 51 printf("MSI: dev 0x%x does not support MSI.\n", dev->bdf); 52 return false; 53 } 54 55 addr = dev->bdf; 56 offset = dev->msi_offset; 57 msi_control = pci_config_readw(addr, offset + PCI_MSI_FLAGS); 58 pci_config_writel(addr, offset + PCI_MSI_ADDRESS_LO, 59 msi_addr & 0xffffffff); 60 61 if (msi_control & PCI_MSI_FLAGS_64BIT) { 62 pci_config_writel(addr, offset + PCI_MSI_ADDRESS_HI, 63 (uint32_t)(msi_addr >> 32)); 64 pci_config_writel(addr, offset + PCI_MSI_DATA_64, msi_data); 65 printf("MSI: dev 0x%x init 64bit address: ", addr); 66 } else { 67 pci_config_writel(addr, offset + PCI_MSI_DATA_32, msi_data); 68 printf("MSI: dev 0x%x init 32bit address: ", addr); 69 } 70 printf("addr=0x%lx, data=0x%x\n", msi_addr, msi_data); 71 72 msi_control |= PCI_MSI_FLAGS_ENABLE; 73 pci_config_writew(addr, offset + PCI_MSI_FLAGS, msi_control); 74 75 return true; 76 } 77 78 void pci_cmd_set_clr(struct pci_dev *dev, uint16_t set, uint16_t clr) 79 { 80 uint16_t val = pci_config_readw(dev->bdf, PCI_COMMAND); 81 82 /* No overlap is allowed */ 83 assert((set & clr) == 0); 84 val |= set; 85 val &= ~clr; 86 87 pci_config_writew(dev->bdf, PCI_COMMAND, val); 88 } 89 90 bool pci_dev_exists(pcidevaddr_t dev) 91 { 92 return (pci_config_readw(dev, PCI_VENDOR_ID) != 0xffff && 93 pci_config_readw(dev, PCI_DEVICE_ID) != 0xffff); 94 } 95 96 void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf) 97 { 98 memset(dev, 0, sizeof(*dev)); 99 dev->bdf = bdf; 100 } 101 102 /* Scan bus look for a specific device. Only bus 0 scanned for now. */ 103 pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id) 104 { 105 pcidevaddr_t dev; 106 107 for (dev = 0; dev < PCI_DEVFN_MAX; ++dev) { 108 if (pci_config_readw(dev, PCI_VENDOR_ID) == vendor_id && 109 pci_config_readw(dev, PCI_DEVICE_ID) == device_id) 110 return dev; 111 } 112 113 return PCIDEVADDR_INVALID; 114 } 115 116 uint32_t pci_bar_mask(uint32_t bar) 117 { 118 return (bar & PCI_BASE_ADDRESS_SPACE_IO) ? 119 PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; 120 } 121 122 uint32_t pci_bar_get(struct pci_dev *dev, int bar_num) 123 { 124 return pci_config_readl(dev->bdf, PCI_BASE_ADDRESS_0 + 125 bar_num * 4); 126 } 127 128 phys_addr_t pci_bar_get_addr(struct pci_dev *dev, int bar_num) 129 { 130 uint32_t bar = pci_bar_get(dev, bar_num); 131 uint32_t mask = pci_bar_mask(bar); 132 uint64_t addr = bar & mask; 133 phys_addr_t phys_addr; 134 135 if (pci_bar_is64(dev, bar_num)) 136 addr |= (uint64_t)pci_bar_get(dev, bar_num + 1) << 32; 137 138 phys_addr = pci_translate_addr(dev->bdf, addr); 139 assert(phys_addr != INVALID_PHYS_ADDR); 140 141 return phys_addr; 142 } 143 144 void pci_bar_set_addr(struct pci_dev *dev, int bar_num, phys_addr_t addr) 145 { 146 int off = PCI_BASE_ADDRESS_0 + bar_num * 4; 147 148 pci_config_writel(dev->bdf, off, (uint32_t)addr); 149 150 if (pci_bar_is64(dev, bar_num)) 151 pci_config_writel(dev->bdf, off + 4, 152 (uint32_t)(addr >> 32)); 153 } 154 155 /* 156 * To determine the amount of address space needed by a PCI device, 157 * one must save the original value of the BAR, write a value of 158 * all 1's to the register, and then read it back. The amount of 159 * memory can be then determined by masking the information bits, 160 * performing a bitwise NOT, and incrementing the value by 1. 161 * 162 * The following pci_bar_size_helper() and pci_bar_size() functions 163 * implement the algorithm. 164 */ 165 static uint32_t pci_bar_size_helper(struct pci_dev *dev, int bar_num) 166 { 167 int off = PCI_BASE_ADDRESS_0 + bar_num * 4; 168 uint16_t bdf = dev->bdf; 169 uint32_t bar, val; 170 171 bar = pci_config_readl(bdf, off); 172 pci_config_writel(bdf, off, ~0u); 173 val = pci_config_readl(bdf, off); 174 pci_config_writel(bdf, off, bar); 175 176 return val; 177 } 178 179 phys_addr_t pci_bar_size(struct pci_dev *dev, int bar_num) 180 { 181 uint32_t bar, size; 182 183 size = pci_bar_size_helper(dev, bar_num); 184 if (!size) 185 return 0; 186 187 bar = pci_bar_get(dev, bar_num); 188 size &= pci_bar_mask(bar); 189 190 if (pci_bar_is64(dev, bar_num)) { 191 phys_addr_t size64 = pci_bar_size_helper(dev, bar_num + 1); 192 size64 = (size64 << 32) | size; 193 194 return ~size64 + 1; 195 } else { 196 return ~size + 1; 197 } 198 } 199 200 bool pci_bar_is_memory(struct pci_dev *dev, int bar_num) 201 { 202 uint32_t bar = pci_bar_get(dev, bar_num); 203 204 return !(bar & PCI_BASE_ADDRESS_SPACE_IO); 205 } 206 207 bool pci_bar_is_valid(struct pci_dev *dev, int bar_num) 208 { 209 return pci_bar_get(dev, bar_num); 210 } 211 212 bool pci_bar_is64(struct pci_dev *dev, int bar_num) 213 { 214 uint32_t bar = pci_bar_get(dev, bar_num); 215 216 if (bar & PCI_BASE_ADDRESS_SPACE_IO) 217 return false; 218 219 return (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == 220 PCI_BASE_ADDRESS_MEM_TYPE_64; 221 } 222 223 void pci_bar_print(struct pci_dev *dev, int bar_num) 224 { 225 phys_addr_t size, start, end; 226 uint32_t bar; 227 228 size = pci_bar_size(dev, bar_num); 229 if (!size) 230 return; 231 232 bar = pci_bar_get(dev, bar_num); 233 start = pci_bar_get_addr(dev, bar_num); 234 end = start + size - 1; 235 236 if (pci_bar_is64(dev, bar_num)) { 237 printf("BAR#%d,%d [%" PRIx64 "-%" PRIx64 " ", 238 bar_num, bar_num + 1, start, end); 239 } else { 240 printf("BAR#%d [%02x-%02x ", 241 bar_num, (uint32_t)start, (uint32_t)end); 242 } 243 244 if (bar & PCI_BASE_ADDRESS_SPACE_IO) { 245 printf("PIO"); 246 } else { 247 printf("MEM"); 248 switch (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { 249 case PCI_BASE_ADDRESS_MEM_TYPE_32: 250 printf("32"); 251 break; 252 case PCI_BASE_ADDRESS_MEM_TYPE_1M: 253 printf("1M"); 254 break; 255 case PCI_BASE_ADDRESS_MEM_TYPE_64: 256 printf("64"); 257 break; 258 default: 259 assert(0); 260 } 261 } 262 263 if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) 264 printf("/p"); 265 266 printf("]"); 267 } 268 269 void pci_dev_print_id(pcidevaddr_t dev) 270 { 271 printf("00.%02x.%1x %04x:%04x", dev / 8, dev % 8, 272 pci_config_readw(dev, PCI_VENDOR_ID), 273 pci_config_readw(dev, PCI_DEVICE_ID)); 274 } 275 276 static void pci_dev_print(pcidevaddr_t dev) 277 { 278 uint8_t header = pci_config_readb(dev, PCI_HEADER_TYPE); 279 uint8_t progif = pci_config_readb(dev, PCI_CLASS_PROG); 280 uint8_t subclass = pci_config_readb(dev, PCI_CLASS_DEVICE); 281 uint8_t class = pci_config_readb(dev, PCI_CLASS_DEVICE + 1); 282 struct pci_dev pci_dev; 283 int i; 284 285 pci_dev_init(&pci_dev, dev); 286 287 pci_dev_print_id(dev); 288 printf(" type %02x progif %02x class %02x subclass %02x\n", 289 header, progif, class, subclass); 290 291 if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL) 292 return; 293 294 for (i = 0; i < PCI_BAR_NUM; i++) { 295 if (pci_bar_size(&pci_dev, i)) { 296 printf("\t"); 297 pci_bar_print(&pci_dev, i); 298 printf("\n"); 299 } 300 if (pci_bar_is64(&pci_dev, i)) 301 i++; 302 } 303 } 304 305 void pci_print(void) 306 { 307 pcidevaddr_t dev; 308 309 for (dev = 0; dev < PCI_DEVFN_MAX; ++dev) { 310 if (pci_dev_exists(dev)) 311 pci_dev_print(dev); 312 } 313 } 314 315 void pci_scan_bars(struct pci_dev *dev) 316 { 317 int i; 318 319 for (i = 0; i < PCI_BAR_NUM; i++) { 320 if (!pci_bar_is_valid(dev, i)) 321 continue; 322 dev->resource[i] = pci_bar_get_addr(dev, i); 323 if (pci_bar_is64(dev, i)) { 324 i++; 325 dev->resource[i] = (phys_addr_t)0; 326 } 327 } 328 } 329 330 uint8_t pci_intx_line(struct pci_dev *dev) 331 { 332 return pci_config_readb(dev->bdf, PCI_INTERRUPT_LINE); 333 } 334 335 void pci_enable_defaults(struct pci_dev *dev) 336 { 337 pci_scan_bars(dev); 338 /* Enable device DMA operations */ 339 pci_cmd_set_clr(dev, PCI_COMMAND_MASTER, 0); 340 pci_cap_walk(dev); 341 } 342