arc_exception.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /* ------------------------------------------
  2. * Copyright (c) 2016, Synopsys, Inc. All rights reserved.
  3. * Redistribution and use in source and binary forms, with or without modification,
  4. * are permitted provided that the following conditions are met:
  5. * 1) Redistributions of source code must retain the above copyright notice, this
  6. * list of conditions and the following disclaimer.
  7. * 2) Redistributions in binary form must reproduce the above copyright notice,
  8. * this list of conditions and the following disclaimer in the documentation and/or
  9. * other materials provided with the distribution.
  10. * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may
  11. * be used to endorse or promote products derived from this software without
  12. * specific prior written permission.
  13. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. *
  24. * \version 2016.05
  25. * \date 2014-07-15
  26. * \author Wayne Ren(Wei.Ren@synopsys.com)
  27. --------------------------------------------- */
  28. /**
  29. * \file
  30. * \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT
  31. * \brief header file of exception and interrupt management module
  32. */
  33. #ifndef _ARC_HAL_EXCEPTION_H_
  34. #define _ARC_HAL_EXCEPTION_H_
  35. #include "inc/embARC_toolchain.h"
  36. #include "inc/arc/arc.h"
  37. #include "inc/arc/arc_builtin.h"
  38. #ifdef __cplusplus
  39. extern "C" {
  40. #endif
  41. /**
  42. * \addtogroup ARC_HAL_EXCEPTION_CPU
  43. * @{
  44. * \todo need a conf.h from application or board to define the
  45. * features of processor, such as number of exception, code
  46. * density and FIQ.
  47. */
  48. #ifndef NUM_EXC_CPU
  49. #define NUM_EXC_CPU 16 /*!< number of CPU exceptions */
  50. #endif
  51. #ifndef NUM_EXC_INT
  52. #define NUM_EXC_INT 9 /*!< number of interrupt exceptions, defined by users*/
  53. #endif
  54. #define NUM_EXC_ALL (NUM_EXC_CPU + NUM_EXC_INT) /*!< total number of exceptions */
  55. #ifdef ARC_FEATURE_SEC_PRESENT
  56. typedef struct int_exc_frame {
  57. uint32_t erbta;
  58. uint32_t r30; /* r30 is useless, skipped? */
  59. uint32_t ilink; /* r29 is useless, skipped?*/
  60. /* r28 is sp, saved other place */
  61. uint32_t fp; /* r27 */
  62. uint32_t gp; /* r26 */
  63. uint32_t r12;
  64. uint32_t lp_end, lp_start, lp_count;
  65. #ifdef ARC_FEATURE_CODE_DENSITY
  66. uint32_t ei, ldi, jli;
  67. #endif
  68. uint32_t r0, r1, r2, r3;
  69. #ifndef ARC_FEATURE_RF16
  70. uint32_t r4, r5, r6, r7, r8, r9;
  71. #endif
  72. uint32_t r10, r11;
  73. uint32_t blink; /* r31 */
  74. uint32_t ret;
  75. uint32_t sec_stat;
  76. uint32_t status32;
  77. } EMBARC_PACKED INT_EXC_FRAME;
  78. #else
  79. typedef struct int_exc_frame {
  80. uint32_t erbta;
  81. uint32_t r30; /* r30 is useless, skipped? */
  82. uint32_t ilink; /* r29 is useless, skipped?*/
  83. /* r28 is sp, saved other place */
  84. uint32_t fp; /* r27 */
  85. uint32_t gp; /* r26 */
  86. uint32_t r12;
  87. uint32_t r0, r1, r2, r3;
  88. #ifndef ARC_FEATURE_RF16
  89. uint32_t r4, r5, r6, r7, r8, r9;
  90. #endif
  91. uint32_t r10, r11;
  92. uint32_t blink; /* r31 */
  93. uint32_t lp_end, lp_start, lp_count;
  94. #ifdef ARC_FEATURE_CODE_DENSITY
  95. uint32_t ei, ldi, jli;
  96. #endif
  97. uint32_t ret;
  98. uint32_t status32;
  99. } EMBARC_PACKED INT_EXC_FRAME;
  100. #endif
  101. typedef struct callee_frame {
  102. #ifndef ARC_FEATURE_RF16
  103. uint32_t r25;
  104. uint32_t r24;
  105. uint32_t r23;
  106. uint32_t r22;
  107. uint32_t r21;
  108. uint32_t r20;
  109. uint32_t r19;
  110. uint32_t r18;
  111. uint32_t r17;
  112. uint32_t r16;
  113. #endif
  114. uint32_t r15;
  115. uint32_t r14;
  116. uint32_t r13;
  117. } EMBARC_PACKED CALLEE_FRAME;
  118. typedef struct processor_frame {
  119. CALLEE_FRAME callee_regs;
  120. INT_EXC_FRAME exc_frame;
  121. } EMBARC_PACKED PROCESSOR_FRAME;
  122. #define ARC_PROCESSOR_FRAME_SIZE (sizeof(PROCESSOR_FRAME) / sizeof(uint32_t))
  123. #define ARC_EXC_FRAME_SIZE (sizeof(INT_EXC_FRAME) / sizeof(uint32_t))
  124. #define ARC_CALLEE_FRAME_SIZE (sizeof(CALLEE_FRAME) / sizeof(uint32_t))
  125. extern uint32_t exc_nest_count;
  126. /**
  127. * \brief write the exception vector base
  128. *
  129. * \param[in] vec_base the target vector base
  130. */
  131. Inline void arc_vector_base_write(const void * vec_base)
  132. {
  133. _arc_aux_write(AUX_INT_VECT_BASE, (uint32_t)vec_base);
  134. }
  135. /**
  136. * \brief read current exception vector base
  137. *
  138. * \returns exception vector base (uint32_t)
  139. */
  140. Inline uint32_t arc_vector_base_read(void)
  141. {
  142. return _arc_aux_read(AUX_INT_VECT_BASE);
  143. }
  144. /**
  145. * \brief sense whether in exc/interrupt processing
  146. *
  147. * \retval 0 not in exc/interrupt processing
  148. * \retval 1 in exc/interrupt processing
  149. */
  150. Inline uint32_t exc_sense(void)
  151. {
  152. return (exc_nest_count > 0U);
  153. }
  154. /** @}*/
  155. /**
  156. * \addtogroup ARC_HAL_EXCEPTION_INTERRUPT
  157. * @{
  158. */
  159. #ifndef INT_PRI_MIN
  160. #define INT_PRI_MIN (-2) /*!< the minimum interrupt priority */
  161. #endif
  162. #define INT_PRI_MAX (-1) /*!< the maximum interrupt priority */
  163. /**
  164. * \brief disable the specific interrupt
  165. *
  166. * \param[in] intno interrupt number
  167. */
  168. Inline void arc_int_disable(const uint32_t intno)
  169. {
  170. _arc_aux_write(AUX_IRQ_SELECT, intno);
  171. _arc_aux_write(AUX_IRQ_ENABLE, 0);
  172. }
  173. /**
  174. * \brief enable the specific int
  175. *
  176. * \param[in] intno interrupt number
  177. */
  178. Inline void arc_int_enable(const uint32_t intno)
  179. {
  180. _arc_aux_write(AUX_IRQ_SELECT, intno);
  181. _arc_aux_write(AUX_IRQ_ENABLE, 1);
  182. }
  183. /**
  184. * \brief check whether the specific int is enabled
  185. *
  186. * \param[in] intno interrupt number
  187. * \return 0 disabled, 1 enabled
  188. */
  189. Inline uint32_t arc_int_enabled(const uint32_t intno)
  190. {
  191. _arc_aux_write(AUX_IRQ_SELECT, intno);
  192. return _arc_aux_read(AUX_IRQ_ENABLE);
  193. }
  194. /**
  195. * \brief get the interrupt priority mask
  196. *
  197. * \returns interrupt priority mask, negative num
  198. */
  199. Inline uint32_t arc_int_ipm_get(void)
  200. {
  201. return ((_arc_aux_read(AUX_STATUS32) >> 1) & 0x0f);
  202. }
  203. /**
  204. * \brief set the interrupt priority mask
  205. *
  206. * \param[in] intpri interrupt priority
  207. */
  208. Inline void arc_int_ipm_set(uint32_t intpri)
  209. {
  210. volatile uint32_t status;
  211. status = _arc_aux_read(AUX_STATUS32) & ~0x1e;
  212. status = status | ((intpri << 1) & 0x1e);
  213. /* sr cannot write AUX_STATUS32 */
  214. Asm("kflag %0"::"ir"(status));
  215. }
  216. /**
  217. * \brief get current interrupt priority mask
  218. *
  219. * \param[in] intno interrupt number
  220. */
  221. Inline uint32_t arc_int_pri_get(const uint32_t intno)
  222. {
  223. _arc_aux_write(AUX_IRQ_SELECT, intno);
  224. return _arc_aux_read(AUX_IRQ_PRIORITY);
  225. }
  226. /**
  227. * \brief set interrupt priority
  228. *
  229. * \param[in] intno interrupt number
  230. * \param[in] intpri interrupt priority
  231. */
  232. Inline void arc_int_pri_set(const uint32_t intno, uint32_t intpri)
  233. {
  234. _arc_aux_write(AUX_IRQ_SELECT, intno);
  235. _arc_aux_write(AUX_IRQ_PRIORITY, intpri | (_arc_aux_read(AUX_IRQ_PRIORITY) & 0xfffffff0));
  236. }
  237. /**
  238. * \brief set interrupt secure or not secure
  239. *
  240. * \param[in] intno interrupt number
  241. * \param[in] secure, 0 for normal, >0 for secure
  242. */
  243. Inline void arc_int_secure_set(const uint32_t intno, uint32_t secure)
  244. {
  245. _arc_aux_write(AUX_IRQ_SELECT, intno);
  246. if (secure) {
  247. _arc_aux_write(AUX_IRQ_PRIORITY, _arc_aux_read(AUX_IRQ_PRIORITY) |
  248. (1 << AUX_IRQ_PRIORITY_BIT_S));
  249. } else {
  250. _arc_aux_write(AUX_IRQ_PRIORITY, _arc_aux_read(AUX_IRQ_PRIORITY) & 0xf);
  251. }
  252. }
  253. /**
  254. * \brief probe the pending status of interrupt
  255. *
  256. * \param[in] intno interrupt number
  257. *
  258. * \returns 1 pending, 0 no pending
  259. */
  260. Inline uint32_t arc_int_probe(const uint32_t intno)
  261. {
  262. _arc_aux_write(AUX_IRQ_SELECT, intno);
  263. return _arc_aux_read(AUX_IRQ_PENDING);
  264. }
  265. /**
  266. * \brief trigger the interrupt in software
  267. *
  268. * \param[in] intno interrupt number
  269. */
  270. Inline void arc_int_sw_trigger(const uint32_t intno)
  271. {
  272. _arc_aux_write(AUX_IRQ_HINT, intno);
  273. }
  274. /**
  275. * \brief config the interrupt level triggered or pulse triggered
  276. *
  277. * \param[in] intno interrupt number
  278. * \param[in] level, 0-level trigger, 1-pluse triggered
  279. */
  280. Inline void arc_int_level_config(const uint32_t intno, const uint32_t level)
  281. {
  282. _arc_aux_write(AUX_IRQ_SELECT, intno);
  283. _arc_aux_write(AUX_IRQ_TRIGGER, level);
  284. }
  285. /**
  286. * \brief lock cpu, disable interrupts
  287. */
  288. Inline void arc_lock(void)
  289. {
  290. Asm("clri");
  291. Asm("":::"memory");
  292. }
  293. /**
  294. * \brief unlock cpu, enable interrupts to happen
  295. */
  296. Inline void arc_unlock(void)
  297. {
  298. Asm("":::"memory");
  299. Asm("seti");
  300. }
  301. /**
  302. * \brief lock cpu and staus
  303. *
  304. * \returns cpu status
  305. */
  306. Inline uint32_t arc_lock_save(void)
  307. {
  308. return _arc_clri();
  309. }
  310. /**
  311. * \brief unlock cpu with the specific status
  312. *
  313. * \param[in] status cpu status saved by cpu_lock_save
  314. */
  315. Inline void arc_unlock_restore(const uint32_t status)
  316. {
  317. _arc_seti(status);
  318. }
  319. /** @}*/
  320. /**
  321. * \addtogroup ARC_HAL_EXCEPTION_CPU
  322. * @{
  323. */
  324. /**
  325. * \typedef EXC_ENTRY
  326. * \brief the data type for exception entry
  327. */
  328. typedef void (*EXC_ENTRY) (void);
  329. /**
  330. * \typedef EXC_HANDLER
  331. * \brief the data type for exception handler
  332. */
  333. typedef void (*EXC_HANDLER) (void *exc_frame);
  334. /** @}*/
  335. /**
  336. * \ingroup ARC_HAL_EXCEPTION_INTERRUPT
  337. * \typedef INT_HANDLER
  338. * \brief the data type for interrupt handler
  339. */
  340. typedef void (*INT_HANDLER) (void *ptr);
  341. extern EXC_ENTRY exc_entry_table[NUM_EXC_ALL];
  342. extern EXC_HANDLER exc_int_handler_table[NUM_EXC_ALL];
  343. /** \ingroup ARC_HAL_EXCEPTION_CPU
  344. * @{
  345. */
  346. /**
  347. * \fn _arc_reset
  348. * \brief the reset entry
  349. */
  350. extern void _arc_reset(void);
  351. /**
  352. * \fn exc_entry_cpu
  353. * \brief the default CPU exception entry
  354. */
  355. extern void exc_entry_cpu(void);
  356. /**
  357. * \fn exc_entry_firq
  358. * \brief the fast interrupt exception entry
  359. */
  360. extern void exc_entry_firq(void);
  361. /**
  362. * \fn exc_entry_int
  363. * \brief the interrupt exception entry
  364. */
  365. extern void exc_entry_int(void);
  366. /** @}*/
  367. /* excetpion related apis */
  368. extern void exc_int_init(void);
  369. extern int32_t exc_entry_install(const uint32_t excno, EXC_ENTRY entry);
  370. extern EXC_ENTRY exc_entry_get(const uint32_t excno);
  371. extern int32_t exc_handler_install(const uint32_t excno, EXC_HANDLER handler);
  372. extern EXC_HANDLER exc_handler_get(const uint32_t excno);
  373. /* interrupt related apis */
  374. extern int32_t int_disable(const uint32_t intno);
  375. extern int32_t int_enable(const uint32_t intno);
  376. extern int32_t int_enabled(const uint32_t intno);
  377. extern int32_t int_ipm_get(void);
  378. extern int32_t int_ipm_set(int32_t intpri);
  379. extern int32_t int_pri_get(const uint32_t intno);
  380. extern int32_t int_pri_set(const uint32_t intno, int32_t intpri);
  381. extern int32_t int_probe(const uint32_t intno);
  382. extern int32_t int_sw_trigger(const uint32_t intno);
  383. extern int32_t int_level_config(const uint32_t intno, const uint32_t level);
  384. extern void cpu_lock(void);
  385. extern void cpu_unlock(void);
  386. extern uint32_t cpu_lock_save(void);
  387. extern void cpu_unlock_restore(const uint32_t status);
  388. extern int32_t int_handler_install(const uint32_t intno, INT_HANDLER handler);
  389. extern INT_HANDLER int_handler_get(const uint32_t intno);
  390. extern int32_t int_secure_set(const uint32_t intno, uint32_t secure);
  391. #ifdef __cplusplus
  392. }
  393. #endif
  394. #endif /* _ARC_HAL_EXCEPTION_H_*/