1 /** @file
2   Capsule library runtime support.
3 
4   Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include <PiDxe.h>
16 
17 #include <Guid/FmpCapsule.h>
18 #include <Guid/SystemResourceTable.h>
19 #include <Guid/EventGroup.h>
20 
21 #include <Library/BaseLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/DxeServicesTableLib.h>
25 #include <Library/UefiBootServicesTableLib.h>
26 #include <Library/UefiRuntimeServicesTableLib.h>
27 #include <Library/MemoryAllocationLib.h>
28 
29 extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable;
30 extern BOOLEAN                   mIsVirtualAddrConverted;
31 
32 /**
33   Convert EsrtTable physical address to virtual address.
34 
35   @param[in] Event      Event whose notification function is being invoked.
36   @param[in] Context    The pointer to the notification function's context, which
37                         is implementation-dependent.
38 **/
39 VOID
40 EFIAPI
DxeCapsuleLibVirtualAddressChangeEvent(IN EFI_EVENT Event,IN VOID * Context)41 DxeCapsuleLibVirtualAddressChangeEvent (
42   IN  EFI_EVENT   Event,
43   IN  VOID        *Context
44   )
45 {
46   UINTN                    Index;
47   EFI_CONFIGURATION_TABLE  *ConfigEntry;
48 
49   //
50   // Get Esrt table first
51   //
52   ConfigEntry = gST->ConfigurationTable;
53   for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
54     if (CompareGuid(&gEfiSystemResourceTableGuid, &ConfigEntry->VendorGuid)) {
55       break;
56     }
57     ConfigEntry++;
58   }
59 
60   //
61   // If no Esrt table installed in Configure Table
62   //
63   if (Index < gST->NumberOfTableEntries) {
64     //
65     // Search Esrt to check given capsule is qualified
66     //
67     mEsrtTable = (EFI_SYSTEM_RESOURCE_TABLE *) ConfigEntry->VendorTable;
68 
69     //
70     // Update protocol pointer to Esrt Table.
71     //
72     gRT->ConvertPointer (0x00, (VOID**) &(mEsrtTable));
73   }
74 
75   mIsVirtualAddrConverted = TRUE;
76 
77 }
78 
79 /**
80   The constructor function hook VirtualAddressChange event to use ESRT table as capsule routing table.
81 
82   @param  ImageHandle   The firmware allocated handle for the EFI image.
83   @param  SystemTable   A pointer to the EFI System Table.
84 
85   @retval EFI_SUCCESS   The constructor successfully .
86 **/
87 EFI_STATUS
88 EFIAPI
DxeRuntimeCapsuleLibConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)89 DxeRuntimeCapsuleLibConstructor (
90   IN EFI_HANDLE         ImageHandle,
91   IN EFI_SYSTEM_TABLE   *SystemTable
92   )
93 {
94   EFI_STATUS     Status;
95   EFI_EVENT      Event;
96 
97   //
98   // Make sure we can handle virtual address changes.
99   //
100   Event = NULL;
101   Status = gBS->CreateEventEx (
102                   EVT_NOTIFY_SIGNAL,
103                   TPL_NOTIFY,
104                   DxeCapsuleLibVirtualAddressChangeEvent,
105                   NULL,
106                   &gEfiEventVirtualAddressChangeGuid,
107                   &Event
108                   );
109   ASSERT_EFI_ERROR (Status);
110 
111   return EFI_SUCCESS;
112 }
113