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 void pci_cmd_set_clr(struct pci_dev *dev, uint16_t set, uint16_t clr) 11 { 12 uint16_t val = pci_config_readw(dev->bdf, PCI_COMMAND); 13 14 /* No overlap is allowed */ 15 assert((set & clr) == 0); 16 val |= set; 17 val &= ~clr; 18 19 pci_config_writew(dev->bdf, PCI_COMMAND, val); 20 } 21 22 bool pci_dev_exists(pcidevaddr_t dev) 23 { 24 return (pci_config_readw(dev, PCI_VENDOR_ID) != 0xffff && 25 pci_config_readw(dev, PCI_DEVICE_ID) != 0xffff); 26 } 27 28 void pci_dev_init(struct pci_dev *dev, pcidevaddr_t bdf) 29 { 30 memset(dev, 0, sizeof(*dev)); 31 dev->bdf = bdf; 32 } 33 34 /* Scan bus look for a specific device. Only bus 0 scanned for now. */ 35 pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id) 36 { 37 pcidevaddr_t dev; 38 39 for (dev = 0; dev < PCI_DEVFN_MAX; ++dev) { 40 if (pci_config_readw(dev, PCI_VENDOR_ID) == vendor_id && 41 pci_config_readw(dev, PCI_DEVICE_ID) == device_id) 42 return dev; 43 } 44 45 return PCIDEVADDR_INVALID; 46 } 47 48 uint32_t pci_bar_mask(uint32_t bar) 49 { 50 return (bar & PCI_BASE_ADDRESS_SPACE_IO) ? 51 PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; 52 } 53 54 uint32_t pci_bar_get(struct pci_dev *dev, int bar_num) 55 { 56 return pci_config_readl(dev->bdf, PCI_BASE_ADDRESS_0 + 57 bar_num * 4); 58 } 59 60 phys_addr_t pci_bar_get_addr(struct pci_dev *dev, int bar_num) 61 { 62 uint32_t bar = pci_bar_get(dev, bar_num); 63 uint32_t mask = pci_bar_mask(bar); 64 uint64_t addr = bar & mask; 65 phys_addr_t phys_addr; 66 67 if (pci_bar_is64(dev, bar_num)) 68 addr |= (uint64_t)pci_bar_get(dev, bar_num + 1) << 32; 69 70 phys_addr = pci_translate_addr(dev->bdf, addr); 71 assert(phys_addr != INVALID_PHYS_ADDR); 72 73 return phys_addr; 74 } 75 76 void pci_bar_set_addr(struct pci_dev *dev, int bar_num, phys_addr_t addr) 77 { 78 int off = PCI_BASE_ADDRESS_0 + bar_num * 4; 79 80 pci_config_writel(dev->bdf, off, (uint32_t)addr); 81 82 if (pci_bar_is64(dev, bar_num)) 83 pci_config_writel(dev->bdf, off + 4, 84 (uint32_t)(addr >> 32)); 85 } 86 87 /* 88 * To determine the amount of address space needed by a PCI device, 89 * one must save the original value of the BAR, write a value of 90 * all 1's to the register, and then read it back. The amount of 91 * memory can be then determined by masking the information bits, 92 * performing a bitwise NOT, and incrementing the value by 1. 93 * 94 * The following pci_bar_size_helper() and pci_bar_size() functions 95 * implement the algorithm. 96 */ 97 static uint32_t pci_bar_size_helper(struct pci_dev *dev, int bar_num) 98 { 99 int off = PCI_BASE_ADDRESS_0 + bar_num * 4; 100 uint16_t bdf = dev->bdf; 101 uint32_t bar, val; 102 103 bar = pci_config_readl(bdf, off); 104 pci_config_writel(bdf, off, ~0u); 105 val = pci_config_readl(bdf, off); 106 pci_config_writel(bdf, off, bar); 107 108 return val; 109 } 110 111 phys_addr_t pci_bar_size(struct pci_dev *dev, int bar_num) 112 { 113 uint32_t bar, size; 114 115 size = pci_bar_size_helper(dev, bar_num); 116 if (!size) 117 return 0; 118 119 bar = pci_bar_get(dev, bar_num); 120 size &= pci_bar_mask(bar); 121 122 if (pci_bar_is64(dev, bar_num)) { 123 phys_addr_t size64 = pci_bar_size_helper(dev, bar_num + 1); 124 size64 = (size64 << 32) | size; 125 126 return ~size64 + 1; 127 } else { 128 return ~size + 1; 129 } 130 } 131 132 bool pci_bar_is_memory(struct pci_dev *dev, int bar_num) 133 { 134 uint32_t bar = pci_bar_get(dev, bar_num); 135 136 return !(bar & PCI_BASE_ADDRESS_SPACE_IO); 137 } 138 139 bool pci_bar_is_valid(struct pci_dev *dev, int bar_num) 140 { 141 return pci_bar_get(dev, bar_num); 142 } 143 144 bool pci_bar_is64(struct pci_dev *dev, int bar_num) 145 { 146 uint32_t bar = pci_bar_get(dev, bar_num); 147 148 if (bar & PCI_BASE_ADDRESS_SPACE_IO) 149 return false; 150 151 return (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == 152 PCI_BASE_ADDRESS_MEM_TYPE_64; 153 } 154 155 void pci_bar_print(struct pci_dev *dev, int bar_num) 156 { 157 phys_addr_t size, start, end; 158 uint32_t bar; 159 160 size = pci_bar_size(dev, bar_num); 161 if (!size) 162 return; 163 164 bar = pci_bar_get(dev, bar_num); 165 start = pci_bar_get_addr(dev, bar_num); 166 end = start + size - 1; 167 168 if (pci_bar_is64(dev, bar_num)) { 169 printf("BAR#%d,%d [%" PRIx64 "-%" PRIx64 " ", 170 bar_num, bar_num + 1, start, end); 171 } else { 172 printf("BAR#%d [%02x-%02x ", 173 bar_num, (uint32_t)start, (uint32_t)end); 174 } 175 176 if (bar & PCI_BASE_ADDRESS_SPACE_IO) { 177 printf("PIO"); 178 } else { 179 printf("MEM"); 180 switch (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { 181 case PCI_BASE_ADDRESS_MEM_TYPE_32: 182 printf("32"); 183 break; 184 case PCI_BASE_ADDRESS_MEM_TYPE_1M: 185 printf("1M"); 186 break; 187 case PCI_BASE_ADDRESS_MEM_TYPE_64: 188 printf("64"); 189 break; 190 default: 191 assert(0); 192 } 193 } 194 195 if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) 196 printf("/p"); 197 198 printf("]"); 199 } 200 201 void pci_dev_print_id(pcidevaddr_t dev) 202 { 203 printf("00.%02x.%1x %04x:%04x", dev / 8, dev % 8, 204 pci_config_readw(dev, PCI_VENDOR_ID), 205 pci_config_readw(dev, PCI_DEVICE_ID)); 206 } 207 208 static void pci_dev_print(pcidevaddr_t dev) 209 { 210 uint8_t header = pci_config_readb(dev, PCI_HEADER_TYPE); 211 uint8_t progif = pci_config_readb(dev, PCI_CLASS_PROG); 212 uint8_t subclass = pci_config_readb(dev, PCI_CLASS_DEVICE); 213 uint8_t class = pci_config_readb(dev, PCI_CLASS_DEVICE + 1); 214 struct pci_dev pci_dev; 215 int i; 216 217 pci_dev_init(&pci_dev, dev); 218 219 pci_dev_print_id(dev); 220 printf(" type %02x progif %02x class %02x subclass %02x\n", 221 header, progif, class, subclass); 222 223 if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL) 224 return; 225 226 for (i = 0; i < PCI_BAR_NUM; i++) { 227 if (pci_bar_size(&pci_dev, i)) { 228 printf("\t"); 229 pci_bar_print(&pci_dev, i); 230 printf("\n"); 231 } 232 if (pci_bar_is64(&pci_dev, i)) 233 i++; 234 } 235 } 236 237 void pci_print(void) 238 { 239 pcidevaddr_t dev; 240 241 for (dev = 0; dev < PCI_DEVFN_MAX; ++dev) { 242 if (pci_dev_exists(dev)) 243 pci_dev_print(dev); 244 } 245 } 246 247 void pci_scan_bars(struct pci_dev *dev) 248 { 249 int i; 250 251 for (i = 0; i < PCI_BAR_NUM; i++) { 252 if (!pci_bar_is_valid(dev, i)) 253 continue; 254 dev->resource[i] = pci_bar_get_addr(dev, i); 255 if (pci_bar_is64(dev, i)) { 256 i++; 257 dev->resource[i] = (phys_addr_t)0; 258 } 259 } 260 } 261 262 void pci_enable_defaults(struct pci_dev *dev) 263 { 264 pci_scan_bars(dev); 265 /* Enable device DMA operations */ 266 pci_cmd_set_clr(dev, PCI_COMMAND_MASTER, 0); 267 } 268