iPXE
efi_pci.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2008 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 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 );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdlib.h>
28#include <string.h>
29#include <errno.h>
30#include <ipxe/pci.h>
31#include <ipxe/acpi.h>
32#include <ipxe/efi/efi.h>
33#include <ipxe/efi/efi_pci.h>
34#include <ipxe/efi/efi_driver.h>
37
38/** @file
39 *
40 * iPXE PCI I/O API for EFI
41 *
42 */
43
44/* Disambiguate the various error causes */
45#define EINFO_EEFI_PCI \
46 __einfo_uniqify ( EINFO_EPLATFORM, 0x01, \
47 "Could not open PCI I/O protocol" )
48#define EINFO_EEFI_PCI_NOT_PCI \
49 __einfo_platformify ( EINFO_EEFI_PCI, EFI_UNSUPPORTED, \
50 "Not a PCI device" )
51#define EEFI_PCI_NOT_PCI __einfo_error ( EINFO_EEFI_PCI_NOT_PCI )
52#define EINFO_EEFI_PCI_IN_USE \
53 __einfo_platformify ( EINFO_EEFI_PCI, EFI_ACCESS_DENIED, \
54 "PCI device already has a driver" )
55#define EEFI_PCI_IN_USE __einfo_error ( EINFO_EEFI_PCI_IN_USE )
56#define EEFI_PCI( efirc ) \
57 EPLATFORM ( EINFO_EEFI_PCI, efirc, \
58 EEFI_PCI_NOT_PCI, EEFI_PCI_IN_USE )
59
60/******************************************************************************
61 *
62 * iPXE PCI API
63 *
64 ******************************************************************************
65 */
66
67/**
68 * Find closest bus:dev.fn address range within a root bridge
69 *
70 * @v pci Starting PCI device
71 * @v handle EFI PCI root bridge handle
72 * @v range PCI bus:dev.fn address range to fill in
73 * @ret rc Return status code
74 */
76 struct pci_range *range ) {
78 union {
79 union acpi_resource *res;
80 void *raw;
81 } acpi;
82 uint32_t best = 0;
86 unsigned int tag;
87 EFI_STATUS efirc;
88 int rc;
89
90 /* Return empty range on error */
91 range->start = 0;
92 range->count = 0;
93
94 /* Open root bridge I/O protocol */
96 &root ) ) != 0 ) {
97 DBGC ( pci, "EFIPCI " PCI_FMT " cannot open %s: %s\n",
98 PCI_ARGS ( pci ), efi_handle_name ( handle ),
99 strerror ( rc ) );
100 return rc;
101 }
102
103 /* Get ACPI resource descriptors */
104 if ( ( efirc = root->Configuration ( root, &acpi.raw ) ) != 0 ) {
105 rc = -EEFI ( efirc );
106 DBGC ( pci, "EFIPCI " PCI_FMT " cannot get configuration for "
107 "%s: %s\n", PCI_ARGS ( pci ),
109 return rc;
110 }
111
112 /* Parse resource descriptors */
113 for ( ; ( ( tag = acpi_resource_tag ( acpi.res ) ) !=
115 acpi.res = acpi_resource_next ( acpi.res ) ) {
116
117 /* Ignore anything other than a bus number range descriptor */
119 continue;
120 if ( acpi.res->qword.type != ACPI_ADDRESS_TYPE_BUS )
121 continue;
122
123 /* Get range for this descriptor */
124 start = PCI_BUSDEVFN ( root->SegmentNumber,
125 le64_to_cpu ( acpi.res->qword.min ),
126 0, 0 );
127 count = PCI_BUSDEVFN ( 0, le64_to_cpu ( acpi.res->qword.len ),
128 0, 0 );
129 DBGC2 ( pci, "EFIPCI " PCI_FMT " found %04x:[%02x-%02x] via "
130 "%s\n", PCI_ARGS ( pci ), root->SegmentNumber,
131 PCI_BUS ( start ), PCI_BUS ( start + count - 1 ),
133
134 /* Check for a matching or new closest range */
135 index = ( pci->busdevfn - start );
136 if ( ( index < count ) || ( index > best ) ) {
137 range->start = start;
138 range->count = count;
139 best = index;
140 }
141
142 /* Stop if this range contains the target bus:dev.fn address */
143 if ( index < count )
144 break;
145 }
146
147 /* If no range descriptors were seen, assume that the root
148 * bridge has a single bus.
149 */
150 if ( ! range->count ) {
151 range->start = PCI_BUSDEVFN ( root->SegmentNumber, 0, 0, 0 );
152 range->count = PCI_BUSDEVFN ( 0, 1, 0, 0 );
153 }
154
155 return 0;
156}
157
158/**
159 * Find closest bus:dev.fn address range within any root bridge
160 *
161 * @v pci Starting PCI device
162 * @v range PCI bus:dev.fn address range to fill in
163 * @v handle PCI root bridge I/O handle to fill in
164 * @ret rc Return status code
165 */
166static int efipci_discover_any ( struct pci_device *pci,
167 struct pci_range *range,
168 EFI_HANDLE *handle ) {
169 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
170 uint32_t best = 0;
172 struct pci_range tmp;
173 EFI_HANDLE *handles;
174 UINTN num_handles;
175 UINTN i;
176 EFI_STATUS efirc;
177 int rc;
178
179 /* Return an empty range and no handle on error */
180 range->start = 0;
181 range->count = 0;
182 *handle = NULL;
183
184 /* Enumerate all root bridge I/O protocol handles */
185 if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol,
187 NULL, &num_handles, &handles ) ) != 0 ) {
188 rc = -EEFI ( efirc );
189 DBGC ( pci, "EFIPCI " PCI_FMT " cannot locate root bridges: "
190 "%s\n", PCI_ARGS ( pci ), strerror ( rc ) );
191 goto err_locate;
192 }
193
194 /* Iterate over all root bridge I/O protocols */
195 for ( i = 0 ; i < num_handles ; i++ ) {
196
197 /* Get matching or closest range for this root bridge */
198 if ( ( rc = efipci_discover_one ( pci, handles[i],
199 &tmp ) ) != 0 )
200 continue;
201
202 /* Check for a matching or new closest range */
203 index = ( pci->busdevfn - tmp.start );
204 if ( ( index < tmp.count ) || ( index > best ) ) {
205 range->start = tmp.start;
206 range->count = tmp.count;
207 best = index;
208 }
209
210 /* Stop if this range contains the target bus:dev.fn address */
211 if ( index < tmp.count ) {
212 *handle = handles[i];
213 break;
214 }
215 }
216
217 /* Check for a range containing the target bus:dev.fn address */
218 if ( ! *handle ) {
219 rc = -ENOENT;
220 goto err_range;
221 }
222
223 /* Success */
224 rc = 0;
225
226 err_range:
227 bs->FreePool ( handles );
228 err_locate:
229 return rc;
230}
231
232/**
233 * Find next PCI bus:dev.fn address range in system
234 *
235 * @v busdevfn Starting PCI bus:dev.fn address
236 * @v range PCI bus:dev.fn address range to fill in
237 */
239 struct pci_device pci;
241
242 /* Find range */
243 memset ( &pci, 0, sizeof ( pci ) );
244 pci_init ( &pci, busdevfn );
245 efipci_discover_any ( &pci, range, &handle );
246}
247
248/**
249 * Open EFI PCI root bridge I/O protocol for ephemeral use
250 *
251 * @v pci PCI device
252 * @ret handle EFI PCI root bridge handle
253 * @ret root EFI PCI root bridge I/O protocol, or NULL if not found
254 * @ret rc Return status code
255 */
256static int efipci_root_open ( struct pci_device *pci, EFI_HANDLE *handle,
258 static struct {
259 struct pci_range range;
261 } cache;
262 int rc;
263
264 /* Find and cache matching root bridge I/O protocol handle, if any */
265 if ( ( pci->busdevfn - cache.range.start ) >= cache.range.count )
266 efipci_discover_any ( pci, &cache.range, &cache.handle );
267 if ( ! cache.handle )
268 return -ENOENT;
269 *handle = cache.handle;
270
271 /* Open PCI root bridge I/O protocol */
273 root ) ) != 0 ) {
274 DBGC ( pci, "EFIPCI " PCI_FMT " cannot open %s: %s\n",
275 PCI_ARGS ( pci ), efi_handle_name ( *handle ),
276 strerror ( rc ) );
277 return rc;
278 }
279
280 return 0;
281}
282
283/**
284 * Calculate EFI PCI configuration space address
285 *
286 * @v pci PCI device
287 * @v location Encoded offset and width
288 * @ret address EFI PCI address
289 */
290static unsigned long efipci_address ( struct pci_device *pci,
291 unsigned long location ) {
292
293 return EFI_PCI_ADDRESS ( PCI_BUS ( pci->busdevfn ),
294 PCI_SLOT ( pci->busdevfn ),
295 PCI_FUNC ( pci->busdevfn ),
296 EFIPCI_OFFSET ( location ) );
297}
298
299/**
300 * Read from PCI configuration space
301 *
302 * @v pci PCI device
303 * @v location Encoded offset and width
304 * @ret value Value
305 * @ret rc Return status code
306 */
307int efipci_read ( struct pci_device *pci, unsigned long location,
308 void *value ) {
311 EFI_STATUS efirc;
312 int rc;
313
314 /* Open root bridge */
315 if ( ( rc = efipci_root_open ( pci, &handle, &root ) ) != 0 )
316 return rc;
317
318 /* Read from configuration space */
319 if ( ( efirc = root->Pci.Read ( root, EFIPCI_WIDTH ( location ),
320 efipci_address ( pci, location ), 1,
321 value ) ) != 0 ) {
322 rc = -EEFI ( efirc );
323 DBGC ( pci, "EFIPCI " PCI_FMT " config read from offset %02lx "
324 "failed: %s\n", PCI_ARGS ( pci ),
325 EFIPCI_OFFSET ( location ), strerror ( rc ) );
326 return rc;
327 }
328
329 return 0;
330}
331
332/**
333 * Write to PCI configuration space
334 *
335 * @v pci PCI device
336 * @v location Encoded offset and width
337 * @v value Value
338 * @ret rc Return status code
339 */
340int efipci_write ( struct pci_device *pci, unsigned long location,
341 unsigned long value ) {
344 EFI_STATUS efirc;
345 int rc;
346
347 /* Open root bridge */
348 if ( ( rc = efipci_root_open ( pci, &handle, &root ) ) != 0 )
349 return rc;
350
351 /* Read from configuration space */
352 if ( ( efirc = root->Pci.Write ( root, EFIPCI_WIDTH ( location ),
353 efipci_address ( pci, location ), 1,
354 &value ) ) != 0 ) {
355 rc = -EEFI ( efirc );
356 DBGC ( pci, "EFIPCI " PCI_FMT " config write to offset %02lx "
357 "failed: %s\n", PCI_ARGS ( pci ),
358 EFIPCI_OFFSET ( location ), strerror ( rc ) );
359 return rc;
360 }
361
362 return 0;
363}
364
365/**
366 * Map PCI bus address as an I/O address
367 *
368 * @v bus_addr PCI bus address
369 * @v len Length of region
370 * @ret io_addr I/O address, or NULL on error
371 */
372void * efipci_ioremap ( struct pci_device *pci, unsigned long bus_addr,
373 size_t len ) {
374 union {
375 union acpi_resource *res;
376 void *raw;
377 } u;
380 unsigned int tag;
384 EFI_STATUS efirc;
385 int rc;
386
387 /* Open root bridge */
388 if ( ( rc = efipci_root_open ( pci, &handle, &root ) ) != 0 )
389 goto err_root;
390
391 /* Get ACPI resource descriptors */
392 if ( ( efirc = root->Configuration ( root, &u.raw ) ) != 0 ) {
393 rc = -EEFI ( efirc );
394 DBGC ( pci, "EFIPCI " PCI_FMT " cannot get configuration: "
395 "%s\n", PCI_ARGS ( pci ), strerror ( rc ) );
396 goto err_config;
397 }
398
399 /* Parse resource descriptors */
400 for ( ; ( ( tag = acpi_resource_tag ( u.res ) ) != ACPI_END_RESOURCE ) ;
401 u.res = acpi_resource_next ( u.res ) ) {
402
403 /* Ignore anything other than a memory range descriptor */
405 continue;
406 if ( u.res->qword.type != ACPI_ADDRESS_TYPE_MEM )
407 continue;
408
409 /* Ignore descriptors that do not cover this memory range */
410 offset = le64_to_cpu ( u.res->qword.offset );
411 start = ( offset + le64_to_cpu ( u.res->qword.min ) );
412 end = ( start + le64_to_cpu ( u.res->qword.len ) );
413 DBGC2 ( pci, "EFIPCI " PCI_FMT " found range [%08llx,%08llx) "
414 "-> [%08llx,%08llx)\n", PCI_ARGS ( pci ), start, end,
415 ( start - offset ), ( end - offset ) );
416 if ( ( bus_addr < start ) || ( ( bus_addr + len ) > end ) )
417 continue;
418
419 /* Use this address space descriptor */
420 DBGC2 ( pci, "EFIPCI " PCI_FMT " %08lx+%zx -> ",
421 PCI_ARGS ( pci ), bus_addr, len );
422 bus_addr -= offset;
423 DBGC2 ( pci, "%08lx\n", bus_addr );
424 break;
425 }
426 if ( tag == ACPI_END_RESOURCE ) {
427 DBGC ( pci, "EFIPCI " PCI_FMT " %08lx+%zx is not within "
428 "root bridge address space\n",
429 PCI_ARGS ( pci ), bus_addr, len );
430 }
431
432 err_config:
433 err_root:
434 return ioremap ( bus_addr, len );
435}
436
447
448/******************************************************************************
449 *
450 * EFI PCI DMA mappings
451 *
452 ******************************************************************************
453 */
454
455/**
456 * Map buffer for DMA
457 *
458 * @v dma DMA device
459 * @v map DMA mapping to fill in
460 * @v addr Buffer address
461 * @v len Length of buffer
462 * @v flags Mapping flags
463 * @ret rc Return status code
464 */
465static int efipci_dma_map ( struct dma_device *dma, struct dma_mapping *map,
466 void *addr, size_t len, int flags ) {
467 struct efi_pci_device *efipci =
469 struct pci_device *pci = &efipci->pci;
470 EFI_PCI_IO_PROTOCOL *pci_io = efipci->io;
473 UINTN count;
474 VOID *mapping;
476 EFI_STATUS efirc;
477 int rc;
478
479 /* Sanity check */
480 assert ( map->dma == NULL );
481 assert ( map->offset == 0 );
482 assert ( map->token == NULL );
483
484 /* Determine operation */
485 switch ( flags ) {
486 case DMA_TX:
488 break;
489 case DMA_RX:
491 break;
492 default:
494 break;
495 }
496
497 /* Map buffer (if non-zero length) */
498 phys = virt_to_phys ( addr );
499 count = len;
500 if ( len ) {
501 if ( ( efirc = pci_io->Map ( pci_io, op, addr, &count, &bus,
502 &mapping ) ) != 0 ) {
503 rc = -EEFI ( efirc );
504 DBGC ( pci, "EFIPCI " PCI_FMT " cannot map %p+%zx: "
505 "%s\n", PCI_ARGS ( pci ), addr, len,
506 strerror ( rc ) );
507 goto err_map;
508 }
509 } else {
510 bus = phys;
511 mapping = NULL;
512 }
513
514 /* Check that full length was mapped. The UEFI specification
515 * allows for multiple mappings to be required, but even the
516 * EDK2 PCI device drivers will fail if a platform ever
517 * requires this.
518 */
519 if ( count != len ) {
520 DBGC ( pci, "EFIPCI " PCI_FMT " attempted split mapping for "
521 "%p+%zx\n", PCI_ARGS ( pci ), addr, len );
522 rc = -ENOTSUP;
523 goto err_len;
524 }
525
526 /* Populate mapping */
527 map->dma = dma;
528 map->offset = ( bus - phys );
529 map->token = mapping;
530
531 /* Increment mapping count (for debugging) */
532 if ( DBG_LOG )
533 dma->mapped++;
534
535 return 0;
536
537 err_len:
538 pci_io->Unmap ( pci_io, mapping );
539 err_map:
540 return rc;
541}
542
543/**
544 * Unmap buffer
545 *
546 * @v dma DMA device
547 * @v map DMA mapping
548 * @v len Used length
549 */
550static void efipci_dma_unmap ( struct dma_device *dma,
551 struct dma_mapping *map, size_t len __unused ) {
552 struct efi_pci_device *efipci =
554 EFI_PCI_IO_PROTOCOL *pci_io = efipci->io;
555
556 /* Unmap buffer (if non-zero length) */
557 if ( map->token )
558 pci_io->Unmap ( pci_io, map->token );
559
560 /* Clear mapping */
561 map->dma = NULL;
562 map->offset = 0;
563 map->token = NULL;
564
565 /* Decrement mapping count (for debugging) */
566 if ( DBG_LOG )
567 dma->mapped--;
568}
569
570/**
571 * Allocate and map DMA-coherent buffer
572 *
573 * @v dma DMA device
574 * @v map DMA mapping to fill in
575 * @v len Length of buffer
576 * @v align Physical alignment
577 * @ret addr Buffer address, or NULL on error
578 */
579static void * efipci_dma_alloc ( struct dma_device *dma,
580 struct dma_mapping *map,
581 size_t len, size_t align __unused ) {
582 struct efi_pci_device *efipci =
584 struct pci_device *pci = &efipci->pci;
585 EFI_PCI_IO_PROTOCOL *pci_io = efipci->io;
586 unsigned int pages;
587 VOID *addr;
588 EFI_STATUS efirc;
589 int rc;
590
591 /* Calculate number of pages */
592 pages = ( ( len + EFI_PAGE_SIZE - 1 ) / EFI_PAGE_SIZE );
593
594 /* Allocate (page-aligned) buffer */
595 if ( ( efirc = pci_io->AllocateBuffer ( pci_io, AllocateAnyPages,
596 EfiBootServicesData, pages,
597 &addr, 0 ) ) != 0 ) {
598 rc = -EEFI ( efirc );
599 DBGC ( pci, "EFIPCI " PCI_FMT " could not allocate %zd bytes: "
600 "%s\n", PCI_ARGS ( pci ), len, strerror ( rc ) );
601 goto err_alloc;
602 }
603
604 /* Clear buffer */
605 memset ( addr, 0, ( pages * EFI_PAGE_SIZE ) );
606
607 /* Map buffer */
608 if ( ( rc = efipci_dma_map ( dma, map, addr, ( pages * EFI_PAGE_SIZE ),
609 DMA_BI ) ) != 0 )
610 goto err_map;
611
612 /* Increment allocation count (for debugging) */
613 if ( DBG_LOG )
614 dma->allocated++;
615
616 return addr;
617
619 err_map:
620 pci_io->FreeBuffer ( pci_io, pages, addr );
621 err_alloc:
622 return NULL;
623}
624
625/**
626 * Unmap and free DMA-coherent buffer
627 *
628 * @v dma DMA device
629 * @v map DMA mapping
630 * @v addr Buffer address
631 * @v len Length of buffer
632 */
633static void efipci_dma_free ( struct dma_device *dma, struct dma_mapping *map,
634 void *addr, size_t len ) {
635 struct efi_pci_device *efipci =
637 EFI_PCI_IO_PROTOCOL *pci_io = efipci->io;
638 unsigned int pages;
639
640 /* Calculate number of pages */
641 pages = ( ( len + EFI_PAGE_SIZE - 1 ) / EFI_PAGE_SIZE );
642
643 /* Unmap buffer */
645
646 /* Free buffer */
647 pci_io->FreeBuffer ( pci_io, pages, addr );
648
649 /* Decrement allocation count (for debugging) */
650 if ( DBG_LOG )
651 dma->allocated--;
652}
653
654/**
655 * Set addressable space mask
656 *
657 * @v dma DMA device
658 * @v mask Addressable space mask
659 */
660static void efipci_dma_set_mask ( struct dma_device *dma, physaddr_t mask ) {
661 struct efi_pci_device *efipci =
663 struct pci_device *pci = &efipci->pci;
664 EFI_PCI_IO_PROTOCOL *pci_io = efipci->io;
666 UINT64 attrs;
667 int is64;
668 EFI_STATUS efirc;
669 int rc;
670
671 /* Set dual address cycle attribute for 64-bit capable devices */
672 is64 = ( ( ( ( uint64_t ) mask ) + 1 ) == 0 );
676 if ( ( efirc = pci_io->Attributes ( pci_io, op, attrs, NULL ) ) != 0 ) {
677 rc = -EEFI ( efirc );
678 DBGC ( pci, "EFIPCI " PCI_FMT " could not %sable DAC: %s\n",
679 PCI_ARGS ( pci ), ( is64 ? "en" : "dis" ),
680 strerror ( rc ) );
681 /* Ignore failure: errors will manifest in mapping attempts */
682 return;
683 }
684}
685
686/** EFI PCI DMA operations */
688 .map = efipci_dma_map,
689 .unmap = efipci_dma_unmap,
690 .alloc = efipci_dma_alloc,
691 .free = efipci_dma_free,
692 .umalloc = efipci_dma_alloc,
693 .ufree = efipci_dma_free,
694 .set_mask = efipci_dma_set_mask,
695};
696
697/******************************************************************************
698 *
699 * EFI PCI device instantiation
700 *
701 ******************************************************************************
702 */
703
704/**
705 * Get EFI PCI device information
706 *
707 * @v device EFI device handle
708 * @v efipci EFI PCI device to fill in
709 * @ret rc Return status code
710 */
712 EFI_PCI_IO_PROTOCOL *pci_io;
713 UINTN pci_segment, pci_bus, pci_dev, pci_fn;
714 unsigned int busdevfn;
715 EFI_STATUS efirc;
716 int rc;
717
718 /* See if device is a PCI device */
720 &pci_io ) ) != 0 ) {
721 DBGCP ( device, "EFIPCI %s cannot open PCI protocols: %s\n",
723 return rc;
724 }
725 efipci->io = pci_io;
726
727 /* Get PCI bus:dev.fn address */
728 if ( ( efirc = pci_io->GetLocation ( pci_io, &pci_segment, &pci_bus,
729 &pci_dev, &pci_fn ) ) != 0 ) {
730 rc = -EEFI ( efirc );
731 DBGC ( device, "EFIPCI %s could not get PCI location: %s\n",
733 return rc;
734 }
735 busdevfn = PCI_BUSDEVFN ( pci_segment, pci_bus, pci_dev, pci_fn );
736 pci_init ( &efipci->pci, busdevfn );
737 dma_init ( &efipci->pci.dma, &efipci_dma_operations );
738 DBGCP ( device, "EFIPCI " PCI_FMT " is %s\n",
739 PCI_ARGS ( &efipci->pci ), efi_handle_name ( device ) );
740
741 /* Try to enable I/O cycles, memory cycles, and bus mastering.
742 * Some platforms will 'helpfully' report errors if these bits
743 * can't be enabled (for example, if the card doesn't actually
744 * support I/O cycles). Work around any such platforms by
745 * enabling bits individually and simply ignoring any errors.
746 */
753
754 /* Populate PCI device */
755 if ( ( rc = pci_read_config ( &efipci->pci ) ) != 0 ) {
756 DBGC ( device, "EFIPCI " PCI_FMT " cannot read PCI "
757 "configuration: %s\n",
758 PCI_ARGS ( &efipci->pci ), strerror ( rc ) );
759 return rc;
760 }
761
762 return 0;
763}
764
765/******************************************************************************
766 *
767 * EFI PCI driver
768 *
769 ******************************************************************************
770 */
771
772/**
773 * Check to see if driver supports a device
774 *
775 * @v device EFI device handle
776 * @ret rc Return status code
777 */
779 struct efi_pci_device efipci;
780 uint8_t hdrtype;
781 int rc;
782
783 /* Get PCI device information */
784 if ( ( rc = efipci_info ( device, &efipci ) ) != 0 )
785 return rc;
786
787 /* Do not attempt to drive bridges */
788 hdrtype = efipci.pci.hdrtype;
789 if ( ( hdrtype & PCI_HEADER_TYPE_MASK ) != PCI_HEADER_TYPE_NORMAL ) {
790 DBGC ( device, "EFIPCI " PCI_FMT " type %02x is not type %02x\n",
791 PCI_ARGS ( &efipci.pci ), hdrtype,
793 return -ENOTTY;
794 }
795
796 /* Look for a driver */
797 if ( ( rc = pci_find_driver ( &efipci.pci ) ) != 0 ) {
798 DBGC ( device, "EFIPCI " PCI_FMT " (%04x:%04x class %06x) "
799 "has no driver\n", PCI_ARGS ( &efipci.pci ),
800 efipci.pci.vendor, efipci.pci.device,
801 efipci.pci.class );
802 return rc;
803 }
804 DBGC ( device, "EFIPCI " PCI_FMT " (%04x:%04x class %06x) has driver "
805 "\"%s\"\n", PCI_ARGS ( &efipci.pci ), efipci.pci.vendor,
806 efipci.pci.device, efipci.pci.class, efipci.pci.id->name );
807
808 return 0;
809}
810
811/**
812 * Exclude existing drivers
813 *
814 * @v device EFI device handle
815 * @ret rc Return status code
816 */
819 int rc;
820
821 /* Exclude existing PCI I/O protocol drivers */
822 if ( ( rc = efi_driver_exclude ( device, protocol ) ) != 0 ) {
823 DBGC ( device, "EFIPCI %s could not exclude drivers: %s\n",
825 return rc;
826 }
827
828 return 0;
829}
830
831/**
832 * Attach driver to device
833 *
834 * @v efidev EFI device
835 * @ret rc Return status code
836 */
837static int efipci_start ( struct efi_device *efidev ) {
838 EFI_HANDLE device = efidev->device;
839 struct efi_pci_device *efipci;
840 int rc;
841
842 /* Allocate PCI device */
843 efipci = zalloc ( sizeof ( *efipci ) );
844 if ( ! efipci ) {
845 rc = -ENOMEM;
846 goto err_alloc;
847 }
848
849 /* Get PCI device information */
850 if ( ( rc = efipci_info ( device, efipci ) ) != 0 )
851 goto err_info;
852
853 /* Open PCI I/O protocol */
855 &efipci->io ) ) != 0 ) {
856 DBGC ( device, "EFIPCI %s could not open PCI device: %s\n",
859 goto err_open;
860 }
861
862 /* Find driver */
863 if ( ( rc = pci_find_driver ( &efipci->pci ) ) != 0 ) {
864 DBGC ( device, "EFIPCI " PCI_FMT " has no driver\n",
865 PCI_ARGS ( &efipci->pci ) );
866 goto err_find_driver;
867 }
868
869 /* Mark PCI device as a child of the EFI device */
870 efipci->pci.dev.parent = &efidev->dev;
871 list_add ( &efipci->pci.dev.siblings, &efidev->dev.children );
872
873 /* Probe driver */
874 if ( ( rc = pci_probe ( &efipci->pci ) ) != 0 ) {
875 DBGC ( device, "EFIPCI " PCI_FMT " could not probe driver "
876 "\"%s\": %s\n", PCI_ARGS ( &efipci->pci ),
877 efipci->pci.id->name, strerror ( rc ) );
878 goto err_probe;
879 }
880 DBGC ( device, "EFIPCI " PCI_FMT " using driver \"%s\"\n",
881 PCI_ARGS ( &efipci->pci ), efipci->pci.id->name );
882
883 efidev_set_drvdata ( efidev, efipci );
884 return 0;
885
886 pci_remove ( &efipci->pci );
887 err_probe:
888 list_del ( &efipci->pci.dev.siblings );
889 err_find_driver:
891 err_open:
892 err_info:
893 free ( efipci );
894 err_alloc:
895 return rc;
896}
897
898/**
899 * Detach driver from device
900 *
901 * @v efidev EFI device
902 */
903static void efipci_stop ( struct efi_device *efidev ) {
904 struct efi_pci_device *efipci = efidev_get_drvdata ( efidev );
905 EFI_HANDLE device = efidev->device;
906
907 pci_remove ( &efipci->pci );
908 list_del ( &efipci->pci.dev.siblings );
909 assert ( efipci->pci.dma.mapped == 0 );
910 assert ( efipci->pci.dma.allocated == 0 );
912 free ( efipci );
913}
914
915/** EFI PCI driver */
916struct efi_driver efipci_driver __efi_driver ( EFI_DRIVER_HARDWARE ) = {
917 .name = "PCI",
918 .supported = efipci_supported,
919 .exclude = efipci_exclude,
920 .start = efipci_start,
921 .stop = efipci_stop,
922};
UINT64 UINTN
Unsigned value of native width.
unsigned long long UINT64
8-byte unsigned value.
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define VOID
Undeclared type.
Definition Base.h:272
__be32 raw[7]
Definition CIB_PRM.h:0
EFI PCI I/O Protocol provides the basic Memory, I/O, PCI configuration, and DMA interfaces that a dri...
#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
Clear for PCI controllers that can not genrate a DAC.
Definition PciIo.h:67
EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION
Definition PciIo.h:102
@ EfiPciIoAttributeOperationDisable
Disable the attributes specified by the bits that are set in Attributes for this PCI controller.
Definition PciIo.h:118
@ EfiPciIoAttributeOperationEnable
Enable the attributes specified by the bits that are set in Attributes for this PCI controller.
Definition PciIo.h:114
#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
Enable the DMA bit in the PCI Config Header.
Definition PciIo.h:62
EFI_PCI_IO_PROTOCOL_OPERATION
Definition PciIo.h:80
@ EfiPciIoOperationBusMasterWrite
A write operation from system memory by a bus master.
Definition PciIo.h:88
@ EfiPciIoOperationBusMasterRead
A read operation from system memory by a bus master.
Definition PciIo.h:84
@ EfiPciIoOperationBusMasterCommonBuffer
Provides both read and write access to system memory by both the processor and a bus master.
Definition PciIo.h:93
#define EFI_PCI_IO_ATTRIBUTE_MEMORY
Enable the Memory decode bit in the PCI Config Header.
Definition PciIo.h:61
struct _EFI_PCI_IO_PROTOCOL EFI_PCI_IO_PROTOCOL
Definition PciIo.h:24
#define EFI_PCI_IO_ATTRIBUTE_IO
Enable the I/O decode bit in the PCI Config Header.
Definition PciIo.h:60
PCI Root Bridge I/O protocol as defined in the UEFI 2.0 specification.
struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
#define EFI_PCI_ADDRESS(bus, dev, func, reg)
#define EFI_PAGE_SIZE
UINT64 EFI_PHYSICAL_ADDRESS
64-bit physical memory address.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
GUID EFI_GUID
128-bit buffer containing a unique identifier value.
@ EfiBootServicesData
The data portions of a loaded Boot Serves Driver, and the default data allocation type used by a Boot...
@ ByProtocol
Retrieve the set of handles from the handle database that support a specified protocol.
Definition UefiSpec.h:1531
@ AllocateAnyPages
Allocate any available range of pages that satisfies the request.
Definition UefiSpec.h:36
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
pseudo_bit_t value[0x00020]
Definition arbel.h:2
unsigned int uint32_t
Definition stdint.h:12
unsigned long physaddr_t
Definition stdint.h:20
unsigned long long uint64_t
Definition stdint.h:13
unsigned char uint8_t
Definition stdint.h:10
long index
Definition bigint.h:65
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint16_t offset
Offset to command line.
Definition bzimage.h:3
union @104331263140136355135267063077374276003064103115 u
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint64_t tag
Identity tag.
Definition edd.h:1
uint8_t bus
Bus.
Definition edd.h:1
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition efi_block.c:67
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
int efi_driver_exclude(EFI_HANDLE device, EFI_GUID *protocol)
Try to disconnect an existing EFI driver.
Definition efi_driver.c:438
EFI driver interface.
#define EFI_DRIVER_HARDWARE
Hardware drivers.
Definition efi_driver.h:73
#define __efi_driver(order)
Declare an EFI driver.
Definition efi_driver.h:70
static void * efidev_get_drvdata(struct efi_device *efidev)
Get EFI driver-private data.
Definition efi_driver.h:98
static void efidev_set_drvdata(struct efi_device *efidev, void *priv)
Set EFI driver-private data.
Definition efi_driver.h:87
EFI_GUID efi_pci_root_bridge_io_protocol_guid
PCI root bridge I/O protocol GUID.
Definition efi_guid.c:317
EFI_GUID efi_pci_io_protocol_guid
PCI I/O protocol GUID.
Definition efi_guid.c:313
void efi_close_by_driver(EFI_HANDLE handle, EFI_GUID *protocol)
Close protocol opened for persistent use by a driver.
Definition efi_open.c:279
static int efipci_start(struct efi_device *efidev)
Attach driver to device.
Definition efi_pci.c:837
static void efipci_dma_free(struct dma_device *dma, struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
Definition efi_pci.c:633
int efipci_read(struct pci_device *pci, unsigned long location, void *value)
Read from PCI configuration space.
Definition efi_pci.c:307
static void efipci_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
Definition efi_pci.c:238
static int efipci_discover_any(struct pci_device *pci, struct pci_range *range, EFI_HANDLE *handle)
Find closest bus:dev.fn address range within any root bridge.
Definition efi_pci.c:166
static int efipci_supported(EFI_HANDLE device)
Check to see if driver supports a device.
Definition efi_pci.c:778
static void efipci_dma_set_mask(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
Definition efi_pci.c:660
int efipci_info(EFI_HANDLE device, struct efi_pci_device *efipci)
Get EFI PCI device information.
Definition efi_pci.c:711
void * efipci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
Definition efi_pci.c:372
int efipci_write(struct pci_device *pci, unsigned long location, unsigned long value)
Write to PCI configuration space.
Definition efi_pci.c:340
static int efipci_discover_one(struct pci_device *pci, EFI_HANDLE handle, struct pci_range *range)
Find closest bus:dev.fn address range within a root bridge.
Definition efi_pci.c:75
static int efipci_exclude(EFI_HANDLE device)
Exclude existing drivers.
Definition efi_pci.c:817
static unsigned long efipci_address(struct pci_device *pci, unsigned long location)
Calculate EFI PCI configuration space address.
Definition efi_pci.c:290
static void * efipci_dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align __unused)
Allocate and map DMA-coherent buffer.
Definition efi_pci.c:579
static int efipci_dma_map(struct dma_device *dma, struct dma_mapping *map, void *addr, size_t len, int flags)
Map buffer for DMA.
Definition efi_pci.c:465
static void efipci_stop(struct efi_device *efidev)
Detach driver from device.
Definition efi_pci.c:903
static int efipci_root_open(struct pci_device *pci, EFI_HANDLE *handle, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **root)
Open EFI PCI root bridge I/O protocol for ephemeral use.
Definition efi_pci.c:256
static void efipci_dma_unmap(struct dma_device *dma, struct dma_mapping *map, size_t len __unused)
Unmap buffer.
Definition efi_pci.c:550
static struct dma_operations efipci_dma_operations
EFI PCI DMA operations.
Definition efi_pci.c:687
EFI driver interface.
#define EFIPCI_OFFSET(_location)
Definition efi_pci_api.h:26
#define EFIPCI_WIDTH(_location)
Definition efi_pci_api.h:27
uint8_t flags
Flags.
Definition ena.h:7
uint16_t busdevfn
PCI bus:dev.fn address.
Definition ena.h:17
static signed char phys[4]
Definition epic100.c:88
Error codes.
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:573
#define DBGC2(...)
Definition compiler.h:522
#define DBGCP(...)
Definition compiler.h:539
#define DBGC(...)
Definition compiler.h:505
#define DBG_LOG
Definition compiler.h:317
uint32_t start
Starting offset.
Definition netvsc.h:1
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define le64_to_cpu(value)
Definition byteswap.h:115
ACPI data structures.
#define ACPI_END_RESOURCE
An ACPI end resource descriptor.
Definition acpi.h:55
#define ACPI_ADDRESS_TYPE_MEM
A memory address space type.
Definition acpi.h:37
static unsigned int acpi_resource_tag(union acpi_resource *res)
Get ACPI resource tag.
Definition acpi.h:121
#define ACPI_ADDRESS_TYPE_BUS
A bus number address space type.
Definition acpi.h:43
#define ACPI_QWORD_ADDRESS_SPACE_RESOURCE
An ACPI QWORD address space resource descriptor.
Definition acpi.h:77
static union acpi_resource * acpi_resource_next(union acpi_resource *res)
Get next ACPI resource descriptor.
Definition acpi.h:169
EFI API.
#define efi_open_by_driver(handle, protocol, interface)
Open protocol for persistent use by a driver.
Definition efi.h:474
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
#define EFI_HANDLE
Definition efi.h:53
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
#define DBGC_EFI_OPENERS(...)
Definition efi.h:345
EFI_SYSTEM_TABLE * efi_systab
void * ioremap(unsigned long bus_addr, size_t len)
Map bus address as an I/O address.
#define PCIAPI_PRIORITY_EFI
EFI PCI I/O protocols.
Definition pci_io.h:196
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_can_probe(struct pci_device *pci)
Check if PCI bus probing is allowed.
void pci_discover(uint32_t busdevfn, struct pci_range *range)
Find next PCI bus:dev.fn address range in system.
int pci_read_config_word(struct pci_device *pci, unsigned int where, uint16_t *value)
Read 16-bit word from PCI configuration space.
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
#define PCI_BUSDEVFN(segment, bus, slot, func)
Definition pci_io.h:30
#define PROVIDE_PCIAPI_RUNTIME(subsys, priority)
Provide a runtime selectable PCI I/O API.
Definition pci_io.h:202
int pci_write_config_byte(struct pci_device *pci, unsigned int where, uint8_t value)
Write byte to PCI configuration space.
int pci_write_config_word(struct pci_device *pci, unsigned int where, uint16_t value)
Write 16-bit word to PCI configuration space.
int pci_read_config_byte(struct pci_device *pci, unsigned int where, uint8_t *value)
Read byte from PCI configuration space.
#define PROVIDE_PCIAPI(_subsys, _api_func, _func)
Provide a PCI I/O API implementation.
Definition pci_io.h:51
int pci_write_config_dword(struct pci_device *pci, unsigned int where, uint32_t value)
Write 32-bit dword to PCI configuration space.
#define PROVIDE_PCIAPI_INLINE(_subsys, _api_func)
Provide a static inline PCI I/O API implementation.
Definition pci_io.h:60
uint16_t handle
Handle.
Definition smbios.h:5
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
static __always_inline void dma_init(struct dma_device *dma, struct dma_operations *op)
Initialise DMA device.
Definition dma.h:454
#define DMA_TX
Device will read data from host memory.
Definition dma.h:135
#define DMA_BI
Device will both read data from and write data to host memory.
Definition dma.h:141
#define DMA_RX
Device will write data to host memory.
Definition dma.h:138
static __always_inline int struct dma_mapping * map
Definition dma.h:184
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
unsigned long tmp
Definition linux_pci.h:65
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#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
uint32_t end
Ending offset.
Definition netvsc.h:7
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
int pci_find_driver(struct pci_device *pci)
Find driver for PCI device.
Definition pci.c:386
int pci_probe(struct pci_device *pci)
Probe a PCI device.
Definition pci.c:418
int pci_read_config(struct pci_device *pci)
Read PCI device configuration.
Definition pci.c:269
void pci_remove(struct pci_device *pci)
Remove a PCI device.
Definition pci.c:440
PCI bus.
#define PCI_FMT
PCI device debug message format.
Definition pci.h:312
#define PCI_FUNC(busdevfn)
Definition pci.h:286
#define PCI_BUS(busdevfn)
Definition pci.h:284
#define PCI_ARGS(pci)
PCI device debug message arguments.
Definition pci.h:315
static void pci_init(struct pci_device *pci, unsigned int busdevfn)
Initialise PCI device.
Definition pci.h:341
#define PCI_HEADER_TYPE_MASK
Header type mask.
Definition pci.h:58
#define PCI_HEADER_TYPE_NORMAL
Normal header.
Definition pci.h:55
#define PCI_SLOT(busdevfn)
Definition pci.h:285
static __always_inline void unsigned long bus_addr
Definition pcibios.h:156
struct pci_range range
PCI bus:dev.fn address range.
Definition pcicloud.c:40
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
struct stp_switch root
Root switch.
Definition stp.h:15
uint16_t protocol
Protocol ID.
Definition stp.h:7
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_FREE_POOL FreePool
Definition UefiSpec.h:1950
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition UefiSpec.h:2008
EFI_PCI_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer
Definition PciIo.h:528
EFI_PCI_IO_PROTOCOL_UNMAP Unmap
Definition PciIo.h:527
EFI_PCI_IO_PROTOCOL_ATTRIBUTES Attributes
Definition PciIo.h:532
EFI_PCI_IO_PROTOCOL_GET_LOCATION GetLocation
Definition PciIo.h:531
EFI_PCI_IO_PROTOCOL_FREE_BUFFER FreeBuffer
Definition PciIo.h:529
EFI_PCI_IO_PROTOCOL_MAP Map
Definition PciIo.h:526
A hardware device.
Definition device.h:77
struct device * parent
Bus device.
Definition device.h:89
struct list_head children
Devices attached to this device.
Definition device.h:87
struct list_head siblings
Devices on the same bus.
Definition device.h:85
A DMA-capable device.
Definition dma.h:48
unsigned int mapped
Total number of mappings (for debugging)
Definition dma.h:54
unsigned int allocated
Total number of allocations (for debugging)
Definition dma.h:56
A DMA mapping.
Definition dma.h:33
DMA operations.
Definition dma.h:60
An EFI device.
Definition efi_driver.h:18
EFI_HANDLE device
EFI device handle.
Definition efi_driver.h:22
struct device dev
Generic device.
Definition efi_driver.h:20
An EFI driver.
Definition efi_driver.h:34
An EFI PCI device.
Definition efi_pci.h:22
EFI_PCI_IO_PROTOCOL * io
PCI I/O protocol.
Definition efi_pci.h:26
struct pci_device pci
PCI device.
Definition efi_pci.h:24
const char * name
Name.
Definition pci.h:177
A PCI device.
Definition pci.h:211
uint32_t busdevfn
Segment, bus, device, and function (bus:dev.fn) number.
Definition pci.h:238
uint32_t class
Device class.
Definition pci.h:232
uint8_t hdrtype
Header type.
Definition pci.h:236
struct device dev
Generic device.
Definition pci.h:213
struct pci_device_id * id
Driver device ID.
Definition pci.h:248
uint16_t vendor
Vendor ID.
Definition pci.h:228
uint16_t device
Device ID.
Definition pci.h:230
struct dma_device dma
DMA device.
Definition pci.h:215
A PCI bus:dev.fn address range.
Definition pci_io.h:23
An ACPI resource descriptor.
Definition acpi.h:102