phytium_interrupt.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. phytium_gic_table = (struct arm_gic *)arm_gic_get_gic_table_addr();
  77. /* initialize vector table */
  78. rt_hw_vector_init();
  79. /* initialize exceptions table */
  80. rt_memset(isr_table, 0x00, sizeof(isr_table));
  81. #if defined(RT_USING_SMART)
  82. gic_dist_base = (rt_uint64_t)rt_ioremap((void *)platform_get_gic_dist_base(), 0x40000);
  83. gic_cpu_base = (rt_uint64_t)rt_ioremap((void*)platform_get_gic_cpu_base(), 0x1000);
  84. #else
  85. gic_dist_base = platform_get_gic_dist_base();
  86. gic_cpu_base = platform_get_gic_cpu_base();
  87. #endif
  88. gic_irq_start = 0;
  89. arm_gic_dist_init(0, gic_dist_base, gic_irq_start);
  90. arm_gic_cpu_init(0, gic_cpu_base);
  91. arm_gic_redist_address_set(0, platform_get_gic_redist_base(), 0);
  92. phytium_aarch64_arm_gic_redist_init();
  93. }
  94. #endif