platform-interrupt-controller-API.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. Platform Interrupt Controller API
  2. =================================
  3. This document lists the optional platform interrupt controller API that
  4. abstracts the runtime configuration and control of interrupt controller from the
  5. generic code. The mandatory APIs are described in the
  6. :ref:`Porting Guide <porting_guide_imf_in_bl31>`.
  7. Function: unsigned int plat_ic_get_running_priority(void); [optional]
  8. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  9. ::
  10. Argument : void
  11. Return : unsigned int
  12. This API should return the priority of the interrupt the PE is currently
  13. servicing. This must be be called only after an interrupt has already been
  14. acknowledged via ``plat_ic_acknowledge_interrupt``.
  15. In the case of Arm standard platforms using GIC, the *Running Priority Register*
  16. is read to determine the priority of the interrupt.
  17. Function: int plat_ic_is_spi(unsigned int id); [optional]
  18. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  19. ::
  20. Argument : unsigned int
  21. Return : int
  22. The API should return whether the interrupt ID (first parameter) is categorized
  23. as a Shared Peripheral Interrupt. Shared Peripheral Interrupts are typically
  24. associated to system-wide peripherals, and these interrupts can target any PE in
  25. the system.
  26. Function: int plat_ic_is_ppi(unsigned int id); [optional]
  27. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  28. ::
  29. Argument : unsigned int
  30. Return : int
  31. The API should return whether the interrupt ID (first parameter) is categorized
  32. as a Private Peripheral Interrupt. Private Peripheral Interrupts are typically
  33. associated with peripherals that are private to each PE. Interrupts from private
  34. peripherals target to that PE only.
  35. Function: int plat_ic_is_sgi(unsigned int id); [optional]
  36. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  37. ::
  38. Argument : unsigned int
  39. Return : int
  40. The API should return whether the interrupt ID (first parameter) is categorized
  41. as a Software Generated Interrupt. Software Generated Interrupts are raised by
  42. explicit programming by software, and are typically used in inter-PE
  43. communication. Secure SGIs are reserved for use by Secure world software.
  44. Function: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional]
  45. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  46. ::
  47. Argument : unsigned int
  48. Return : int
  49. This API should return the *active* status of the interrupt ID specified by the
  50. first parameter, ``id``.
  51. In case of Arm standard platforms using GIC, the implementation of the API reads
  52. the GIC *Set Active Register* to read and return the active status of the
  53. interrupt.
  54. Function: void plat_ic_enable_interrupt(unsigned int id); [optional]
  55. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  56. ::
  57. Argument : unsigned int
  58. Return : void
  59. This API should enable the interrupt ID specified by the first parameter,
  60. ``id``. PEs in the system are expected to receive only enabled interrupts.
  61. In case of Arm standard platforms using GIC, the implementation of the API
  62. inserts barrier to make memory updates visible before enabling interrupt, and
  63. then writes to GIC *Set Enable Register* to enable the interrupt.
  64. Function: void plat_ic_disable_interrupt(unsigned int id); [optional]
  65. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  66. ::
  67. Argument : unsigned int
  68. Return : void
  69. This API should disable the interrupt ID specified by the first parameter,
  70. ``id``. PEs in the system are not expected to receive disabled interrupts.
  71. In case of Arm standard platforms using GIC, the implementation of the API
  72. writes to GIC *Clear Enable Register* to disable the interrupt, and inserts
  73. barrier to make memory updates visible afterwards.
  74. Function: void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); [optional]
  75. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  76. ::
  77. Argument : unsigned int
  78. Argument : unsigned int
  79. Return : void
  80. This API should set the priority of the interrupt specified by first parameter
  81. ``id`` to the value set by the second parameter ``priority``.
  82. In case of Arm standard platforms using GIC, the implementation of the API
  83. writes to GIC *Priority Register* set interrupt priority.
  84. Function: bool plat_ic_has_interrupt_type(unsigned int type); [optional]
  85. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  86. ::
  87. Argument : unsigned int
  88. Return : bool
  89. This API should return whether the platform supports a given interrupt type. The
  90. parameter ``type`` shall be one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``, or
  91. ``INTR_TYPE_NS``.
  92. In case of Arm standard platforms using GICv3, the implementation of the API
  93. returns *true* for all interrupt types.
  94. In case of Arm standard platforms using GICv2, the API always return *true* for
  95. ``INTR_TYPE_NS``. Return value for other types depends on the value of build
  96. option ``GICV2_G0_FOR_EL3``:
  97. - For interrupt type ``INTR_TYPE_EL3``:
  98. - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns *false*, indicating no support
  99. for EL3 interrupts.
  100. - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns *true*, indicating support for
  101. EL3 interrupts.
  102. - For interrupt type ``INTR_TYPE_S_EL1``:
  103. - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns *true*, indicating support for
  104. Secure EL1 interrupts.
  105. - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns *false*, indicating no support
  106. for Secure EL1 interrupts.
  107. Function: void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); [optional]
  108. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  109. ::
  110. Argument : unsigned int
  111. Argument : unsigned int
  112. Return : void
  113. This API should set the interrupt specified by first parameter ``id`` to the
  114. type specified by second parameter ``type``. The ``type`` parameter can be
  115. one of:
  116. - ``INTR_TYPE_NS``: interrupt is meant to be consumed by the Non-secure world.
  117. - ``INTR_TYPE_S_EL1``: interrupt is meant to be consumed by Secure EL1.
  118. - ``INTR_TYPE_EL3``: interrupt is meant to be consumed by EL3.
  119. In case of Arm standard platforms using GIC, the implementation of the API
  120. writes to the GIC *Group Register* and *Group Modifier Register* (only GICv3) to
  121. assign the interrupt to the right group.
  122. For GICv3:
  123. - ``INTR_TYPE_NS`` maps to Group 1 interrupt.
  124. - ``INTR_TYPE_S_EL1`` maps to Secure Group 1 interrupt.
  125. - ``INTR_TYPE_EL3`` maps to Secure Group 0 interrupt.
  126. For GICv2:
  127. - ``INTR_TYPE_NS`` maps to Group 1 interrupt.
  128. - When the build option ``GICV2_G0_FOR_EL3`` is set to ``0`` (the default),
  129. ``INTR_TYPE_S_EL1`` maps to Group 0. Otherwise, ``INTR_TYPE_EL3`` maps to
  130. Group 0 interrupt.
  131. Function: void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target); [optional]
  132. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  133. ::
  134. Argument : int
  135. Argument : u_register_t
  136. Return : void
  137. This API should raise an EL3 SGI. The first parameter, ``sgi_num``, specifies
  138. the ID of the SGI. The second parameter, ``target``, must be the MPIDR of the
  139. target PE.
  140. In case of Arm standard platforms using GIC, the implementation of the API
  141. inserts barrier to make memory updates visible before raising SGI, then writes
  142. to appropriate *SGI Register* in order to raise the EL3 SGI.
  143. Function: void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, u_register_t mpidr); [optional]
  144. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  145. ::
  146. Argument : unsigned int
  147. Argument : unsigned int
  148. Argument : u_register_t
  149. Return : void
  150. This API should set the routing mode of Share Peripheral Interrupt (SPI)
  151. specified by first parameter ``id`` to that specified by the second parameter
  152. ``routing_mode``.
  153. The ``routing_mode`` parameter can be one of:
  154. - ``INTR_ROUTING_MODE_ANY`` means the interrupt can be routed to any PE in the
  155. system. The ``mpidr`` parameter is ignored in this case.
  156. - ``INTR_ROUTING_MODE_PE`` means the interrupt is routed to the PE whose MPIDR
  157. value is specified by the parameter ``mpidr``.
  158. In case of Arm standard platforms using GIC, the implementation of the API
  159. writes to the GIC *Target Register* (GICv2) or *Route Register* (GICv3) to set
  160. the routing.
  161. Function: void plat_ic_set_interrupt_pending(unsigned int id); [optional]
  162. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  163. ::
  164. Argument : unsigned int
  165. Return : void
  166. This API should set the interrupt specified by first parameter ``id`` to
  167. *Pending*.
  168. In case of Arm standard platforms using GIC, the implementation of the API
  169. inserts barrier to make memory updates visible before setting interrupt pending,
  170. and writes to the GIC *Set Pending Register* to set the interrupt pending
  171. status.
  172. Function: void plat_ic_clear_interrupt_pending(unsigned int id); [optional]
  173. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  174. ::
  175. Argument : unsigned int
  176. Return : void
  177. This API should clear the *Pending* status of the interrupt specified by first
  178. parameter ``id``.
  179. In case of Arm standard platforms using GIC, the implementation of the API
  180. writes to the GIC *Clear Pending Register* to clear the interrupt pending
  181. status, and inserts barrier to make memory updates visible afterwards.
  182. Function: unsigned int plat_ic_set_priority_mask(unsigned int id); [optional]
  183. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  184. ::
  185. Argument : unsigned int
  186. Return : int
  187. This API should set the priority mask (first parameter) in the interrupt
  188. controller such that only interrupts of higher priority than the supplied one
  189. may be signalled to the PE. The API should return the current priority value
  190. that it's overwriting.
  191. In case of Arm standard platforms using GIC, the implementation of the API
  192. inserts barriers to order memory updates before updating mask,
  193. then writes to the GIC *Priority Mask Register*, and make sure memory updates
  194. are visible before potential trigger due to mask update.
  195. Function: unsigned int plat_ic_deactivate_priority(unsigned int id); [optional]
  196. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  197. ::
  198. Argument : unsigned int
  199. Return : int
  200. This API performs the operations of plat_ic_set_priority_mask along with
  201. calling the errata workaround gicv3_apply_errata_wa_2384374(). This is
  202. performed when priority mask is restored to it's older value. This API returns
  203. the current priority value that it's overwriting.
  204. In case of Arm standard platforms using GIC, the implementation of the API
  205. inserts barriers to order memory updates before updating mask, then writes
  206. to the GIC *Priority Mask Register*, and make sure memory updates
  207. are visible before potential trigger due to mask update, and
  208. applies 2384374 GIC errata workaround to process pending interrupt packets.
  209. .. _plat_ic_get_interrupt_id:
  210. Function: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional]
  211. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  212. ::
  213. Argument : unsigned int
  214. Return : unsigned int
  215. This API should extract and return the interrupt number from the raw value
  216. obtained by the acknowledging the interrupt (read using
  217. ``plat_ic_acknowledge_interrupt()``). If the interrupt ID is invalid, this API
  218. should return ``INTR_ID_UNAVAILABLE``.
  219. In case of Arm standard platforms using GIC, the implementation of the API
  220. masks out the interrupt ID field from the acknowledged value from GIC.
  221. --------------
  222. *Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.*