TianoCore EDK2 master
Loading...
Searching...
No Matches
ReportStatusCodeRouterCommon.c
Go to the documentation of this file.
1
11
12LIST_ENTRY mCallbackListHead = INITIALIZE_LIST_HEAD_VARIABLE (mCallbackListHead);
13
14//
15// Report operation nest status.
16// If it is set, then the report operation has nested.
17//
18UINT32 mStatusCodeNestStatus = 0;
19
20EFI_MM_STATUS_CODE_PROTOCOL mSmmStatusCodeProtocol = {
22};
23
24EFI_MM_RSC_HANDLER_PROTOCOL mSmmRscHandlerProtocol = {
27};
28
46EFIAPI
48 IN EFI_MM_RSC_HANDLER_CALLBACK Callback
49 )
50{
51 LIST_ENTRY *Link;
52 MM_RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
53
54 if (Callback == NULL) {
55 return EFI_INVALID_PARAMETER;
56 }
57
58 for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link); Link = GetNextNode (&mCallbackListHead, Link)) {
59 CallbackEntry = CR (Link, MM_RSC_HANDLER_CALLBACK_ENTRY, Node, MM_RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
60 if (CallbackEntry->RscHandlerCallback == Callback) {
61 //
62 // If the function was already registered. It can't be registered again.
63 //
64 return EFI_ALREADY_STARTED;
65 }
66 }
67
69 ASSERT (CallbackEntry != NULL);
70
71 CallbackEntry->Signature = MM_RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE;
72 CallbackEntry->RscHandlerCallback = Callback;
73
74 InsertTailList (&mCallbackListHead, &CallbackEntry->Node);
75
76 return EFI_SUCCESS;
77}
78
93EFIAPI
95 IN EFI_MM_RSC_HANDLER_CALLBACK Callback
96 )
97{
98 LIST_ENTRY *Link;
99 MM_RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
100
101 if (Callback == NULL) {
102 return EFI_INVALID_PARAMETER;
103 }
104
105 for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link); Link = GetNextNode (&mCallbackListHead, Link)) {
106 CallbackEntry = CR (Link, MM_RSC_HANDLER_CALLBACK_ENTRY, Node, MM_RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
107 if (CallbackEntry->RscHandlerCallback == Callback) {
108 //
109 // If the function is found in list, delete it and return.
110 //
111 RemoveEntryList (&CallbackEntry->Node);
112 FreePool (CallbackEntry);
113 return EFI_SUCCESS;
114 }
115 }
116
117 return EFI_NOT_FOUND;
118}
119
140EFIAPI
143 IN EFI_STATUS_CODE_TYPE CodeType,
145 IN UINT32 Instance,
146 IN CONST EFI_GUID *CallerId,
147 IN EFI_STATUS_CODE_DATA *Data OPTIONAL
148 )
149{
150 LIST_ENTRY *Link;
151 MM_RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
152
153 //
154 // Use atom operation to avoid the reentant of report.
155 // If current status is not zero, then the function is reentrancy.
156 //
157 if (InterlockedCompareExchange32 (&mStatusCodeNestStatus, 0, 1) == 1) {
158 return EFI_DEVICE_ERROR;
159 }
160
161 for (Link = GetFirstNode (&mCallbackListHead); !IsNull (&mCallbackListHead, Link);) {
162 CallbackEntry = CR (Link, MM_RSC_HANDLER_CALLBACK_ENTRY, Node, MM_RSC_HANDLER_CALLBACK_ENTRY_SIGNATURE);
163 //
164 // The handler may remove itself, so get the next handler in advance.
165 //
166 Link = GetNextNode (&mCallbackListHead, Link);
167 CallbackEntry->RscHandlerCallback (
168 CodeType,
169 Value,
170 Instance,
171 (EFI_GUID *)CallerId,
172 Data
173 );
174 }
175
176 //
177 // Restore the nest status of report
178 //
179 InterlockedCompareExchange32 (&mStatusCodeNestStatus, 1, 0);
180
181 return EFI_SUCCESS;
182}
183
195 VOID
196 )
197{
198 EFI_STATUS Status;
199 EFI_HANDLE Handle;
200
201 Handle = NULL;
202
203 //
204 // Install SmmRscHandler Protocol
205 //
206 Status = gMmst->MmInstallProtocolInterface (
207 &Handle,
208 &gEfiMmRscHandlerProtocolGuid,
210 &mSmmRscHandlerProtocol
211 );
212 ASSERT_EFI_ERROR (Status);
213
214 //
215 // Install SmmStatusCode Protocol
216 //
217 Status = gMmst->MmInstallProtocolInterface (
218 &Handle,
219 &gEfiMmStatusCodeProtocolGuid,
221 &mSmmStatusCodeProtocol
222 );
223 ASSERT_EFI_ERROR (Status);
224
225 return EFI_SUCCESS;
226}
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
#define INITIALIZE_LIST_HEAD_VARIABLE(ListHead)
Definition: BaseLib.h:2904
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define CR(Record, TYPE, Field, TestSignature)
Definition: DebugLib.h:659
UINT32 EFI_STATUS_CODE_VALUE
Definition: PiStatusCode.h:67
UINT32 EFI_STATUS_CODE_TYPE
Definition: PiStatusCode.h:24
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI Unregister(IN EFI_MM_RSC_HANDLER_CALLBACK Callback)
EFI_STATUS EFIAPI ReportDispatcher(IN CONST EFI_MM_STATUS_CODE_PROTOCOL *This, IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance, IN CONST EFI_GUID *CallerId, IN EFI_STATUS_CODE_DATA *Data OPTIONAL)
EFI_STATUS GenericStatusCodeCommonEntry(VOID)
EFI_STATUS EFIAPI Register(IN EFI_MM_RSC_HANDLER_CALLBACK Callback)
UINT32 EFIAPI InterlockedCompareExchange32(IN OUT volatile UINT32 *Value, IN UINT32 CompareValue, IN UINT32 ExchangeValue)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_INSTALL_PROTOCOL_INTERFACE MmInstallProtocolInterface
Definition: PiMmCis.h:327
Definition: Base.h:213