{\r
EFI_HANDLE Handle = NULL;\r
EFI_STATUS Status;\r
- UINTN TimerCtrlReg;\r
+ UINTN TimerCtrlReg;\r
+ UINT32 TimerHypIntrNum;\r
\r
if (ArmIsArchTimerImplemented () == 0) {\r
DEBUG ((EFI_D_ERROR, "ARM Architectural Timer is not available in the CPU, hence cann't use this Driver \n"));\r
Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerVirtIntrNum), TimerInterruptHandler);\r
ASSERT_EFI_ERROR (Status);\r
\r
- Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerHypIntrNum), TimerInterruptHandler);\r
- ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // The hypervisor timer interrupt may be omitted by implementations that\r
+ // execute under virtualization.\r
+ //\r
+ TimerHypIntrNum = PcdGet32 (PcdArmArchTimerHypIntrNum);\r
+ if (TimerHypIntrNum != 0) {\r
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, TimerHypIntrNum, TimerInterruptHandler);\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
\r
Status = gInterrupt->RegisterInterruptSource (gInterrupt, PcdGet32 (PcdArmArchTimerSecIntrNum), TimerInterruptHandler);\r
ASSERT_EFI_ERROR (Status);\r
// hypervisor timers, in that order.\r
//\r
InterruptProp = fdt_getprop (DeviceTreeBase, Node, "interrupts", &Len);\r
- ASSERT (Len == 48);\r
+ ASSERT (Len == 36 || Len == 48);\r
\r
SecIntrNum = fdt32_to_cpu (InterruptProp[0].Number)\r
+ (InterruptProp[0].Type ? 16 : 0);\r
+ (InterruptProp[1].Type ? 16 : 0);\r
VirtIntrNum = fdt32_to_cpu (InterruptProp[2].Number)\r
+ (InterruptProp[2].Type ? 16 : 0);\r
- HypIntrNum = fdt32_to_cpu (InterruptProp[3].Number)\r
- + (InterruptProp[3].Type ? 16 : 0);\r
+ HypIntrNum = Len < 48 ? 0 : fdt32_to_cpu (InterruptProp[3].Number)\r
+ + (InterruptProp[3].Type ? 16 : 0);\r
\r
DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",\r
SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum));\r