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