iPXE
pcibridge.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
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26#include <stddef.h>
27#include <stdint.h>
28#include <errno.h>
29#include <byteswap.h>
30#include <ipxe/pci.h>
31#include <ipxe/pcibridge.h>
32
33/** @file
34 *
35 * PCI-to-PCI bridge
36 *
37 */
38
39/** List of all PCI bridges */
40static LIST_HEAD ( pcibridges );
41
42/**
43 * Find bridge attached to a PCI device
44 *
45 * @v pci PCI device
46 * @ret bridge PCI bridge, or NULL
47 */
49 unsigned int bus = PCI_BUS ( pci->busdevfn );
50 struct pci_bridge *bridge;
51
52 /* Find matching bridge */
53 list_for_each_entry ( bridge, &pcibridges, list ) {
54 if ( bus == bridge->secondary )
55 return bridge;
56 }
57
58 return NULL;
59}
60
61/**
62 * Probe PCI device
63 *
64 * @v pci PCI device
65 * @ret rc Return status code
66 */
67static int pcibridge_probe ( struct pci_device *pci ) {
68 struct pci_bridge *bridge;
71 uint32_t base_hi;
72 uint32_t limit_hi;
73 int rc;
74
75 /* Allocate and initialise structure */
76 bridge = zalloc ( sizeof ( *bridge ) );
77 if ( ! bridge ) {
78 rc = -ENOMEM;
79 goto err_alloc;
80 }
81 bridge->pci = pci;
82
83 /* Read bus configuration */
86
87 /* Read memory base and limit */
89 bridge->membase = ( ( base & ~PCI_MEM_MASK ) << 16 );
91 bridge->memlimit = ( ( ( ( limit | PCI_MEM_MASK ) + 1 ) << 16 ) - 1 );
92
93 /* Read prefetchable memory base and limit */
96 bridge->prefmembase = ( ( ( base & ~PCI_MEM_MASK ) << 16 ) |
97 ( ( ( uint64_t ) base_hi ) << 32 ) );
100 bridge->prefmemlimit = ( ( ( ( ( limit | PCI_MEM_MASK ) + 1 ) << 16 ) |
101 ( ( ( uint64_t ) limit_hi ) << 32 ) ) - 1 );
102
103 DBGC ( bridge, "BRIDGE " PCI_FMT " bus %02x to [%02x,%02x)\n",
104 PCI_ARGS ( pci ), bridge->primary, bridge->secondary,
105 bridge->subordinate );
106 DBGC ( bridge, "BRIDGE " PCI_FMT " mem [%08x,%08x) prefmem "
107 "[%08llx,%08llx)\n", PCI_ARGS ( pci ), bridge->membase,
108 bridge->memlimit, ( ( unsigned long long ) bridge->prefmembase ),
109 ( ( unsigned long long ) bridge->prefmemlimit ) );
110
111 /* Add to list of PCI bridges */
112 list_add ( &bridge->list, &pcibridges );
113
114 pci_set_drvdata ( pci, bridge );
115 return 0;
116
117 free ( bridge );
118 err_alloc:
119 return rc;
120}
121
122/**
123 * Remove PCI device
124 *
125 * @v pci PCI device
126 */
127static void pcibridge_remove ( struct pci_device *pci ) {
128 struct pci_bridge *bridge = pci_get_drvdata ( pci );
129
130 /* Remove from list of bridges */
131 list_del ( &bridge->list );
132
133 /* Free device */
134 free ( bridge );
135}
136
137/** Bridge PCI device IDs */
138static struct pci_device_id pcibridge_ids[] = {
139 PCI_ROM ( 0xffff, 0xffff, "bridge", "Bridge", 0 ),
140};
141
142/** Bridge PCI driver */
143struct pci_driver pcibridge_driver __pci_driver = {
144 .ids = pcibridge_ids,
145 .id_count = ( sizeof ( pcibridge_ids ) / sizeof ( pcibridge_ids[0] ) ),
147 PCI_ANY_ID ),
148 .probe = pcibridge_probe,
149 .remove = pcibridge_remove,
150};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define PCI_CLASS_BRIDGE
Definition Pci22.h:184
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
unsigned long long uint64_t
Definition stdint.h:13
uint8_t bus
Bus.
Definition edd.h:1
Error codes.
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOMEM
Not enough space.
Definition errno.h:535
#define cpu_to_le32s(ptr)
Definition byteswap.h:120
int pci_read_config_dword(struct pci_device *pci, unsigned int where, uint32_t *value)
Read 32-bit dword from PCI configuration space.
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
uint16_t limit
Limit.
Definition librm.h:1
uint32_t base
Base.
Definition librm.h:3
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
PCI bus.
#define PCI_MEM_MASK
Definition pci.h:155
#define PCI_ANY_ID
Match-anything ID.
Definition pci.h:187
#define PCI_FMT
PCI device debug message format.
Definition pci.h:312
#define PCI_PRIMARY
Primary bus number.
Definition pci.h:144
#define PCI_PREFMEM_LIMIT
Definition pci.h:157
#define PCI_MEM_BASE
Memory base and limit.
Definition pci.h:153
#define __pci_driver
Declare a PCI driver.
Definition pci.h:278
#define PCI_BUS(busdevfn)
Definition pci.h:284
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:315
#define PCI_MEM_LIMIT
Definition pci.h:154
#define PCI_CLASS_BRIDGE_PCI
PCI-to-PCI bridge.
Definition pci.h:133
#define PCI_PREFMEM_BASE
Definition pci.h:156
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:366
#define PCI_PREFMEM_LIMIT_HI
Definition pci.h:159
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition pci.h:308
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:376
#define PCI_CLASS_ID(base, sub, progif)
Construct PCI class ID.
Definition pci.h:203
#define PCI_PREFMEM_BASE_HI
Definition pci.h:158
static void pcibridge_remove(struct pci_device *pci)
Remove PCI device.
Definition pcibridge.c:127
struct pci_bridge * pcibridge_find(struct pci_device *pci)
Find bridge attached to a PCI device.
Definition pcibridge.c:48
static struct pci_device_id pcibridge_ids[]
Bridge PCI device IDs.
Definition pcibridge.c:138
static int pcibridge_probe(struct pci_device *pci)
Probe PCI device.
Definition pcibridge.c:67
PCI-to-PCI bridge.
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
A PCI-to-PCI bridge.
Definition pcibridge.h:17
uint8_t primary
Primary bus.
Definition pcibridge.h:26
uint64_t prefmembase
Prefetchable memory base.
Definition pcibridge.h:38
struct list_head list
List of bridges.
Definition pcibridge.h:42
uint8_t secondary
Secondary bus.
Definition pcibridge.h:28
uint8_t subordinate
Subordinate bus.
Definition pcibridge.h:30
uint64_t prefmemlimit
Prefetchable memory limit.
Definition pcibridge.h:40
struct pci_device * pci
PCI device.
Definition pcibridge.h:19
uint32_t memlimit
Memory limit.
Definition pcibridge.h:36
uint32_t membase
Memory base.
Definition pcibridge.h:34
uint32_t buses
Raw dword.
Definition pcibridge.h:23
A PCI device ID list entry.
Definition pci.h:175
A PCI device.
Definition pci.h:211
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition pci.h:238
A PCI driver.
Definition pci.h:252