在在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
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