traps.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * interrupt vector setup
  3. *
  4. * Copyright (c) 2009 Openmoko Inc.
  5. *
  6. * Authors Daniel Mack <daniel@caiaq.de>
  7. * Christopher Hall <hsw@openmoko.com>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. #include <wikilib.h>
  23. #include <input.h>
  24. #include <regs.h>
  25. #include <interrupt.h>
  26. #include <misc.h>
  27. #include <button.h>
  28. #include <ctp.h>
  29. #include "traps.h"
  30. #include "serial.h"
  31. #define CLEAR_IRQ(reg,val) \
  32. do { \
  33. (reg) = (val); \
  34. } while (0)
  35. static void undef_irq_handler(void) __attribute__((interrupt_handler));
  36. static void illegal_instruction(void) __attribute__((interrupt_handler));
  37. static void illegal_irq_handler(void) __attribute__((interrupt_handler));
  38. static void serial0_err_irq(void) __attribute__((interrupt_handler));
  39. static void serial0_in_irq(void) __attribute__((interrupt_handler));
  40. static void serial0_out_irq(void) __attribute__((interrupt_handler));
  41. static void serial1_out_irq(void) __attribute__((interrupt_handler));
  42. static void unaligned_data_access(void) __attribute__((interrupt_handler));
  43. void panic(const char *s, const uint32_t *stack)
  44. {
  45. uint32_t *sp = (uint32_t *)((uint32_t)stack & ~3);
  46. print_char('\n');
  47. print(s);
  48. print("\nSP = ");
  49. print_u32((uint32_t)stack);
  50. print_char('\n');
  51. {
  52. register unsigned int i = 0;
  53. register unsigned int j = 0;
  54. register unsigned int p = 0;
  55. for (i = 0; i <= 15; ++i) {
  56. print("R");
  57. print_dec32(i);
  58. if ( i < 10) {
  59. print_char(' ');
  60. }
  61. print(" = ");
  62. print_u32(sp[p]);
  63. print(" [");
  64. print_dec32(sp[p++]);
  65. print("]\n");
  66. }
  67. print("PS");
  68. print(" = ");
  69. print_u32(sp[p++]);
  70. print_char('\n');
  71. print("IP");
  72. print(" = ");
  73. i = sp[p++];
  74. print_u32(i);
  75. print(" [-1..]: ");
  76. for (j = 0; j < 8; j += 2) {
  77. print_char(' ');
  78. print_byte(((uint8_t *)i)[j - 2]);
  79. print_byte(((uint8_t *)i)[j - 1]);
  80. }
  81. print_char('\n');
  82. for (i = 0; i < 8; ++i) {
  83. print("sp[");
  84. print_dec32(p);
  85. print("] = ");
  86. for (j = 0; j < 4; ++j) {
  87. print_u32(sp[p++]);
  88. print_char(' ');
  89. }
  90. print_char('\n');
  91. }
  92. }
  93. hex_dump(stack, 256);
  94. for (;;) {
  95. }
  96. }
  97. #define PANIC(str) \
  98. do { \
  99. asm volatile( \
  100. "\tpushn\t%%r15\n" \
  101. "\txld.w\t%%r6, %0\n" \
  102. "\tld.w\t%%r7, %%sp\n" \
  103. "\txcall\tpanic\n" \
  104. : \
  105. : "i"((str)) \
  106. ); \
  107. } while (0)
  108. static void undef_irq_handler(void)
  109. {
  110. PANIC("Undefined interrupt");
  111. }
  112. static void nmi_handler(void)
  113. {
  114. PANIC("Non-maskable interrupt");
  115. }
  116. static void illegal_irq_handler(void)
  117. {
  118. PANIC("Illegal interrupt");
  119. }
  120. static void illegal_instruction(void)
  121. {
  122. PANIC("Illegal instruction");
  123. }
  124. static void unaligned_data_access(void)
  125. {
  126. PANIC("Unaligned data access");
  127. }
  128. static void serial0_err_irq(void)
  129. {
  130. CLEAR_IRQ(REG_INT_FSIF01, 1 << 0);
  131. }
  132. static void serial0_in_irq(void)
  133. {
  134. serial_filled_0();
  135. CLEAR_IRQ(REG_INT_FSIF01, 1 << 1);
  136. }
  137. static void serial0_out_irq(void)
  138. {
  139. serial_drained_0();
  140. }
  141. static void serial1_out_irq(void)
  142. {
  143. CLEAR_IRQ(REG_INT_FSIF01, 1 << 5);
  144. }
  145. #define N_TRAPS 108
  146. typedef void (*irq_callback)(void);
  147. irq_callback trap_table[N_TRAPS] = {
  148. undef_irq_handler, // 0 Reset
  149. undef_irq_handler, // 1 *reserved*
  150. undef_irq_handler, // 2 ext exception
  151. illegal_instruction, // 3 Undefined instruction exception
  152. undef_irq_handler, // 4 *reserved*
  153. undef_irq_handler, // 5 *reserved*
  154. unaligned_data_access, // 6 Address misaligned exception
  155. nmi_handler, // 7 NMI
  156. undef_irq_handler, // 8 *reserved*
  157. undef_irq_handler, // 9 *reserved*
  158. undef_irq_handler, // 10 *reserved*
  159. illegal_irq_handler, // 11 Illegal interrupt exception
  160. undef_irq_handler, // 12 Software exception 0
  161. undef_irq_handler, // 13 Software exception 1
  162. undef_irq_handler, // 14 Software exception 2
  163. undef_irq_handler, // 15 Software exception 3
  164. undef_irq_handler, // 16 Port input interrupt 0
  165. undef_irq_handler, // 17 Port input interrupt 1
  166. undef_irq_handler, // 18 Port input interrupt 2
  167. Button_PowerInterrupt, // 19 Port input interrupt 3
  168. Button_KeyInterrupt, // 20 Key input interrupt 0
  169. Button_KeyInterrupt, // 21 Key input interrupt 1
  170. undef_irq_handler, // 22 High-speed DMA Ch.0
  171. undef_irq_handler, // 23 High-speed DMA Ch.1
  172. undef_irq_handler, // 24 High-speed DMA Ch.2
  173. undef_irq_handler, // 25 High-speed DMA Ch.3
  174. undef_irq_handler, // 26 Intelligent DMA
  175. undef_irq_handler, // 27 *reserved*
  176. undef_irq_handler, // 28 *reserved*
  177. undef_irq_handler, // 29 *reserved*
  178. undef_irq_handler, // 30 16-bit timer 0 - compare-match B
  179. undef_irq_handler, // 31 16-bit timer 0 - compare-match A
  180. undef_irq_handler, // 32 *reserved*
  181. undef_irq_handler, // 33 *reserved*
  182. undef_irq_handler, // 34 16-bit timer 1 - compare-match B
  183. undef_irq_handler, // 35 16-bit timer 1 - compare-match A
  184. undef_irq_handler, // 36 *reserved*
  185. undef_irq_handler, // 37 *reserved*
  186. undef_irq_handler, // 38 16-bit timer 2 - compare-match B
  187. undef_irq_handler, // 39 16-bit timer 2 - compare-match A
  188. undef_irq_handler, // 40 *reserved*
  189. undef_irq_handler, // 41 *reserved*
  190. undef_irq_handler, // 42 16-bit timer 3 - compare-match B
  191. undef_irq_handler, // 43 16-bit timer 3 - compare-match A
  192. undef_irq_handler, // 44 *reserved*
  193. undef_irq_handler, // 45 *reserved*
  194. undef_irq_handler, // 46 16-bit timer 4 - compare-match B
  195. undef_irq_handler, // 47 16-bit timer 4 - compare-match A
  196. undef_irq_handler, // 48 *reserved*
  197. undef_irq_handler, // 49 *reserved*
  198. undef_irq_handler, // 50 16-bit timer 5 - compare-match B
  199. undef_irq_handler, // 51 16-bit timer 5 - compare-match A
  200. undef_irq_handler, // 52 *reserved*
  201. undef_irq_handler, // 53 *reserved*
  202. undef_irq_handler, // 54 *reserved*
  203. undef_irq_handler, // 55 *reserved*
  204. serial0_err_irq, // 56 Serial interface Ch.0 - Receive error
  205. serial0_in_irq, // 57 Serial interface Ch.0 - Receive buffer full
  206. serial0_out_irq, // 58 Serial interface Ch.0 - Transmit buffer empty
  207. undef_irq_handler, // 59 *reserved*
  208. CTP_interrupt, // 60 Serial interface Ch.1 - Receive error
  209. CTP_interrupt, // 61 Serial interface Ch.1 - Receive buffer full
  210. serial1_out_irq, // 62 Serial interface Ch.1 - Transmit buffer empty
  211. undef_irq_handler, // 63 A/D converter - Result out of range
  212. undef_irq_handler, // 64 A/D converter - End of conversion
  213. undef_irq_handler, // 65 RTC
  214. undef_irq_handler, // 66 *reserved*
  215. undef_irq_handler, // 67 *reserved*
  216. undef_irq_handler, // 68 Port input interrupt 4
  217. undef_irq_handler, // 69 Port input interrupt 5
  218. undef_irq_handler, // 70 Port input interrupt 6
  219. undef_irq_handler, // 71 Port input interrupt 7
  220. undef_irq_handler, // 72 *reserved*
  221. undef_irq_handler, // 73 LCDC
  222. undef_irq_handler, // 74 *reserved*
  223. undef_irq_handler, // 75 *reserved*
  224. undef_irq_handler, // 76 Serial interface Ch.2 - Receive error
  225. undef_irq_handler, // 77 Serial interface Ch.2 - Receive buffer full
  226. undef_irq_handler, // 78 Serial interface Ch.2 - Transmit buffer empty
  227. undef_irq_handler, // 79 *reserved*
  228. undef_irq_handler, // 80 *reserved*
  229. undef_irq_handler, // 81 SPI - Receive DMA request
  230. undef_irq_handler, // 82 SPI - Transmit DMA request
  231. undef_irq_handler, // 83 *reserved*
  232. undef_irq_handler, // 84 Port input interrupt 8 / SPI - SPI interrupt
  233. undef_irq_handler, // 85 Port input interrupt 9 / USB PDREQ - USB DMA request
  234. undef_irq_handler, // 86 Port input interrupt 10 / USB - USBinterrupt
  235. undef_irq_handler, // 87 Port input interrupt 11 / DCSIO - DCSIO interrupt
  236. undef_irq_handler, // 88 Port input interrupt 12
  237. undef_irq_handler, // 89 Port input interrupt 13
  238. undef_irq_handler, // 90 Port input interrupt 14
  239. undef_irq_handler, // 91 Port input interrupt 15
  240. undef_irq_handler, // 92 *reserved*
  241. undef_irq_handler, // 93 *reserved*
  242. undef_irq_handler, // 94 I2S interface - I2S FIFO empty
  243. undef_irq_handler, // 95 *reserved*
  244. undef_irq_handler, // 96 *reserved*
  245. undef_irq_handler, // 97 *reserved*
  246. undef_irq_handler, // 98 *reserved*
  247. undef_irq_handler, // 99 *reserved*
  248. undef_irq_handler, // 100 *reserved*
  249. undef_irq_handler, // 101 *reserved*
  250. undef_irq_handler, // 102 *reserved*
  251. undef_irq_handler, // 103 *reserved*
  252. undef_irq_handler, // 104 *reserved*
  253. undef_irq_handler, // 105 *reserved*
  254. undef_irq_handler, // 106 *reserved*
  255. undef_irq_handler, // 107 *reserved*
  256. };
  257. void traps_init(void)
  258. {
  259. (void)Interrupt_disable();
  260. /* WAKEUP=1 */
  261. REG_CMU_PROTECT = CMU_PROTECT_OFF;
  262. REG_CMU_OPT |= 0x1;
  263. REG_CMU_PROTECT = CMU_PROTECT_ON;
  264. /* relocate the trap table */
  265. asm("ld.w %%ttbr, %0" :: "r"(0x84000));
  266. Interrupt_enable(true);
  267. void traps_check(void);
  268. print("traps_init\n");
  269. traps_check();
  270. }
  271. void traps_check(void)
  272. {
  273. register uint32_t *tt, nh;
  274. asm volatile (
  275. "xld.w %0, trap_table\n"
  276. "xld.w %1, nmi_handler\n"
  277. : "=r"(tt), "=r"(nh)
  278. :
  279. );
  280. if (tt[7] != nh) {
  281. print("trap_table is corrupt\n");
  282. print_u32(tt[7]);
  283. print(" should be ");
  284. print_u32(nh);
  285. print("\n");
  286. }
  287. }