13af9b38827fff65fc7e303eec07448b6d04d5f0fxli/** @file
23af9b38827fff65fc7e303eec07448b6d04d5f0fxli  Serial I/O status code reporting worker.
33af9b38827fff65fc7e303eec07448b6d04d5f0fxli
45d0f0ac4808b2ad7595f209e29ddfa7c8d8edb3aLi, Elvin  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
5e5eed7d3641d71d7ea539e5379ea9c6a5cd97004hhtian  This program and the accompanying materials
63af9b38827fff65fc7e303eec07448b6d04d5f0fxli  are licensed and made available under the terms and conditions of the BSD License
73af9b38827fff65fc7e303eec07448b6d04d5f0fxli  which accompanies this distribution.  The full text of the license may be found at
83af9b38827fff65fc7e303eec07448b6d04d5f0fxli  http://opensource.org/licenses/bsd-license.php
93af9b38827fff65fc7e303eec07448b6d04d5f0fxli
103af9b38827fff65fc7e303eec07448b6d04d5f0fxli  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
113af9b38827fff65fc7e303eec07448b6d04d5f0fxli  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
123af9b38827fff65fc7e303eec07448b6d04d5f0fxli
133af9b38827fff65fc7e303eec07448b6d04d5f0fxli**/
143af9b38827fff65fc7e303eec07448b6d04d5f0fxli
153af9b38827fff65fc7e303eec07448b6d04d5f0fxli#include "StatusCodeHandlerRuntimeDxe.h"
163af9b38827fff65fc7e303eec07448b6d04d5f0fxli
173af9b38827fff65fc7e303eec07448b6d04d5f0fxli/**
183af9b38827fff65fc7e303eec07448b6d04d5f0fxli  Convert status code value and extended data to readable ASCII string, send string to serial I/O device.
193af9b38827fff65fc7e303eec07448b6d04d5f0fxli
203af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @param  CodeType         Indicates the type of status code being reported.
213af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @param  Value            Describes the current status of a hardware or software entity.
223af9b38827fff65fc7e303eec07448b6d04d5f0fxli                           This included information about the class and subclass that is used to
233af9b38827fff65fc7e303eec07448b6d04d5f0fxli                           classify the entity as well as an operation.
243af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @param  Instance         The enumeration of a hardware or software entity within
253af9b38827fff65fc7e303eec07448b6d04d5f0fxli                           the system. Valid instance numbers start with 1.
263af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @param  CallerId         This optional parameter may be used to identify the caller.
273af9b38827fff65fc7e303eec07448b6d04d5f0fxli                           This parameter allows the status code driver to apply different rules to
283af9b38827fff65fc7e303eec07448b6d04d5f0fxli                           different callers.
293af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @param  Data             This optional parameter may be used to pass additional data.
303af9b38827fff65fc7e303eec07448b6d04d5f0fxli
313af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @retval EFI_SUCCESS      Status code reported to serial I/O successfully.
323af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @retval EFI_DEVICE_ERROR EFI serial device cannot work after ExitBootService() is called.
333af9b38827fff65fc7e303eec07448b6d04d5f0fxli  @retval EFI_DEVICE_ERROR EFI serial device cannot work with TPL higher than TPL_CALLBACK.
343af9b38827fff65fc7e303eec07448b6d04d5f0fxli
353af9b38827fff65fc7e303eec07448b6d04d5f0fxli**/
363af9b38827fff65fc7e303eec07448b6d04d5f0fxliEFI_STATUS
37e798cd87ca9a3a30c4cea50c5f5de84e10a8bc5ageekboyEFIAPI
383af9b38827fff65fc7e303eec07448b6d04d5f0fxliSerialStatusCodeReportWorker (
393af9b38827fff65fc7e303eec07448b6d04d5f0fxli  IN EFI_STATUS_CODE_TYPE     CodeType,
403af9b38827fff65fc7e303eec07448b6d04d5f0fxli  IN EFI_STATUS_CODE_VALUE    Value,
413af9b38827fff65fc7e303eec07448b6d04d5f0fxli  IN UINT32                   Instance,
423af9b38827fff65fc7e303eec07448b6d04d5f0fxli  IN EFI_GUID                 *CallerId,
433af9b38827fff65fc7e303eec07448b6d04d5f0fxli  IN EFI_STATUS_CODE_DATA     *Data OPTIONAL
443af9b38827fff65fc7e303eec07448b6d04d5f0fxli  )
453af9b38827fff65fc7e303eec07448b6d04d5f0fxli{
463af9b38827fff65fc7e303eec07448b6d04d5f0fxli  CHAR8           *Filename;
473af9b38827fff65fc7e303eec07448b6d04d5f0fxli  CHAR8           *Description;
483af9b38827fff65fc7e303eec07448b6d04d5f0fxli  CHAR8           *Format;
4990eaa3c1e022e2b676da65cb41aa66136a18b4ealzeng  CHAR8           Buffer[MAX_DEBUG_MESSAGE_LENGTH];
503af9b38827fff65fc7e303eec07448b6d04d5f0fxli  UINT32          ErrorLevel;
513af9b38827fff65fc7e303eec07448b6d04d5f0fxli  UINT32          LineNumber;
523af9b38827fff65fc7e303eec07448b6d04d5f0fxli  UINTN           CharCount;
533af9b38827fff65fc7e303eec07448b6d04d5f0fxli  BASE_LIST       Marker;
543af9b38827fff65fc7e303eec07448b6d04d5f0fxli
553af9b38827fff65fc7e303eec07448b6d04d5f0fxli  Buffer[0] = '\0';
563af9b38827fff65fc7e303eec07448b6d04d5f0fxli
573af9b38827fff65fc7e303eec07448b6d04d5f0fxli  if (Data != NULL &&
583af9b38827fff65fc7e303eec07448b6d04d5f0fxli      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {
593af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
603af9b38827fff65fc7e303eec07448b6d04d5f0fxli    // Print ASSERT() information into output buffer.
613af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
623af9b38827fff65fc7e303eec07448b6d04d5f0fxli    CharCount = AsciiSPrint (
633af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Buffer,
643af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  sizeof (Buffer),
653af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  "\n\rDXE_ASSERT!: %a (%d): %a\n\r",
663af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Filename,
673af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  LineNumber,
683af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Description
693af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  );
703af9b38827fff65fc7e303eec07448b6d04d5f0fxli  } else if (Data != NULL &&
713af9b38827fff65fc7e303eec07448b6d04d5f0fxli             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {
723af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
733af9b38827fff65fc7e303eec07448b6d04d5f0fxli    // Print DEBUG() information into output buffer.
743af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
753af9b38827fff65fc7e303eec07448b6d04d5f0fxli    CharCount = AsciiBSPrint (
763af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Buffer,
773af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  sizeof (Buffer),
783af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Format,
793af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Marker
803af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  );
813af9b38827fff65fc7e303eec07448b6d04d5f0fxli  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
823af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
833af9b38827fff65fc7e303eec07448b6d04d5f0fxli    // Print ERROR information into output buffer.
843af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
853af9b38827fff65fc7e303eec07448b6d04d5f0fxli    CharCount = AsciiSPrint (
863af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Buffer,
873af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  sizeof (Buffer),
885d0f0ac4808b2ad7595f209e29ddfa7c8d8edb3aLi, Elvin                  "ERROR: C%08x:V%08x I%x",
893af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  CodeType,
903af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Value,
913af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Instance
923af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  );
93fbe12b79aef4c2706e90078cc75b94dcf7926ba8ydong    ASSERT (CharCount > 0);
943af9b38827fff65fc7e303eec07448b6d04d5f0fxli
953af9b38827fff65fc7e303eec07448b6d04d5f0fxli    if (CallerId != NULL) {
963af9b38827fff65fc7e303eec07448b6d04d5f0fxli      CharCount += AsciiSPrint (
9730d636c8d97057a2b5b3d696757c868710a94d2cli-elvin                     &Buffer[CharCount],
983af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
993af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     " %g",
1003af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     CallerId
1013af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     );
1023af9b38827fff65fc7e303eec07448b6d04d5f0fxli    }
1033af9b38827fff65fc7e303eec07448b6d04d5f0fxli
1043af9b38827fff65fc7e303eec07448b6d04d5f0fxli    if (Data != NULL) {
1053af9b38827fff65fc7e303eec07448b6d04d5f0fxli      CharCount += AsciiSPrint (
10630d636c8d97057a2b5b3d696757c868710a94d2cli-elvin                     &Buffer[CharCount],
1073af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
1083af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     " %x",
1093af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     Data
1103af9b38827fff65fc7e303eec07448b6d04d5f0fxli                     );
1113af9b38827fff65fc7e303eec07448b6d04d5f0fxli    }
1123af9b38827fff65fc7e303eec07448b6d04d5f0fxli
1133af9b38827fff65fc7e303eec07448b6d04d5f0fxli    CharCount += AsciiSPrint (
11430d636c8d97057a2b5b3d696757c868710a94d2cli-elvin                   &Buffer[CharCount],
1153af9b38827fff65fc7e303eec07448b6d04d5f0fxli                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
1163af9b38827fff65fc7e303eec07448b6d04d5f0fxli                   "\n\r"
1173af9b38827fff65fc7e303eec07448b6d04d5f0fxli                   );
1183af9b38827fff65fc7e303eec07448b6d04d5f0fxli  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
1193af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
1203af9b38827fff65fc7e303eec07448b6d04d5f0fxli    // Print PROGRESS information into output buffer.
1213af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
1223af9b38827fff65fc7e303eec07448b6d04d5f0fxli    CharCount = AsciiSPrint (
1233af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Buffer,
1243af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  sizeof (Buffer),
1255d0f0ac4808b2ad7595f209e29ddfa7c8d8edb3aLi, Elvin                  "PROGRESS CODE: V%08x I%x\n\r",
1263af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Value,
1273af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Instance
1283af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  );
129bc369e79758f08661d031514657a1036ffd052a9xli  } else if (Data != NULL &&
130bc369e79758f08661d031514657a1036ffd052a9xli             CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid) &&
13196a2516355feae4bf10009fe28722c689af7a3e6xli             ((EFI_STATUS_CODE_STRING_DATA *) Data)->StringType == EfiStringAscii) {
13296a2516355feae4bf10009fe28722c689af7a3e6xli    //
13396a2516355feae4bf10009fe28722c689af7a3e6xli    // EFI_STATUS_CODE_STRING_DATA
13496a2516355feae4bf10009fe28722c689af7a3e6xli    //
13596a2516355feae4bf10009fe28722c689af7a3e6xli    CharCount = AsciiSPrint (
13696a2516355feae4bf10009fe28722c689af7a3e6xli                  Buffer,
13796a2516355feae4bf10009fe28722c689af7a3e6xli                  sizeof (Buffer),
13896a2516355feae4bf10009fe28722c689af7a3e6xli                  "%a\n\r",
13996a2516355feae4bf10009fe28722c689af7a3e6xli                  ((EFI_STATUS_CODE_STRING_DATA *) Data)->String.Ascii
14096a2516355feae4bf10009fe28722c689af7a3e6xli                  );
1413af9b38827fff65fc7e303eec07448b6d04d5f0fxli  } else {
1423af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
1433af9b38827fff65fc7e303eec07448b6d04d5f0fxli    // Code type is not defined.
1443af9b38827fff65fc7e303eec07448b6d04d5f0fxli    //
1453af9b38827fff65fc7e303eec07448b6d04d5f0fxli    CharCount = AsciiSPrint (
1463af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Buffer,
1473af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  sizeof (Buffer),
1485d0f0ac4808b2ad7595f209e29ddfa7c8d8edb3aLi, Elvin                  "Undefined: C%08x:V%08x I%x\n\r",
1493af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  CodeType,
1503af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Value,
1513af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  Instance
1523af9b38827fff65fc7e303eec07448b6d04d5f0fxli                  );
1533af9b38827fff65fc7e303eec07448b6d04d5f0fxli  }
1543af9b38827fff65fc7e303eec07448b6d04d5f0fxli
1553af9b38827fff65fc7e303eec07448b6d04d5f0fxli  //
1563af9b38827fff65fc7e303eec07448b6d04d5f0fxli  // Call SerialPort Lib function to do print.
1573af9b38827fff65fc7e303eec07448b6d04d5f0fxli  //
1583af9b38827fff65fc7e303eec07448b6d04d5f0fxli  SerialPortWrite ((UINT8 *) Buffer, CharCount);
1593af9b38827fff65fc7e303eec07448b6d04d5f0fxli
1603af9b38827fff65fc7e303eec07448b6d04d5f0fxli  return EFI_SUCCESS;
1613af9b38827fff65fc7e303eec07448b6d04d5f0fxli}
1623af9b38827fff65fc7e303eec07448b6d04d5f0fxli
163