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 <Guid/RootBridgesConnectedEventGroup.h>
17 #include "AcpiPlatform.h"
18 
19 STATIC
20 EFI_ACPI_TABLE_PROTOCOL *
FindAcpiTableProtocol(VOID)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
OnRootBridgesConnected(IN EFI_EVENT Event,IN VOID * Context)41 OnRootBridgesConnected (
42   IN EFI_EVENT Event,
43   IN VOID      *Context
44   )
45 {
46   EFI_STATUS Status;
47 
48   DEBUG ((EFI_D_INFO,
49     "%a: root bridges have been connected, installing ACPI tables\n",
50     __FUNCTION__));
51   Status = InstallAcpiTables (FindAcpiTableProtocol ());
52   if (EFI_ERROR (Status)) {
53     DEBUG ((EFI_D_ERROR, "%a: InstallAcpiTables: %r\n", __FUNCTION__, Status));
54   }
55   gBS->CloseEvent (Event);
56 }
57 
58 
59 EFI_STATUS
60 EFIAPI
AcpiPlatformEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)61 AcpiPlatformEntryPoint (
62   IN EFI_HANDLE         ImageHandle,
63   IN EFI_SYSTEM_TABLE   *SystemTable
64   )
65 {
66   EFI_STATUS Status;
67   EFI_EVENT  RootBridgesConnected;
68 
69   //
70   // If the platform doesn't support PCI, or PCI enumeration has been disabled,
71   // install the tables at once, and let the entry point's return code reflect
72   // the full functionality.
73   //
74   if (PcdGetBool (PcdPciDisableBusEnumeration)) {
75     DEBUG ((EFI_D_INFO, "%a: PCI or its enumeration disabled, installing "
76       "ACPI tables\n", __FUNCTION__));
77     return InstallAcpiTables (FindAcpiTableProtocol ());
78   }
79 
80   //
81   // Otherwise, delay installing the ACPI tables until root bridges are
82   // connected. The entry point's return status will only reflect the callback
83   // setup. (Note that we're a DXE_DRIVER; our entry point function is invoked
84   // strictly before BDS is entered and can connect the root bridges.)
85   //
86   Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
87                   OnRootBridgesConnected, NULL /* Context */,
88                   &gRootBridgesConnectedEventGroupGuid, &RootBridgesConnected);
89   if (!EFI_ERROR (Status)) {
90     DEBUG ((EFI_D_INFO,
91       "%a: waiting for root bridges to be connected, registered callback\n",
92       __FUNCTION__));
93   }
94 
95   return Status;
96 }
97