uefi timer 中断

在在mdemodulepkg/core/dxe/dxemain/dexmainc中会调用CoreNotifyOnProtocolInstallation ();
VOID
CoreNotifyOnProtocolInstallation (
  VOID
  )
{
  CoreNotifyOnProtocolEntryTable (mArchProtocols);
  CoreNotifyOnProtocolEntryTable (mOptionalProtocols);
}
我们只关注CoreNotifyOnProtocolEntryTable,注意这个函数的参数是mArchProtocols
在mdemodulepkg/core/dxe/dxemain/dxeprotocalnotify.c 中会定义一个数组
EFI_CORE_PROTOCOL_NOTIFY_ENTRY  mArchProtocols[] = {
  { &gEfiSecurityArchProtocolGuid,         (VOID **)&gSecurity,      NULL, NULL, FALSE },
  { &gEfiCpuArchProtocolGuid,              (VOID **)&gCpu,           NULL, NULL, FALSE },
  { &gEfiMetronomeArchProtocolGuid,        (VOID **)&gMetronome,     NULL, NULL, FALSE },
  { &gEfiTimerArchProtocolGuid,            (VOID **)&gTimer,         NULL, NULL, FALSE },
  { &gEfiBdsArchProtocolGuid,              (VOID **)&gBds,           NULL, NULL, FALSE },
  { &gEfiWatchdogTimerArchProtocolGuid,    (VOID **)&gWatchdogTimer, NULL, NULL, FALSE },
  { &gEfiRuntimeArchProtocolGuid,          (VOID **)&gRuntime,       NULL, NULL, FALSE },
  { &gEfiVariableArchProtocolGuid,         (VOID **)NULL,            NULL, NULL, FALSE },
  { &gEfiVariableWriteArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },
  { &gEfiCapsuleArchProtocolGuid,          (VOID **)NULL,            NULL, NULL, FALSE },
  { &gEfiMonotonicCounterArchProtocolGuid, (VOID **)NULL,            NULL, NULL, FALSE },
  { &gEfiResetArchProtocolGuid,            (VOID **)NULL,            NULL, NULL, FALSE },
  { &gEfiRealTimeClockArchProtocolGuid,    (VOID **)NULL,            NULL, NULL, FALSE },
  { NULL,                                  (VOID **)NULL,            NULL, NULL, FALSE }
};
CoreNotifyOnProtocolEntryTable 会做两件事情,
VOID
CoreNotifyOnProtocolEntryTable (
  EFI_CORE_PROTOCOL_NOTIFY_ENTRY  *Entry
  )
{
  EFI_STATUS  Status;

  for (; Entry->ProtocolGuid != NULL; Entry++) {
    //
    // Create the event
    //
    Status = CoreCreateEvent (
              EVT_NOTIFY_SIGNAL,
              TPL_CALLBACK,
              GenericProtocolNotify,
              Entry,
              &Entry->Event
              );
    ASSERT_EFI_ERROR(Status);

    //
    // Register for protocol notifactions on this event
    //
    Status = CoreRegisterProtocolNotify (
              Entry->ProtocolGuid,
              Entry->Event,
              &Entry->Registration
              );
    ASSERT_EFI_ERROR(Status);
  }
}
第一件是为mArchProtocols 中的每一项注册一个event,且event的回调函数统一是GenericProtocolNotify。
第二件是当mArchProtocols 中的每一项protocol注册是一个notify函数,举个例子,也就是在注册gEfiTimerArchProtocolGuid的时候会调用GenericProtocolNotify 这个函数,后面详细在分析.我们重点先看GenericProtocolNotify
GenericProtocolNotify (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS                      Status;
  EFI_CORE_PROTOCOL_NOTIFY_ENTRY  *Entry;
  VOID                            *Protocol;
  LIST_ENTRY                      *Link;
  LIST_ENTRY                      TempLinkNode;

  Protocol = NULL;

  //
  // Get Entry from Context
  //
  Entry = (EFI_CORE_PROTOCOL_NOTIFY_ENTRY *)Context;

  //
  // See if the expected protocol is present in the handle database
  //
  Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Mark the protocol as present
  //
  Entry->Present = TRUE;

  //
  // Update protocol global variable if one exists. Entry->Protocol points to a global variable
  // if one exists in the DXE core for this Architectural Protocol
  //
  if (Entry->Protocol != NULL) {
    *(Entry->Protocol) = Protocol;
  }

  //
  // Do special operations for Architectural Protocols
  //

  if (CompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {
    //
    // Register the Core timer tick handler with the Timer AP
    //
    gTimer->RegisterHandler (gTimer, CoreTimerTick);
  }

}
当调用GenericProtocolNotify是发现现在正在注册time的protocol,则调用gTimer->RegisterHandler (gTimer, CoreTimerTick);
EFI_TIMER_ARCH_PROTOCOL   gTimer = {
  TimerDriverRegisterHandler,
  TimerDriverSetTimerPeriod,
  TimerDriverGetTimerPeriod,
  TimerDriverGenerateSoftInterrupt
};

而gTimer->RegisterHandler == TimerDriverRegisterHandler
TimerDriverRegisterHandler (
  IN EFI_TIMER_ARCH_PROTOCOL  *This,
  IN EFI_TIMER_NOTIFY         NotifyFunction
  )
{
  if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
    return EFI_ALREADY_STARTED;
  }

  mTimerNotifyFunction = NotifyFunction;

  return EFI_SUCCESS;
}
可见最终执行的效果就是mTimerNotifyFunction == CoreTimerTick。
也就是在中断的处理函数中会call mTimerNotifyFunction 也就是 CoreTimerTick
而mTimerNotifyFunction 是在TimerInterruptHandler 中调用
TimerInterruptHandler (
  IN  HARDWARE_INTERRUPT_SOURCE   Source,
  IN  EFI_SYSTEM_CONTEXT          SystemContext
  )
{
  EFI_TPL      OriginalTPL;
  UINT64       CurrentValue;
  UINT64       CompareValue;

    if (mTimerNotifyFunction) {
      mTimerNotifyFunction (mTimerPeriod * mElapsedPeriod);
    }
}

  // Install interrupt handler
  Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
