iPXE
pcicloud.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <ipxe/init.h>
28 #include <ipxe/pci.h>
29 #include <ipxe/ecam.h>
30 #include <ipxe/pcibios.h>
31 #include <ipxe/pcidirect.h>
32 #include <ipxe/pcicloud.h>
33 
34 /** @file
35  *
36  * Cloud VM PCI configuration space access
37  *
38  */
39 
40 /** Selected PCI configuration space access API */
41 static struct pci_api *pcicloud = &ecam_api;
42 
43 /**
44  * Find next PCI bus:dev.fn address range in system
45  *
46  * @v busdevfn Starting PCI bus:dev.fn address
47  * @v range PCI bus:dev.fn address range to fill in
48  */
50 
52 }
53 
54 /**
55  * Read byte from PCI configuration space
56  *
57  * @v pci PCI device
58  * @v where Location within PCI configuration space
59  * @v value Value read
60  * @ret rc Return status code
61  */
62 static int pcicloud_read_config_byte ( struct pci_device *pci,
63  unsigned int where, uint8_t *value ) {
64 
65  return pcicloud->pci_read_config_byte ( pci, where, value );
66 }
67 
68 /**
69  * Read 16-bit word from PCI configuration space
70  *
71  * @v pci PCI device
72  * @v where Location within PCI configuration space
73  * @v value Value read
74  * @ret rc Return status code
75  */
76 static int pcicloud_read_config_word ( struct pci_device *pci,
77  unsigned int where, uint16_t *value ) {
78 
79  return pcicloud->pci_read_config_word ( pci, where, value );
80 }
81 
82 /**
83  * Read 32-bit dword from PCI configuration space
84  *
85  * @v pci PCI device
86  * @v where Location within PCI configuration space
87  * @v value Value read
88  * @ret rc Return status code
89  */
90 static int pcicloud_read_config_dword ( struct pci_device *pci,
91  unsigned int where, uint32_t *value ) {
92 
93  return pcicloud->pci_read_config_dword ( pci, where, value );
94 }
95 
96 /**
97  * Write byte to PCI configuration space
98  *
99  * @v pci PCI device
100  * @v where Location within PCI configuration space
101  * @v value Value to be written
102  * @ret rc Return status code
103  */
104 static int pcicloud_write_config_byte ( struct pci_device *pci,
105  unsigned int where, uint8_t value ) {
106 
107  return pcicloud->pci_write_config_byte ( pci, where, value );
108 }
109 
110 /**
111  * Write 16-bit word to PCI configuration space
112  *
113  * @v pci PCI device
114  * @v where Location within PCI configuration space
115  * @v value Value to be written
116  * @ret rc Return status code
117  */
118 static int pcicloud_write_config_word ( struct pci_device *pci,
119  unsigned int where, uint16_t value ) {
120 
121  return pcicloud->pci_write_config_word ( pci, where, value );
122 }
123 
124 /**
125  * Write 32-bit dword to PCI configuration space
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 int pcicloud_write_config_dword ( struct pci_device *pci,
133  unsigned int where, uint32_t value ) {
134 
135  return pcicloud->pci_write_config_dword ( pci, where, value );
136 }
137 
138 /**
139  * Map PCI bus address as an I/O address
140  *
141  * @v bus_addr PCI bus address
142  * @v len Length of region
143  * @ret io_addr I/O address, or NULL on error
144  */
145 static void * pcicloud_ioremap ( struct pci_device *pci,
146  unsigned long bus_addr, size_t len ) {
147 
148  return pcicloud->pci_ioremap ( pci, bus_addr, len );
149 }
150 
159 
160 /**
161  * Initialise cloud VM PCI configuration space access
162  *
163  */
164 static void pcicloud_init ( void ) {
165  static struct pci_api *apis[] = {
167  };
168  struct pci_device pci;
170  unsigned int i;
171  int rc;
172 
173  /* Select first API that successfully discovers a PCI device */
174  for ( i = 0 ; i < ( sizeof ( apis ) / sizeof ( apis[0] ) ) ; i++ ) {
175  pcicloud = apis[i];
176  busdevfn = 0;
177  if ( ( rc = pci_find_next ( &pci, &busdevfn ) ) == 0 ) {
178  DBGC ( pcicloud, "PCICLOUD selected %s API (found "
179  PCI_FMT ")\n", pcicloud->name,
180  PCI_ARGS ( &pci ) );
181  return;
182  }
183  }
184 
185  /* Fall back to using final attempted API if no devices found */
186  pcicloud = apis[ i - 1 ];
187  DBGC ( pcicloud, "PCICLOUD selected %s API (nothing detected)\n",
188  pcicloud->name );
189 }
190 
191 /** Cloud VM PCI configuration space access initialisation function */
192 struct init_fn pcicloud_init_fn __init_fn ( INIT_EARLY ) = {
194 };
static void pcicloud_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
Definition: pcicloud.c:49
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned short uint16_t
Definition: stdint.h:11
static __always_inline void struct pci_range * range
Definition: efi_pci_api.h:43
typeof() pci_discover * pci_discover
Definition: pci_io.h:156
void(* initialise)(void)
Definition: init.h:15
typeof() pci_read_config_word * pci_read_config_word
Definition: pci_io.h:158
typeof() pci_write_config_byte * pci_write_config_byte
Definition: pci_io.h:160
PCI configuration space access via PCI BIOS.
typeof() pci_read_config_dword * pci_read_config_dword
Definition: pci_io.h:159
#define INIT_EARLY
Early initialisation.
Definition: init.h:28
PROVIDE_PCIAPI(cloud, pci_discover, pcicloud_discover)
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
#define DBGC(...)
Definition: compiler.h:505
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
static int pcicloud_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
Definition: pcicloud.c:76
struct pci_api ecam_api
Definition: ecam.c:288
Cloud VM PCI configuration space access.
struct pci_api pcidirect_api
Definition: pcidirect.c:57
struct pci_api pcibios_api
Definition: pcibios.c:132
static int pcicloud_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
Definition: pcicloud.c:118
uint16_t busdevfn
PCI bus:dev.fn address.
Definition: ena.h:28
int pci_find_next(struct pci_device *pci, uint32_t *busdevfn)
Find next device on PCI bus.
Definition: pci.c:236
An initialisation function.
Definition: init.h:14
const char * name
Definition: pci_io.h:155
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
typeof() pci_write_config_word * pci_write_config_word
Definition: pci_io.h:161
struct init_fn pcicloud_init_fn __init_fn(INIT_EARLY)
Cloud VM PCI configuration space access initialisation function.
A PCI bus:dev.fn address range.
Definition: pci_io.h:21
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
#define PCI_FMT
PCI device debug message format.
Definition: pci.h:307
PCI bus.
static int pcicloud_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
Definition: pcicloud.c:132
A PCI device.
Definition: pci.h:206
A runtime selectable PCI I/O API.
Definition: pci_io.h:154
static void * pcicloud_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
Definition: pcicloud.c:145
PCI I/O API for Enhanced Configuration Access Mechanism (ECAM)
typeof() pci_read_config_byte * pci_read_config_byte
Definition: pci_io.h:157
typeof() pci_ioremap * pci_ioremap
Definition: pci_io.h:163
static int pcicloud_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
Definition: pcicloud.c:90
unsigned char uint8_t
Definition: stdint.h:10
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
unsigned int uint32_t
Definition: stdint.h:12
void pci_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
PCI configuration space access via Type 1 accesses.
uint32_t len
Length.
Definition: ena.h:14
static int pcicloud_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
Definition: pcicloud.c:104
static struct pci_api * pcicloud
Selected PCI configuration space access API.
Definition: pcicloud.c:41
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition: pci.h:310
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
static void pcicloud_init(void)
Initialise cloud VM PCI configuration space access.
Definition: pcicloud.c:164
static int pcicloud_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.
Definition: pcicloud.c:62
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
static __always_inline void unsigned long bus_addr
Definition: ecam_io.h:135
static __always_inline int unsigned int where
Definition: ecam_io.h:46
typeof() pci_write_config_dword * pci_write_config_dword
Definition: pci_io.h:162
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.