ATF官方文档翻译(十五):ATF固件设计(Firmware Design)-发布和订阅框架&&性能测量框架

1、发布和订阅框架

发布和订阅框架允许EL3组件定义和发布其他EL3组件可以订阅的事件。
框架提供了以下宏:

  • •REGISTER_PUBSUB_EVENT(事件):定义事件,并接受一个参数,即事件名称,该参数必须是有效的C标识符。对REGISTER_PUBSUB_EVENT宏的所有调用都必须放在PUBSUB_events.h文件中。

  • •PUBLISH_EVENT_ARG(事件,ARG):通过迭代订阅的处理程序并依次调用它们,发布已定义的事件。将向处理程序传递参数arg。预期的用例是广播事件。

  • •PUBLISH_EVENT(事件):与PUBLISH-EVENT_ARG类似,只是将值NULL传递给订阅的汉德勒。

  • •SUBSCRIBE_TO_EVENT(事件,处理程序):注册处理程序以订阅事件。无论何时发布事件,都将执行处理程序。

  • •for_each_subscriber(事件,订阅者):遍历订阅事件的所有处理程序。
    subscriber必须是pubsubcb类型的本地变量,并在迭代期间依次指向每个订阅的处理程序。此宏可用于PUBLISH_EVENT_()宏都未覆盖的模式。

发布未使用REGISTER_PUBSUB_event定义的事件将导致生成错误。但是,订阅未定义的事件不会。
订阅的处理程序必须是pubsub_cb_t类型,具有以下函数签名:

在这里插入图片描述
可能有任意数量的处理程序注册到同一事件。未定义发布事件时通知订阅的处理程序的顺序。订阅的处理程序可以按任何顺序执行;处理程序不应假定它们之间有任何相对顺序。

在PE上发布事件将导致订阅的处理程序仅在该PE上执行;它不会导致处理程序在不同的PE上执行。

注意,在PE上发布事件会阻止所有订阅的处理程序在PE上完成执行。

TF-A通用代码发布和订阅中的某些事件。不鼓励平台端口订阅它们。这些事件将来可能会被撤回、重命名或更改其语义。然而,平台可以注册、发布和订阅特定于平台的事件。

1、发布和订阅示例

想要发布事件foo的发布者将:

  • •在pubsub_events.h中定义事件foo。
    在这里插入图片描述

  • •根据事件的性质,使用PUBLISH_EVENT_*()宏之一在适当的路径和执行时间发布事件。

想要订阅上面发布的事件foo的订阅者将实现:
在这里插入图片描述
ATF官方文档翻译(十五):ATF固件设计(Firmware Design)-发布和订阅框架&&性能测量框架_第1张图片

2、回收BL31初始化代码

用于BL31初始化的大量代码在引导时间之后不再需要。为了减少运行时内存占用,可以在初始化完成后回收用于此代码的内存,并将其用于运行时数据。

构建选项RECLAIM_INIT_CODE可以设置为使用.text.INIT.*属性标记此启动时代码,该属性可以被过滤并适当地放置在BL映像中,以便稍后由平台回收。平台可以通过plat.ld.S链接器脚本为BL31中的这个init部分指定筛选器和内存区域。例如,在FVP上,此部分与辅助CPU堆栈重叠放置,以便在冷启动完成后,可以为堆栈回收此内存。

init内存部分最初使用RO、EXECUTE属性进行映射。BL31初始化完成后,FVP将此部分的属性更改为RW,EXECUTE_NEVER,允许将其用于运行时数据。内存属性在bl31_plat_runtime_setup平台挂钩中更改。对于冷启动初始化后访问的任何数据,可以回收init部分,由平台做出决定。

2、性能测量框架

性能度量框架(PMF)便于注册服务收集时间戳,并提供接口从TF-A中检索时间戳。平台可以选择公开适当的SMC来检索这些收集的时间戳。

默认情况下,全局物理计数器用于时间戳值,并通过CNTPCT_EL0读取。该框架允许检索其他CPU捕获的时间戳。

1、时间戳标识符格式

PMF时间戳通过时间戳ID或tid在整个系统中唯一标识。tid组成如下:

在这里插入图片描述

  • 1.服务标识符。每个PMF服务由服务名称和服务标识符标识。服务名称和标识符在整个系统中都是唯一的。

  • 2.本地时间戳标识符。该标识符在给定服务中是唯一的。

2、注册PMF服务

要注册PMF服务,使用PMF.h中的PMF_register_service()宏。所需的参数包括服务名称、服务ID、要捕获的本地时间戳总数和一组标志。

标志字段可以指定为以下值的按位OR:

在这里插入图片描述
构建时间。此外,它还定义了必要的函数,以在运行时捕获和检索给定服务的特定时间戳。

宏PMF_REGISTER_SERVICE()仅允许从TF-A中捕获PMF时间戳。为了从TF-A外部重新检索时间戳,必须改用PMF_REGISTER_SERVICE_SMC()宏。此宏接受与PMF_REGISTER_SERVICE()宏相同的参数集,但另外支持使用SMC检索时间戳。

3、捕获时间戳

PMF时间戳存储在每个服务时间戳区域中。在具有多个CPU的系统上,每个时间戳都被捕获并存储在每CPU缓存行对齐的内存区域中。

注册服务后,可以使用PMF_CAPTURE_TIMESTAMP()宏在使用位置捕获时间戳。宏将服务名称、本地时间戳标识符和标志作为参数。

标志字段参数可以是零,也可以是PMF_CACHE_MAINT,它指示PMF在捕获后进行缓存维护。如果在禁用数据缓存的情况下捕获服务的任何时间戳,则需要进行缓存维护。

要在汇编代码中捕获时间戳,调用者应该使用pmf_calc_timestamp_addr宏(在pmf_asm_macros.S中定义)来计算存储时间戳的地址。然后,调用者应该读取CNTPCT_EL0寄存器以获得时间戳,并将其存储在确定的地址以供以后检索。

4、检索时间戳

在TF-A中,可以使用PMF_GET_TIMESTAMP_BY_MPIDR()或PMF_GE_TIMESTAMP_BY_INDEX()宏检索各个CPU的时间戳。这些宏分别接受CPU的MPIDR值或其序号位置。

从TF-A外部,可以通过调用pmf_smc_handler()来检索各个CPU的时间戳。
ATF官方文档翻译(十五):ATF固件设计(Firmware Design)-发布和订阅框架&&性能测量框架_第2张图片
ATF官方文档翻译(十五):ATF固件设计(Firmware Design)-发布和订阅框架&&性能测量框架_第3张图片

其余的参数x4、cookie、句柄和标志在此实现中未使用。

5、PMF代码结构

  • 1.pmfmain.c由实现服务注册、初始化、存储、转储和检索时间戳的核心功能组成。

  • 2.pmf_smc.c包含已注册pmf服务的smc处理。

  • 3.pmf.h包含性能度量框架的公共接口。

  • 4.pmf_asm_macros.S由宏组成,以便于在汇编代码中捕获时间戳。

  • 5.pmf_helpers.h是pmf.h使用的内部标头。

你可能感兴趣的:(#,ATF原生,ATF,系统安全)