UEFI学习——事件函数WaitForEvent和CreateEvent/CreateEventEx

       本文参考戴正华《UEFI原理与编程》

1.等待事件的服务WaitForEvent

       启动服务中的WaitForEvent服务的函数原型:

/**等待Event数组内任一事件被触发@retval EFI_SUCCESS               下表为*index的事件被触发@retval EFI_UNSUPPORTED           当前的TPL不是TPL_APPLICATION@retval EFI_INVALID_PARAMETER     下标为*index的事件类型为EVT_NOTIFY_SIGNAL
**/
typedef EFI_STATUS (EFIAPI *EFI_WAIT_FOR_EVENT) (IN UINTN NumberOfEvents,          //Event数组内Event的个数IN EFI_EVENT *Event,              //Event数组OUT UINTN *Index                  //返回处于触发态的事件在数组内的下标);

       WaitForEvent是阻塞操作,直到Event数组内任一事件被触发,或任一事件导致错误出现,WaitForEvent才返回。WaitForEvent从前到后依次检查Event数组内的事件,发现有被触发的事件或遇到错误则返回,如果所有事件都没有被触发,则从头开始重新检查。
       当检查到某个事件处于触发态时,*Index赋值为该事件在Event数组中的下标,返回前该事件将重置为非触发态。
当检查到某个事件是EVT_NOTIFY_SIGNAL类型时,*Index赋值为该事件在Event数组中的下标,并返回EFI_INVALID_PARAMETER。
       WaitForEvent必须运行在TPL_APPLICATION级别,否则将返回EFI_UNSUPPORTED。

2.生成事件的服务CreateEvent

       启动服务中的CreateEvent服务的函数原型

//生成一个事件
typedef EFI_STATUS (EFIAPI *EFI_CREATE_EVENT) (IN UINT32 Type,                               //事件类型IN EFI_TPL NotifyTpl,                         //事件Notification函数的优先级IN EFI_EVENT_NOTIFY NotifyFunction,           //事件Notification函数IN VOID *NotifyContext,                       //传给事件Notification函数的参数OUT EFI_EVENT *Event                          //生成的事件
);

       参数IN UINT32 Type是事件的类型,常用的几种事件类型如表1所示。
                                                                                                         表1

事件类型事件特征
EVT_TIMER定时器事件。普通Timer事件,没有Notification函数。生成事件后需调用SetTimer服务设置时钟属性。事件可以:
①通过SetTimer()设置等待事件 ②到期后通过SignalEvent()触发
③通过WaitForEvent()等待事件被触发④通过CheckEvent()检查状态
EVT_NOTIFY_WAIT普通事件。这个事件有一个Notification函数,当这个事件通过CheckEvent()检查状态或通过WaitForEvent()等待时,这个Notification函数会被放到待执行队列gEventQueue[Event->NotifyTpl]中
EVT_NOTIFY_SIGNAL普通事件。这个事件有一个Notification函数,当这个事件通过SignalEvent()被触发时,这个Notification函数会被放到待执行队列gEventQueue[Event->NotifyTpl]中
0x00000000普通事件。此类事件没有Notification函数。事件可以:
①通过SignalEvent()被触发②通过WaitForEvent()等待事件被触发③通过CheckEvent()检查状态
EVT_TIMER | EVT_NOTIFY_WAIT带Notification函数的定时器事件。此类事件除了具有EVT_TIMER的特性外,还有EVT_NOTIFY_WAIT的特性,即到后期通过SignalEvent()触发。当事件通过CheckEvent()检查状态或通过WaitForEvent()等待时,这个Notification函数回被放到执行队列gEventQueue[Event->NotifyTpl]中
EVT_TIMER | EVT_NOTIFY_SIGNAL带Notification函数的定时器事件。此类事件除了具有EVT_TIMER的特性外,还有EVT_NOTIFY_SIGNAL的特性,即到后期通过SignalEvent()触发。当这个事件通过SignalEvent()被触发时,这个Notification函数会被放到待执行队列gEventQueue[Event->NotifyTpl]中

       CreateEvent的第二个参数为NotifyTPL(即任务优先级),它可以是0~31的一个整数。UEFI预定义了以下4个优先级。

#define TPL_APPLICATION   4
#define TPL_CALLBACK      8
#define TPL_NOTIFY        16
#define TPL_HIGH_LEVEL    31

       优先级别高的任务可以中断级别低的任务,并且从高优先级返回低优先级前会完成所有高于低优先级的任务。表2列出了UEFI预定义的4个任务优先级。
                                                                                                         表2

任务优先级用法函数
TPL_APPLICATION这是预定义的4个级别中最低的一个优先级。应用程序运行(包括Boot Manager和OS Loader)在这个级别。当程序运行在这个级别时,任务队列中没有任何处于就绪状态的事件Notification函数下列函数运行在此级别:
ExitBootServices()、WaitForEvent()、User Manager Protocol/Identify()、Form Browser2 Protocol/SendForm
下列函数运行在此级别或更低级别:
Simple Input Protocol
TPL_CALLBACK比较耗时的操作通常在这个优先级执行,如文件系统、磁盘操作等下列函数运行在此级别或更低级别:
Exit();Serial I/O Protocol、UnloadImage()、Variable Services、NetWork Service Binding、Network Protocol
下列函数运行在低于8的级别:
LoadImage()、StartImage()
TPL_NOTIFY运行在这个级别的程序不允许阻塞,必须尽快执行完毕并且返回。如果需要更多操作,则需要使用Event由内核重新调度。通常,底层的IO操作允许在这个级别,例如UEFI内核中读取键盘状态的代码。大部分Event的Notification函数允许在这个级别下列函数运行在此级别或更低级别:
Protocol Handle Services、Memory Allocation Services、Simple Text Output Protocol、ACPI Table Protocol、User Manager Protocol、User Credential Protocol、User Info Protocol、Authentication Info、Device Path Utilities、Device Path Form Text、EDID Discovered、EDID Active、Graphics Output EDID Override、iSCSI Initiator Name、Tape IO、Deferred Image Load Protocol、HII Protocols、Driver Health
下列函数运行在低于16的级别:
ACPI Table Protocol
TPL_HIGH_LEVEL优先级最高级别。在此级别,中断被禁止。UEFI 内核全局变量的修改需要允许在这个级别下列函数运行在此级别或更低级别:
SignalEvent()、Stall()
下列函数运行在低于31的级别:
CheckEvent()、CloseEvent()、CreateEvent()、SetTimer()、Event Notofication Levels运行在(TPL_APPLICATION,TPL_HIGH_LEVEL)区间的优先级上

       CreateEvent的第三个参数NotifyFunction是EFI_EVENT_NOTIFY类型的函数指针,它的函数原型是:

/**Invoke a notification event@param[in]  Event                 Event whose notification function is being invoked.@param[in]  Context               The pointer to the notification function's context,which is implementation-dependent.**/
typedef
VOID
(EFIAPI *EFI_EVENT_NOTIFY)(IN  EFI_EVENT                Event,IN  VOID                     *Context);

       如果事件的类型是EVENT_NOTIFY_WAIT,则EFI_EVENT_NOTIFY函数会在等待此事件的过程中被调用;如果事件的类型是EVT_NOTIFY_SIGNAL,则EFI_EVENT_NOTIFY函数会在事件触发时被调用。既没有EVT_NOTIFY_WAIT属性也没有EVT_NOTIFY_SIGNAL属性的事件,Notification参数将被忽略。
       CreateEvent的第4个参数是NotifyContext,将在Notification函数被调用时作为Notification函数的第2个参数传递给该函数,用于指向这个Notification函数的上下文。

3.CreateEventEx服务

       函数原型(其函数指针):

/**Creates an event in a group.@param[in]   Type             The type of event to create and its mode and attributes.@param[in]   NotifyTpl        The task priority level of event notifications,if needed.@param[in]   NotifyFunction   The pointer to the event's notification function, if any.@param[in]   NotifyContext    The pointer to the notification function's context; corresponds to parameterContext in the notification function.@param[in]   EventGroup       The pointer to the unique identifier of the group to which this event belongs.If this is NULL, then the function behaves as if the parameters were passedto CreateEvent.@param[out]  Event            The pointer to the newly created event if the call succeeds; undefinedotherwise.@retval EFI_SUCCESS           The event structure was created.@retval EFI_INVALID_PARAMETER One or more parameters are invalid.@retval EFI_OUT_OF_RESOURCES  The event could not be allocated.**/
typedef
EFI_STATUS
(EFIAPI *EFI_CREATE_EVENT_EX)(IN       UINT32                 Type,                       //事件类型IN       EFI_TPL                NotifyTpl,                  //事件Notification函数的优先级IN       EFI_EVENT_NOTIFY       NotifyFunction OPTIONAL,    //事件Notification函数IN CONST VOID                   *NotifyContext OPTIONAL,    //传给事件Notification函数的参数IN CONST EFI_GUID               *EventGroup    OPTIONAL,    //事件组OUT      EFI_EVENT              *Event                      //生成的事件);

       由CreateEventEx生成的事件会加入到EventGroup中,当EventGroup中的任一事件被触发后,组中的所有其他事件都会被触发,进而同组内所有的Notification函数都将被加入到待执行队列。同组内NotifyTpl(优先级)高的Notification函数会先被执行。
如果输入参数EventGroup为NULL,则CreateEventEx退化为CreateEvent。
       关于CreateEventEx的示例代码可以看我的另一篇博客:UEFI学习——使用gRT->GetVariable读取Setup选项值
       在这个博客中对CreateEventEx的使用过程如下图:
                                                 在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/354169.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

开宗明义—UEFI介绍 (二)

UEFI介绍 声明 上一篇介绍了UEFI的发展历史,以及对UEFI在ARM嵌入式领域的生态状况做了简单的调研。本篇旨在对UEFI规范和PI规范的内容以及二者之间的关系做一个简单的梳理。 本篇参考内容主要来源于以下3方面: (1) 微信公众号“ Wolf UEFI社区 ”系列文章…

UEFI学习——使用gRT->GetVariable读取Setup选项值

先列出代码&#xff0c;程序的解释在后面。 代码&#xff1a; #include <Uefi.h> #include <Library/UefiBootServicesTableLib.h> #include <Library/UefiRuntimeServicesTableLib.h> #include <Library/DebugLib.h> #include <Universal\DriverS…

2.1 对称量量化和非对称量化

前言 int8的数据范围可以表示为-128到127之间的整数 uint8的数据范围可以表示为0到255之间的整数 注释&#xff1a;int8就是用8个比特位来保存整数&#xff0c;第一位用来表示符号。uint8表示无符号整数&#xff0c;没有符号位&#xff0c;8个比特位全部用来表示整数。 1.问题…

Zinx框架学习 - 连接管理

Zinx - V0.9 连接管理 每个服务器的能够处理的最大IO数量是有限的&#xff0c;根据当前服务器能开辟的IO数量决定&#xff0c;最终决定权是内存大小现在我们要为Zinx框架增加链接个数的限定&#xff0c;如果超过⼀定量的客户端个数&#xff0c;Zinx为了保证后端的及时响应&…

澳网:公茂鑫/张择创历史 中国男网夺大满贯首胜

资料图&#xff1a;张择在比赛中。 中新网1月16日电 16日&#xff0c;2019年澳大利亚网球公开赛男双第一轮展开争夺&#xff0c;中国组合张择/公茂鑫苦战3盘战胜马特沃斯基/克里赞&#xff0c;收获中国男网在大满贯正赛的首场胜利&#xff0c;创造历史。 首盘比赛&#xff0c…

吴易昺,创造历史

中国网坛历史性一刻图片 当地时间2月12日 在ATP250达拉斯男单决赛中 中国球员吴易昺&#xff08;bǐng&#xff09;延续出色状态 顶住对手44记ACE的猛烈冲击&#xff0c;化解四个赛点后&#xff0c;以6-7(4)、7-6(3)、7-6(12)击败伊斯内尔&#xff0c;夺得个人以及中国大陆男网…

百合网“免费”革命 一场饮鸩止渴的大戏

在线婚恋市场一直以来都是有风乍起&#xff0c;吹乱一池春水的同时&#xff0c;也往往会带来自身的迷茫。 刚宣布融了15亿资的百合网计划下一步登陆A股&#xff0c; 于是推出了免费沟通的杀手锏&#xff0c;更是号称要彻底颠覆婚恋行业——果然是腰包鼓了&#xff0c;说话都财大…

澳网见证三巨头书写伟大时代 中国军团多点开花

中新网客户端北京1月28日电(记者 岳川) 随着排名世界第一的德约科维奇在男单决赛中直落三盘击败老对手纳达尔&#xff0c;2019年度澳大利亚网球公开赛大幕落下。这是一届注定会在未来被时常提起的赛事&#xff0c;罗德-拉沃尔球场见证了女单新霸主的诞生&#xff0c;见证了德约…

全球最大同性交友平台骚操作

文章目录 搜索快捷键高亮显示插件 github作为全球最大代码库&#xff0c;日常学习or工作都离不开她&#xff0c;这里介绍一些平时使用方面的技巧。 搜索 比如我们需要搜索spring boot相关的项目&#xff0c;如果直接搜索spring boot&#xff0c;结果如下&#xff1a; 可以看到…

RSA加密算法解析

目录 RSA加密 数学原理 证明: 欧拉函数 欧拉定理 模反元素 模运算 指数运算 同余 欧几里德算法GCD 填充(padding) 对称加密的应用工作流程 非对称加密的应用工作流程 1&#xff09;加密过程 2&#xff09;解密过程 代码实现 密码学知识扩展 加密体制 如何破解…

探究Vue源码:mustache模板引擎(1) 什么是模板引擎

之前在讲虚拟dom和diff算法时说过后续会讲模板引擎 啊 那这边 说到做到哈 对这个问题 有个比较官方的回答 模板引擎是将数据变为视图的最优雅的解决方案 比如 将左侧数据变为右侧视图 大家应该最先想到的就是 v-for 其实 v-for 就是一种模板引擎语法 从图中看出 模板引擎处理…

氟化物选择吸附树脂Tulsimer ®CH-87 ,锂电行业废水行业矿井水除氟专用树脂

氟化物选择吸附树脂 Tulsimer CH-87 是一款去除水溶液中氟离子的专用的凝胶型选择性离子交换树脂。它是具有氟化物选择性官能团的交联聚苯乙烯共聚物架构的树脂。 去除氟离子的能力可以达到 1ppm 以下的水平。中性至碱性的PH范围内有较好的工作效率&#xff0c;并且很容易再生…

学习HTTP2

这是有关HTTP最后一部分内容的学习啦~今天一起来学习HTTP/2&#xff01; HTTP2 HTTP/2&#xff08;超文本传输协议第2版&#xff0c;最初命名为HTTP 2.0&#xff09;&#xff0c;简称为h2&#xff08;基于TLS/1.2或以上版本的加密连接&#xff09;或h2c&#xff08;非加密连接…

补番推荐

目录 first弹丸论破 second 学园默示录 third罪恶王冠 FIRST 弹丸论破 http://v.pptv.com/show/Dym1MpoAcK4Rj1M.html 本作在背景设定方面&#xff0c;游戏中当玩家们找出犯人的时候&#xff0c;犯人将会因此而被处置杀害。不过如果玩家们不能找出真正的犯人&#xff0c…

职业生涯规划-转[Mark.Chan]

转载自:https://www.cnblogs.com/mark-chan/p/5380135.html 担任公司高管的几年间&#xff0c;我面试过数以百计的各个层面的员工&#xff0c;其中最让我感到遗憾的一个现象就是很多人有着非常好的素质&#xff0c;甚至有的还是名校的毕业生&#xff0c;因为不懂得去规划自己的…

qq修改群名服务器失败,qq建群失败什么原因 q群一直创建失败 - 云骑士一键重装系统...

Q群聊创建一直失败是什么原因&#xff0c;一起来了解一下吧 QQ群创建失败会有以下几种情况&#xff0c;请您参考&#xff1a; 提示“敏感字眼/输入不符合规范”&#xff1a; 由于群名称或群简介内容中含敏感受限词汇导致&#xff0c;建议您检查后删除再尝试。 提示“系统繁忙&a…

python数据可视化-matplotlib学习总结

目录 &#xff08;一&#xff09;常见的图形 1、趋势图&#xff08;直线图&#xff09;&#xff1a;plot&#xff08;&#xff09; 2、散点图&#xff1a;scatter(): (二&#xff09;统计图形 1、柱状图&#xff1a;bar( 2、条形图&#xff1a;barh() 3、直方图&#xff…

搭建ubuntu容器内C/C++开发调试环境

一、创建容器 为了让容器内的调试器&#xff08;gdb、lldb&#xff09;能够正常调试&#xff0c;在创建容器时需要添加参数&#xff1a; podman添加参数&#xff1a;--cap-addSYS_PTRACE&#xff0c;docker添加参数--cap-addSYS_PTRACE --security-opt seccompunconfined 否…

不知道图片变漫画怎么弄?来跟我学这几个简单的方法

我想问经常换头像的朋友一个问题&#xff0c;你们有用过自己的漫画脸当头像吗&#xff1f;如果我们把自己的头像做成漫画脸不仅不容易和别人撞头像而且更加能贴合我们自身的形象。那你们知道漫画脸怎么拍吗&#xff1f;今天我来给大家分享几个漫画脸制作都的方法。有兴趣的朋友…

适合剪辑新手的几个网站

现在越来越多的人喜欢剪辑视频了&#xff0c;现在我就推荐几个不错的适合剪辑新手的网站。 1.Videvo 这是一个提供高清或 4K 音频和视频的网站。它的视频分类详细&#xff0c;主要的分类有镜头和图文。 我更喜欢它的镜头类型下的视频&#xff0c;每一帧都很好看&#xff01; …