而gInterrupt 是在TimerInitialize 函数中赋值的

TimerInitialize (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  // Find the interrupt controller protocol.  ASSERT if not found.
  Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
  ASSERT_EFI_ERROR (Status);
}
而RegisterInterruptSource的实现如下
EFI_STATUS
EFIAPI
RegisterInterruptSource (
  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
  IN HARDWARE_INTERRUPT_SOURCE          Source,
  IN HARDWARE_INTERRUPT_HANDLER         Handler
  )
{
  if (Source >= mGicNumInterrupts) {
    ASSERT(FALSE);
    return EFI_UNSUPPORTED;
  }

  if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
    return EFI_ALREADY_STARTED;
  }

  gRegisteredInterruptHandlers[Source] = Handler;


}
在RegisterInterruptSource 中有将TimerInterruptHandler 赋值给gRegisteredInterruptHandlers

GicV2IrqInterruptHandler 是在GicV2DxeInitialize 中注册的。
GicV2DxeInitialize
{
 Status = InstallAndRegisterInterruptService (
          &gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent);

}
而在GicV2IrqInterruptHandler 有将gRegisteredInterruptHandlers 赋值给InterruptHandler
GicV2IrqInterruptHandler (
  IN EFI_EXCEPTION_TYPE           InterruptType,
  IN EFI_SYSTEM_CONTEXT           SystemContext
  )
{
  UINT32                      GicInterrupt;
  HARDWARE_INTERRUPT_HANDLER  InterruptHandler;

  GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);

  // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
  if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {
    // The special interrupt do not need to be acknowledge
    return;
  }

  InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
  if (InterruptHandler != NULL) {
    // Call the registered interrupt handler.
    InterruptHandler (GicInterrupt, SystemContext);
  } else {
    DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
    GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
  }
}

 
上面的InterruptHandler 也就是InstallAndRegisterInterruptService的第一个形参gHardwareInterruptV2Protocol
EFI_STATUS
InstallAndRegisterInterruptService (
  IN EFI_HARDWARE_INTERRUPT_PROTOCOL   *InterruptProtocol,
  IN EFI_CPU_INTERRUPT_HANDLER          InterruptHandler,
  IN EFI_EVENT_NOTIFY                   ExitBootServicesEvent
  )
{
  EFI_STATUS               Status;
  EFI_CPU_ARCH_PROTOCOL   *Cpu;

  // Initialize the array for the Interrupt Handlers
  gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
  if (gRegisteredInterruptHandlers == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &gHardwareInterruptHandle,
                  &gHardwareInterruptProtocolGuid, InterruptProtocol,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the CPU protocol that this driver requires.
  //
  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Unregister the default exception handler.
  //
  Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Register to receive interrupts
  //
  Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // Register for an ExitBootServicesEvent
  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);

  return Status;
}
InstallAndRegisterInterruptService最终把GicV2IrqInterruptHandler 注册给cpu
而Cpu 就代表gCpu
EFI_CPU_ARCH_PROTOCOL  gCpu = {
  CpuFlushCpuDataCache,
  CpuEnableInterrupt,
  CpuDisableInterrupt,
  CpuGetInterruptState,
  CpuInit,
  CpuRegisterInterruptHandler,
  CpuGetTimerValue,
  CpuSetMemoryAttributes,
  1,                          // NumberOfTimers
  4                           // DmaBufferAlignment
};
而RegisterCpuInterruptHandler 又是赋值给gExceptionHandlers
RegisterCpuInterruptHandler(
  IN EFI_EXCEPTION_TYPE             ExceptionType,
  IN EFI_CPU_INTERRUPT_HANDLER      ExceptionHandler
  ) {
  if (ExceptionType > gMaxExceptionNumber) {
    return RETURN_UNSUPPORTED;
  }

  if ((ExceptionHandler != NULL) && (gExceptionHandlers[ExceptionType] != NULL)) {
    return RETURN_ALREADY_STARTED;
  }

  gExceptionHandlers[ExceptionType] = ExceptionHandler;

  return RETURN_SUCCESS;
}
也就是 gExceptionHandlers[ExceptionType] = GicV2IrqInterruptHandler
最终会在AArch64Exception.s call gExceptionHandlers
gExceptionHandlers:
    .zero    32
    .section    .bss.gDebuggerNoHandlerValue,"aw",%nobits
    .align    3
    .type    gDebuggerNoHandlerValue, %object
    .size    gDebuggerNoHandlerValue, 8
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值