]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.c
MdeModulePkg/Universal/StatusCodeHandler: Fix a bug about log lost
[mirror_edk2.git] / MdeModulePkg / Universal / StatusCodeHandler / RuntimeDxe / StatusCodeHandlerRuntimeDxe.c
1 /** @file
2 Status Code Handler Driver which produces general handlers and hook them
3 onto the DXE status code router.
4
5 Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "StatusCodeHandlerRuntimeDxe.h"
11
12 EFI_EVENT mVirtualAddressChangeEvent = NULL;
13 EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
14
15 /**
16 Unregister status code callback functions only available at boot time from
17 report status code router when exiting boot services.
18
19 **/
20 VOID
21 EFIAPI
22 UnregisterSerialBootTimeHandlers (
23 VOID
24 )
25 {
26 if (PcdGetBool (PcdStatusCodeUseSerial)) {
27 mRscHandlerProtocol->Unregister (SerialStatusCodeReportWorker);
28 }
29 }
30
31 /**
32 Virtual address change notification call back. It converts global pointer
33 to virtual address.
34
35 @param Event Event whose notification function is being invoked.
36 @param Context Pointer to the notification function's context, which is
37 always zero in current implementation.
38
39 **/
40 VOID
41 EFIAPI
42 VirtualAddressChangeCallBack (
43 IN EFI_EVENT Event,
44 IN VOID *Context
45 )
46 {
47 //
48 // Convert memory status code table to virtual address;
49 //
50 EfiConvertPointer (
51 0,
52 (VOID **) &mRtMemoryStatusCodeTable
53 );
54 }
55
56 /**
57 Dispatch initialization request to sub status code devices based on
58 customized feature flags.
59
60 **/
61 VOID
62 InitializationDispatcherWorker (
63 VOID
64 )
65 {
66 EFI_PEI_HOB_POINTERS Hob;
67 EFI_STATUS Status;
68 MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader;
69 MEMORY_STATUSCODE_RECORD *Record;
70 UINTN Index;
71 UINTN MaxRecordNumber;
72
73 //
74 // If enable UseSerial, then initialize serial port.
75 // if enable UseRuntimeMemory, then initialize runtime memory status code worker.
76 //
77 if (PcdGetBool (PcdStatusCodeUseSerial)) {
78 //
79 // Call Serial Port Lib API to initialize serial port.
80 //
81 Status = SerialPortInitialize ();
82 ASSERT_EFI_ERROR (Status);
83 }
84 if (PcdGetBool (PcdStatusCodeUseMemory)) {
85 Status = RtMemoryStatusCodeInitializeWorker ();
86 ASSERT_EFI_ERROR (Status);
87 }
88
89 //
90 // Replay Status code which saved in GUID'ed HOB to all supported devices.
91 //
92 if (FeaturePcdGet (PcdStatusCodeReplayIn)) {
93 //
94 // Journal GUID'ed HOBs to find all record entry, if found,
95 // then output record to support replay device.
96 //
97 Hob.Raw = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid);
98 if (Hob.Raw != NULL) {
99 PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid);
100 Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1);
101 MaxRecordNumber = (UINTN) PacketHeader->RecordIndex;
102 if (PacketHeader->PacketIndex > 0) {
103 //
104 // Record has been wrapped around. So, record number has arrived at max number.
105 //
106 MaxRecordNumber = (UINTN) PacketHeader->MaxRecordsNumber;
107 }
108 for (Index = 0; Index < MaxRecordNumber; Index++) {
109 //
110 // Dispatch records to devices based on feature flag.
111 //
112 if (PcdGetBool (PcdStatusCodeUseSerial)) {
113 SerialStatusCodeReportWorker (
114 Record[Index].CodeType,
115 Record[Index].Value,
116 Record[Index].Instance,
117 NULL,
118 NULL
119 );
120 }
121 if (PcdGetBool (PcdStatusCodeUseMemory)) {
122 RtMemoryStatusCodeReportWorker (
123 Record[Index].CodeType,
124 Record[Index].Value,
125 Record[Index].Instance,
126 NULL,
127 NULL
128 );
129 }
130 }
131 }
132 }
133 }
134
135 /**
136 Entry point of DXE Status Code Driver.
137
138 This function is the entry point of this DXE Status Code Driver.
139 It initializes registers status code handlers, and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
140
141 @param ImageHandle The firmware allocated handle for the EFI image.
142 @param SystemTable A pointer to the EFI System Table.
143
144 @retval EFI_SUCCESS The entry point is executed successfully.
145
146 **/
147 EFI_STATUS
148 EFIAPI
149 StatusCodeHandlerRuntimeDxeEntry (
150 IN EFI_HANDLE ImageHandle,
151 IN EFI_SYSTEM_TABLE *SystemTable
152 )
153 {
154 EFI_STATUS Status;
155
156 Status = gBS->LocateProtocol (
157 &gEfiRscHandlerProtocolGuid,
158 NULL,
159 (VOID **) &mRscHandlerProtocol
160 );
161 ASSERT_EFI_ERROR (Status);
162
163 //
164 // Dispatch initialization request to supported devices
165 //
166 InitializationDispatcherWorker ();
167
168 if (PcdGetBool (PcdStatusCodeUseSerial)) {
169 mRscHandlerProtocol->Register (SerialStatusCodeReportWorker, TPL_HIGH_LEVEL);
170 }
171 if (PcdGetBool (PcdStatusCodeUseMemory)) {
172 mRscHandlerProtocol->Register (RtMemoryStatusCodeReportWorker, TPL_HIGH_LEVEL);
173 }
174
175 Status = gBS->CreateEventEx (
176 EVT_NOTIFY_SIGNAL,
177 TPL_NOTIFY,
178 VirtualAddressChangeCallBack,
179 NULL,
180 &gEfiEventVirtualAddressChangeGuid,
181 &mVirtualAddressChangeEvent
182 );
183 ASSERT_EFI_ERROR (Status);
184
185 return EFI_SUCCESS;
186 }