1456c55bcSAndrew Jones /* 2456c55bcSAndrew Jones * Copyright (C) 2013, Red Hat Inc, Michael S. Tsirkin <mst@redhat.com> 3456c55bcSAndrew Jones * 4456c55bcSAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2. 5456c55bcSAndrew Jones */ 64932b58aSMichael S. Tsirkin #include <linux/pci_regs.h> 74932b58aSMichael S. Tsirkin #include "pci.h" 8456c55bcSAndrew Jones #include "asm/pci.h" 94932b58aSMichael S. Tsirkin 104932b58aSMichael S. Tsirkin /* Scan bus look for a specific device. Only bus 0 scanned for now. */ 114932b58aSMichael S. Tsirkin pcidevaddr_t pci_find_dev(uint16_t vendor_id, uint16_t device_id) 124932b58aSMichael S. Tsirkin { 13ebb58e7eSAlexander Gordeev pcidevaddr_t dev; 14ebb58e7eSAlexander Gordeev 154932b58aSMichael S. Tsirkin for (dev = 0; dev < 256; ++dev) { 16d8369c77SAlexander Gordeev if (pci_config_readw(dev, PCI_VENDOR_ID) == vendor_id && 17d8369c77SAlexander Gordeev pci_config_readw(dev, PCI_DEVICE_ID) == device_id) 184932b58aSMichael S. Tsirkin return dev; 194932b58aSMichael S. Tsirkin } 20ebb58e7eSAlexander Gordeev 214932b58aSMichael S. Tsirkin return PCIDEVADDR_INVALID; 224932b58aSMichael S. Tsirkin } 234932b58aSMichael S. Tsirkin 24*7aa83307SAlexander Gordeev static uint32_t pci_bar_get(pcidevaddr_t dev, int bar_num) 25*7aa83307SAlexander Gordeev { 26*7aa83307SAlexander Gordeev return pci_config_readl(dev, PCI_BASE_ADDRESS_0 + bar_num * 4); 27*7aa83307SAlexander Gordeev } 28*7aa83307SAlexander Gordeev 294932b58aSMichael S. Tsirkin unsigned long pci_bar_addr(pcidevaddr_t dev, int bar_num) 304932b58aSMichael S. Tsirkin { 31*7aa83307SAlexander Gordeev uint32_t bar = pci_bar_get(dev, bar_num); 32ebb58e7eSAlexander Gordeev 33ebb58e7eSAlexander Gordeev if (bar & PCI_BASE_ADDRESS_SPACE_IO) 344932b58aSMichael S. Tsirkin return bar & PCI_BASE_ADDRESS_IO_MASK; 35ebb58e7eSAlexander Gordeev else 364932b58aSMichael S. Tsirkin return bar & PCI_BASE_ADDRESS_MEM_MASK; 374932b58aSMichael S. Tsirkin } 384932b58aSMichael S. Tsirkin 394932b58aSMichael S. Tsirkin bool pci_bar_is_memory(pcidevaddr_t dev, int bar_num) 404932b58aSMichael S. Tsirkin { 41*7aa83307SAlexander Gordeev uint32_t bar = pci_bar_get(dev, bar_num); 42ebb58e7eSAlexander Gordeev 434932b58aSMichael S. Tsirkin return !(bar & PCI_BASE_ADDRESS_SPACE_IO); 444932b58aSMichael S. Tsirkin } 454932b58aSMichael S. Tsirkin 464932b58aSMichael S. Tsirkin bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num) 474932b58aSMichael S. Tsirkin { 48*7aa83307SAlexander Gordeev return pci_bar_get(dev, bar_num); 494932b58aSMichael S. Tsirkin } 50