arm_gicv3_common.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2017-2024, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. /*
  7. * Driver for implementation defined features that are identical in ARM GICv3
  8. * implementations (GIC-500 and GIC-600 for now). This driver only overrides
  9. * APIs that are different to those generic ones in GICv3 driver.
  10. */
  11. #include <assert.h>
  12. #include <arch_helpers.h>
  13. #include <drivers/arm/arm_gicv3_common.h>
  14. #include <drivers/arm/gicv3.h>
  15. #include "gicv3_private.h"
  16. /*
  17. * Flush the internal GIC cache of the LPIs pending tables to memory before
  18. * saving the state of the Redistributor. This is required before powering off
  19. * the GIC when the pending status must be preserved.
  20. * `rdist_proc_num` is the processor number corresponding to the Redistributor of the
  21. * current CPU.
  22. */
  23. void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num)
  24. {
  25. uintptr_t gicr_base = 0;
  26. unsigned int typer_reg;
  27. assert(gicv3_driver_data);
  28. assert(gicv3_driver_data->rdistif_base_addrs);
  29. assert(gicv3_driver_data->gicd_base != 0U);
  30. typer_reg = gicd_read_typer(gicv3_driver_data->gicd_base);
  31. /*
  32. * The GICR_WAKER.Sleep bit should be set only when both
  33. * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on
  34. * all the Redistributors.
  35. */
  36. for (unsigned int i = 0; i < gicv3_driver_data->rdistif_num; i++) {
  37. gicr_base = gicv3_driver_data->rdistif_base_addrs[i];
  38. assert(gicr_base);
  39. assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT);
  40. assert(gicr_read_waker(gicr_base) & WAKER_PS_BIT);
  41. }
  42. gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num];
  43. /*
  44. * According to the TRM, there is only one instance of the
  45. * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed
  46. * through any of the Redistributor.
  47. */
  48. /*
  49. * Set GICR_WAKER.Sleep
  50. * After this point, the system must be configured so that the
  51. * wake_request signals for the right cores are asserted when a wakeup
  52. * interrupt is detected. The GIC will not be able to do that anymore
  53. * when the GICR_WAKER.Sleep bit is set to 1.
  54. */
  55. gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT);
  56. /*
  57. * If LPIs are supported, wait until the GICR_WAKER.Quiescent bit is
  58. * set.
  59. */
  60. if ((typer_reg & TYPER_LPIS) != 0U) {
  61. while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT))
  62. ;
  63. }
  64. }
  65. /*
  66. * Allow the LPIs pending state to be read back from the tables in memory after
  67. * having restored the state of the GIC Redistributor.
  68. */
  69. void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num)
  70. {
  71. uintptr_t gicr_base;
  72. assert(gicv3_driver_data);
  73. assert(gicv3_driver_data->rdistif_base_addrs);
  74. /*
  75. * According to the TRM, there is only one instance of the
  76. * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed
  77. * through any of the Redistributor.
  78. */
  79. gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num];
  80. assert(gicr_base);
  81. /*
  82. * If the GIC had power removed, the GICR_WAKER state will be reset.
  83. * Since the GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits are cleared,
  84. * we can exit early. This also prevents the following assert from
  85. * erroneously triggering.
  86. */
  87. if (!(gicr_read_waker(gicr_base) & WAKER_SL_BIT))
  88. return;
  89. /*
  90. * Writes to GICR_WAKER.Sleep bit are ignored if GICR_WAKER.Quiescent
  91. * bit is not set. We should be alright on power on path, therefore
  92. * coming out of sleep and Quiescent should be set, but we assert in
  93. * case.
  94. */
  95. assert(gicr_read_waker(gicr_base) & WAKER_QSC_BIT);
  96. /* Clear GICR_WAKER.Sleep */
  97. gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_SL_BIT);
  98. /*
  99. * We don't know if the effects of setting GICR_WAKER.Sleep bit is
  100. * instantaneous, so we wait until the interface is not Quiescent
  101. * anymore.
  102. */
  103. while (gicr_read_waker(gicr_base) & WAKER_QSC_BIT)
  104. ;
  105. }