iPXE
pciextra.c
Go to the documentation of this file.
1 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
2 FILE_SECBOOT ( PERMITTED );
3 
4 #include <stdint.h>
5 #include <ipxe/timer.h>
6 #include <ipxe/pci.h>
7 #include <ipxe/pcibackup.h>
8 
9 static int pci_find_capability_common ( struct pci_device *pci,
10  uint8_t pos, int cap ) {
11  uint8_t id;
12  int ttl = 48;
13 
14  while ( ttl-- && pos >= 0x40 ) {
15  pos &= ~3;
16  pci_read_config_byte ( pci, pos + PCI_CAP_ID, &id );
17  DBG ( "PCI Capability: %d\n", id );
18  if ( id == 0xff )
19  break;
20  if ( id == cap )
21  return pos;
22  pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &pos );
23  }
24  return 0;
25 }
26 
27 /**
28  * Look for a PCI capability
29  *
30  * @v pci PCI device to query
31  * @v cap Capability code
32  * @ret address Address of capability, or 0 if not found
33  *
34  * Determine whether or not a device supports a given PCI capability.
35  * Returns the address of the requested capability structure within
36  * the device's PCI configuration space, or 0 if the device does not
37  * support it.
38  */
39 int pci_find_capability ( struct pci_device *pci, int cap ) {
41  uint8_t pos;
42  uint8_t hdr_type;
43 
45  if ( ! ( status & PCI_STATUS_CAP_LIST ) )
46  return 0;
47 
48  pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdr_type );
49  switch ( hdr_type & PCI_HEADER_TYPE_MASK ) {
52  default:
54  break;
57  break;
58  }
59  return pci_find_capability_common ( pci, pos, cap );
60 }
61 
62 /**
63  * Look for another PCI capability
64  *
65  * @v pci PCI device to query
66  * @v pos Address of the current capability
67  * @v cap Capability code
68  * @ret address Address of capability, or 0 if not found
69  *
70  * Determine whether or not a device supports a given PCI capability
71  * starting the search at a given address within the device's PCI
72  * configuration space. Returns the address of the next capability
73  * structure within the device's PCI configuration space, or 0 if the
74  * device does not support another such capability.
75  */
76 int pci_find_next_capability ( struct pci_device *pci, int pos, int cap ) {
77  uint8_t new_pos;
78 
79  pci_read_config_byte ( pci, pos + PCI_CAP_NEXT, &new_pos );
80  return pci_find_capability_common ( pci, new_pos, cap );
81 }
82 
83 /**
84  * Perform PCI Express function-level reset (FLR)
85  *
86  * @v pci PCI device
87  * @v exp PCI Express Capability address
88  */
89 void pci_reset ( struct pci_device *pci, unsigned int exp ) {
90  struct pci_config_backup backup;
92 
93  /* Back up configuration space */
94  pci_backup ( pci, &backup, PCI_CONFIG_BACKUP_STANDARD, NULL );
95 
96  /* Perform a PCIe function-level reset */
97  pci_read_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), &control );
99  pci_write_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), control );
100 
101  /* Allow time for reset to complete */
103 
104  /* Restore configuration */
105  pci_restore ( pci, &backup, PCI_CONFIG_BACKUP_STANDARD, NULL );
106 }
#define PCI_HEADER_TYPE_BRIDGE
PCI-to-PCI bridge header.
Definition: pci.h:56
void pci_restore(struct pci_device *pci, struct pci_config_backup *backup, unsigned int limit, const uint8_t *exclude)
Restore PCI configuration space.
Definition: pcibackup.c:88
unsigned short uint16_t
Definition: stdint.h:11
#define PCI_CONFIG_BACKUP_STANDARD
Limit of standard PCI configuration space.
Definition: pcibackup.h:19
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int pci_find_capability(struct pci_device *pci, int cap)
Look for a PCI capability.
Definition: pciextra.c:39
static int pci_find_capability_common(struct pci_device *pci, uint8_t pos, int cap)
Definition: pciextra.c:9
#define PCI_CAPABILITY_LIST
PCI capabilities pointer.
Definition: pci.h:85
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
#define PCI_HEADER_TYPE_MASK
Header type mask.
Definition: pci.h:58
#define PCI_EXP_FLR_DELAY_MS
PCI Express function level reset delay (in ms)
Definition: pci.h:172
#define PCI_HEADER_TYPE_CARDBUS
CardBus header.
Definition: pci.h:57
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
iPXE timers
#define PCI_CAP_NEXT
Next capability.
Definition: pci.h:103
void pci_reset(struct pci_device *pci, unsigned int exp)
Perform PCI Express function-level reset (FLR)
Definition: pciextra.c:89
#define PCI_EXP_DEVCTL_FLR
Function level reset.
Definition: pci.h:113
#define PCI_HEADER_TYPE
PCI header type.
Definition: pci.h:54
int pci_find_next_capability(struct pci_device *pci, int pos, int cap)
Look for another PCI capability.
Definition: pciextra.c:76
#define PCI_CB_CAPABILITY_LIST
CardBus capabilities pointer.
Definition: pci.h:88
#define PCI_HEADER_TYPE_NORMAL
Normal header.
Definition: pci.h:55
uint8_t id
Request identifier.
Definition: ena.h:12
#define PCI_CAP_ID
Capability ID.
Definition: pci.h:94
PCI bus.
A PCI device.
Definition: pci.h:211
FILE_SECBOOT(PERMITTED)
A PCI configuration space backup.
Definition: pcibackup.h:22
uint32_t control
Control.
Definition: myson.h:14
unsigned char uint8_t
Definition: stdint.h:10
#define PCI_STATUS
PCI status.
Definition: pci.h:36
uint8_t status
Status.
Definition: ena.h:16
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:79
void pci_backup(struct pci_device *pci, struct pci_config_backup *backup, unsigned int limit, const uint8_t *exclude)
Back up PCI configuration space.
Definition: pcibackup.c:68
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define PCI_STATUS_CAP_LIST
Capabilities list.
Definition: pci.h:37
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define PCI_EXP_DEVCTL
PCI Express.
Definition: pci.h:112
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.
PCI configuration space backup and restoration.