xref: /aosp_15_r20/external/coreboot/src/arch/x86/include/arch/pci_io_cfg.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef _PCI_IO_CFG_H
4 #define _PCI_IO_CFG_H
5 
6 #include <stdint.h>
7 #include <arch/io.h>
8 #include <device/pci_type.h>
9 
10 #define PCI_IO_CONFIG_INDEX		0xcf8
11 #define PCI_IO_CONFIG_DATA		0xcfc
12 #define PCI_IO_CONFIG_PORT_COUNT	8
13 #define PCI_IO_CONFIG_LAST_PORT		(PCI_IO_CONFIG_INDEX + PCI_IO_CONFIG_PORT_COUNT - 1)
14 
15 static __always_inline
pci_io_encode_addr(pci_devfn_t dev,uint16_t reg)16 uint32_t pci_io_encode_addr(pci_devfn_t dev, uint16_t reg)
17 {
18 	uint32_t addr = 1U << 31;
19 
20 	addr |= dev >> 4;
21 	addr |= reg & 0xfc;
22 
23 	if (CONFIG(PCI_IO_CFG_EXT))
24 		addr |= (reg & 0xf00) << 16;
25 
26 	return addr;
27 }
28 
29 static __always_inline
pci_io_read_config8(pci_devfn_t dev,uint16_t reg)30 uint8_t pci_io_read_config8(pci_devfn_t dev, uint16_t reg)
31 {
32 	uint32_t addr = pci_io_encode_addr(dev, reg);
33 	outl(addr, PCI_IO_CONFIG_INDEX);
34 	return inb(PCI_IO_CONFIG_DATA + (reg & 3));
35 }
36 
37 static __always_inline
pci_io_read_config16(pci_devfn_t dev,uint16_t reg)38 uint16_t pci_io_read_config16(pci_devfn_t dev, uint16_t reg)
39 {
40 	uint32_t addr = pci_io_encode_addr(dev, reg);
41 	outl(addr, PCI_IO_CONFIG_INDEX);
42 	return inw(PCI_IO_CONFIG_DATA + (reg & 2));
43 }
44 
45 static __always_inline
pci_io_read_config32(pci_devfn_t dev,uint16_t reg)46 uint32_t pci_io_read_config32(pci_devfn_t dev, uint16_t reg)
47 {
48 	uint32_t addr = pci_io_encode_addr(dev, reg);
49 	outl(addr, PCI_IO_CONFIG_INDEX);
50 	return inl(PCI_IO_CONFIG_DATA);
51 }
52 
53 static __always_inline
pci_io_write_config8(pci_devfn_t dev,uint16_t reg,uint8_t value)54 void pci_io_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
55 {
56 	uint32_t addr = pci_io_encode_addr(dev, reg);
57 	outl(addr, PCI_IO_CONFIG_INDEX);
58 	outb(value, PCI_IO_CONFIG_DATA + (reg & 3));
59 }
60 
61 static __always_inline
pci_io_write_config16(pci_devfn_t dev,uint16_t reg,uint16_t value)62 void pci_io_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
63 {
64 	uint32_t addr = pci_io_encode_addr(dev, reg);
65 	outl(addr, PCI_IO_CONFIG_INDEX);
66 	outw(value, PCI_IO_CONFIG_DATA + (reg & 2));
67 }
68 
69 static __always_inline
pci_io_write_config32(pci_devfn_t dev,uint16_t reg,uint32_t value)70 void pci_io_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
71 {
72 	uint32_t addr = pci_io_encode_addr(dev, reg);
73 	outl(addr, PCI_IO_CONFIG_INDEX);
74 	outl(value, PCI_IO_CONFIG_DATA);
75 }
76 
77 #if !CONFIG(ECAM_MMCONF_SUPPORT)
78 
79 /* Avoid name collisions as different stages have different signature
80  * for these functions. The _s_ stands for simple, fundamental IO or
81  * MMIO variant.
82  */
83 
84 static __always_inline
pci_s_read_config8(pci_devfn_t dev,uint16_t reg)85 uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg)
86 {
87 	return pci_io_read_config8(dev, reg);
88 }
89 
90 static __always_inline
pci_s_read_config16(pci_devfn_t dev,uint16_t reg)91 uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
92 {
93 	return pci_io_read_config16(dev, reg);
94 }
95 
96 static __always_inline
pci_s_read_config32(pci_devfn_t dev,uint16_t reg)97 uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
98 {
99 	return pci_io_read_config32(dev, reg);
100 }
101 
102 static __always_inline
pci_s_write_config8(pci_devfn_t dev,uint16_t reg,uint8_t value)103 void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
104 {
105 	pci_io_write_config8(dev, reg, value);
106 }
107 
108 static __always_inline
pci_s_write_config16(pci_devfn_t dev,uint16_t reg,uint16_t value)109 void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
110 {
111 	pci_io_write_config16(dev, reg, value);
112 }
113 
114 static __always_inline
pci_s_write_config32(pci_devfn_t dev,uint16_t reg,uint32_t value)115 void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
116 {
117 	pci_io_write_config32(dev, reg, value);
118 }
119 
120 #endif
121 
122 #endif /* _PCI_IO_CFG_H */
123