xref: /kvm-unit-tests/lib/pci.c (revision 7aa8330797745d05703169951e922d2359eff9b2)
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