interrupt.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2010-11-13 weety first version
  9. */
  10. #include <rtthread.h>
  11. #include <rthw.h>
  12. #include "dm36x.h"
  13. #define MAX_HANDLERS 64
  14. extern rt_uint32_t rt_interrupt_nest;
  15. struct rt_irq_desc irq_desc[MAX_HANDLERS];
  16. /* exception and interrupt handler table */
  17. rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
  18. rt_uint32_t rt_thread_switch_interrupt_flag;
  19. #define IRQ_BIT(irq) ((irq) & 0x1f)
  20. #define FIQ_REG0_OFFSET 0x0000
  21. #define FIQ_REG1_OFFSET 0x0004
  22. #define IRQ_REG0_OFFSET 0x0008
  23. #define IRQ_REG1_OFFSET 0x000C
  24. #define IRQ_ENT_REG0_OFFSET 0x0018
  25. #define IRQ_ENT_REG1_OFFSET 0x001C
  26. #define IRQ_INCTL_REG_OFFSET 0x0020
  27. #define IRQ_EABASE_REG_OFFSET 0x0024
  28. #define IRQ_INTPRI0_REG_OFFSET 0x0030
  29. #define IRQ_INTPRI7_REG_OFFSET 0x004C
  30. /* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
  31. static const rt_uint8_t dm365_default_priorities[DAVINCI_N_AINTC_IRQ] = {
  32. [IRQ_DM3XX_VPSSINT0] = 2,
  33. [IRQ_DM3XX_VPSSINT1] = 6,
  34. [IRQ_DM3XX_VPSSINT2] = 6,
  35. [IRQ_DM3XX_VPSSINT3] = 6,
  36. [IRQ_DM3XX_VPSSINT4] = 6,
  37. [IRQ_DM3XX_VPSSINT5] = 6,
  38. [IRQ_DM3XX_VPSSINT6] = 6,
  39. [IRQ_DM3XX_VPSSINT7] = 7,
  40. [IRQ_DM3XX_VPSSINT8] = 6,
  41. [IRQ_ASQINT] = 6,
  42. [IRQ_DM365_IMXINT0] = 6,
  43. [IRQ_DM3XX_IMCOPINT] = 6,
  44. [IRQ_USBINT] = 4,
  45. [IRQ_DM3XX_RTOINT] = 4,
  46. [IRQ_DM3XX_TINT5] = 7,
  47. [IRQ_DM3XX_TINT6] = 7,
  48. [IRQ_CCINT0] = 5, /* dma */
  49. [IRQ_DM3XX_SPINT1_0] = 5, /* dma */
  50. [IRQ_DM3XX_SPINT1_1] = 5, /* dma */
  51. [IRQ_DM3XX_SPINT2_0] = 5, /* dma */
  52. [IRQ_DM365_PSCINT] = 7,
  53. [IRQ_DM3XX_SPINT2_1] = 7,
  54. [IRQ_DM3XX_TINT7] = 4,
  55. [IRQ_DM3XX_SDIOINT0] = 7,
  56. [IRQ_DM365_MBXINT] = 7,
  57. [IRQ_DM365_MBRINT] = 7,
  58. [IRQ_DM3XX_MMCINT0] = 7,
  59. [IRQ_DM3XX_MMCINT1] = 7,
  60. [IRQ_DM3XX_PWMINT3] = 7,
  61. [IRQ_DM365_DDRINT] = 7,
  62. [IRQ_DM365_AEMIFINT] = 7,
  63. [IRQ_DM3XX_SDIOINT1] = 4,
  64. [IRQ_DM365_TINT0] = 2, /* clockevent */
  65. [IRQ_DM365_TINT1] = 2, /* clocksource */
  66. [IRQ_DM365_TINT2] = 7, /* DSP timer */
  67. [IRQ_DM365_TINT3] = 7, /* system tick */
  68. [IRQ_PWMINT0] = 7,
  69. [IRQ_PWMINT1] = 7,
  70. [IRQ_DM365_PWMINT2] = 7,
  71. [IRQ_DM365_IICINT] = 3,
  72. [IRQ_UARTINT0] = 3,
  73. [IRQ_UARTINT1] = 3,
  74. [IRQ_DM3XX_SPINT0_0] = 3,
  75. [IRQ_DM3XX_SPINT0_1] = 3,
  76. [IRQ_DM3XX_GPIO0] = 3,
  77. [IRQ_DM3XX_GPIO1] = 7,
  78. [IRQ_DM3XX_GPIO2] = 4,
  79. [IRQ_DM3XX_GPIO3] = 4,
  80. [IRQ_DM3XX_GPIO4] = 7,
  81. [IRQ_DM3XX_GPIO5] = 7,
  82. [IRQ_DM3XX_GPIO6] = 7,
  83. [IRQ_DM3XX_GPIO7] = 7,
  84. [IRQ_DM3XX_GPIO8] = 7,
  85. [IRQ_DM3XX_GPIO9] = 7,
  86. [IRQ_DM365_GPIO10] = 7,
  87. [IRQ_DM365_GPIO11] = 7,
  88. [IRQ_DM365_GPIO12] = 7,
  89. [IRQ_DM365_GPIO13] = 7,
  90. [IRQ_DM365_GPIO14] = 7,
  91. [IRQ_DM365_GPIO15] = 7,
  92. [IRQ_DM365_KEYINT] = 7,
  93. [IRQ_DM365_COMMTX] = 7,
  94. [IRQ_DM365_COMMRX] = 7,
  95. [IRQ_EMUINT] = 7,
  96. };
  97. static inline unsigned int davinci_irq_readl(int offset)
  98. {
  99. return davinci_readl(DAVINCI_ARM_INTC_BASE + offset);
  100. }
  101. static inline void davinci_irq_writel(unsigned long value, int offset)
  102. {
  103. davinci_writel(value, DAVINCI_ARM_INTC_BASE + offset);
  104. }
  105. /**
  106. * @addtogroup DM36X
  107. */
  108. /*@{*/
  109. rt_isr_handler_t rt_hw_interrupt_handle(int vector, void *param)
  110. {
  111. rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
  112. return RT_NULL;
  113. }
  114. /**
  115. * This function will initialize hardware interrupt
  116. */
  117. void rt_hw_interrupt_init(void)
  118. {
  119. int i;
  120. register rt_uint32_t idx;
  121. const rt_uint8_t *priority;
  122. priority = dm365_default_priorities;
  123. /* Clear all interrupt requests */
  124. davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
  125. davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
  126. davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
  127. davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
  128. /* Disable all interrupts */
  129. davinci_irq_writel(0x0, IRQ_ENT_REG0_OFFSET);
  130. davinci_irq_writel(0x0, IRQ_ENT_REG1_OFFSET);
  131. /* Interrupts disabled immediately, IRQ entry reflects all */
  132. davinci_irq_writel(0x0, IRQ_INCTL_REG_OFFSET);
  133. /* we don't use the hardware vector table, just its entry addresses */
  134. davinci_irq_writel(0, IRQ_EABASE_REG_OFFSET);
  135. /* Clear all interrupt requests */
  136. davinci_irq_writel(~0x0, FIQ_REG0_OFFSET);
  137. davinci_irq_writel(~0x0, FIQ_REG1_OFFSET);
  138. davinci_irq_writel(~0x0, IRQ_REG0_OFFSET);
  139. davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
  140. for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
  141. unsigned j;
  142. rt_uint32_t pri;
  143. for (j = 0, pri = 0; j < 32; j += 4, priority++)
  144. pri |= (*priority & 0x07) << j;
  145. davinci_irq_writel(pri, i);
  146. }
  147. /* init exceptions table */
  148. for(idx=0; idx < MAX_HANDLERS; idx++)
  149. {
  150. irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
  151. irq_desc[idx].param = RT_NULL;
  152. #ifdef RT_USING_INTERRUPT_INFO
  153. rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
  154. irq_desc[idx].counter = 0;
  155. #endif
  156. }
  157. /* init interrupt nest, and context in thread sp */
  158. rt_interrupt_nest = 0;
  159. rt_interrupt_from_thread = 0;
  160. rt_interrupt_to_thread = 0;
  161. rt_thread_switch_interrupt_flag = 0;
  162. }
  163. /**
  164. * This function will mask a interrupt.
  165. * @param vector the interrupt number
  166. */
  167. void rt_hw_interrupt_mask(int irq)
  168. {
  169. unsigned int mask;
  170. rt_uint32_t l;
  171. mask = 1 << IRQ_BIT(irq);
  172. if (irq > 31) {
  173. l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
  174. l &= ~mask;
  175. davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
  176. } else {
  177. l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
  178. l &= ~mask;
  179. davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
  180. }
  181. }
  182. /**
  183. * This function will un-mask a interrupt.
  184. * @param vector the interrupt number
  185. */
  186. void rt_hw_interrupt_umask(int irq)
  187. {
  188. unsigned int mask;
  189. rt_uint32_t l;
  190. mask = 1 << IRQ_BIT(irq);
  191. if (irq > 31) {
  192. l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
  193. l |= mask;
  194. davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
  195. } else {
  196. l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
  197. l |= mask;
  198. davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
  199. }
  200. }
  201. /**
  202. * This function will install a interrupt service routine to a interrupt.
  203. * @param vector the interrupt number
  204. * @param handler the interrupt service routine to be installed
  205. * @param param the interrupt service function parameter
  206. * @param name the interrupt name
  207. * @return old handler
  208. */
  209. rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
  210. void *param, const char *name)
  211. {
  212. rt_isr_handler_t old_handler = RT_NULL;
  213. if(vector < MAX_HANDLERS)
  214. {
  215. old_handler = irq_desc[vector].handler;
  216. if (handler != RT_NULL)
  217. {
  218. irq_desc[vector].handler = (rt_isr_handler_t)handler;
  219. irq_desc[vector].param = param;
  220. #ifdef RT_USING_INTERRUPT_INFO
  221. rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
  222. irq_desc[vector].counter = 0;
  223. #endif
  224. }
  225. }
  226. return old_handler;
  227. }
  228. #ifdef RT_USING_FINSH
  229. #ifdef RT_USING_INTERRUPT_INFO
  230. void list_irq(void)
  231. {
  232. int irq;
  233. rt_kprintf("number\tcount\tname\n");
  234. for (irq = 0; irq < MAX_HANDLERS; irq++)
  235. {
  236. if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default")))
  237. {
  238. rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name);
  239. }
  240. }
  241. }
  242. #include <finsh.h>
  243. FINSH_FUNCTION_EXPORT(list_irq, list system irq);
  244. #ifdef FINSH_USING_MSH
  245. int cmd_list_irq(int argc, char** argv)
  246. {
  247. list_irq();
  248. return 0;
  249. }
  250. MSH_CMD_EXPORT_ALIAS(cmd_list_irq, list_irq, list system irq);
  251. #endif
  252. #endif
  253. #endif
  254. /*@}*/