gicv3.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /*
  2. * Copyright (c) 2006-2026, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2013-07-20 Bernard first version
  9. * 2014-04-03 Grissiom many enhancements
  10. * 2018-11-22 Jesven add rt_hw_ipi_send()
  11. * add rt_hw_ipi_handler_install()
  12. */
  13. #include <rthw.h>
  14. #include <rtthread.h>
  15. #include "gicv3.h"
  16. #include "cp15.h"
  17. #ifndef RT_CPUS_NR
  18. #define RT_CPUS_NR 1
  19. #endif
  20. struct arm_gic_v3
  21. {
  22. rt_uint32_t offset; /* the first interrupt index in the vector table */
  23. rt_uint32_t redist_hw_base[RT_CPUS_NR]; /* the pointer of the gic redistributor */
  24. rt_uint32_t dist_hw_base; /* the base address of the gic distributor */
  25. rt_uint32_t cpu_hw_base[RT_CPUS_NR]; /* the base addrees of the gic cpu interface */
  26. };
  27. /* 'ARM_GIC_MAX_NR' is the number of cores */
  28. static struct arm_gic_v3 _gic_table[ARM_GIC_MAX_NR];
  29. static unsigned int _gic_max_irq;
  30. static rt_bool_t arm_gic_irq_is_valid(rt_uint32_t index, int irq)
  31. {
  32. RT_ASSERT(index < ARM_GIC_MAX_NR);
  33. if ((irq < 0) || ((rt_uint32_t)irq >= _gic_max_irq))
  34. {
  35. return RT_FALSE;
  36. }
  37. return s100_board_irq_is_supported(irq);
  38. }
  39. static rt_uint64_t arm_gic_cpumask_to_irouter_affinity(unsigned int cpumask)
  40. {
  41. rt_uint64_t aff = get_main_cpu_affval();
  42. unsigned int aff0 = 0U;
  43. while (((cpumask & 0x1U) == 0U) && (aff0 < 32U))
  44. {
  45. cpumask >>= 1;
  46. aff0++;
  47. }
  48. aff &= ~0xFFULL;
  49. aff |= (rt_uint64_t)aff0;
  50. return aff;
  51. }
  52. /**
  53. * @name: arm_gic_cpumask_to_affval
  54. * @msg:
  55. * @in param cpu_mask:
  56. * @out param cluster_id: aff1 [0:7],aff2 [8:15],aff3 [16:23]
  57. * @out param target_list: Target List. The set of PEs for which SGI interrupts will be generated. Each bit corresponds to the
  58. * PE within a cluster with an Affinity 0 value equal to the bit number.
  59. * @return {rt_uint32_t} 0 is finish , 1 is data valid
  60. */
  61. rt_weak rt_uint32_t arm_gic_cpumask_to_affval(rt_uint32_t *cpu_mask, rt_uint32_t *cluster_id, rt_uint32_t *target_list)
  62. {
  63. return 0;
  64. }
  65. rt_weak rt_uint64_t get_main_cpu_affval(void)
  66. {
  67. return 0;
  68. }
  69. int arm_gic_get_active_irq(rt_uint32_t index)
  70. {
  71. int irq;
  72. RT_ASSERT(index < ARM_GIC_MAX_NR);
  73. __get_gicv3_reg(ICC_IAR1, irq);
  74. irq = (irq & 0x1FFFFFF) + _gic_table[index].offset;
  75. return irq;
  76. }
  77. void arm_gic_ack(rt_uint32_t index, int irq)
  78. {
  79. RT_ASSERT(index < ARM_GIC_MAX_NR);
  80. RT_ASSERT(irq >= 0);
  81. __DSB();
  82. __set_gicv3_reg(ICC_EOIR1, irq);
  83. }
  84. void arm_gic_mask(rt_uint32_t index, int irq)
  85. {
  86. rt_uint32_t mask;
  87. RT_ASSERT(index < ARM_GIC_MAX_NR);
  88. if (!arm_gic_irq_is_valid(index, irq))
  89. {
  90. return;
  91. }
  92. mask = 1U << (irq % 32U);
  93. irq = irq - _gic_table[index].offset;
  94. RT_ASSERT(irq >= 0);
  95. if (irq < 32)
  96. {
  97. rt_int32_t cpu_id = rt_hw_cpu_id();
  98. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  99. GIC_RDISTSGI_ICENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask;
  100. }
  101. else
  102. {
  103. GIC_DIST_ENABLE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
  104. }
  105. }
  106. void arm_gic_umask(rt_uint32_t index, int irq)
  107. {
  108. rt_uint32_t mask;
  109. RT_ASSERT(index < ARM_GIC_MAX_NR);
  110. if (!arm_gic_irq_is_valid(index, irq))
  111. {
  112. return;
  113. }
  114. mask = 1U << (irq % 32U);
  115. irq = irq - _gic_table[index].offset;
  116. RT_ASSERT(irq > 0U);
  117. if (irq < 32)
  118. {
  119. rt_int32_t cpu_id = rt_hw_cpu_id();
  120. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  121. GIC_RDISTSGI_ISENABLER0(_gic_table[index].redist_hw_base[cpu_id]) = mask;
  122. }
  123. else
  124. {
  125. GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) = mask;
  126. }
  127. }
  128. rt_uint32_t arm_gic_get_pending_irq(rt_uint32_t index, int irq)
  129. {
  130. rt_uint32_t pend;
  131. RT_ASSERT(index < ARM_GIC_MAX_NR);
  132. if (!arm_gic_irq_is_valid(index, irq))
  133. {
  134. return 0U;
  135. }
  136. irq = irq - _gic_table[index].offset;
  137. RT_ASSERT(irq > 0U);
  138. if (irq >= 16)
  139. {
  140. pend = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
  141. }
  142. else
  143. {
  144. /* INTID 0-15 Software Generated Interrupt */
  145. pend = (GIC_DIST_SPENDSGI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL;
  146. /* No CPU identification offered */
  147. if (pend != 0U)
  148. {
  149. pend = 1U;
  150. }
  151. else
  152. {
  153. pend = 0U;
  154. }
  155. }
  156. return (pend);
  157. }
  158. void arm_gic_set_pending_irq(rt_uint32_t index, int irq)
  159. {
  160. RT_ASSERT(index < ARM_GIC_MAX_NR);
  161. if (!arm_gic_irq_is_valid(index, irq))
  162. {
  163. return;
  164. }
  165. irq = irq - _gic_table[index].offset;
  166. RT_ASSERT(irq > 0U);
  167. if (irq >= 16)
  168. {
  169. GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) = 1U << (irq % 32U);
  170. }
  171. else
  172. {
  173. /* INTID 0-15 Software Generated Interrupt */
  174. /* Forward the interrupt to the CPU interface that requested it */
  175. GIC_DIST_SOFTINT(_gic_table[index].dist_hw_base) = (irq | 0x02000000U);
  176. }
  177. }
  178. void arm_gic_clear_pending_irq(rt_uint32_t index, int irq)
  179. {
  180. rt_uint32_t mask;
  181. RT_ASSERT(index < ARM_GIC_MAX_NR);
  182. if (!arm_gic_irq_is_valid(index, irq))
  183. {
  184. return;
  185. }
  186. irq = irq - _gic_table[index].offset;
  187. RT_ASSERT(irq > 0U);
  188. if (irq >= 16U)
  189. {
  190. mask = 1U << (irq % 32U);
  191. GIC_DIST_PENDING_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
  192. }
  193. else
  194. {
  195. mask = 1U << ((irq % 4U) * 8U);
  196. GIC_DIST_CPENDSGI(_gic_table[index].dist_hw_base, irq) = mask;
  197. }
  198. }
  199. void arm_gic_set_configuration(rt_uint32_t index, int irq, rt_uint32_t config)
  200. {
  201. rt_uint32_t icfgr;
  202. rt_uint32_t shift;
  203. RT_ASSERT(index < ARM_GIC_MAX_NR);
  204. if (!arm_gic_irq_is_valid(index, irq))
  205. {
  206. return;
  207. }
  208. irq = irq - _gic_table[index].offset;
  209. RT_ASSERT(irq > 0U);
  210. icfgr = GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq);
  211. shift = (irq % 16U) << 1U;
  212. icfgr &= (~(3U << shift));
  213. icfgr |= ((config & 0x1U) << (shift + 1U));
  214. GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) = icfgr;
  215. }
  216. rt_uint32_t arm_gic_get_configuration(rt_uint32_t index, int irq)
  217. {
  218. RT_ASSERT(index < ARM_GIC_MAX_NR);
  219. if (!arm_gic_irq_is_valid(index, irq))
  220. {
  221. return 0U;
  222. }
  223. irq = irq - _gic_table[index].offset;
  224. RT_ASSERT(irq > 0U);
  225. return (GIC_DIST_CONFIG(_gic_table[index].dist_hw_base, irq) >> (((irq % 16U) << 1U) + 1U)) & 0x1U;
  226. }
  227. void arm_gic_clear_active(rt_uint32_t index, int irq)
  228. {
  229. rt_uint32_t mask;
  230. RT_ASSERT(index < ARM_GIC_MAX_NR);
  231. if (!arm_gic_irq_is_valid(index, irq))
  232. {
  233. return;
  234. }
  235. mask = 1U << (irq % 32U);
  236. irq = irq - _gic_table[index].offset;
  237. RT_ASSERT(irq > 0U);
  238. GIC_DIST_ACTIVE_CLEAR(_gic_table[index].dist_hw_base, irq) = mask;
  239. }
  240. /* Set up the cpu mask for the specific interrupt */
  241. void arm_gic_set_cpu(rt_uint32_t index, int irq, unsigned int cpumask)
  242. {
  243. rt_uint64_t aff;
  244. RT_ASSERT(index < ARM_GIC_MAX_NR);
  245. if (!arm_gic_irq_is_valid(index, irq))
  246. {
  247. return;
  248. }
  249. irq = irq - _gic_table[index].offset;
  250. RT_ASSERT(irq > 0U);
  251. if (irq < 32U)
  252. {
  253. /*
  254. * SGI/PPI are redistributor-local resources; their target CPU is not
  255. * configured through IROUTER.
  256. */
  257. return;
  258. }
  259. if (cpumask == 0U)
  260. {
  261. return;
  262. }
  263. aff = arm_gic_cpumask_to_irouter_affinity(cpumask);
  264. GIC_DIST_IROUTER_LOW(_gic_table[index].dist_hw_base, irq) = (rt_uint32_t)aff;
  265. GIC_DIST_IROUTER_HIGH(_gic_table[index].dist_hw_base, irq) = (rt_uint32_t)(aff >> 32);
  266. }
  267. rt_uint32_t arm_gic_get_target_cpu(rt_uint32_t index, int irq)
  268. {
  269. rt_uint64_t aff;
  270. rt_uint64_t main_aff;
  271. rt_uint32_t aff0;
  272. RT_ASSERT(index < ARM_GIC_MAX_NR);
  273. if (!arm_gic_irq_is_valid(index, irq))
  274. {
  275. return 0U;
  276. }
  277. irq = irq - _gic_table[index].offset;
  278. RT_ASSERT(irq > 0U);
  279. if (irq < 32U)
  280. {
  281. return 1U << rt_hw_cpu_id();
  282. }
  283. aff = ((rt_uint64_t)GIC_DIST_IROUTER_HIGH(_gic_table[index].dist_hw_base, irq) << 32) |
  284. (rt_uint64_t)GIC_DIST_IROUTER_LOW(_gic_table[index].dist_hw_base, irq);
  285. main_aff = get_main_cpu_affval();
  286. if ((aff & ~0xFFULL) != (main_aff & ~0xFFULL))
  287. {
  288. return 0U;
  289. }
  290. aff0 = (rt_uint32_t)(aff & 0xFFULL);
  291. if (aff0 >= 32U)
  292. {
  293. return 0U;
  294. }
  295. return 1U << aff0;
  296. }
  297. void arm_gic_set_priority(rt_uint32_t index, int irq, rt_uint32_t priority)
  298. {
  299. rt_uint32_t mask;
  300. RT_ASSERT(index < ARM_GIC_MAX_NR);
  301. if (!arm_gic_irq_is_valid(index, irq))
  302. {
  303. return;
  304. }
  305. irq = irq - _gic_table[index].offset;
  306. RT_ASSERT(irq > 0U);
  307. if (irq < 32U)
  308. {
  309. rt_int32_t cpu_id = rt_hw_cpu_id();
  310. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  311. mask = GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq);
  312. mask &= ~(0xFFUL << ((irq % 4U) * 8U));
  313. mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U));
  314. GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) = mask;
  315. }
  316. else
  317. {
  318. mask = GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq);
  319. mask &= ~(0xFFUL << ((irq % 4U) * 8U));
  320. mask |= ((priority & 0xFFUL) << ((irq % 4U) * 8U));
  321. GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) = mask;
  322. }
  323. }
  324. rt_uint32_t arm_gic_get_priority(rt_uint32_t index, int irq)
  325. {
  326. RT_ASSERT(index < ARM_GIC_MAX_NR);
  327. if (!arm_gic_irq_is_valid(index, irq))
  328. {
  329. return 0U;
  330. }
  331. irq = irq - _gic_table[index].offset;
  332. RT_ASSERT(irq > 0U);
  333. if (irq < 32U)
  334. {
  335. rt_int32_t cpu_id = rt_hw_cpu_id();
  336. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  337. return (GIC_RDISTSGI_IPRIORITYR(_gic_table[index].redist_hw_base[cpu_id], irq) >> ((irq % 4U) * 8U)) & 0xFFUL;
  338. }
  339. else
  340. {
  341. return (GIC_DIST_PRI(_gic_table[index].dist_hw_base, irq) >> ((irq % 4U) * 8U)) & 0xFFUL;
  342. }
  343. }
  344. void arm_gic_set_system_register_enable_mask(rt_uint32_t index, rt_uint32_t value)
  345. {
  346. RT_ASSERT(index < ARM_GIC_MAX_NR);
  347. value &= 0xFFUL;
  348. /* set priority mask */
  349. __set_gicv3_reg(ICC_SRE, value);
  350. __ISB();
  351. /* __asm volatile ("isb 0xF":: */
  352. /* :"memory"); */
  353. }
  354. rt_uint32_t arm_gic_get_system_register_enable_mask(rt_uint32_t index)
  355. {
  356. RT_ASSERT(index < ARM_GIC_MAX_NR);
  357. rt_uint32_t value;
  358. __get_gicv3_reg(ICC_SRE, value);
  359. return value;
  360. }
  361. void arm_gic_set_interface_prior_mask(rt_uint32_t index, rt_uint32_t priority)
  362. {
  363. RT_ASSERT(index < ARM_GIC_MAX_NR);
  364. priority &= 0xFFUL;
  365. /* set priority mask */
  366. __set_gicv3_reg(ICC_PMR, priority);
  367. }
  368. rt_uint32_t arm_gic_get_interface_prior_mask(rt_uint32_t index)
  369. {
  370. RT_ASSERT(index < ARM_GIC_MAX_NR);
  371. rt_uint32_t priority;
  372. __get_gicv3_reg(ICC_PMR, priority);
  373. return priority;
  374. }
  375. void arm_gic_set_binary_point(rt_uint32_t index, rt_uint32_t binary_point)
  376. {
  377. index = index;
  378. binary_point &= 0x7U;
  379. __set_gicv3_reg(ICC_BPR1, binary_point);
  380. }
  381. rt_uint32_t arm_gic_get_binary_point(rt_uint32_t index)
  382. {
  383. rt_uint32_t binary_point;
  384. index = index;
  385. __get_gicv3_reg(ICC_BPR1, binary_point);
  386. return binary_point;
  387. }
  388. rt_uint32_t arm_gic_get_irq_status(rt_uint32_t index, int irq)
  389. {
  390. rt_uint32_t pending;
  391. rt_uint32_t active;
  392. RT_ASSERT(index < ARM_GIC_MAX_NR);
  393. if (!arm_gic_irq_is_valid(index, irq))
  394. {
  395. return 0U;
  396. }
  397. irq = irq - _gic_table[index].offset;
  398. RT_ASSERT(irq > 0U);
  399. active = (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
  400. pending = (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
  401. return ((active << 1U) | pending);
  402. }
  403. rt_uint32_t arm_gic_get_high_pending_irq(rt_uint32_t index)
  404. {
  405. rt_uint32_t irq;
  406. RT_ASSERT(index < ARM_GIC_MAX_NR);
  407. index = index;
  408. __get_gicv3_reg(ICC_HPPIR1, irq);
  409. return irq;
  410. }
  411. rt_uint32_t arm_gic_get_interface_id(rt_uint32_t index)
  412. {
  413. RT_ASSERT(index < ARM_GIC_MAX_NR);
  414. return GIC_CPU_IIDR(_gic_table[index].cpu_hw_base);
  415. }
  416. void arm_gic_set_group(rt_uint32_t index, int irq, rt_uint32_t group)
  417. {
  418. rt_uint32_t igroupr;
  419. rt_uint32_t shift;
  420. RT_ASSERT(index < ARM_GIC_MAX_NR);
  421. RT_ASSERT(group <= 1U);
  422. if (!arm_gic_irq_is_valid(index, irq))
  423. {
  424. return;
  425. }
  426. irq = irq - _gic_table[index].offset;
  427. RT_ASSERT(irq > 0U);
  428. igroupr = GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq);
  429. shift = (irq % 32U);
  430. igroupr &= (~(1U << shift));
  431. igroupr |= ((group & 0x1U) << shift);
  432. GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) = igroupr;
  433. }
  434. rt_uint32_t arm_gic_get_group(rt_uint32_t index, int irq)
  435. {
  436. RT_ASSERT(index < ARM_GIC_MAX_NR);
  437. if (!arm_gic_irq_is_valid(index, irq))
  438. {
  439. return 0U;
  440. }
  441. irq = irq - _gic_table[index].offset;
  442. RT_ASSERT(irq > 0U);
  443. return (GIC_DIST_IGROUP(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1UL;
  444. }
  445. static int arm_gicv3_wait_rwp(rt_uint32_t index, rt_uint32_t irq)
  446. {
  447. rt_uint32_t rwp_bit;
  448. rt_uint32_t base;
  449. RT_ASSERT(index < ARM_GIC_MAX_NR);
  450. if (irq < 32u)
  451. {
  452. rt_int32_t cpu_id = rt_hw_cpu_id();
  453. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  454. base = _gic_table[index].redist_hw_base[cpu_id];
  455. rwp_bit = GICR_CTLR_RWP;
  456. }
  457. else
  458. {
  459. base = _gic_table[index].dist_hw_base;
  460. rwp_bit = GICD_CTLR_RWP;
  461. }
  462. while (__REG32(base) & rwp_bit)
  463. {
  464. ;
  465. }
  466. return 0;
  467. }
  468. int arm_gic_dist_init(rt_uint32_t index, rt_uint32_t dist_base, int irq_start)
  469. {
  470. rt_uint64_t cpu0_affval;
  471. unsigned int gic_type;
  472. rt_size_t irq_index;
  473. rt_uint32_t irq;
  474. rt_uint32_t shift;
  475. rt_uint32_t value;
  476. RT_ASSERT(index < ARM_GIC_MAX_NR);
  477. _gic_table[index].dist_hw_base = dist_base;
  478. _gic_table[index].offset = irq_start;
  479. /* Find out how many interrupts are supported. */
  480. gic_type = GIC_DIST_TYPE(dist_base);
  481. _gic_max_irq = ((gic_type & 0x1fU) + 1U) * 32U;
  482. /*
  483. * The GIC only supports up to 1020 interrupt sources.
  484. * Limit this to either the architected maximum, or the
  485. * platform maximum.
  486. */
  487. if (_gic_max_irq > 1020U)
  488. _gic_max_irq = 1020U;
  489. if (_gic_max_irq > ARM_GIC_NR_IRQS) /* the platform maximum interrupts */
  490. _gic_max_irq = ARM_GIC_NR_IRQS;
  491. GIC_DIST_CTRL(dist_base) = 0x0U;
  492. /* Wait for register write pending */
  493. arm_gicv3_wait_rwp(0, 32);
  494. cpu0_affval = get_main_cpu_affval();
  495. /* Only configure SPI interrupts that are declared by the current board. */
  496. for (irq_index = 0; irq_index < s100_mcu1_rt_irq_configs_count; irq_index++)
  497. {
  498. irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[irq_index].irq_number;
  499. if ((irq < 32U) || (irq >= _gic_max_irq))
  500. {
  501. continue;
  502. }
  503. shift = (irq % 16U) << 1U;
  504. value = GIC_DIST_CONFIG(dist_base, irq);
  505. value &= ~(3U << shift);
  506. GIC_DIST_CONFIG(dist_base, irq) = value;
  507. GIC_DIST_IROUTER_LOW(dist_base, irq) = (rt_uint32_t)cpu0_affval;
  508. GIC_DIST_IROUTER_HIGH(dist_base, irq) = (rt_uint32_t)(cpu0_affval >> 32);
  509. value = GIC_DIST_PRI(dist_base, irq);
  510. value &= ~(0xFFUL << ((irq % 4U) * 8U));
  511. value |= (0xA0UL << ((irq % 4U) * 8U));
  512. GIC_DIST_PRI(dist_base, irq) = value;
  513. GIC_DIST_PENDING_CLEAR(dist_base, irq) = 1U << (irq % 32U);
  514. GIC_DIST_ENABLE_CLEAR(dist_base, irq) = 1U << (irq % 32U);
  515. GIC_DIST_IGROUP(dist_base, irq) |= 1U << (irq % 32U);
  516. }
  517. arm_gicv3_wait_rwp(0, 32);
  518. /*
  519. The Distributor control register (GICD_CTLR) must be configured to enable the interrupt groups and to set the routing mode.
  520. Enable Affinity routing (ARE bits) The ARE bits in GICD_CTLR control whether affinity routing is enabled.
  521. If affinity routing is not enabled, GICv3 can be configured for legacy operation.
  522. Whether affinity routing is enabled or not can be controlled separately for Secure and Non-secure state.
  523. Enables GICD_CTLR contains separate enable bits for Group 0, Secure Group 1 and Non-secure Group 1:
  524. GICD_CTLR.EnableGrp1S enables distribution of Secure Group 1 interrupts.
  525. GICD_CTLR.EnableGrp1NS enables distribution of Non-secure Group 1 interrupts.
  526. GICD_CTLR.EnableGrp0 enables distribution of Group 0 interrupts.
  527. */
  528. GIC_DIST_CTRL(dist_base) = GICD_CTLR_ARE_NS | GICD_CTLR_ENGRP1NS;
  529. return 0;
  530. }
  531. int arm_gic_redist_address_set(rt_uint32_t index, rt_uint32_t redist_addr, rt_uint32_t cpu_id)
  532. {
  533. RT_ASSERT(index < ARM_GIC_MAX_NR);
  534. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  535. _gic_table[index].redist_hw_base[cpu_id] = redist_addr;
  536. return 0;
  537. }
  538. int arm_gic_cpu_interface_address_set(rt_uint32_t index, rt_uint32_t interface_addr, rt_uint32_t cpu_id)
  539. {
  540. RT_ASSERT(index < ARM_GIC_MAX_NR);
  541. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  542. _gic_table[index].cpu_hw_base[cpu_id] = interface_addr;
  543. return 0;
  544. }
  545. int arm_gic_redist_init(rt_uint32_t index)
  546. {
  547. unsigned int i;
  548. rt_uint32_t base;
  549. rt_int32_t cpu_id = rt_hw_cpu_id();
  550. RT_ASSERT(index < ARM_GIC_MAX_NR);
  551. RT_ASSERT((cpu_id) < RT_CPUS_NR);
  552. base = _gic_table[index].redist_hw_base[cpu_id];
  553. /* redistributor enable */
  554. /* 将原来的值的第二位清零,其他位保持不变 */
  555. GIC_RDIST_WAKER(base) &= ~(1U << 1);
  556. /* 一直执行,直到GIC_RDIST_WAKER(base)的值的第2位(从0开始计数)为0 */
  557. while (GIC_RDIST_WAKER(base) & (1 << 2))
  558. {
  559. ;
  560. }
  561. /* Disable all sgi and ppi interrupt */
  562. GIC_RDISTSGI_ICENABLER0(base) = 0xFFFFFFFF;
  563. arm_gicv3_wait_rwp(0, 0);
  564. /* Clear all inetrrupt pending */
  565. GIC_RDISTSGI_ICPENDR0(base) = 0xFFFFFFFF;
  566. /* the corresponding interrupt is Group 1 or Non-secure Group 1. */
  567. GIC_RDISTSGI_IGROUPR0(base, 0) = 0xFFFFFFFF;
  568. GIC_RDISTSGI_IGRPMODR0(base, 0) = 0xFFFFFFFF;
  569. /* Configure default priorities for SGI 0:15 and PPI 16:31. */
  570. for (i = 0; i < 32; i += 4)
  571. {
  572. GIC_RDISTSGI_IPRIORITYR(base, i) = 0xa0a0a0a0U;
  573. }
  574. /* Trigger level for PPI interrupts*/
  575. GIC_RDISTSGI_ICFGR1(base) = 0x0U; /* PPI is level-sensitive. */
  576. return 0;
  577. }
  578. int arm_gic_cpu_init(rt_uint32_t index)
  579. {
  580. rt_uint32_t value;
  581. RT_ASSERT(index < ARM_GIC_MAX_NR);
  582. /* The Priority Mask sets the minimum priority an
  583. * interrupt must have in order to be forwarded to the PE.
  584. */
  585. value = arm_gic_get_system_register_enable_mask(index);
  586. value |= (1U << 0);
  587. arm_gic_set_system_register_enable_mask(index, value);
  588. __set_gicv3_reg(ICC_CTLR, 0);
  589. arm_gic_set_interface_prior_mask(index, 0xFFU);
  590. /* Enable group1 interrupt */
  591. value = 0x1U;
  592. __set_gicv3_reg(ICC_IGRPEN1, value);
  593. /* The Binary Point register is used
  594. * for priority grouping and preemption.
  595. */
  596. arm_gic_set_binary_point(0, 0);
  597. /* ICC_BPR0_EL1 determines the preemption group for both
  598. Group 0 and Group 1 interrupts.
  599. */
  600. value = 0x1U;
  601. __set_gicv3_reg(ICC_CTLR, value);
  602. return 0;
  603. }
  604. #ifdef RT_USING_SMP
  605. void arm_gic_secondary_cpu_init(void)
  606. {
  607. arm_gic_redist_init(0);
  608. arm_gic_cpu_init(0);
  609. }
  610. #endif
  611. void arm_gic_dump_type(rt_uint32_t index)
  612. {
  613. unsigned int gic_type;
  614. gic_type = GIC_DIST_TYPE(_gic_table[index].dist_hw_base);
  615. rt_kprintf("GICv%d on %p, max IRQs: %d, %s security extension(%08x)\n",
  616. (GIC_DIST_ICPIDR2(_gic_table[index].dist_hw_base) >> 4U) & 0xfUL,
  617. _gic_table[index].dist_hw_base,
  618. _gic_max_irq,
  619. gic_type & (1U << 10U) ? "has" : "no",
  620. gic_type);
  621. }
  622. void arm_gic_dump(rt_uint32_t index)
  623. {
  624. unsigned int k;
  625. rt_size_t i;
  626. rt_uint32_t irq;
  627. k = arm_gic_get_high_pending_irq(0);
  628. rt_kprintf("--- high pending priority: %d(%08x)\n", k, k);
  629. rt_kprintf("--- hw mask ---\n");
  630. for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++)
  631. {
  632. irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[i].irq_number;
  633. if ((irq < 32U) || (irq >= _gic_max_irq))
  634. {
  635. continue;
  636. }
  637. rt_kprintf("irq %3u %-16s enable=%u\n",
  638. irq,
  639. s100_mcu1_rt_irq_configs[i].name,
  640. (GIC_DIST_ENABLE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1U);
  641. }
  642. rt_kprintf("\n--- hw pending ---\n");
  643. for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++)
  644. {
  645. irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[i].irq_number;
  646. if ((irq < 32U) || (irq >= _gic_max_irq))
  647. {
  648. continue;
  649. }
  650. rt_kprintf("irq %3u %-16s pending=%u\n",
  651. irq,
  652. s100_mcu1_rt_irq_configs[i].name,
  653. (GIC_DIST_PENDING_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1U);
  654. }
  655. rt_kprintf("\n--- hw active ---\n");
  656. for (i = 0; i < s100_mcu1_rt_irq_configs_count; i++)
  657. {
  658. irq = (rt_uint32_t)s100_mcu1_rt_irq_configs[i].irq_number;
  659. if ((irq < 32U) || (irq >= _gic_max_irq))
  660. {
  661. continue;
  662. }
  663. rt_kprintf("irq %3u %-16s active=%u\n",
  664. irq,
  665. s100_mcu1_rt_irq_configs[i].name,
  666. (GIC_DIST_ACTIVE_SET(_gic_table[index].dist_hw_base, irq) >> (irq % 32U)) & 0x1U);
  667. }
  668. rt_kprintf("\n");
  669. }
  670. long gic_dump(void)
  671. {
  672. arm_gic_dump_type(0);
  673. arm_gic_dump(0);
  674. return 0;
  675. }