Home | History | Annotate | Download | only in AcpiPlatformDxe
      1 /** @file
      2   Entry point of OVMF ACPI Platform Driver
      3 
      4   Copyright (C) 2015, Red Hat, Inc.
      5   Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
      6 
      7   This program and the accompanying materials are licensed and made available
      8   under the terms and conditions of the BSD License which accompanies this
      9   distribution.  The full text of the license may be found at
     10   http://opensource.org/licenses/bsd-license.php
     11 
     12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
     13   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 **/
     15 
     16 #include <Protocol/PciEnumerationComplete.h>
     17 #include "AcpiPlatform.h"
     18 
     19 STATIC
     20 EFI_ACPI_TABLE_PROTOCOL *
     21 FindAcpiTableProtocol (
     22   VOID
     23   )
     24 {
     25   EFI_STATUS              Status;
     26   EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
     27 
     28   Status = gBS->LocateProtocol (
     29                   &gEfiAcpiTableProtocolGuid,
     30                   NULL,
     31                   (VOID**)&AcpiTable
     32                   );
     33   ASSERT_EFI_ERROR (Status);
     34   return AcpiTable;
     35 }
     36 
     37 
     38 STATIC
     39 VOID
     40 EFIAPI
     41 OnPciEnumerated (
     42   IN EFI_EVENT Event,
     43   IN VOID      *Context
     44   )
     45 {
     46   EFI_STATUS Status;
     47 
     48   DEBUG ((EFI_D_INFO, "%a: PCI enumeration complete, installing ACPI tables\n",
     49     __FUNCTION__));
     50   Status = InstallAcpiTables (FindAcpiTableProtocol ());
     51   if (EFI_ERROR (Status)) {
     52     DEBUG ((EFI_D_ERROR, "%a: InstallAcpiTables: %r\n", __FUNCTION__, Status));
     53   }
     54   gBS->CloseEvent (Event);
     55 }
     56 
     57 
     58 EFI_STATUS
     59 EFIAPI
     60 AcpiPlatformEntryPoint (
     61   IN EFI_HANDLE         ImageHandle,
     62   IN EFI_SYSTEM_TABLE   *SystemTable
     63   )
     64 {
     65   EFI_STATUS Status;
     66   VOID       *Interface;
     67   EFI_EVENT  PciEnumerated;
     68   VOID       *Registration;
     69 
     70   //
     71   // If the platform doesn't support PCI, or PCI enumeration has been disabled,
     72   // install the tables at once, and let the entry point's return code reflect
     73   // the full functionality.
     74   //
     75   if (PcdGetBool (PcdPciDisableBusEnumeration)) {
     76     DEBUG ((EFI_D_INFO, "%a: PCI or its enumeration disabled, installing "
     77       "ACPI tables\n", __FUNCTION__));
     78     return InstallAcpiTables (FindAcpiTableProtocol ());
     79   }
     80 
     81   //
     82   // Similarly, if PCI enumeration has already completed, install the tables
     83   // immediately.
     84   //
     85   Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,
     86                   NULL /* Registration */, &Interface);
     87   if (!EFI_ERROR (Status)) {
     88     DEBUG ((EFI_D_INFO, "%a: PCI enumeration already complete, "
     89       "installing ACPI tables\n", __FUNCTION__));
     90     return InstallAcpiTables (FindAcpiTableProtocol ());
     91   }
     92   ASSERT (Status == EFI_NOT_FOUND);
     93 
     94   //
     95   // Otherwise, delay installing the ACPI tables until PCI enumeration
     96   // completes. The entry point's return status will only reflect the callback
     97   // setup.
     98   //
     99   Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, OnPciEnumerated,
    100                   NULL /* Context */, &PciEnumerated);
    101   if (EFI_ERROR (Status)) {
    102     return Status;
    103   }
    104 
    105   Status = gBS->RegisterProtocolNotify (
    106                   &gEfiPciEnumerationCompleteProtocolGuid, PciEnumerated,
    107                   &Registration);
    108   if (EFI_ERROR (Status)) {
    109     gBS->CloseEvent (PciEnumerated);
    110   } else {
    111     DEBUG ((EFI_D_INFO, "%a: PCI enumeration pending, registered callback\n",
    112       __FUNCTION__));
    113   }
    114 
    115   return Status;
    116 }
    117