PlatformStatusCode.c 10 KB

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