]> git.proxmox.com Git - mirror_edk2.git/blame - EdkModulePkg/Library/EdkRuntimeStatusCodeLib/RtMemoryStatusCode/RtMemoryStatusCode.c
Initial import.
[mirror_edk2.git] / EdkModulePkg / Library / EdkRuntimeStatusCodeLib / RtMemoryStatusCode / RtMemoryStatusCode.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 \r
14 RtMemoryStatusCode.c\r
15 \r
16Abstract:\r
17\r
18 EFI lib to provide memory journal status code reporting routines.\r
19\r
20--*/\r
21\r
22#include <Ppi/StatusCodeMemory.h>\r
23\r
24//\r
25// Global variables\r
26//\r
27PEI_STATUS_CODE_MEMORY_PPI mStatusCodeMemoryPpi = { 0, 0, 0, 0 };\r
28\r
29//\r
30// Function implementations\r
31//\r
32EFI_STATUS\r
33RtMemoryReportStatusCode (\r
34 IN EFI_STATUS_CODE_TYPE CodeType,\r
35 IN EFI_STATUS_CODE_VALUE Value,\r
36 IN UINT32 Instance,\r
37 IN EFI_GUID * CallerId,\r
38 IN EFI_STATUS_CODE_DATA * Data OPTIONAL\r
39 )\r
40/*++\r
41\r
42Routine Description:\r
43\r
44 Log a status code to a memory journal. If no memory journal exists, \r
45 we will just return.\r
46\r
47Arguments:\r
48\r
49 Same as ReportStatusCode AP\r
50 \r
51Returns:\r
52\r
53 EFI_SUCCESS This function always returns success\r
54\r
55--*/\r
56{\r
57 EFI_STATUS_CODE_ENTRY *CurrentEntry;\r
58 UINTN MaxEntry;\r
59\r
60 //\r
61 // We don't care to log debug codes.\r
62 //\r
63 if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
64 return EFI_SUCCESS;\r
65 }\r
66 //\r
67 // Update the latest entry in the journal.\r
68 //\r
69 MaxEntry = mStatusCodeMemoryPpi.Length / sizeof (EFI_STATUS_CODE_ENTRY);\r
70 if (!MaxEntry) {\r
71 //\r
72 // If we don't have any entries, then we can return.\r
73 // This effectively means that no memory buffer was passed forward from PEI.\r
74 //\r
75 return EFI_SUCCESS;\r
76 }\r
77\r
78 CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (mStatusCodeMemoryPpi.Address + (mStatusCodeMemoryPpi.LastEntry * sizeof (EFI_STATUS_CODE_ENTRY)));\r
79\r
80 mStatusCodeMemoryPpi.LastEntry = (mStatusCodeMemoryPpi.LastEntry + 1) % MaxEntry;\r
81 if (mStatusCodeMemoryPpi.LastEntry == mStatusCodeMemoryPpi.FirstEntry) {\r
82 mStatusCodeMemoryPpi.FirstEntry = (mStatusCodeMemoryPpi.FirstEntry + 1) % MaxEntry;\r
83 }\r
84\r
85 CurrentEntry->Type = CodeType;\r
86 CurrentEntry->Value = Value;\r
87 CurrentEntry->Instance = Instance;\r
88\r
89 return EFI_SUCCESS;\r
90}\r
91\r
92VOID\r
93RtMemoryStatusCodeInitialize (\r
94 VOID\r
95 )\r
96/*++\r
97\r
98Routine Description:\r
99\r
100 Initialization routine.\r
101 Allocates heap space for storing Status Codes.\r
102 Installs a PPI to point to that heap space.\r
103 Installs a callback to switch to memory.\r
104 Installs a callback to \r
105\r
106Arguments: \r
107\r
108 (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r
109\r
110Returns: \r
111\r
112 None\r
113\r
114--*/\r
115{\r
116 EFI_HOB_GUID_TYPE *GuidHob;\r
117 PEI_STATUS_CODE_MEMORY_PPI **StatusCodeMemoryPpi;\r
118\r
119 GuidHob = GetFirstGuidHob (&gPeiStatusCodeMemoryPpiGuid);\r
120 if (GuidHob == NULL) {\r
121 return;\r
122 }\r
123\r
124 StatusCodeMemoryPpi = GET_GUID_HOB_DATA (GuidHob);\r
125\r
126 //\r
127 // Copy data to our structure since the HOB will go away at runtime\r
128 //\r
129 // BUGBUG: Virtualize for RT\r
130 //\r
131 mStatusCodeMemoryPpi.FirstEntry = (*StatusCodeMemoryPpi)->FirstEntry;\r
132 mStatusCodeMemoryPpi.LastEntry = (*StatusCodeMemoryPpi)->LastEntry;\r
133 mStatusCodeMemoryPpi.Address = (*StatusCodeMemoryPpi)->Address;\r
134 mStatusCodeMemoryPpi.Length = (*StatusCodeMemoryPpi)->Length;\r
135}\r
136\r
137VOID\r
138PlaybackStatusCodes (\r
139 IN EFI_REPORT_STATUS_CODE ReportStatusCodeFunc\r
140 )\r
141/*++\r
142\r
143Routine Description:\r
144\r
145 Call the input ReportStatusCode function with every status code recorded in\r
146 the journal.\r
147\r
148Arguments: \r
149\r
150 ReportStatusCode ReportStatusCode function to call.\r
151\r
152Returns: \r
153\r
154 None\r
155\r
156--*/\r
157{\r
158 UINTN MaxEntry;\r
159 EFI_STATUS_CODE_ENTRY *CurrentEntry;\r
160 UINTN Counter;\r
161\r
162 if (ReportStatusCodeFunc == RtMemoryReportStatusCode) {\r
163 return ;\r
164 }\r
165 //\r
166 // Playback prior status codes to current listeners\r
167 //\r
168 MaxEntry = mStatusCodeMemoryPpi.Length / sizeof (EFI_STATUS_CODE_ENTRY);\r
169 for (Counter = mStatusCodeMemoryPpi.FirstEntry; Counter != mStatusCodeMemoryPpi.LastEntry; Counter++) {\r
170 //\r
171 // Check if we have to roll back to beginning of queue buffer\r
172 //\r
173 if (Counter == MaxEntry) {\r
174 Counter = 0;\r
175 }\r
176 //\r
177 // Play current entry\r
178 //\r
179 CurrentEntry = (EFI_STATUS_CODE_ENTRY *) (UINTN) (mStatusCodeMemoryPpi.Address + (Counter * sizeof (EFI_STATUS_CODE_ENTRY)));\r
180 ReportStatusCodeFunc (\r
181 CurrentEntry->Type,\r
182 CurrentEntry->Value,\r
183 CurrentEntry->Instance,\r
184 NULL,\r
185 NULL\r
186 );\r
187 }\r
188}\r