CoreTimerTick 是ueif的timer中断的处理函数,也是uefi中唯一支持的中断。
其路径在mdemodulepkg/core/dxe/event
CoreTimerTick (
IN UINT64 Duration
)
{
IEVENT *Event;
CoreAcquireLock (&mEfiSystemTimeLock);
mEfiSystemTime += Duration;
if (!IsListEmpty (&mEfiTimerList)) {
Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE);
if (Event->Timer.TriggerTime <= mEfiSystemTime) {
CoreSignalEvent (mEfiCheckTimerEvent);
}
}
CoreReleaseLock (&mEfiSystemTimeLock);
}
CoreTimerTick 中首先更新系统时间 mEfiSystemTime += Duration;通过下面方式的到系统时间的时候要加锁,
UINT64
CoreCurrentSystemTime (
VOID
)
{
UINT64 SystemTime;
CoreAcquireLock (&mEfiSystemTimeLock);
SystemTime = mEfiSystemTime;
CoreReleaseLock (&mEfiSystemTimeLock);
return SystemTime;
}
就是因为会在中断函数CoreTimerTick 中更新这个值。
CoreTimerTick 中还有检测系统中定时器事件是否到期,如果到期的话就触发event函数CoreSignalEvent (mEfiCheckTimerEvent);
CoreSignalEvent (
IN EFI_EVENT UserEvent
)
{
IEVENT *Event;
Event = UserEvent;
if (Event == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Event->Signature != EVENT_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
CoreAcquireEventLock ();
//
// If the event is not already signalled, do so
//
if (Event->SignalCount == 0x00000000) {
Event->SignalCount++;
//
// If signalling type is a notify function, queue it
//
if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
if ((Event->ExFlag & EVT_EXFLAG_EVENT_GROUP) != 0) {
//
// The CreateEventEx() style requires all members of the Event Group
// to be signaled.
//
CoreReleaseEventLock ();
CoreNotifySignalList (&Event->EventGroup);
CoreAcquireEventLock ();
} else {
CoreNotifyEvent (Event);
}
}
}
CoreReleaseEventLock ();
return EFI_SUCCESS;
}
CoreSignalEvent 中会比较Event->Type & EVT_NOTIFY_SIGNAL ,如果不成立说明不需要发送event直接返回
如果成立的话还要判断Event->ExFlag & EVT_EXFLAG_EVENT_GROUP 也就是有没有设定event group ,如果设定的话
就call CoreNotifySignalList (&Event->EventGroup);
来判断Event->EventGroup 是否和mEfiCheckTimerEvent 的event group是否相等
VOID
CoreNotifySignalList (
IN EFI_GUID *EventGroup
)
{
LIST_ENTRY *Link;
LIST_ENTRY *Head;
IEVENT *Event;
CoreAcquireEventLock ();
Head = &gEventSignalQueue;
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
if (CompareGuid (&Event->EventGroup, EventGroup)) {
CoreNotifyEvent (Event);
}
}
CoreReleaseEventLock ();
}
如果相等就调用CoreNotifyEvent来将这个event加入到gEventQueue 中,
VOID
CoreNotifyEvent (
IN IEVENT *Event
)
{
//
// Event database must be locked
//
ASSERT_LOCKED (&gEventQueueLock);
//
// If the event is queued somewhere, remove it
//
if (Event->NotifyLink.ForwardLink != NULL) {
RemoveEntryList (&Event->NotifyLink);
Event->NotifyLink.ForwardLink = NULL;
}
//
// Queue the event to the pending notification list
//
InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
gEventPending |= (UINTN)(1 << Event->NotifyTpl);
}
也就是这个时候其实并没有触发event,所以uefi里的timer event会在规定时候晚一点执行
具体是在CoreRestoreTpl ->CoreDispatchEventNotifies 才来触发event
在CoreRestoreTpl 中会按照Priority 来调用CoreDispatchEventNotifies。一个level的Priority执行完后在call下一个Priority
**/
VOID
CoreDispatchEventNotifies (
IN EFI_TPL Priority
)
{
IEVENT *Event;
LIST_ENTRY *Head;
CoreAcquireEventLock ();
ASSERT (gEventQueueLock.OwnerTpl == Priority);
Head = &gEventQueue[Priority];
//
// Dispatch all the pending notifications
//
while (!IsListEmpty (Head)) {
Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
RemoveEntryList (&Event->NotifyLink);
Event->NotifyLink.ForwardLink = NULL;
//
// Only clear the SIGNAL status if it is a SIGNAL type event.
// WAIT type events are only cleared in CheckEvent()
//
if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
Event->SignalCount = 0;
}
CoreReleaseEventLock ();
//
// Notify this event
//
ASSERT (Event->NotifyFunction != NULL);
Event->NotifyFunction (Event, Event->NotifyContext);
//
// Check for next pending event
//
CoreAcquireEventLock ();
}
gEventPending &= ~(UINTN)(1 << Priority);
CoreReleaseEventLock ();
}
CoreDispatchEventNotifies 中就首先执行注册event的时候的NotifyFunction函数。Event->NotifyFunction (Event, Event->NotifyContext);
最后将这一个Priority 需要需要执行的pendingevent清零. gEventPending &= ~(UINTN)(1 << Priority);
其路径在mdemodulepkg/core/dxe/event
CoreTimerTick (
IN UINT64 Duration
)
{
IEVENT *Event;
CoreAcquireLock (&mEfiSystemTimeLock);
mEfiSystemTime += Duration;
if (!IsListEmpty (&mEfiTimerList)) {
Event = CR (mEfiTimerList.ForwardLink, IEVENT, Timer.Link, EVENT_SIGNATURE);
if (Event->Timer.TriggerTime <= mEfiSystemTime) {
CoreSignalEvent (mEfiCheckTimerEvent);
}
}
CoreReleaseLock (&mEfiSystemTimeLock);
}
CoreTimerTick 中首先更新系统时间 mEfiSystemTime += Duration;通过下面方式的到系统时间的时候要加锁,
UINT64
CoreCurrentSystemTime (
VOID
)
{
UINT64 SystemTime;
CoreAcquireLock (&mEfiSystemTimeLock);
SystemTime = mEfiSystemTime;
CoreReleaseLock (&mEfiSystemTimeLock);
return SystemTime;
}
就是因为会在中断函数CoreTimerTick 中更新这个值。
CoreTimerTick 中还有检测系统中定时器事件是否到期,如果到期的话就触发event函数CoreSignalEvent (mEfiCheckTimerEvent);
CoreSignalEvent (
IN EFI_EVENT UserEvent
)
{
IEVENT *Event;
Event = UserEvent;
if (Event == NULL) {
return EFI_INVALID_PARAMETER;
}
if (Event->Signature != EVENT_SIGNATURE) {
return EFI_INVALID_PARAMETER;
}
CoreAcquireEventLock ();
//
// If the event is not already signalled, do so
//
if (Event->SignalCount == 0x00000000) {
Event->SignalCount++;
//
// If signalling type is a notify function, queue it
//
if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
if ((Event->ExFlag & EVT_EXFLAG_EVENT_GROUP) != 0) {
//
// The CreateEventEx() style requires all members of the Event Group
// to be signaled.
//
CoreReleaseEventLock ();
CoreNotifySignalList (&Event->EventGroup);
CoreAcquireEventLock ();
} else {
CoreNotifyEvent (Event);
}
}
}
CoreReleaseEventLock ();
return EFI_SUCCESS;
}
CoreSignalEvent 中会比较Event->Type & EVT_NOTIFY_SIGNAL ,如果不成立说明不需要发送event直接返回
如果成立的话还要判断Event->ExFlag & EVT_EXFLAG_EVENT_GROUP 也就是有没有设定event group ,如果设定的话
就call CoreNotifySignalList (&Event->EventGroup);
来判断Event->EventGroup 是否和mEfiCheckTimerEvent 的event group是否相等
VOID
CoreNotifySignalList (
IN EFI_GUID *EventGroup
)
{
LIST_ENTRY *Link;
LIST_ENTRY *Head;
IEVENT *Event;
CoreAcquireEventLock ();
Head = &gEventSignalQueue;
for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
if (CompareGuid (&Event->EventGroup, EventGroup)) {
CoreNotifyEvent (Event);
}
}
CoreReleaseEventLock ();
}
如果相等就调用CoreNotifyEvent来将这个event加入到gEventQueue 中,
VOID
CoreNotifyEvent (
IN IEVENT *Event
)
{
//
// Event database must be locked
//
ASSERT_LOCKED (&gEventQueueLock);
//
// If the event is queued somewhere, remove it
//
if (Event->NotifyLink.ForwardLink != NULL) {
RemoveEntryList (&Event->NotifyLink);
Event->NotifyLink.ForwardLink = NULL;
}
//
// Queue the event to the pending notification list
//
InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
gEventPending |= (UINTN)(1 << Event->NotifyTpl);
}
也就是这个时候其实并没有触发event,所以uefi里的timer event会在规定时候晚一点执行
具体是在CoreRestoreTpl ->CoreDispatchEventNotifies 才来触发event
在CoreRestoreTpl 中会按照Priority 来调用CoreDispatchEventNotifies。一个level的Priority执行完后在call下一个Priority
**/
VOID
CoreDispatchEventNotifies (
IN EFI_TPL Priority
)
{
IEVENT *Event;
LIST_ENTRY *Head;
CoreAcquireEventLock ();
ASSERT (gEventQueueLock.OwnerTpl == Priority);
Head = &gEventQueue[Priority];
//
// Dispatch all the pending notifications
//
while (!IsListEmpty (Head)) {
Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
RemoveEntryList (&Event->NotifyLink);
Event->NotifyLink.ForwardLink = NULL;
//
// Only clear the SIGNAL status if it is a SIGNAL type event.
// WAIT type events are only cleared in CheckEvent()
//
if ((Event->Type & EVT_NOTIFY_SIGNAL) != 0) {
Event->SignalCount = 0;
}
CoreReleaseEventLock ();
//
// Notify this event
//
ASSERT (Event->NotifyFunction != NULL);
Event->NotifyFunction (Event, Event->NotifyContext);
//
// Check for next pending event
//
CoreAcquireEventLock ();
}
gEventPending &= ~(UINTN)(1 << Priority);
CoreReleaseEventLock ();
}
CoreDispatchEventNotifies 中就首先执行注册event的时候的NotifyFunction函数。Event->NotifyFunction (Event, Event->NotifyContext);
最后将这一个Priority 需要需要执行的pendingevent清零. gEventPending &= ~(UINTN)(1 << Priority);