phytium_interrupt.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "rtconfig.h"
  2. #if defined(TARGET_ARMV8_AARCH64)
  3. #include <rthw.h>
  4. #include <rtthread.h>
  5. #include "interrupt.h"
  6. #include "gic.h"
  7. #include "gicv3.h"
  8. #include "ioremap.h"
  9. #include "phytium_cpu.h"
  10. #include "ftypes.h"
  11. #include "fparameters.h"
  12. struct arm_gic *phytium_gic_table;
  13. extern struct rt_irq_desc isr_table[MAX_HANDLERS];
  14. int arm_gic_redist_address_set(rt_uint64_t index, rt_uint64_t redist_addr, int cpu_id)
  15. {
  16. RT_ASSERT(index < ARM_GIC_MAX_NR);
  17. if (cpu_id == 0)
  18. {
  19. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, &cpu_id, sizeof(cpu_id));
  20. }
  21. phytium_gic_table[index].redist_hw_base[cpu_id] = redist_addr;
  22. return 0;
  23. }
  24. static int arm_gicv3_wait_rwp(rt_uint64_t index, rt_uint64_t irq)
  25. {
  26. rt_uint64_t rwp_bit;
  27. rt_uint64_t base;
  28. RT_ASSERT(index < ARM_GIC_MAX_NR);
  29. if (irq < 32)
  30. {
  31. rt_int32_t cpu_id = rt_hw_cpu_id();
  32. base = phytium_gic_table[index].redist_hw_base[cpu_id];
  33. rwp_bit = GICR_CTLR_RWP;
  34. }
  35. else
  36. {
  37. base = phytium_gic_table[index].dist_hw_base;
  38. rwp_bit = GICD_CTLR_RWP;
  39. }
  40. while (HWREG32(base) & rwp_bit)
  41. {
  42. }
  43. return 0;
  44. }
  45. int phytium_aarch64_arm_gic_redist_init()
  46. {
  47. rt_uint64_t cpu_id = rt_hw_cpu_id();
  48. rt_uint64_t redist_base = phytium_gic_table[0].redist_hw_base[cpu_id];
  49. /* redistributor enable */
  50. GIC_RDIST_WAKER(redist_base) &= ~(1 << 1);
  51. while (GIC_RDIST_WAKER(redist_base) & (1 << 2))
  52. {
  53. }
  54. /* Disable all sgi and ppi interrupt */
  55. GIC_RDISTSGI_ICENABLER0(redist_base) = 0xffffffff;
  56. arm_gicv3_wait_rwp(0, 0);
  57. /* Clear all inetrrupt pending */
  58. GIC_RDISTSGI_ICPENDR0(redist_base) = 0xffffffff;
  59. /* the corresponding interrupt is Group 1 or Non-secure Group 1. */
  60. GIC_RDISTSGI_IGROUPR0(redist_base, 0) = 0xffffffff;
  61. GIC_RDISTSGI_IGRPMODR0(redist_base, 0) = 0xffffffff;
  62. /* Configure default priorities for SGI 0:15 and PPI 16:31. */
  63. for (int i = 0; i < 32; i += 4)
  64. {
  65. GIC_RDISTSGI_IPRIORITYR(redist_base, i) = 0xa0a0a0a0U;
  66. }
  67. /* Trigger level for PPI interrupts*/
  68. GIC_RDISTSGI_ICFGR1(redist_base) = 0;
  69. return 0;
  70. }
  71. void phytium_interrupt_init(void)
  72. {
  73. rt_uint64_t gic_cpu_base;
  74. rt_uint64_t gic_dist_base;
  75. rt_uint64_t gic_irq_start;
  76. rt_uint64_t redist_addr;
  77. phytium_gic_table = (struct arm_gic *)arm_gic_get_gic_table_addr();
  78. /* initialize vector table */
  79. rt_hw_vector_init();
  80. /* initialize exceptions table */
  81. rt_memset(isr_table, 0x00, sizeof(isr_table));
  82. #if defined(RT_USING_SMART)
  83. gic_dist_base = (rt_uint64_t)rt_ioremap((void *)platform_get_gic_dist_base(), 0x40000);
  84. gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
  85. redist_addr = (rt_uint64_t)rt_ioremap(GICV3_RD_BASE_ADDR, 4 * GICV3_RD_OFFSET);
  86. #else
  87. gic_dist_base = platform_get_gic_dist_base();
  88. gic_cpu_base = platform_get_gic_cpu_base();
  89. redist_addr = GICV3_RD_BASE_ADDR;
  90. #endif
  91. gic_irq_start = 0;
  92. arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
  93. arm_gic_cpu_init(0, gic_cpu_base);
  94. arm_gic_redist_address_set(0, redist_addr + 2 * GICV3_RD_OFFSET, 0);
  95. #if defined(TARGET_E2000Q) || defined(TARGET_PHYTIUMPI)
  96. #if RT_CPUS_NR == 2
  97. arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
  98. #elif RT_CPUS_NR == 3
  99. arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
  100. arm_gic_redist_address_set(0, redist_addr, 2);
  101. #elif RT_CPUS_NR == 4
  102. arm_gic_redist_address_set(0, redist_addr + 3 * GICV3_RD_OFFSET, 1);
  103. arm_gic_redist_address_set(0, redist_addr, 2);
  104. arm_gic_redist_address_set(0, redist_addr + GICV3_RD_OFFSET, 3);
  105. #endif
  106. #else
  107. #if defined(TARGET_E2000D)
  108. rt_uint32_t cpu_offset = 2;
  109. #endif
  110. #if RT_CPUS_NR == 2
  111. arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
  112. #elif RT_CPUS_NR == 3
  113. arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
  114. arm_gic_redist_address_set(0, redist_addr + (2 + cpu_offset) * GICV3_RD_OFFSET, 2);
  115. #elif RT_CPUS_NR == 4
  116. arm_gic_redist_address_set(0, redist_addr + (1 + cpu_offset) * GICV3_RD_OFFSET, 1);
  117. arm_gic_redist_address_set(0, redist_addr + (2 + cpu_offset) * GICV3_RD_OFFSET, 2);
  118. arm_gic_redist_address_set(0, redist_addr + (3 + cpu_offset) * GICV3_RD_OFFSET, 3);
  119. #endif
  120. #endif
  121. phytium_aarch64_arm_gic_redist_init();
  122. }
  123. #endif