/** @file
System prints Trace Hub message in DXE/SMM based on fixed PCDs and HOB.
Trace Hub PCDs will be applied if no HOB exist.
Copyright (c) 2023, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "InternalTraceHubApiCommon.h"
#include "InternalTraceHubApi.h"
GLOBAL_REMOVE_IF_UNREFERENCED TRACEHUB_DEBUG_INFO_HOB *mThDebugInstArray = NULL;
GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mDbgInstCount = 0;
/**
Write debug string to specified Trace Hub MMIO address.
@param[in] SeverityType Severity type of input message.
@param[in] Buffer A pointer to the data buffer.
@param[in] NumberOfBytes The size of data buffer.
@retval RETURN_SUCCESS Data was written to Trace Hub.
@retval Other Failed to output Trace Hub message.
**/
RETURN_STATUS
EFIAPI
TraceHubSysTDebugWrite (
IN TRACE_HUB_SEVERITY_TYPE SeverityType,
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
MIPI_SYST_HANDLE MipiSystHandle;
MIPI_SYST_HEADER MipiSystHeader;
RETURN_STATUS Status;
UINT32 Index;
if ((mDbgInstCount == 0) || (mThDebugInstArray == NULL)) {
return RETURN_ABORTED;
}
if (NumberOfBytes == 0) {
//
// No data need to be written to Trace Hub
//
return RETURN_SUCCESS;
}
if (Buffer == NULL) {
return RETURN_INVALID_PARAMETER;
}
ZeroMem (&MipiSystHandle, sizeof (MIPI_SYST_HANDLE));
MipiSystHandle.systh_header = &MipiSystHeader;
Status = InitMipiSystHandle (&MipiSystHandle);
if (RETURN_ERROR (Status)) {
return Status;
}
for (Index = 0; Index < mDbgInstCount; Index++) {
Status = CheckWhetherToOutputMsg (
&MipiSystHandle,
(UINT8 *)&mThDebugInstArray[Index],
SeverityType,
TraceHubDebugType
);
if (!RETURN_ERROR (Status)) {
Status = MipiSystWriteDebug (
&MipiSystHandle,
SeverityType,
(UINT16)NumberOfBytes,
(CHAR8 *)Buffer
);
if (RETURN_ERROR (Status)) {
break;
}
}
}
return Status;
}
/**
Write catalog status code message to specified Trace Hub MMIO address.
@param[in] SeverityType Severity type of input message.
@param[in] Id Catalog ID.
@param[in] Guid Driver Guid.
@retval RETURN_SUCCESS Data was written to Trace Hub.
@retval Other Failed to output Trace Hub message.
**/
RETURN_STATUS
EFIAPI
TraceHubSysTWriteCataLog64StatusCode (
IN TRACE_HUB_SEVERITY_TYPE SeverityType,
IN UINT64 Id,
IN GUID *Guid
)
{
MIPI_SYST_HANDLE MipiSystHandle;
MIPI_SYST_HEADER MipiSystHeader;
UINTN Index;
RETURN_STATUS Status;
if ((mDbgInstCount == 0) || (mThDebugInstArray == NULL)) {
return RETURN_ABORTED;
}
ZeroMem (&MipiSystHandle, sizeof (MIPI_SYST_HANDLE));
MipiSystHandle.systh_header = &MipiSystHeader;
Status = InitMipiSystHandle (&MipiSystHandle);
if (RETURN_ERROR (Status)) {
return Status;
}
if (Guid != NULL) {
SwapBytesGuid (Guid, (GUID *)(VOID *)&MipiSystHandle.systh_guid);
MipiSystHandle.systh_tag.et_guid = 1;
} else {
MipiSystHandle.systh_tag.et_modunit = 2;
MipiSystHandle.systh_tag.et_guid = 0;
}
for (Index = 0; Index < mDbgInstCount; Index++) {
Status = CheckWhetherToOutputMsg (
&MipiSystHandle,
(UINT8 *)&mThDebugInstArray[Index],
SeverityType,
TraceHubCatalogType
);
if (!RETURN_ERROR (Status)) {
Status = MipiSystWriteCatalog (
&MipiSystHandle,
SeverityType,
Id
);
if (RETURN_ERROR (Status)) {
break;
}
}
}
return Status;
}
/**
Write catalog message to specified Trace Hub MMIO address.
@param[in] SeverityType Severity type of input message.
@param[in] Id Catalog ID.
@param[in] NumberOfParams Number of entries in argument list.
@param[in] ... Catalog message parameters.
@retval RETURN_SUCCESS Data was written to Trace Hub.
@retval Other Failed to output Trace Hub message.
**/
RETURN_STATUS
EFIAPI
TraceHubSysTWriteCataLog64 (
IN TRACE_HUB_SEVERITY_TYPE SeverityType,
IN UINT64 Id,
IN UINTN NumberOfParams,
...
)
{
MIPI_SYST_HANDLE MipiSystHandle;
MIPI_SYST_HEADER MipiSystHeader;
VA_LIST Args;
UINTN Index;
RETURN_STATUS Status;
if (NumberOfParams > sizeof (MipiSystHandle.systh_param) / sizeof (UINT32)) {
return RETURN_INVALID_PARAMETER;
}
if ((mDbgInstCount == 0) || (mThDebugInstArray == NULL)) {
return RETURN_ABORTED;
}
ZeroMem (&MipiSystHandle, sizeof (MIPI_SYST_HANDLE));
MipiSystHandle.systh_header = &MipiSystHeader;
Status = InitMipiSystHandle (&MipiSystHandle);
if (RETURN_ERROR (Status)) {
return Status;
}
MipiSystHandle.systh_param_count = (UINT32)NumberOfParams;
VA_START (Args, NumberOfParams);
for (Index = 0; Index < NumberOfParams; Index++) {
MipiSystHandle.systh_param[Index] = VA_ARG (Args, UINT32);
}
VA_END (Args);
for (Index = 0; Index < mDbgInstCount; Index++) {
Status = CheckWhetherToOutputMsg (
&MipiSystHandle,
(UINT8 *)&mThDebugInstArray[Index],
SeverityType,
TraceHubCatalogType
);
if (!RETURN_ERROR (Status)) {
Status = MipiSystWriteCatalog (
&MipiSystHandle,
SeverityType,
Id
);
if (RETURN_ERROR (Status)) {
break;
}
}
}
return Status;
}
/**
Constructor to get TraceHob configuration data
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS.
@retval RETURN_OUT_OF_RESOURCES There are not enough resources available to retrieve the matching FFS section.
**/
RETURN_STATUS
EFIAPI
DxeSmmTraceHubDebugSysTLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
if (mDbgInstCount == 0) {
mDbgInstCount = CountThDebugInstance ();
}
mThDebugInstArray = AllocateZeroPool (mDbgInstCount * sizeof (TRACEHUB_DEBUG_INFO_HOB));
if (mThDebugInstArray != NULL) {
PackThDebugInstance (mThDebugInstArray, mDbgInstCount);
} else {
return RETURN_OUT_OF_RESOURCES;
}
return RETURN_SUCCESS;
}