1 /******************************************************************************
2 * pci.c
3 *
4 * Architecture-dependent PCI access functions.
5 */
6
7 #include <xen/spinlock.h>
8 #include <xen/pci.h>
9 #include <asm/io.h>
10
11 #define PCI_CONF_ADDRESS(bus, dev, func, reg) \
12 (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
13
pci_conf_read8(unsigned int seg,unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg)14 uint8_t pci_conf_read8(
15 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
16 unsigned int reg)
17 {
18 u32 value;
19
20 if ( seg || reg > 255 )
21 {
22 pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 1, &value);
23 return value;
24 }
25 else
26 {
27 BUG_ON((bus > 255) || (dev > 31) || (func > 7));
28 return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1);
29 }
30 }
31
pci_conf_read16(unsigned int seg,unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg)32 uint16_t pci_conf_read16(
33 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
34 unsigned int reg)
35 {
36 u32 value;
37
38 if ( seg || reg > 255 )
39 {
40 pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 2, &value);
41 return value;
42 }
43 else
44 {
45 BUG_ON((bus > 255) || (dev > 31) || (func > 7));
46 return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2);
47 }
48 }
49
pci_conf_read32(unsigned int seg,unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg)50 uint32_t pci_conf_read32(
51 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
52 unsigned int reg)
53 {
54 u32 value;
55
56 if ( seg || reg > 255 )
57 {
58 pci_mmcfg_read(seg, bus, PCI_DEVFN(dev, func), reg, 4, &value);
59 return value;
60 }
61 else
62 {
63 BUG_ON((bus > 255) || (dev > 31) || (func > 7));
64 return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4);
65 }
66 }
67
pci_conf_write8(unsigned int seg,unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg,uint8_t data)68 void pci_conf_write8(
69 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
70 unsigned int reg, uint8_t data)
71 {
72 if ( seg || reg > 255 )
73 pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 1, data);
74 else
75 {
76 BUG_ON((bus > 255) || (dev > 31) || (func > 7));
77 pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1, data);
78 }
79 }
80
pci_conf_write16(unsigned int seg,unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg,uint16_t data)81 void pci_conf_write16(
82 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
83 unsigned int reg, uint16_t data)
84 {
85 if ( seg || reg > 255 )
86 pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 2, data);
87 else
88 {
89 BUG_ON((bus > 255) || (dev > 31) || (func > 7));
90 pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2, data);
91 }
92 }
93
pci_conf_write32(unsigned int seg,unsigned int bus,unsigned int dev,unsigned int func,unsigned int reg,uint32_t data)94 void pci_conf_write32(
95 unsigned int seg, unsigned int bus, unsigned int dev, unsigned int func,
96 unsigned int reg, uint32_t data)
97 {
98 if ( seg || reg > 255 )
99 pci_mmcfg_write(seg, bus, PCI_DEVFN(dev, func), reg, 4, data);
100 else
101 {
102 BUG_ON((bus > 255) || (dev > 31) || (func > 7));
103 pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data);
104 }
105 }
106