3 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
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.
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.
21 Contains Platform specific implementations required to use status codes.
25 #include "PlatformStatusCode.h"
27 #include <PlatformBaseAddresses.h>
28 #include <Library/PeiServicesLib.h>
29 #include <Library/PcdLib.h>
32 EFI_STATUS_CODE_DATA DataHeader
;
34 } PEIM_FILE_HANDLE_EXTENDED_DATA
;
36 #define CONFIG_PORT0 0x4E
40 #define PCI_LPC_BASE (0x8000F800)
41 #define PCI_LPC_REG(x) (PCI_LPC_BASE + (x))
44 // Function implementations
47 PeiCodeTypeToPostCode (
48 IN EFI_STATUS_CODE_TYPE CodeType
,
49 IN EFI_STATUS_CODE_VALUE Value
,
54 Provide a port 80 status code
56 @param Same as ReportStatusCode PPI
58 @retval EFI_SUCCESS Always returns success.
63 Port80ReportStatusCode (
64 IN CONST EFI_PEI_SERVICES
**PeiServices
,
65 IN EFI_STATUS_CODE_TYPE CodeType
,
66 IN EFI_STATUS_CODE_VALUE Value
,
68 IN CONST EFI_GUID
*CallerId
,
69 IN CONST EFI_STATUS_CODE_DATA
*Data OPTIONAL
74 EFI_FV_FILE_INFO FvFileInfo
;
75 UINT16 Port80Code
= 0;
78 // Progress or error code, Output Port 80h card.
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
,
86 if (!EFI_ERROR (Status
)) {
87 Port80Code
= (FvFileInfo
.FileName
.Data4
[6]<<8) + (FvFileInfo
.FileName
.Data4
[7]);
92 IoWrite16 (0x80, (UINT16
) Port80Code
);
93 DEBUG ((EFI_D_ERROR
, "POSTCODE=<%04x>\n", Port80Code
));
99 Provide a serial status code
101 @param Same as ReportStatusCode PPI
103 @retval EFI_SUCCESS Always returns success.
108 SerialReportStatusCode (
109 IN CONST EFI_PEI_SERVICES
**PeiServices
,
110 IN EFI_STATUS_CODE_TYPE CodeType
,
111 IN EFI_STATUS_CODE_VALUE Value
,
113 IN CONST EFI_GUID
* CallerId
,
114 IN CONST EFI_STATUS_CODE_DATA
* Data OPTIONAL
120 CHAR8 Buffer
[EFI_STATUS_CODE_DATA_MAX_SIZE
];
129 ReportStatusCodeExtractAssertInfo (CodeType
, Value
, Data
, &Filename
, &Description
, &LineNumber
)) {
131 // Print ASSERT() information into output buffer.
133 CharCount
= AsciiSPrint (
136 "\n\rPEI_ASSERT!: %a (%d): %a\n\r",
141 } else if (Data
!= NULL
&&
142 ReportStatusCodeExtractDebugInfo (Data
, &ErrorLevel
, &Marker
, &Format
)) {
144 // Print DEBUG() information into output buffer.
146 CharCount
= AsciiBSPrint (
152 } else if ((CodeType
& EFI_STATUS_CODE_TYPE_MASK
) == EFI_ERROR_CODE
) {
154 // Print ERROR information into output buffer.
156 CharCount
= AsciiSPrint (
159 "ERROR: C%x:V%x I%x",
165 ASSERT(CharCount
> 0);
167 if (CallerId
!= NULL
) {
168 CharCount
+= AsciiSPrint (
170 (sizeof (Buffer
) - (sizeof (Buffer
[0]) * CharCount
)),
177 CharCount
+= AsciiSPrint (
179 (sizeof (Buffer
) - (sizeof (Buffer
[0]) * CharCount
)),
185 CharCount
+= AsciiSPrint (
187 (sizeof (Buffer
) - (sizeof (Buffer
[0]) * CharCount
)),
190 } else if ((CodeType
& EFI_STATUS_CODE_TYPE_MASK
) == EFI_PROGRESS_CODE
) {
192 // Print PROGRESS information into output buffer.
194 CharCount
= AsciiSPrint (
197 "PROGRESS CODE: V%x I%x\n\r",
201 } else if (Data
!= NULL
&&
202 CompareGuid (&Data
->Type
, &gEfiStatusCodeDataTypeStringGuid
) &&
203 ((EFI_STATUS_CODE_STRING_DATA
*) Data
)->StringType
== EfiStringAscii
) {
205 // EFI_STATUS_CODE_STRING_DATA
207 CharCount
= AsciiSPrint (
211 ((EFI_STATUS_CODE_STRING_DATA
*) Data
)->String
.Ascii
215 // Code type is not defined.
217 CharCount
= AsciiSPrint (
220 "Undefined: C%x:V%x I%x\n\r",
228 // Call SerialPort Lib function to do print.
230 SerialPortWrite ((UINT8
*) Buffer
, CharCount
);
237 Call all status code listeners in the MonoStatusCode.
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.
246 @retval EFI_SUCCESS If status code is successfully reported.
247 @retval EFI_NOT_AVAILABLE_YET If StatusCodePpi has not been installed.
252 PlatformReportStatusCode (
253 IN CONST EFI_PEI_SERVICES
**PeiServices
,
254 IN EFI_STATUS_CODE_TYPE CodeType
,
255 IN EFI_STATUS_CODE_VALUE Value
,
257 IN CONST EFI_GUID
* CallerId
,
258 IN CONST EFI_STATUS_CODE_DATA
* Data OPTIONAL
262 // If we are in debug mode, we will allow serial status codes
264 SerialReportStatusCode (PeiServices
, CodeType
, Value
, Instance
, CallerId
, Data
);
266 Port80ReportStatusCode (PeiServices
, CodeType
, Value
, Instance
, CallerId
, Data
);
272 Install the PEIM. Initialize listeners, publish the PPI and HOB for PEI and
273 DXE use respectively.
275 @param FfsHeader FV this PEIM was loaded from.
276 @param PeiServices General purpose services available to every PEIM.
278 @retval EFI_SUCCESS The function always returns success.
283 InstallMonoStatusCode (
284 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
285 IN CONST EFI_PEI_SERVICES
**PeiServices
290 // Initialize all listeners
292 InitializeMonoStatusCode (FfsHeader
, PeiServices
);
295 // Publish the listener in a HOB for DXE use.
297 InitializeDxeReportStatusCode (PeiServices
);
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
308 extern PCH_STEPPING EFIAPI
PchStepping (VOID
);
316 Enable legacy decoding on ICH6
320 @retval EFI_SUCCESS Always returns success.
330 // Program and enable PMC Base.
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
));
336 // Enable COM1 for debug message output.
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
);
343 if (PchStepping()>= PchB0
)
344 MmioOr8 (ILB_BASE_ADDRESS
+ R_PCH_ILB_IRQE
, (UINT8
) V_PCH_ILB_IRQE_UARTIRQEN_IRQ4
);
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
);
357 INIT the SIO. Ported this code and I don't undertand the comments either.
359 @param FfsHeader FV this PEIM was loaded from.
360 @param PeiServices General purpose services available to every PEIM.
367 PlatformInitializeStatusCode (
368 IN EFI_FFS_FILE_HEADER
*FfsHeader
,
369 IN CONST EFI_PEI_SERVICES
**PeiServices
374 // Enable internal COM1 on South Cluster.
376 EnableInternalUart();
380 // Initialize additional debug status code listeners.
382 SerialPortInitialize();