878ddf1f |
1 | /*++\r |
2 | \r |
3 | Copyright (c) 2006, Intel Corporation \r |
4 | All rights reserved. This program and the accompanying materials \r |
5 | are licensed and made available under the terms and conditions of the BSD License \r |
6 | which accompanies this distribution. The full text of the license may be found at \r |
7 | http://opensource.org/licenses/bsd-license.php \r |
8 | \r |
9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r |
10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r |
11 | \r |
12 | Module Name:\r |
13 | \r |
14 | RtMemoryStatusCode.c\r |
15 | \r |
16 | Abstract:\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 |
27 | PEI_STATUS_CODE_MEMORY_PPI mStatusCodeMemoryPpi = { 0, 0, 0, 0 };\r |
28 | \r |
29 | //\r |
30 | // Function implementations\r |
31 | //\r |
32 | EFI_STATUS\r |
33 | RtMemoryReportStatusCode (\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 |
42 | Routine 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 |
47 | Arguments:\r |
48 | \r |
49 | Same as ReportStatusCode AP\r |
50 | \r |
51 | Returns:\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 |
59b05fbb |
58 | UINT32 MaxEntry;\r |
878ddf1f |
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 |
92 | VOID\r |
93 | RtMemoryStatusCodeInitialize (\r |
94 | VOID\r |
95 | )\r |
96 | /*++\r |
97 | \r |
98 | Routine 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 |
106 | Arguments: \r |
107 | \r |
108 | (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)\r |
109 | \r |
110 | Returns: \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 |
137 | VOID\r |
138 | PlaybackStatusCodes (\r |
139 | IN EFI_REPORT_STATUS_CODE ReportStatusCodeFunc\r |
140 | )\r |
141 | /*++\r |
142 | \r |
143 | Routine Description:\r |
144 | \r |
145 | Call the input ReportStatusCode function with every status code recorded in\r |
146 | the journal.\r |
147 | \r |
148 | Arguments: \r |
149 | \r |
150 | ReportStatusCode ReportStatusCode function to call.\r |
151 | \r |
152 | Returns: \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 |