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