123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /** @file
- Temporarily enable IO and MMIO decoding for all PCI devices while QEMU
- regenerates the ACPI tables.
- Copyright (C) 2016, Red Hat, Inc.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/MemoryAllocationLib.h>
- #include "AcpiPlatform.h"
- /**
- Collect all PciIo protocol instances in the system. Save their original
- attributes, and enable IO and MMIO decoding for each.
- This is a best effort function; it doesn't return status codes. Its
- caller is supposed to proceed even if this function fails.
- @param[out] OriginalAttributes On output, a dynamically allocated array of
- ORIGINAL_ATTRIBUTES elements. The array lists
- the PciIo protocol instances found in the
- system at the time of the call, plus the
- original PCI attributes for each.
- Before returning, the function enables IO and
- MMIO decoding for each PciIo instance it
- finds.
- On error, or when no such instances are
- found, OriginalAttributes is set to NULL.
- @param[out] Count On output, the number of elements in
- OriginalAttributes. On error it is set to
- zero.
- **/
- VOID
- EnablePciDecoding (
- OUT ORIGINAL_ATTRIBUTES **OriginalAttributes,
- OUT UINTN *Count
- )
- {
- EFI_STATUS Status;
- UINTN NoHandles;
- EFI_HANDLE *Handles;
- ORIGINAL_ATTRIBUTES *OrigAttrs;
- UINTN Idx;
- *OriginalAttributes = NULL;
- *Count = 0;
- if (PcdGetBool (PcdPciDisableBusEnumeration)) {
- //
- // The platform downloads ACPI tables from QEMU in general, but there are
- // no root bridges in this execution. We're done.
- //
- return;
- }
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiPciIoProtocolGuid,
- NULL /* SearchKey */,
- &NoHandles,
- &Handles
- );
- if (Status == EFI_NOT_FOUND) {
- //
- // No PCI devices were found on either of the root bridges. We're done.
- //
- return;
- }
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_WARN,
- "%a: LocateHandleBuffer(): %r\n",
- __FUNCTION__,
- Status
- ));
- return;
- }
- OrigAttrs = AllocatePool (NoHandles * sizeof *OrigAttrs);
- if (OrigAttrs == NULL) {
- DEBUG ((
- DEBUG_WARN,
- "%a: AllocatePool(): out of resources\n",
- __FUNCTION__
- ));
- goto FreeHandles;
- }
- for (Idx = 0; Idx < NoHandles; ++Idx) {
- EFI_PCI_IO_PROTOCOL *PciIo;
- UINT64 Attributes;
- //
- // Look up PciIo on the handle and stash it
- //
- Status = gBS->HandleProtocol (
- Handles[Idx],
- &gEfiPciIoProtocolGuid,
- (VOID **)&PciIo
- );
- ASSERT_EFI_ERROR (Status);
- OrigAttrs[Idx].PciIo = PciIo;
- //
- // Stash the current attributes
- //
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationGet,
- 0,
- &OrigAttrs[Idx].PciAttributes
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_WARN,
- "%a: EfiPciIoAttributeOperationGet: %r\n",
- __FUNCTION__,
- Status
- ));
- goto RestoreAttributes;
- }
- //
- // Retrieve supported attributes
- //
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationSupported,
- 0,
- &Attributes
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_WARN,
- "%a: EfiPciIoAttributeOperationSupported: %r\n",
- __FUNCTION__,
- Status
- ));
- goto RestoreAttributes;
- }
- //
- // Enable IO and MMIO decoding
- //
- Attributes &= EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY;
- Status = PciIo->Attributes (
- PciIo,
- EfiPciIoAttributeOperationEnable,
- Attributes,
- NULL
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((
- DEBUG_WARN,
- "%a: EfiPciIoAttributeOperationEnable: %r\n",
- __FUNCTION__,
- Status
- ));
- goto RestoreAttributes;
- }
- }
- //
- // Success
- //
- FreePool (Handles);
- *OriginalAttributes = OrigAttrs;
- *Count = NoHandles;
- return;
- RestoreAttributes:
- while (Idx > 0) {
- --Idx;
- OrigAttrs[Idx].PciIo->Attributes (
- OrigAttrs[Idx].PciIo,
- EfiPciIoAttributeOperationSet,
- OrigAttrs[Idx].PciAttributes,
- NULL
- );
- }
- FreePool (OrigAttrs);
- FreeHandles:
- FreePool (Handles);
- }
- /**
- Restore the original PCI attributes saved with EnablePciDecoding().
- @param[in] OriginalAttributes The array allocated and populated by
- EnablePciDecoding(). This parameter may be
- NULL. If OriginalAttributes is NULL, then the
- function is a no-op; otherwise the PciIo
- attributes will be restored, and the
- OriginalAttributes array will be freed.
- @param[in] Count The Count value stored by EnablePciDecoding(),
- the number of elements in OriginalAttributes.
- Count may be zero if and only if
- OriginalAttributes is NULL.
- **/
- VOID
- RestorePciDecoding (
- IN ORIGINAL_ATTRIBUTES *OriginalAttributes,
- IN UINTN Count
- )
- {
- UINTN Idx;
- ASSERT ((OriginalAttributes == NULL) == (Count == 0));
- if (OriginalAttributes == NULL) {
- return;
- }
- for (Idx = 0; Idx < Count; ++Idx) {
- OriginalAttributes[Idx].PciIo->Attributes (
- OriginalAttributes[Idx].PciIo,
- EfiPciIoAttributeOperationSet,
- OriginalAttributes[Idx].PciAttributes,
- NULL
- );
- }
- FreePool (OriginalAttributes);
- }
|