1#ifndef _GPXE_EFI_PCI_H
2#define _GPXE_EFI_PCI_H
3
4/** @file
5 *
6 * gPXE PCI I/O API for EFI
7 *
8 */
9
10FILE_LICENCE ( GPL2_OR_LATER );
11
12#ifdef PCIAPI_EFI
13#define PCIAPI_PREFIX_efi
14#else
15#define PCIAPI_PREFIX_efi __efi_
16#endif
17
18/* EFI PCI width codes defined by EFI spec */
19#define EFIPCI_WIDTH_BYTE 0
20#define EFIPCI_WIDTH_WORD 1
21#define EFIPCI_WIDTH_DWORD 2
22
23#define EFIPCI_LOCATION( _offset, _width ) \
24	( (_offset) | ( (_width) << 16 ) )
25#define EFIPCI_OFFSET( _location ) ( (_location) & 0xffff )
26#define EFIPCI_WIDTH( _location ) ( (_location) >> 16 )
27
28struct pci_device;
29
30extern int efipci_read ( struct pci_device *pci, unsigned long location,
31			 void *value );
32extern int efipci_write ( struct pci_device *pci, unsigned long location,
33			  unsigned long value );
34
35/**
36 * Determine maximum PCI bus number within system
37 *
38 * @ret max_bus		Maximum bus number
39 */
40static inline __always_inline int
41PCIAPI_INLINE ( efi, pci_max_bus ) ( void ) {
42	/* No way to work this out via EFI */
43	return 0xff;
44}
45
46/**
47 * Read byte from PCI configuration space via EFI
48 *
49 * @v pci	PCI device
50 * @v where	Location within PCI configuration space
51 * @v value	Value read
52 * @ret rc	Return status code
53 */
54static inline __always_inline int
55PCIAPI_INLINE ( efi, pci_read_config_byte ) ( struct pci_device *pci,
56					      unsigned int where,
57					      uint8_t *value ) {
58	return efipci_read ( pci,
59			     EFIPCI_LOCATION ( where, EFIPCI_WIDTH_BYTE ),
60			     value );
61}
62
63/**
64 * Read word from PCI configuration space via EFI
65 *
66 * @v pci	PCI device
67 * @v where	Location within PCI configuration space
68 * @v value	Value read
69 * @ret rc	Return status code
70 */
71static inline __always_inline int
72PCIAPI_INLINE ( efi, pci_read_config_word ) ( struct pci_device *pci,
73					      unsigned int where,
74					      uint16_t *value ) {
75	return efipci_read ( pci,
76			     EFIPCI_LOCATION ( where, EFIPCI_WIDTH_WORD ),
77			     value );
78}
79
80/**
81 * Read dword from PCI configuration space via EFI
82 *
83 * @v pci	PCI device
84 * @v where	Location within PCI configuration space
85 * @v value	Value read
86 * @ret rc	Return status code
87 */
88static inline __always_inline int
89PCIAPI_INLINE ( efi, pci_read_config_dword ) ( struct pci_device *pci,
90					       unsigned int where,
91					       uint32_t *value ) {
92	return efipci_read ( pci,
93			     EFIPCI_LOCATION ( where, EFIPCI_WIDTH_DWORD ),
94			     value );
95}
96
97/**
98 * Write byte to PCI configuration space via EFI
99 *
100 * @v pci	PCI device
101 * @v where	Location within PCI configuration space
102 * @v value	Value to be written
103 * @ret rc	Return status code
104 */
105static inline __always_inline int
106PCIAPI_INLINE ( efi, pci_write_config_byte ) ( struct pci_device *pci,
107					       unsigned int where,
108					       uint8_t value ) {
109	return efipci_write ( pci,
110			      EFIPCI_LOCATION ( where, EFIPCI_WIDTH_BYTE ),
111			      value );
112}
113
114/**
115 * Write word to PCI configuration space via EFI
116 *
117 * @v pci	PCI device
118 * @v where	Location within PCI configuration space
119 * @v value	Value to be written
120 * @ret rc	Return status code
121 */
122static inline __always_inline int
123PCIAPI_INLINE ( efi, pci_write_config_word ) ( struct pci_device *pci,
124					       unsigned int where,
125					       uint16_t value ) {
126	return efipci_write ( pci,
127			      EFIPCI_LOCATION ( where, EFIPCI_WIDTH_WORD ),
128			      value );
129}
130
131/**
132 * Write dword to PCI configuration space via EFI
133 *
134 * @v pci	PCI device
135 * @v where	Location within PCI configuration space
136 * @v value	Value to be written
137 * @ret rc	Return status code
138 */
139static inline __always_inline int
140PCIAPI_INLINE ( efi, pci_write_config_dword ) ( struct pci_device *pci,
141						unsigned int where,
142						uint32_t value ) {
143	return efipci_write ( pci,
144			      EFIPCI_LOCATION ( where, EFIPCI_WIDTH_DWORD ),
145			      value );
146}
147
148#endif /* _GPXE_EFI_PCI_H */
149