ArmVirtTimerFdtClientLib.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /** @file
  2. FDT client library for ARM's TimerDxe
  3. Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Uefi.h>
  7. #include <Library/BaseLib.h>
  8. #include <Library/DebugLib.h>
  9. #include <Library/PcdLib.h>
  10. #include <Library/UefiBootServicesTableLib.h>
  11. #include <Protocol/FdtClient.h>
  12. #pragma pack (1)
  13. typedef struct {
  14. UINT32 Type;
  15. UINT32 Number;
  16. UINT32 Flags;
  17. } INTERRUPT_PROPERTY;
  18. #pragma pack ()
  19. RETURN_STATUS
  20. EFIAPI
  21. ArmVirtTimerFdtClientLibConstructor (
  22. VOID
  23. )
  24. {
  25. EFI_STATUS Status;
  26. FDT_CLIENT_PROTOCOL *FdtClient;
  27. CONST INTERRUPT_PROPERTY *InterruptProp;
  28. UINT32 PropSize;
  29. INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum;
  30. RETURN_STATUS PcdStatus;
  31. Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
  32. (VOID **)&FdtClient);
  33. ASSERT_EFI_ERROR (Status);
  34. Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv7-timer",
  35. "interrupts", (CONST VOID **)&InterruptProp,
  36. &PropSize);
  37. if (Status == EFI_NOT_FOUND) {
  38. Status = FdtClient->FindCompatibleNodeProperty (FdtClient,
  39. "arm,armv8-timer", "interrupts",
  40. (CONST VOID **)&InterruptProp,
  41. &PropSize);
  42. }
  43. if (EFI_ERROR (Status)) {
  44. return Status;
  45. }
  46. //
  47. // - interrupts : Interrupt list for secure, non-secure, virtual and
  48. // hypervisor timers, in that order.
  49. //
  50. ASSERT (PropSize == 36 || PropSize == 48);
  51. SecIntrNum = SwapBytes32 (InterruptProp[0].Number)
  52. + (InterruptProp[0].Type ? 16 : 0);
  53. IntrNum = SwapBytes32 (InterruptProp[1].Number)
  54. + (InterruptProp[1].Type ? 16 : 0);
  55. VirtIntrNum = SwapBytes32 (InterruptProp[2].Number)
  56. + (InterruptProp[2].Type ? 16 : 0);
  57. HypIntrNum = PropSize < 48 ? 0 : SwapBytes32 (InterruptProp[3].Number)
  58. + (InterruptProp[3].Type ? 16 : 0);
  59. DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n",
  60. SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum));
  61. PcdStatus = PcdSet32S (PcdArmArchTimerSecIntrNum, SecIntrNum);
  62. ASSERT_RETURN_ERROR (PcdStatus);
  63. PcdStatus = PcdSet32S (PcdArmArchTimerIntrNum, IntrNum);
  64. ASSERT_RETURN_ERROR (PcdStatus);
  65. PcdStatus = PcdSet32S (PcdArmArchTimerVirtIntrNum, VirtIntrNum);
  66. ASSERT_RETURN_ERROR (PcdStatus);
  67. PcdStatus = PcdSet32S (PcdArmArchTimerHypIntrNum, HypIntrNum);
  68. ASSERT_RETURN_ERROR (PcdStatus);
  69. return EFI_SUCCESS;
  70. }