1 #ifndef _PCIDIRECT_H
2 #define _PCIDIRECT_H
3 
4 FILE_LICENCE ( GPL2_OR_LATER );
5 
6 #include <stdint.h>
7 #include <gpxe/io.h>
8 
9 #ifdef PCIAPI_DIRECT
10 #define PCIAPI_PREFIX_direct
11 #else
12 #define PCIAPI_PREFIX_direct __direct_
13 #endif
14 
15 /** @file
16  *
17  * PCI configuration space access via Type 1 accesses
18  *
19  */
20 
21 #define PCIDIRECT_CONFIG_ADDRESS	0xcf8
22 #define PCIDIRECT_CONFIG_DATA		0xcfc
23 
24 struct pci_device;
25 
26 extern void pcidirect_prepare ( struct pci_device *pci, int where );
27 
28 /**
29  * Determine maximum PCI bus number within system
30  *
31  * @ret max_bus		Maximum bus number
32  */
33 static inline __always_inline int
PCIAPI_INLINE(direct,pci_max_bus)34 PCIAPI_INLINE ( direct, pci_max_bus ) ( void ) {
35 	/* No way to work this out via Type 1 accesses */
36 	return 0xff;
37 }
38 
39 /**
40  * Read byte from PCI configuration space via Type 1 access
41  *
42  * @v pci	PCI device
43  * @v where	Location within PCI configuration space
44  * @v value	Value read
45  * @ret rc	Return status code
46  */
47 static inline __always_inline int
PCIAPI_INLINE(direct,pci_read_config_byte)48 PCIAPI_INLINE ( direct, pci_read_config_byte ) ( struct pci_device *pci,
49 						 unsigned int where,
50 						 uint8_t *value ) {
51 	pcidirect_prepare ( pci, where );
52 	*value = inb ( PCIDIRECT_CONFIG_DATA + ( where & 3 ) );
53 	return 0;
54 }
55 
56 /**
57  * Read word from PCI configuration space via Type 1 access
58  *
59  * @v pci	PCI device
60  * @v where	Location within PCI configuration space
61  * @v value	Value read
62  * @ret rc	Return status code
63  */
64 static inline __always_inline int
PCIAPI_INLINE(direct,pci_read_config_word)65 PCIAPI_INLINE ( direct, pci_read_config_word ) ( struct pci_device *pci,
66 						 unsigned int where,
67 						 uint16_t *value ) {
68 	pcidirect_prepare ( pci, where );
69 	*value = inw ( PCIDIRECT_CONFIG_DATA + ( where & 2 ) );
70 	return 0;
71 }
72 
73 /**
74  * Read dword from PCI configuration space via Type 1 access
75  *
76  * @v pci	PCI device
77  * @v where	Location within PCI configuration space
78  * @v value	Value read
79  * @ret rc	Return status code
80  */
81 static inline __always_inline int
PCIAPI_INLINE(direct,pci_read_config_dword)82 PCIAPI_INLINE ( direct, pci_read_config_dword ) ( struct pci_device *pci,
83 						  unsigned int where,
84 						  uint32_t *value ) {
85 	pcidirect_prepare ( pci, where );
86 	*value = inl ( PCIDIRECT_CONFIG_DATA );
87 	return 0;
88 }
89 
90 /**
91  * Write byte to PCI configuration space via Type 1 access
92  *
93  * @v pci	PCI device
94  * @v where	Location within PCI configuration space
95  * @v value	Value to be written
96  * @ret rc	Return status code
97  */
98 static inline __always_inline int
PCIAPI_INLINE(direct,pci_write_config_byte)99 PCIAPI_INLINE ( direct, pci_write_config_byte ) ( struct pci_device *pci,
100 						  unsigned int where,
101 						  uint8_t value ) {
102 	pcidirect_prepare ( pci, where );
103 	outb ( value, PCIDIRECT_CONFIG_DATA + ( where & 3 ) );
104 	return 0;
105 }
106 
107 /**
108  * Write word to PCI configuration space via Type 1 access
109  *
110  * @v pci	PCI device
111  * @v where	Location within PCI configuration space
112  * @v value	Value to be written
113  * @ret rc	Return status code
114  */
115 static inline __always_inline int
PCIAPI_INLINE(direct,pci_write_config_word)116 PCIAPI_INLINE ( direct, pci_write_config_word ) ( struct pci_device *pci,
117 						  unsigned int where,
118 						  uint16_t value ) {
119 	pcidirect_prepare ( pci, where );
120 	outw ( value, PCIDIRECT_CONFIG_DATA + ( where & 2 ) );
121 	return 0;
122 }
123 
124 /**
125  * Write dword to PCI configuration space via Type 1 access
126  *
127  * @v pci	PCI device
128  * @v where	Location within PCI configuration space
129  * @v value	Value to be written
130  * @ret rc	Return status code
131  */
132 static inline __always_inline int
PCIAPI_INLINE(direct,pci_write_config_dword)133 PCIAPI_INLINE ( direct, pci_write_config_dword ) ( struct pci_device *pci,
134 						   unsigned int where,
135 						   uint32_t value ) {
136 	pcidirect_prepare ( pci, where );
137 	outl ( value, PCIDIRECT_CONFIG_DATA );
138 	return 0;
139 }
140 
141 #endif /* _PCIDIRECT_H */
142