]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleRuntime.c
MdeModulePkg/DxeCapsuleLibFmp: clone ESRT for runtime access
[mirror_edk2.git] / MdeModulePkg / Library / DxeCapsuleLibFmp / DxeCapsuleRuntime.c
1 /** @file
2 Capsule library runtime support.
3
4 Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PiDxe.h>
10
11 #include <Guid/FmpCapsule.h>
12 #include <Guid/SystemResourceTable.h>
13 #include <Guid/EventGroup.h>
14
15 #include <Library/BaseLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/DxeServicesTableLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/UefiRuntimeServicesTableLib.h>
21 #include <Library/MemoryAllocationLib.h>
22
23 extern EFI_SYSTEM_RESOURCE_TABLE *mEsrtTable;
24 extern BOOLEAN mIsVirtualAddrConverted;
25 EFI_EVENT mDxeRuntimeCapsuleLibVirtualAddressChangeEvent = NULL;
26 EFI_EVENT mDxeRuntimeCapsuleLibReadyToBootEvent = NULL;
27
28 /**
29 Convert EsrtTable physical address to virtual address.
30
31 @param[in] Event Event whose notification function is being invoked.
32 @param[in] Context The pointer to the notification function's context, which
33 is implementation-dependent.
34 **/
35 VOID
36 EFIAPI
37 DxeCapsuleLibVirtualAddressChangeEvent (
38 IN EFI_EVENT Event,
39 IN VOID *Context
40 )
41 {
42 gRT->ConvertPointer (EFI_OPTIONAL_PTR, (VOID **)&mEsrtTable);
43 mIsVirtualAddrConverted = TRUE;
44 }
45
46 /**
47 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT.
48
49 @param[in] Event The Event that is being processed.
50 @param[in] Context The Event Context.
51
52 **/
53 STATIC
54 VOID
55 EFIAPI
56 DxeCapsuleLibReadyToBootEventNotify (
57 IN EFI_EVENT Event,
58 IN VOID *Context
59 )
60 {
61 UINTN Index;
62 EFI_CONFIGURATION_TABLE *ConfigEntry;
63 EFI_SYSTEM_RESOURCE_TABLE *EsrtTable;
64
65 //
66 // Get Esrt table first
67 //
68 ConfigEntry = gST->ConfigurationTable;
69 for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
70 if (CompareGuid(&gEfiSystemResourceTableGuid, &ConfigEntry->VendorGuid)) {
71 break;
72 }
73 ConfigEntry++;
74 }
75
76 //
77 // If no Esrt table installed in Configure Table
78 //
79 if (Index < gST->NumberOfTableEntries) {
80 //
81 // Search Esrt to check given capsule is qualified
82 //
83 EsrtTable = (EFI_SYSTEM_RESOURCE_TABLE *) ConfigEntry->VendorTable;
84
85 mEsrtTable = AllocateRuntimeCopyPool (
86 sizeof (EFI_SYSTEM_RESOURCE_TABLE) +
87 EsrtTable->FwResourceCount * sizeof (EFI_SYSTEM_RESOURCE_ENTRY),
88 EsrtTable);
89 ASSERT (mEsrtTable != NULL);
90
91 //
92 // Set FwResourceCountMax to a sane value.
93 //
94 mEsrtTable->FwResourceCountMax = mEsrtTable->FwResourceCount;
95 }
96 }
97
98 /**
99 The constructor function hook VirtualAddressChange event to use ESRT table as capsule routing table.
100
101 @param ImageHandle The firmware allocated handle for the EFI image.
102 @param SystemTable A pointer to the EFI System Table.
103
104 @retval EFI_SUCCESS The constructor successfully .
105 **/
106 EFI_STATUS
107 EFIAPI
108 DxeRuntimeCapsuleLibConstructor (
109 IN EFI_HANDLE ImageHandle,
110 IN EFI_SYSTEM_TABLE *SystemTable
111 )
112 {
113 EFI_STATUS Status;
114
115 //
116 // Make sure we can handle virtual address changes.
117 //
118 Status = gBS->CreateEventEx (
119 EVT_NOTIFY_SIGNAL,
120 TPL_NOTIFY,
121 DxeCapsuleLibVirtualAddressChangeEvent,
122 NULL,
123 &gEfiEventVirtualAddressChangeGuid,
124 &mDxeRuntimeCapsuleLibVirtualAddressChangeEvent
125 );
126 ASSERT_EFI_ERROR (Status);
127
128 //
129 // Register notify function to cache the FMP capsule GUIDs at ReadyToBoot.
130 //
131 Status = gBS->CreateEventEx (
132 EVT_NOTIFY_SIGNAL,
133 TPL_CALLBACK,
134 DxeCapsuleLibReadyToBootEventNotify,
135 NULL,
136 &gEfiEventReadyToBootGuid,
137 &mDxeRuntimeCapsuleLibReadyToBootEvent
138 );
139 ASSERT_EFI_ERROR (Status);
140
141 return EFI_SUCCESS;
142 }
143
144 /**
145 The destructor function closes the VirtualAddressChange event.
146
147 @param ImageHandle The firmware allocated handle for the EFI image.
148 @param SystemTable A pointer to the EFI System Table.
149
150 @retval EFI_SUCCESS The destructor completed successfully.
151 **/
152 EFI_STATUS
153 EFIAPI
154 DxeRuntimeCapsuleLibDestructor (
155 IN EFI_HANDLE ImageHandle,
156 IN EFI_SYSTEM_TABLE *SystemTable
157 )
158 {
159 EFI_STATUS Status;
160
161 //
162 // Close the VirtualAddressChange event.
163 //
164 Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibVirtualAddressChangeEvent);
165 ASSERT_EFI_ERROR (Status);
166
167 //
168 // Close the ReadyToBoot event.
169 //
170 Status = gBS->CloseEvent (mDxeRuntimeCapsuleLibReadyToBootEvent);
171 ASSERT_EFI_ERROR (Status);
172
173 return EFI_SUCCESS;
174 }