gic.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /*
  2. * GIC Initialization Routines.
  3. *
  4. * (C) Copyright 2013
  5. * David Feng <fenghua@phytium.com.cn>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <asm-offsets.h>
  10. #include <config.h>
  11. #include <linux/linkage.h>
  12. #include <asm/macro.h>
  13. #include <asm/gic.h>
  14. /*************************************************************************
  15. *
  16. * void gic_init(void) __attribute__((weak));
  17. *
  18. * Currently, this routine only initialize secure copy of GIC
  19. * with Security Extensions at EL3.
  20. *
  21. *************************************************************************/
  22. WEAK(gic_init)
  23. branch_if_slave x0, 2f
  24. /* Initialize Distributor and SPIs */
  25. ldr x1, =GICD_BASE
  26. mov w0, #0x3 /* EnableGrp0 | EnableGrp1 */
  27. str w0, [x1, GICD_CTLR] /* Secure GICD_CTLR */
  28. ldr w0, [x1, GICD_TYPER]
  29. and w2, w0, #0x1f /* ITLinesNumber */
  30. cbz w2, 2f /* No SPIs */
  31. add x1, x1, (GICD_IGROUPRn + 4)
  32. mov w0, #~0 /* Config SPIs as Grp1 */
  33. 1: str w0, [x1], #0x4
  34. sub w2, w2, #0x1
  35. cbnz w2, 1b
  36. /* Initialize SGIs and PPIs */
  37. 2: ldr x1, =GICD_BASE
  38. mov w0, #~0 /* Config SGIs and PPIs as Grp1 */
  39. str w0, [x1, GICD_IGROUPRn] /* GICD_IGROUPR0 */
  40. mov w0, #0x1 /* Enable SGI 0 */
  41. str w0, [x1, GICD_ISENABLERn]
  42. /* Initialize Cpu Interface */
  43. ldr x1, =GICC_BASE
  44. mov w0, #0x1e7 /* Disable IRQ/FIQ Bypass & */
  45. /* Enable Ack Group1 Interrupt & */
  46. /* EnableGrp0 & EnableGrp1 */
  47. str w0, [x1, GICC_CTLR] /* Secure GICC_CTLR */
  48. mov w0, #0x1 << 7 /* Non-Secure access to GICC_PMR */
  49. str w0, [x1, GICC_PMR]
  50. ret
  51. ENDPROC(gic_init)
  52. /*************************************************************************
  53. *
  54. * void gic_send_sgi(u64 sgi) __attribute__((weak));
  55. *
  56. *************************************************************************/
  57. WEAK(gic_send_sgi)
  58. ldr x1, =GICD_BASE
  59. mov w2, #0x8000
  60. movk w2, #0x100, lsl #16
  61. orr w2, w2, w0
  62. str w2, [x1, GICD_SGIR]
  63. ret
  64. ENDPROC(gic_send_sgi)
  65. /*************************************************************************
  66. *
  67. * void wait_for_wakeup(void) __attribute__((weak));
  68. *
  69. * Wait for SGI 0 from master.
  70. *
  71. *************************************************************************/
  72. WEAK(wait_for_wakeup)
  73. ldr x1, =GICC_BASE
  74. 0: wfi
  75. ldr w0, [x1, GICC_AIAR]
  76. str w0, [x1, GICC_AEOIR]
  77. cbnz w0, 0b
  78. ret
  79. ENDPROC(wait_for_wakeup)
  80. /*************************************************************************
  81. *
  82. * void smp_kick_all_cpus(void) __attribute__((weak));
  83. *
  84. *************************************************************************/
  85. WEAK(smp_kick_all_cpus)
  86. /* Kick secondary cpus up by SGI 0 interrupt */
  87. mov x0, xzr /* SGI 0 */
  88. mov x29, lr /* Save LR */
  89. bl gic_send_sgi
  90. mov lr, x29 /* Restore LR */
  91. ret
  92. ENDPROC(smp_kick_all_cpus)