☰
EDK II TraceHubDebugSysTLib 全解析:基于 MIPI SYS-T 的 Trace Hub 消息输出库
2026/10/4 1:47:43 网站建设 项目流程
  • 固件
  • 操作系统
  • 驱动开发
  • 嵌入式

【免费下载链接】edk2

EDK II

项目地址:https://gitcode.com/gh_mirrors/ed/edk2
点击查看免费下载

本篇文章围绕 MdeModulePkg 中TraceHubDebugSysTLib库展开,系统讲解 EDK II 固件如何借助 Trace Hub 硬件与 MIPI SYS-T 子模块,在 SEC/PEI/DXE/SMM 各阶段输出调试消息与目录(Catalog)消息。读者读完可以掌握该库的顶层 API、三个库实例(Base/Pei/DxeSmm)的选型差异、三个 Trace Hub 相关 PCD 与gTraceHubDebugInfoHobGuidHOB 的配置方法,以及底层实例计数、可见性判断与 MMIO 地址解析的实现机制,从而在自己的平台 DSC/FDF 中正确集成并配置 Trace Hub 调试能力。

TraceHubDebugSysTLib 是什么

TraceHubDebugSysTLib是 EDK II 中用于输出 Trace Hub 消息的顶层(top level)库。它本身不直接操作 Trace Hub 寄存器,而是通过MIPI SYS-T 子模块(即MipiSysTLib,头文件mipi_syst.h)将调试字符串、目录消息(Catalog Message)以 MIPI SYS-T 协议格式写到 Trace Hub 的 MMIO 地址上,供 Trace Hub 硬件采集并经调试探针(如 Intel DCI / ITP)在主机侧还原为可读日志。

该库的公共 API 声明位于 MdePkg/Include/Library/TraceHubDebugSysTLib.h,实现代码位于 MdeModulePkg/Library/TraceHubDebugSysTLib 目录,该目录下共包含三个可实例化的库(各有一个.inf与其对应实现.c),外加两个内部公共实现文件:

  • BaseTraceHubDebugSysTLib.inf/BaseTraceHubDebugSysTLib.c
  • PeiTraceHubDebugSysTLib.inf/PeiTraceHubDebugSysTLib.c
  • DxeSmmTraceHubDebugSysTLib.inf/DxeSmmTraceHubDebugSysTLib.c
  • InternalTraceHubApi.c/InternalTraceHubApi.h(非公共接口:实例计数与打包)
  • InternalTraceHubApiCommon.c/InternalTraceHubApiCommon.h(公共内部接口:可见性判断、GUID 字节序转换、消息输出判定、MMIO 地址与消息可见性读取)

使用该库前,用户必须正确配置三个 Trace Hub 相关 PCD 以及一个 HOB(详见下文)。PCD 的详细定义见 MdeModulePkg.dec,HOB 的详细定义见 TraceHubDebugInfoHob.h。

顶层 API:三种消息输出接口

库对外只暴露三个函数,全部位于MdePkg/Include/Library/TraceHubDebugSysTLib.h,所有实现均遵循EFIAPI调用约定并返回RETURN_STATUS。

1.TraceHubSysTDebugWrite— 输出调试字符串

RETURN_STATUS EFIAPI TraceHubSysTDebugWrite ( IN TRACE_HUB_SEVERITY_TYPE SeverityType, IN UINT8 *Buffer, IN UINTN NumberOfBytes );

将一段原始调试字符串(Buffer,长度NumberOfBytes)按SeverityType指定的严重级别写入 Trace Hub。参数校验逻辑(见 BaseTraceHubDebugSysTLib.c)为:NumberOfBytes == 0时直接返回RETURN_SUCCESS(无数据可写),Buffer == NULL时返回RETURN_INVALID_PARAMETER。

2.TraceHubSysTWriteCataLog64StatusCode— 输出目录状态码消息

RETURN_STATUS EFIAPI TraceHubSysTWriteCataLog64StatusCode ( IN TRACE_HUB_SEVERITY_TYPE SeverityType, IN UINT64 Id, IN GUID *Guid );

输出一条带目录 ID(Id)和驱动 GUID(Guid)的状态码消息。实现中会先将 GUID 从小端转为大端写入MipiSystHandle.systh_guid,并置位systh_tag.et_guid = 1(见 PeiTraceHubDebugSysTLib.c);若Guid == NULL,则退化为模块/单元标签模式(et_modunit = 2、et_guid = 0)。Guid == NULL在 Base 实现中会直接返回RETURN_INVALID_PARAMETER。

3.TraceHubSysTWriteCataLog64— 输出带参数的目录消息

RETURN_STATUS EFIAPI TraceHubSysTWriteCataLog64 ( IN TRACE_HUB_SEVERITY_TYPE SeverityType, IN UINT64 Id, IN UINTN NumberOfParams, ... );

变参函数,输出目录消息并可携带最多与MipiSystHandle.systh_param数组容量等长的 32 位参数(实现通过VA_START/VA_ARG逐一填充systh_param,见 BaseTraceHubDebugSysTLib.c);NumberOfParams超过systh_param容量时返回RETURN_INVALID_PARAMETER。

严重级别枚举TRACE_HUB_SEVERITY_TYPE

三个 API 的第一个参数统一使用该枚举(定义于TraceHubDebugSysTLib.h):

值枚举名含义
0SeverityNone无级别
1SeverityFatal致命错误
2SeverityError错误
3SeverityWarning警告
4SeverityNormal常规信息
5–7SeverityUser1/2/3用户自定义级别

三个 Trace Hub PCD 配置详解

按 Readme.md 要求,使用本库前必须配置以下三个 PCD(均属于gEfiMdeModulePkgTokenSpaceGuid,定义于 MdeModulePkg.dec):

PcdTraceHubDebugLevel(UINT8,默认 0x0)

指示 Trace Hub 的调试级别,决定哪些严重级别的消息会被输出。合法取值如下:

值宏允许输出的严重级别
0x0TraceHubDebugLevelError仅SeverityFatal、SeverityError
0x1TraceHubDebugLevelErrorWarning追加SeverityWarning
0x2TraceHubDebugLevelErrorWarningInfo追加SeverityNormal
0x3TraceHubDebugLevelErrorWarningInfoVerbose全部级别

该过滤逻辑实现在 InternalTraceHubApiCommon.c 的TraceHubDataEnabled()中:先判断使能标志,再按调试级别与消息严重级别的组合决定放行或丢弃。

PcdEnableTraceHubDebugMsg(BOOLEAN,默认 FALSE)

全局开关:FALSE关闭 Trace Hub 调试消息,TRUE打开。对应 HOB 结构中的Flag字段。

PcdTraceHubDebugMmioAddress(UINT64,默认 0)

Trace Hub 消息输出目标的 MMIO 基地址。实现中(CheckWhetherToOutputMsg,见 InternalTraceHubApiCommon.c)会将该地址填入MipiSystHandle.systh_platform.TraceHubPlatformData.MmioAddr,若地址为 0 则直接判定消息无需输出(返回RETURN_ABORTED)。因此该 PCD 必须被配置为平台实际 Trace Hub MMIO 基地址,否则即使使能开关打开也不会产生任何输出。

在平台中覆盖 PCD

三个库的.inf均声明了上述 PCD(例如 PeiTraceHubDebugSysTLib.inf 的[Pcd]段)。平台可在 DSC 的[PcdsFixedAtBuild]或[PcdsDynamic]中覆盖默认值,例如:

[PcdsFixedAtBuild] gEfiMdeModulePkgTokenSpaceGuid.PcdEnableTraceHubDebugMsg|TRUE gEfiMdeModulePkgTokenSpaceGuid.PcdTraceHubDebugLevel|0x2 gEfiMdeModulePkgTokenSpaceGuid.PcdTraceHubDebugMmioAddress|0xFED0F000

Trace Hub HOB:gTraceHubDebugInfoHobGuid

除 PCD 外,Readme 还要求配置gTraceHubDebugInfoHobGuid对应的 HOB。其 GUID 定义为:

{ 0xf88c9c23, 0x646c, 0x4f6c, { 0x8e, 0x3d, 0x36, 0xa9, 0x43, 0xc1, 0x08, 0x35 } }

(见 MdeModulePkg.dec 的[Guids]段。)

HOB 数据结构TRACEHUB_DEBUG_INFO_HOB定义于 TraceHubDebugInfoHob.h,当前修订版本号TRACEHUB_DEBUG_INFO_HOB_REVISION = 1:

typedef struct { UINT16 Revision; // 结构修订版本 BOOLEAN Flag; // 使能/禁用 Trace Hub 调试消息 UINT8 DebugLevel; // Trace Hub 调试级别 UINT8 Rvsd[4]; // 保留字段 UINT64 TraceHubMmioAddress; // Trace Hub 调试消息输出 MMIO 地址 } TRACEHUB_DEBUG_INFO_HOB;

该 HOB 的作用是让早期阶段(如 SEC/PEI)发现多个 Trace Hub 调试实例时,把每个实例的配置以 HOB 形式传递给后续阶段,从而支持多 Trace Hub 实例场景。这与单一固定 PCD 仅能描述一个实例形成对比。

三个库实例的差异与选型

Readme 将库分为三个实例,它们共享顶层 API 与大部分内部逻辑,差异集中在"配置来源"和"适用模块类型"上。

BaseTraceHubDebugSysTLib.inf — 固定 PCD,单实例

  • 适用阶段:LIBRARY_CLASS = TraceHubDebugSysTLib(无模块类型限定,即 SEC/PEI/DXE/SMM 均可用),见 BaseTraceHubDebugSysTLib.inf。
  • 行为:仅基于固定 PCD 输出 Trace Hub 消息,只支持单个 Trace Hub 调试实例。其CountThDebugInstance()直接返回 1(见 BaseTraceHubDebugSysTLib.c),不会查询 HOB。
  • 适用场景:不需要 HOB 机制、硬件只有一个 Trace Hub 实例的简单平台,或 SEC 等尚无 HOB 服务的阶段。

PeiTraceHubDebugSysTLib.inf — PEI 阶段,PCD + HOB

  • 适用阶段:LIBRARY_CLASS = TraceHubDebugSysTLib|PEI_CORE PEIM,见 PeiTraceHubDebugSysTLib.inf。
  • 行为:基于固定 PCD 与 HOB 输出消息。一旦检测到gTraceHubDebugInfoHobGuidHOB 即应用 HOB 中的配置(Flag、DebugLevel、TraceHubMmioAddress);若不存在 HOB 则回退使用 PCD 配置。
  • 实例遍历:CountThDebugInstance()(见 InternalTraceHubApi.c)会统计系统中该 GUID HOB 的个数;无 HOB 时计为 1(即回退到 PCD 的单实例)。消息循环用GetFirstGuidHob/GetNextGuidHob遍历全部实例(见 PeiTraceHubDebugSysTLib.c)。

DxeSmmTraceHubDebugSysTLib.inf — DXE/SMM 阶段,PCD + HOB

  • 适用阶段:LIBRARY_CLASS = TraceHubDebugSysTLib|DXE_CORE DXE_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION,见 DxeSmmTraceHubDebugSysTLib.inf。
  • 行为:与 PEI 实例相同,基于固定 PCD 与 HOB 输出消息,无 HOB 时回退到 PCD。
  • 构造器机制:该库声明了CONSTRUCTOR = DxeSmmTraceHubDebugSysTLibConstructor。构造器(见 DxeSmmTraceHubDebugSysTLib.c)在库被链接进模块时执行一次:先CountThDebugInstance()统计实例数,再用AllocateZeroPool分配实例数组,最后调用PackThDebugInstance()把所有实例配置一次性打包进内存数组。PackThDebugInstance()(见 InternalTraceHubApi.c)在有 HOB 时逐个CopyMem复制 HOB 数据,无 HOB 时用三个固定 PCD 填充数组元素。这种"构造时快照"避免了每次输出消息都重复遍历 HOB 列表,更适合 DXE/SMM 高频调用场景。

三个实例速查对比

库实例配置来源实例数适用模块类型特殊机制
BaseTraceHubDebugSysTLib仅固定 PCD固定 1 个通用(无模块限定)无
PeiTraceHubDebugSysTLibPCD + HOB(HOB 优先)按 HOB 计数,无 HOB 则 1PEI_CORE、PEIM每次调用遍历 HOB
DxeSmmTraceHubDebugSysTLibPCD + HOB(HOB 优先)按 HOB 计数,无 HOB 则 1DXE/SMM 系列模块库构造器快照实例配置

内部实现机制:消息如何被决定输出

无论哪个实例,底层都会复用 InternalTraceHubApiCommon.c 中的公共判定逻辑,一条消息是否真正写入 Trace Hub 取决于三层条件:

  1. 使能标志:GetTraceHubMsgVisibility()读取配置(有 HOB 时读ThDbgContext->Flag,否则读FixedPcdGetBool (PcdEnableTraceHubDebugMsg));TraceHubDataEnabled()中Flag == TraceHubRoutingDisable(即 FALSE)直接不输出。
  2. 调试级别过滤:TraceHubDataEnabled()按DbgLevel与SeverityType组合判定(见上文 PCD 取值表),例如DbgLevel == TraceHubDebugLevelError时只有SeverityFatal/SeverityError放行。
  3. MMIO 地址有效性:GetTraceHubMmioAddress()解析输出地址(HOB 优先,否则FixedPcdGet64 (PcdTraceHubDebugMmioAddress)),地址为 0 时CheckWhetherToOutputMsg返回RETURN_ABORTED,消息被丢弃。

只有全部条件通过,MipiSystWriteDebug或MipiSystWriteCatalog才会真正把消息写入 Trace Hub MMIO。此外,目录消息还会通过SwapBytesGuid()(InternalTraceHubApiCommon.c)将 GUID 的Data1/Data2/Data3字段做小端/大端互换,以满足 MIPI SYS-T 协议对 GUID 字段的字节序要求。

使用限制与注意事项

Readme 明确给出一条重要限制:Trace Hub 调试库目前不支持DXE_RUNTIME_DRIVER类型的模块。这是因为运行时驱动在 ExitBootServices 之后运行于无 MMU 映射保障的环境,直接访问 Trace Hub MMIO 地址可能导致异常;需要运行时输出时应改用其他日志通道(如普通串口DebugLib或非易失性日志),或将消息发送逻辑放在 DXE 驱动而非 Runtime 驱动中。

另外还需注意:TraceHubDebugSysTLib是输出路径的"顶层库",它依赖MipiSysTLib(mipi_syst.h)完成 SYS-T 协议封装;平台若要启用完整 Trace Hub 调试链路,还需保证硬件侧 Trace Hub 控制器(通常位于 SoC 的 Debug 子系统)已被正确初始化和使能,并把对应的 MMIO 基地址填入 PCD/HOB。

在平台中的集成步骤

综合上文,在一个 EDK II 平台中启用 Trace Hub 调试消息的完整步骤如下:

  1. 声明库依赖:在模块的.inf中[LibraryClasses]添加TraceHubDebugSysTLib(以及传递依赖的MipiSysTLib),并[Packages]包含MdePkg/MdePkg.dec与MdeModulePkg/MdeModulePkg.dec。若需要 HOB 支持,还需在[Guids]中声明gTraceHubDebugInfoHobGuid(参考 PeiTraceHubDebugSysTLib.inf 的写法)。
  2. 选择实例:在平台 DSC 的[LibraryClasses.common.PEIM]、[LibraryClasses.common.DXE_DRIVER]等段中,把TraceHubDebugSysTLib映射到PeiTraceHubDebugSysTLib/DxeSmmTraceHubDebugSysTLib(或纯固定 PCD 场景使用BaseTraceHubDebugSysTLib)。
  3. 配置三个 PCD:按上文表格在[PcdsFixedAtBuild]或动态 PCD 段设置PcdEnableTraceHubDebugMsg、PcdTraceHubDebugLevel、PcdTraceHubDebugMmioAddress。
  4. (可选)发布 HOB:多实例场景下,由早期阶段(SEC/PEI)以gTraceHubDebugInfoHobGuid为 GUID 构建TRACEHUB_DEBUG_INFO_HOB数据并发布,后续阶段即可自动发现并遍历所有实例;无 HOB 时库会安全回退到 PCD。
  5. 调用 API:在代码中#include <Library/TraceHubDebugSysTLib.h>,按需调用TraceHubSysTDebugWrite(调试字符串)、TraceHubSysTWriteCataLog64StatusCode(状态码)或TraceHubSysTWriteCataLog64(带参目录消息)。

通过以上配置,固件即可在 SEC/PEI/DXE/SMM 各阶段把调试消息经 MIPI SYS-T 协议送入 Trace Hub,由调试探针在主机侧还原成可读日志——这也是 Intel 平台固件调试中"无串口"场景下常用的可追踪日志方案。

  • 固件
  • 操作系统
  • 驱动开发
  • 嵌入式

【免费下载链接】edk2

EDK II

项目地址:https://gitcode.com/gh_mirrors/ed/edk2
点击查看免费下载

相关推荐

上一篇:MMPose WholeBody:重新定义全身姿态估计的133关键点革命
下一篇:工作流参数传递:Apache DolphinScheduler上下文变量使用技巧

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询