]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/MonoStatusCode/PlatformStatusCode.c
MdeModulePkg: Fix use-after-free error in InstallConfigurationTable()
[mirror_edk2.git] / Vlv2TbltDevicePkg / MonoStatusCode / PlatformStatusCode.c
CommitLineData
3cbfba02
DW
1/** @file\r
2\r
3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
4 \r\r
5 This program and the accompanying materials are licensed and made available under\r\r
6 the terms and conditions of the BSD License that accompanies this distribution. \r\r
7 The full text of the license may be found at \r\r
8 http://opensource.org/licenses/bsd-license.php. \r\r
9 \r\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r\r
12 \r\r
13\r
14Module Name:\r
15\r
16\r
17 PlatformStatusCode.c\r
18\r
19Abstract:\r
20\r
21 Contains Platform specific implementations required to use status codes.\r
22\r
23--*/\r
24\r
25#include "PlatformStatusCode.h"\r
26#include <PchRegs.h>\r
27#include <PlatformBaseAddresses.h>\r
28#include <Library/PeiServicesLib.h>\r
29#include <Library/PcdLib.h>\r
30\r
31typedef struct {\r
32 EFI_STATUS_CODE_DATA DataHeader;\r
33 EFI_HANDLE Handle;\r
34} PEIM_FILE_HANDLE_EXTENDED_DATA;\r
35\r
36#define CONFIG_PORT0 0x4E\r
37#define PCI_IDX 0xCF8\r
38#define PCI_DAT 0xCFC\r
39\r
40#define PCI_LPC_BASE (0x8000F800)\r
41#define PCI_LPC_REG(x) (PCI_LPC_BASE + (x))\r
42\r
43//\r
44// Function implementations\r
45//\r
46BOOLEAN\r
47PeiCodeTypeToPostCode (\r
48 IN EFI_STATUS_CODE_TYPE CodeType,\r
49 IN EFI_STATUS_CODE_VALUE Value,\r
50 OUT UINT8 *PostCode\r
51 );\r
52\r
53/**\r
54 Provide a port 80 status code\r
55\r
56 @param Same as ReportStatusCode PPI\r
57\r
58 @retval EFI_SUCCESS Always returns success.\r
59\r
60**/\r
61EFI_STATUS\r
62EFIAPI\r
63Port80ReportStatusCode (\r
64 IN CONST EFI_PEI_SERVICES **PeiServices,\r
65 IN EFI_STATUS_CODE_TYPE CodeType,\r
66 IN EFI_STATUS_CODE_VALUE Value,\r
67 IN UINT32 Instance,\r
68 IN CONST EFI_GUID *CallerId,\r
69 IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL\r
70 )\r
71\r
72{\r
73 EFI_STATUS Status;\r
74 EFI_FV_FILE_INFO FvFileInfo;\r
75 UINT16 Port80Code = 0;\r
76\r
77 //\r
78 // Progress or error code, Output Port 80h card.\r
79 //\r
80 if (!PeiCodeTypeToPostCode (CodeType, Value, (UINT8 *)&Port80Code)) {\r
81 if ((Data != NULL) && (Value ==(EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN))){\r
82 Status = PeiServicesFfsGetFileInfo (\r
83 ((PEIM_FILE_HANDLE_EXTENDED_DATA *) (Data + 1))->Handle,\r
84 &FvFileInfo\r
85 );\r
86 if (!EFI_ERROR (Status)) {\r
87 Port80Code = (FvFileInfo.FileName.Data4[6]<<8) + (FvFileInfo.FileName.Data4[7]);\r
88 }\r
89 }\r
90 }\r
91 if (Port80Code != 0){\r
92 IoWrite16 (0x80, (UINT16) Port80Code);\r
93 DEBUG ((EFI_D_ERROR, "POSTCODE=<%04x>\n", Port80Code));\r
94 }\r
95 return EFI_SUCCESS;\r
96}\r
97\r
98/**\r
99 Provide a serial status code\r
100\r
101 @param Same as ReportStatusCode PPI\r
102\r
103 @retval EFI_SUCCESS Always returns success.\r
104\r
105**/\r
106EFI_STATUS\r
107EFIAPI\r
108SerialReportStatusCode (\r
109 IN CONST EFI_PEI_SERVICES **PeiServices,\r
110 IN EFI_STATUS_CODE_TYPE CodeType,\r
111 IN EFI_STATUS_CODE_VALUE Value,\r
112 IN UINT32 Instance,\r
113 IN CONST EFI_GUID * CallerId,\r
114 IN CONST EFI_STATUS_CODE_DATA * Data OPTIONAL\r
115 )\r
116{\r
117 CHAR8 *Filename;\r
118 CHAR8 *Description;\r
119 CHAR8 *Format;\r
120 CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];\r
121 UINT32 ErrorLevel;\r
122 UINT32 LineNumber;\r
123 UINTN CharCount;\r
124 BASE_LIST Marker;\r
125\r
126 Buffer[0] = '\0';\r
127\r
128 if (Data != NULL &&\r
129 ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {\r
130 //\r
131 // Print ASSERT() information into output buffer.\r
132 //\r
133 CharCount = AsciiSPrint (\r
134 Buffer,\r
135 sizeof (Buffer),\r
136 "\n\rPEI_ASSERT!: %a (%d): %a\n\r",\r
137 Filename,\r
138 LineNumber,\r
139 Description\r
140 );\r
141 } else if (Data != NULL &&\r
142 ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
143 //\r
144 // Print DEBUG() information into output buffer.\r
145 //\r
146 CharCount = AsciiBSPrint (\r
147 Buffer,\r
148 sizeof (Buffer),\r
149 Format,\r
150 Marker\r
151 );\r
152 } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {\r
153 //\r
154 // Print ERROR information into output buffer.\r
155 //\r
156 CharCount = AsciiSPrint (\r
157 Buffer,\r
158 sizeof (Buffer),\r
159 "ERROR: C%x:V%x I%x",\r
160 CodeType,\r
161 Value,\r
162 Instance\r
163 );\r
164\r
165 ASSERT(CharCount > 0);\r
166\r
167 if (CallerId != NULL) {\r
168 CharCount += AsciiSPrint (\r
169 &Buffer[CharCount],\r
170 (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),\r
171 " %g",\r
172 CallerId\r
173 );\r
174 }\r
175\r
176 if (Data != NULL) {\r
177 CharCount += AsciiSPrint (\r
178 &Buffer[CharCount],\r
179 (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),\r
180 " %x",\r
181 Data\r
182 );\r
183 }\r
184\r
185 CharCount += AsciiSPrint (\r
186 &Buffer[CharCount],\r
187 (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),\r
188 "\n\r"\r
189 );\r
190 } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
191 //\r
192 // Print PROGRESS information into output buffer.\r
193 //\r
194 CharCount = AsciiSPrint (\r
195 Buffer,\r
196 sizeof (Buffer),\r
197 "PROGRESS CODE: V%x I%x\n\r",\r
198 Value,\r
199 Instance\r
200 );\r
201 } else if (Data != NULL &&\r
202 CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&\r
203 ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {\r
204 //\r
205 // EFI_STATUS_CODE_STRING_DATA\r
206 //\r
207 CharCount = AsciiSPrint (\r
208 Buffer,\r
209 sizeof (Buffer),\r
210 "%a\n\r",\r
211 ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii\r
212 );\r
213 } else {\r
214 //\r
215 // Code type is not defined.\r
216 //\r
217 CharCount = AsciiSPrint (\r
218 Buffer,\r
219 sizeof (Buffer),\r
220 "Undefined: C%x:V%x I%x\n\r",\r
221 CodeType,\r
222 Value,\r
223 Instance\r
224 );\r
225 }\r
226\r
227 //\r
228 // Call SerialPort Lib function to do print.\r
229 //\r
230 SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
231\r
232 return EFI_SUCCESS;\r
233}\r
234\r
235/**\r
236\r
237 Call all status code listeners in the MonoStatusCode.\r
238\r
239 @param PeiServices The PEI core services table.\r
240 @param CodeType Type of Status Code.\r
241 @param Value Value to output for Status Code.\r
242 @param Instance Instance Number of this status code.\r
243 @param CallerId ID of the caller of this status code.\r
244 @param Data Optional data associated with this status code.\r
245\r
246 @retval EFI_SUCCESS If status code is successfully reported.\r
247 @retval EFI_NOT_AVAILABLE_YET If StatusCodePpi has not been installed.\r
248\r
249**/\r
250EFI_STATUS\r
251EFIAPI\r
252PlatformReportStatusCode (\r
253 IN CONST EFI_PEI_SERVICES **PeiServices,\r
254 IN EFI_STATUS_CODE_TYPE CodeType,\r
255 IN EFI_STATUS_CODE_VALUE Value,\r
256 IN UINT32 Instance,\r
257 IN CONST EFI_GUID * CallerId,\r
258 IN CONST EFI_STATUS_CODE_DATA * Data OPTIONAL\r
259 )\r
260{\r
261 //\r
262 // If we are in debug mode, we will allow serial status codes\r
263 //\r
264 SerialReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId, Data);\r
265\r
266 Port80ReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId, Data);\r
267\r
268 return EFI_SUCCESS;\r
269}\r
270\r
271/**\r
272 Install the PEIM. Initialize listeners, publish the PPI and HOB for PEI and\r
273 DXE use respectively.\r
274\r
275 @param FfsHeader FV this PEIM was loaded from.\r
276 @param PeiServices General purpose services available to every PEIM.\r
277\r
278 @retval EFI_SUCCESS The function always returns success.\r
279\r
280**/\r
281EFI_STATUS\r
282EFIAPI\r
283InstallMonoStatusCode (\r
284 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
285 IN CONST EFI_PEI_SERVICES **PeiServices\r
286 )\r
287{\r
288\r
289 //\r
290 // Initialize all listeners\r
291 //\r
292 InitializeMonoStatusCode (FfsHeader, PeiServices);\r
293\r
294 //\r
295 // Publish the listener in a HOB for DXE use.\r
296 //\r
297 InitializeDxeReportStatusCode (PeiServices);\r
298\r
299 return EFI_SUCCESS;\r
300}\r
301\r
302#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ3 BIT3 // UART IRQ3 Enable\r
303#define V_PCH_ILB_IRQE_UARTIRQEN_IRQ4 BIT4 // UART IRQ4 Enable\r
304#define PCIEX_BASE_ADDRESS 0xE0000000\r
305#define PciD31F0RegBase PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)\r
306#define SB_RCBA 0xfed1c000\r
307\r
308extern PCH_STEPPING EFIAPI PchStepping (VOID);\r
309\r
310VOID\r
311RamDebugInit (\r
312 VOID\r
313 );\r
314\r
315/**\r
316 Enable legacy decoding on ICH6\r
317\r
318 @param none\r
319\r
320 @retval EFI_SUCCESS Always returns success.\r
321\r
322**/\r
323EFI_STATUS\r
324EnableInternalUart(\r
325 VOID\r
326 )\r
327{\r
328\r
329 //\r
330 // Program and enable PMC Base.\r
331 //\r
332 IoWrite32 (PCI_IDX, PCI_LPC_REG(R_PCH_LPC_PMC_BASE));\r
333 IoWrite32 (PCI_DAT, (PMC_BASE_ADDRESS | B_PCH_LPC_PMC_BASE_EN));\r
334\r
335 //\r
336 // Enable COM1 for debug message output.\r
337 //\r
338 MmioAndThenOr32 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, (UINT32) (~(B_PCH_PMC_GEN_PMCON_SUS_PWR_FLR + B_PCH_PMC_GEN_PMCON_PWROK_FLR)), BIT24);\r
339\r
340 //\r
341 // Silicon Steppings\r
342 //\r
343 if (PchStepping()>= PchB0)\r
344 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ4);\r
345 else\r
346 MmioOr8 (ILB_BASE_ADDRESS + R_PCH_ILB_IRQE, (UINT8) V_PCH_ILB_IRQE_UARTIRQEN_IRQ3);\r
347 MmioAnd32(IO_BASE_ADDRESS + 0x0520, (UINT32)~(0x00000187));\r
348 MmioOr32 (IO_BASE_ADDRESS + 0x0520, (UINT32)0x81); // UART3_RXD-L\r
349 MmioAnd32(IO_BASE_ADDRESS + 0x0530, (UINT32)~(0x00000007));\r
350 MmioOr32 (IO_BASE_ADDRESS + 0x0530, (UINT32)0x1); // UART3_RXD-L\r
351 MmioOr8 (PciD31F0RegBase + R_PCH_LPC_UART_CTRL, (UINT8) B_PCH_LPC_UART_CTRL_COM1_EN);\r
352\r
353 return EFI_SUCCESS;\r
354}\r
355\r
356/**\r
357 INIT the SIO. Ported this code and I don't undertand the comments either.\r
358\r
359 @param FfsHeader FV this PEIM was loaded from.\r
360 @param PeiServices General purpose services available to every PEIM.\r
361\r
362 None\r
363\r
364**/\r
365VOID\r
366EFIAPI\r
367PlatformInitializeStatusCode (\r
368 IN EFI_FFS_FILE_HEADER *FfsHeader,\r
369 IN CONST EFI_PEI_SERVICES **PeiServices\r
370 )\r
371{\r
372\r
373 //\r
374 // Enable internal COM1 on South Cluster.\r
375 //\r
376 EnableInternalUart();\r
377\r
378\r
379 //\r
380 // Initialize additional debug status code listeners.\r
381 //\r
382 SerialPortInitialize();\r
383\r
384}\r
385//#endif //EFI_DEBUG\r
386\r