EDK II TraceHubDebugSysTLib 全解析:基于 MIPI SYS-T 的 Trace Hub 消息输出库
固件操作系统驱动开发嵌入式【免费下载链接】edk2EDK 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.cPeiTraceHubDebugSysTLib.inf/PeiTraceHubDebugSysTLib.cDxeSmmTraceHubDebugSysTLib.inf/DxeSmmTraceHubDebugSysTLib.cInternalTraceHubApi.c/InternalTraceHubApi.h非公共接口实例计数与打包InternalTraceHubApiCommon.c/InternalTraceHubApiCommon.h公共内部接口可见性判断、GUID 字节序转换、消息输出判定、MMIO 地址与消息可见性读取使用该库前用户必须正确配置三个 Trace Hub 相关 PCD 以及一个 HOB详见下文。PCD 的详细定义见 MdeModulePkg.decHOB 的详细定义见 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 );输出一条带目录 IDId和驱动 GUIDGuid的状态码消息。实现中会先将 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.cNumberOfParams超过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.decPcdTraceHubDebugLevelUINT8默认 0x0指示 Trace Hub 的调试级别决定哪些严重级别的消息会被输出。合法取值如下值宏允许输出的严重级别0x0TraceHubDebugLevelError仅SeverityFatal、SeverityError0x1TraceHubDebugLevelErrorWarning追加SeverityWarning0x2TraceHubDebugLevelErrorWarningInfo追加SeverityNormal0x3TraceHubDebugLevelErrorWarningInfoVerbose全部级别该过滤逻辑实现在 InternalTraceHubApiCommon.c 的TraceHubDataEnabled()中先判断使能标志再按调试级别与消息严重级别的组合决定放行或丢弃。PcdEnableTraceHubDebugMsgBOOLEAN默认 FALSE全局开关FALSE关闭 Trace Hub 调试消息TRUE打开。对应 HOB 结构中的Flag字段。PcdTraceHubDebugMmioAddressUINT64默认 0Trace 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|0xFED0F000Trace Hub HOBgTraceHubDebugInfoHobGuid除 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 1typedef 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 HOBHOB 优先按 HOB 计数无 HOB 则 1PEI_CORE、PEIM每次调用遍历 HOBDxeSmmTraceHubDebugSysTLibPCD HOBHOB 优先按 HOB 计数无 HOB 则 1DXE/SMM 系列模块库构造器快照实例配置内部实现机制消息如何被决定输出无论哪个实例底层都会复用 InternalTraceHubApiCommon.c 中的公共判定逻辑一条消息是否真正写入 Trace Hub 取决于三层条件使能标志GetTraceHubMsgVisibility()读取配置有 HOB 时读ThDbgContext-Flag否则读FixedPcdGetBool (PcdEnableTraceHubDebugMsg)TraceHubDataEnabled()中Flag TraceHubRoutingDisable即 FALSE直接不输出。调试级别过滤TraceHubDataEnabled()按DbgLevel与SeverityType组合判定见上文 PCD 取值表例如DbgLevel TraceHubDebugLevelError时只有SeverityFatal/SeverityError放行。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是输出路径的顶层库它依赖MipiSysTLibmipi_syst.h完成 SYS-T 协议封装平台若要启用完整 Trace Hub 调试链路还需保证硬件侧 Trace Hub 控制器通常位于 SoC 的 Debug 子系统已被正确初始化和使能并把对应的 MMIO 基地址填入 PCD/HOB。在平台中的集成步骤综合上文在一个 EDK II 平台中启用 Trace Hub 调试消息的完整步骤如下声明库依赖在模块的.inf中[LibraryClasses]添加TraceHubDebugSysTLib以及传递依赖的MipiSysTLib并[Packages]包含MdePkg/MdePkg.dec与MdeModulePkg/MdeModulePkg.dec。若需要 HOB 支持还需在[Guids]中声明gTraceHubDebugInfoHobGuid参考 PeiTraceHubDebugSysTLib.inf 的写法。选择实例在平台 DSC 的[LibraryClasses.common.PEIM]、[LibraryClasses.common.DXE_DRIVER]等段中把TraceHubDebugSysTLib映射到PeiTraceHubDebugSysTLib/DxeSmmTraceHubDebugSysTLib或纯固定 PCD 场景使用BaseTraceHubDebugSysTLib。配置三个 PCD按上文表格在[PcdsFixedAtBuild]或动态 PCD 段设置PcdEnableTraceHubDebugMsg、PcdTraceHubDebugLevel、PcdTraceHubDebugMmioAddress。可选发布 HOB多实例场景下由早期阶段SEC/PEI以gTraceHubDebugInfoHobGuid为 GUID 构建TRACEHUB_DEBUG_INFO_HOB数据并发布后续阶段即可自动发现并遍历所有实例无 HOB 时库会安全回退到 PCD。调用 API在代码中#include Library/TraceHubDebugSysTLib.h按需调用TraceHubSysTDebugWrite调试字符串、TraceHubSysTWriteCataLog64StatusCode状态码或TraceHubSysTWriteCataLog64带参目录消息。通过以上配置固件即可在 SEC/PEI/DXE/SMM 各阶段把调试消息经 MIPI SYS-T 协议送入 Trace Hub由调试探针在主机侧还原成可读日志——这也是 Intel 平台固件调试中无串口场景下常用的可追踪日志方案。赞分享固件操作系统驱动开发嵌入式【免费下载链接】edk2EDK II项目地址https://gitcode.com/gh_mirrors/ed/edk2点击查看免费下载相关推荐UEFI固件更新工具基于EDK II的CapsuleApp开发全指南UEFI固件更新工具基于EDK II的CapsuleApp开发全指南 引言固件更新的痛点与解决方案 你是否曾面临过UEFI固件更新过程中认证失败、依赖冲突或固件操作系统驱动开发嵌入式V8 Message 测试框架解析基于预期输出的 JavaScript 错误消息测试指南V8 Message 测试框架解析基于预期输出的 JavaScript 错误消息测试指南 导读 本文以 V8 仓库中 test/message/README.语言运行时编译器JIT编译解释器内存管理UEFI NVMe驱动开发基于EDK II的PCIe设备驱动实现UEFI NVMe驱动开发基于EDK II的PCIe设备驱动实现 引言NVMe驱动开发的技术挑战与解决方案 你是否在UEFI环境中面临NVMeNon Vo固件操作系统驱动开发嵌入式上一篇MMPose WholeBody重新定义全身姿态估计的133关键点革命下一篇工作流参数传递Apache DolphinScheduler上下文变量使用技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考