4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/* $Id$ */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * DxeVBoxOemHookStatusCodeLib.c - Logging.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Copyright (C) 2009-2010 Oracle Corporation
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * available from http://www.virtualbox.org. This file is free software;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * General Public License (GPL) as published by the Free Software
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * The contents of this file may alternatively be used under the terms
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * of the Common Development and Distribution License Version 1.0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * VirtualBox OSE distribution, in which case the provisions of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * CDDL are applicable instead of those of the GPL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * You may elect to license modified versions of this file under the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * terms and conditions of either the GPL or the CDDL or both.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/*******************************************************************************
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync* Header Files *
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync*******************************************************************************/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/ReportStatusCodeLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/OemHookStatusCodeLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/PrintLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Library/BaseMemoryLib.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Guid/StatusCodeDataTypeId.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include <Guid/StatusCodeDataTypeDebug.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if 0 /* See VBoxSecExtractDebugInfo */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync# include <DebugInfo.h>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "VBoxDebugLib.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "DevEFI.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS EFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncOemHookStatusCodeInitialize(VOID)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString("OemHookStatusCodeInitialize\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if 0 /* vvl: With thbe new version the API changed a bit and VA_LIST isn't used any more. Before applying
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * any changes here I would like to understand in which cases we need this help function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * bird: Some components sent information in this format. Search for the UUID or EFI_DEBUG_INFO usage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Helper VBoxSecPeiReportStatusCode uses for catching some odd reports.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic BOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVBoxSecExtractDebugInfo(IN CONST EFI_STATUS_CODE_DATA *pData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT UINT32 *puErrorLevel,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT VA_LIST *pVa,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT CHAR8 **ppszFormat)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_DEBUG_INFO *pDebugInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ( !CompareGuid(&pData->Type, &gEfiStatusCodeSpecificDataGuid)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || pData->HeaderSize != sizeof(*pData)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || pData->Size <= sizeof(UINT64) * 12 + sizeof(EFI_DEBUG_INFO) + 1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pDebugInfo = (EFI_DEBUG_INFO *)(pData + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *pVa = (VA_LIST)(pDebugInfo + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *ppszFormat = (CHAR8 *)((UINT64 *)pVa + 12);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** Worker that dumps the raw data. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncstatic void
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVBoxOemHookStatusCodeReportRawDump(EFI_STATUS_CODE_TYPE Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS_CODE_VALUE Value,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CONST EFI_GUID *CallerId)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString("Report: Type=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(Type, sizeof(Type));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" Value=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(Value, sizeof(Value));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" Instance=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(Instance, sizeof(Instance));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (CallerId)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" CallerId=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintGuid(CallerId);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define CASE_PRINT(Head,Print,Tail) \
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync case Head ## Print ## Tail : VBoxPrintString(" " #Print); break
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Type & EFI_STATUS_CODE_SEVERITY_MASK) /* quick guess work... */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_ERROR_,MINOR,);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_ERROR_,MAJOR,);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_ERROR_,UNRECOVERED,);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_ERROR_,UNCONTAINED,);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync switch (Type & EFI_STATUS_CODE_TYPE_MASK) /* quick guess work... */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_,PROGRESS,_CODE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_,ERROR,_CODE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CASE_PRINT(EFI_,DEBUG,_CODE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#undef CASE_PRINT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintChar('\n');
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS EFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncOemHookStatusCodeReport(IN EFI_STATUS_CODE_TYPE Type,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_STATUS_CODE_VALUE Value,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_GUID *CallerId OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_STATUS_CODE_DATA *Data OPTIONAL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Try figure out the data payload
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Data != NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 *pszFilename;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 *pszDescription;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 uLine;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 uErrorLevel;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BASE_LIST bs;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 *pszFormat;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ReportStatusCodeExtractAssertInfo(Type, Value, Data, &pszFilename,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &pszDescription, &uLine))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString("Assertion Failed! Line=0x");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(uLine, sizeof(uLine));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (pszFilename)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" File=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(pszFilename);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (pszDescription)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" Desc=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(pszDescription);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintChar('\n');
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else if ( ReportStatusCodeExtractDebugInfo(Data, &uErrorLevel, &bs, &pszFormat)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#if 0 /* See question at VBoxSecExtractDebugInfo. */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || VBoxSecExtractDebugInfo(Data, &uErrorLevel, &va, &pszFormat)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#endif
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CHAR8 szBuf[128];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINTN cch;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cch = AsciiBSPrint(szBuf, sizeof(szBuf), pszFormat, bs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (cch >= sizeof(szBuf))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cch = sizeof(szBuf) - 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ( cch > 0
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync && ( szBuf[cch - 1] == '\n'
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync || szBuf[cch - 1] == '\r'))
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cch--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync szBuf[cch] = '\0';
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString("DBG/");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(uErrorLevel, sizeof(uErrorLevel));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(": ");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(szBuf);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintChar('\n');
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * Unknown data, resort to raw dump of everything.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxOemHookStatusCodeReportRawDump(Type, Value, Instance, CallerId);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString("OemReport: Unknown data type ");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintGuid(&Data->Type);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" (Size=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(Data->Size, sizeof(Data->Size));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(" HeaderSize=");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHex(Data->HeaderSize, sizeof(Data->HeaderSize));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintString(")\n");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Data->Size > 0 && Data->Size <= 128)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxPrintHexDump(Data + 1, Data->Size);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync /*
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync * No data, do a raw dump.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync */
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VBoxOemHookStatusCodeReportRawDump(Type, Value, Instance, CallerId);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync