kgdb_asm.S 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. /*
  2. * Copyright (C) 2004 Axis Communications AB
  3. *
  4. * Code for handling break 8, hardware breakpoint, single step, and serial
  5. * port exceptions for kernel debugging purposes.
  6. */
  7. #include <linux/config.h>
  8. #include <asm/arch/hwregs/intr_vect.h>
  9. ;; Exported functions.
  10. .globl kgdb_handle_exception
  11. kgdb_handle_exception:
  12. ;; Create a register image of the caller.
  13. ;;
  14. ;; First of all, save the ACR on the stack since we need it for address calculations.
  15. ;; We put it into the register struct later.
  16. subq 4, $sp
  17. move.d $acr, [$sp]
  18. ;; Now we are free to use ACR all we want.
  19. ;; If we were running this handler with interrupts on, we would have to be careful
  20. ;; to save and restore CCS manually, but since we aren't we treat it like every other
  21. ;; register.
  22. move.d reg, $acr
  23. move.d $r0, [$acr] ; Save R0 (start of register struct)
  24. addq 4, $acr
  25. move.d $r1, [$acr] ; Save R1
  26. addq 4, $acr
  27. move.d $r2, [$acr] ; Save R2
  28. addq 4, $acr
  29. move.d $r3, [$acr] ; Save R3
  30. addq 4, $acr
  31. move.d $r4, [$acr] ; Save R4
  32. addq 4, $acr
  33. move.d $r5, [$acr] ; Save R5
  34. addq 4, $acr
  35. move.d $r6, [$acr] ; Save R6
  36. addq 4, $acr
  37. move.d $r7, [$acr] ; Save R7
  38. addq 4, $acr
  39. move.d $r8, [$acr] ; Save R8
  40. addq 4, $acr
  41. move.d $r9, [$acr] ; Save R9
  42. addq 4, $acr
  43. move.d $r10, [$acr] ; Save R10
  44. addq 4, $acr
  45. move.d $r11, [$acr] ; Save R11
  46. addq 4, $acr
  47. move.d $r12, [$acr] ; Save R12
  48. addq 4, $acr
  49. move.d $r13, [$acr] ; Save R13
  50. addq 4, $acr
  51. move.d $sp, [$acr] ; Save SP (R14)
  52. addq 4, $acr
  53. ;; The ACR register is already saved on the stack, so pop it from there.
  54. move.d [$sp],$r0
  55. move.d $r0, [$acr]
  56. addq 4, $acr
  57. move $bz, [$acr]
  58. addq 1, $acr
  59. move $vr, [$acr]
  60. addq 1, $acr
  61. move $pid, [$acr]
  62. addq 4, $acr
  63. move $srs, [$acr]
  64. addq 1, $acr
  65. move $wz, [$acr]
  66. addq 2, $acr
  67. move $exs, [$acr]
  68. addq 4, $acr
  69. move $eda, [$acr]
  70. addq 4, $acr
  71. move $mof, [$acr]
  72. addq 4, $acr
  73. move $dz, [$acr]
  74. addq 4, $acr
  75. move $ebp, [$acr]
  76. addq 4, $acr
  77. move $erp, [$acr]
  78. addq 4, $acr
  79. move $srp, [$acr]
  80. addq 4, $acr
  81. move $nrp, [$acr]
  82. addq 4, $acr
  83. move $ccs, [$acr]
  84. addq 4, $acr
  85. move $usp, [$acr]
  86. addq 4, $acr
  87. move $spc, [$acr]
  88. addq 4, $acr
  89. ;; Skip the pseudo-PC.
  90. addq 4, $acr
  91. ;; Save the support registers in bank 0 - 3.
  92. clear.d $r1 ; Bank counter
  93. move.d sreg, $acr
  94. ;; Bank 0
  95. move $r1, $srs
  96. nop
  97. nop
  98. nop
  99. move $s0, $r0
  100. move.d $r0, [$acr]
  101. addq 4, $acr
  102. move $s1, $r0
  103. move.d $r0, [$acr]
  104. addq 4, $acr
  105. move $s2, $r0
  106. move.d $r0, [$acr]
  107. addq 4, $acr
  108. move $s3, $r0
  109. move.d $r0, [$acr]
  110. addq 4, $acr
  111. move $s4, $r0
  112. move.d $r0, [$acr]
  113. addq 4, $acr
  114. move $s5, $r0
  115. move.d $r0, [$acr]
  116. addq 4, $acr
  117. move $s6, $r0
  118. move.d $r0, [$acr]
  119. addq 4, $acr
  120. move $s7, $r0
  121. move.d $r0, [$acr]
  122. addq 4, $acr
  123. move $s8, $r0
  124. move.d $r0, [$acr]
  125. addq 4, $acr
  126. move $s9, $r0
  127. move.d $r0, [$acr]
  128. addq 4, $acr
  129. move $s10, $r0
  130. move.d $r0, [$acr]
  131. addq 4, $acr
  132. move $s11, $r0
  133. move.d $r0, [$acr]
  134. addq 4, $acr
  135. move $s12, $r0
  136. move.d $r0, [$acr]
  137. addq 4, $acr
  138. ;; Nothing in S13 - S15, bank 0
  139. clear.d [$acr]
  140. addq 4, $acr
  141. clear.d [$acr]
  142. addq 4, $acr
  143. clear.d [$acr]
  144. addq 4, $acr
  145. ;; Bank 1 and bank 2 have the same layout, hence the loop.
  146. addq 1, $r1
  147. 1:
  148. move $r1, $srs
  149. nop
  150. nop
  151. nop
  152. move $s0, $r0
  153. move.d $r0, [$acr]
  154. addq 4, $acr
  155. move $s1, $r0
  156. move.d $r0, [$acr]
  157. addq 4, $acr
  158. move $s2, $r0
  159. move.d $r0, [$acr]
  160. addq 4, $acr
  161. move $s3, $r0
  162. move.d $r0, [$acr]
  163. addq 4, $acr
  164. move $s4, $r0
  165. move.d $r0, [$acr]
  166. addq 4, $acr
  167. move $s5, $r0
  168. move.d $r0, [$acr]
  169. addq 4, $acr
  170. move $s6, $r0
  171. move.d $r0, [$acr]
  172. addq 4, $acr
  173. ;; Nothing in S7 - S15, bank 1 and 2
  174. clear.d [$acr]
  175. addq 4, $acr
  176. clear.d [$acr]
  177. addq 4, $acr
  178. clear.d [$acr]
  179. addq 4, $acr
  180. clear.d [$acr]
  181. addq 4, $acr
  182. clear.d [$acr]
  183. addq 4, $acr
  184. clear.d [$acr]
  185. addq 4, $acr
  186. clear.d [$acr]
  187. addq 4, $acr
  188. clear.d [$acr]
  189. addq 4, $acr
  190. clear.d [$acr]
  191. addq 4, $acr
  192. addq 1, $r1
  193. cmpq 3, $r1
  194. bne 1b
  195. nop
  196. ;; Bank 3
  197. move $r1, $srs
  198. nop
  199. nop
  200. nop
  201. move $s0, $r0
  202. move.d $r0, [$acr]
  203. addq 4, $acr
  204. move $s1, $r0
  205. move.d $r0, [$acr]
  206. addq 4, $acr
  207. move $s2, $r0
  208. move.d $r0, [$acr]
  209. addq 4, $acr
  210. move $s3, $r0
  211. move.d $r0, [$acr]
  212. addq 4, $acr
  213. move $s4, $r0
  214. move.d $r0, [$acr]
  215. addq 4, $acr
  216. move $s5, $r0
  217. move.d $r0, [$acr]
  218. addq 4, $acr
  219. move $s6, $r0
  220. move.d $r0, [$acr]
  221. addq 4, $acr
  222. move $s7, $r0
  223. move.d $r0, [$acr]
  224. addq 4, $acr
  225. move $s8, $r0
  226. move.d $r0, [$acr]
  227. addq 4, $acr
  228. move $s9, $r0
  229. move.d $r0, [$acr]
  230. addq 4, $acr
  231. move $s10, $r0
  232. move.d $r0, [$acr]
  233. addq 4, $acr
  234. move $s11, $r0
  235. move.d $r0, [$acr]
  236. addq 4, $acr
  237. move $s12, $r0
  238. move.d $r0, [$acr]
  239. addq 4, $acr
  240. move $s13, $r0
  241. move.d $r0, [$acr]
  242. addq 4, $acr
  243. move $s14, $r0
  244. move.d $r0, [$acr]
  245. addq 4, $acr
  246. ;; Nothing in S15, bank 3
  247. clear.d [$acr]
  248. addq 4, $acr
  249. ;; Check what got us here: get IDX field of EXS.
  250. move $exs, $r10
  251. and.d 0xff00, $r10
  252. lsrq 8, $r10
  253. #if defined(CONFIG_ETRAX_KGDB_PORT0)
  254. cmp.d SER0_INTR_VECT, $r10 ; IRQ for serial port 0
  255. beq sigint
  256. nop
  257. #elif defined(CONFIG_ETRAX_KGDB_PORT1)
  258. cmp.d SER1_INTR_VECT, $r10 ; IRQ for serial port 1
  259. beq sigint
  260. nop
  261. #elif defined(CONFIG_ETRAX_KGDB_PORT2)
  262. cmp.d SER2_INTR_VECT, $r10 ; IRQ for serial port 2
  263. beq sigint
  264. nop
  265. #elif defined(CONFIG_ETRAX_KGDB_PORT3)
  266. cmp.d SER3_INTR_VECT, $r10 ; IRQ for serial port 3
  267. beq sigint
  268. nop
  269. #endif
  270. ;; Multiple interrupt must be due to serial break.
  271. cmp.d 0x30, $r10 ; Multiple interrupt
  272. beq sigint
  273. nop
  274. ;; Neither of those? Then it's a sigtrap.
  275. ba handle_comm
  276. moveq 5, $r10 ; Set SIGTRAP (delay slot)
  277. sigint:
  278. ;; Serial interrupt; get character
  279. jsr getDebugChar
  280. nop ; Delay slot
  281. cmp.b 3, $r10 ; \003 (Ctrl-C)?
  282. bne return ; No, get out of here
  283. nop
  284. moveq 2, $r10 ; Set SIGINT
  285. ;;
  286. ;; Handle the communication
  287. ;;
  288. handle_comm:
  289. move.d internal_stack+1020, $sp ; Use the internal stack which grows upwards
  290. jsr handle_exception ; Interactive routine
  291. nop
  292. ;;
  293. ;; Return to the caller
  294. ;;
  295. return:
  296. ;; First of all, write the support registers.
  297. clear.d $r1 ; Bank counter
  298. move.d sreg, $acr
  299. ;; Bank 0
  300. move $r1, $srs
  301. nop
  302. nop
  303. nop
  304. move.d [$acr], $r0
  305. move $r0, $s0
  306. addq 4, $acr
  307. move.d [$acr], $r0
  308. move $r0, $s1
  309. addq 4, $acr
  310. move.d [$acr], $r0
  311. move $r0, $s2
  312. addq 4, $acr
  313. move.d [$acr], $r0
  314. move $r0, $s3
  315. addq 4, $acr
  316. move.d [$acr], $r0
  317. move $r0, $s4
  318. addq 4, $acr
  319. move.d [$acr], $r0
  320. move $r0, $s5
  321. addq 4, $acr
  322. ;; Nothing in S6 - S7, bank 0.
  323. addq 4, $acr
  324. addq 4, $acr
  325. move.d [$acr], $r0
  326. move $r0, $s8
  327. addq 4, $acr
  328. move.d [$acr], $r0
  329. move $r0, $s9
  330. addq 4, $acr
  331. move.d [$acr], $r0
  332. move $r0, $s10
  333. addq 4, $acr
  334. move.d [$acr], $r0
  335. move $r0, $s11
  336. addq 4, $acr
  337. move.d [$acr], $r0
  338. move $r0, $s12
  339. addq 4, $acr
  340. ;; Nothing in S13 - S15, bank 0
  341. addq 4, $acr
  342. addq 4, $acr
  343. addq 4, $acr
  344. ;; Bank 1 and bank 2 have the same layout, hence the loop.
  345. addq 1, $r1
  346. 2:
  347. move $r1, $srs
  348. nop
  349. nop
  350. nop
  351. move.d [$acr], $r0
  352. move $r0, $s0
  353. addq 4, $acr
  354. move.d [$acr], $r0
  355. move $r0, $s1
  356. addq 4, $acr
  357. move.d [$acr], $r0
  358. move $r0, $s2
  359. addq 4, $acr
  360. ;; S3 (MM_CAUSE) is read-only.
  361. addq 4, $acr
  362. move.d [$acr], $r0
  363. move $r0, $s4
  364. addq 4, $acr
  365. ;; FIXME: Actually write S5/S6? (Affects MM_CAUSE.)
  366. addq 4, $acr
  367. addq 4, $acr
  368. ;; Nothing in S7 - S15, bank 1 and 2
  369. addq 4, $acr
  370. addq 4, $acr
  371. addq 4, $acr
  372. addq 4, $acr
  373. addq 4, $acr
  374. addq 4, $acr
  375. addq 4, $acr
  376. addq 4, $acr
  377. addq 4, $acr
  378. addq 1, $r1
  379. cmpq 3, $r1
  380. bne 2b
  381. nop
  382. ;; Bank 3
  383. move $r1, $srs
  384. nop
  385. nop
  386. nop
  387. move.d [$acr], $r0
  388. move $r0, $s0
  389. addq 4, $acr
  390. move.d [$acr], $r0
  391. move $r0, $s1
  392. addq 4, $acr
  393. move.d [$acr], $r0
  394. move $r0, $s2
  395. addq 4, $acr
  396. move.d [$acr], $r0
  397. move $r0, $s3
  398. addq 4, $acr
  399. move.d [$acr], $r0
  400. move $r0, $s4
  401. addq 4, $acr
  402. move.d [$acr], $r0
  403. move $r0, $s5
  404. addq 4, $acr
  405. move.d [$acr], $r0
  406. move $r0, $s6
  407. addq 4, $acr
  408. move.d [$acr], $r0
  409. move $r0, $s7
  410. addq 4, $acr
  411. move.d [$acr], $r0
  412. move $r0, $s8
  413. addq 4, $acr
  414. move.d [$acr], $r0
  415. move $r0, $s9
  416. addq 4, $acr
  417. move.d [$acr], $r0
  418. move $r0, $s10
  419. addq 4, $acr
  420. move.d [$acr], $r0
  421. move $r0, $s11
  422. addq 4, $acr
  423. move.d [$acr], $r0
  424. move $r0, $s12
  425. addq 4, $acr
  426. move.d [$acr], $r0
  427. move $r0, $s13
  428. addq 4, $acr
  429. move.d [$acr], $r0
  430. move $r0, $s14
  431. addq 4, $acr
  432. ;; Nothing in S15, bank 3
  433. addq 4, $acr
  434. ;; Now, move on to the regular register restoration process.
  435. move.d reg, $acr ; Reset ACR to point at the beginning of the register image
  436. move.d [$acr], $r0 ; Restore R0
  437. addq 4, $acr
  438. move.d [$acr], $r1 ; Restore R1
  439. addq 4, $acr
  440. move.d [$acr], $r2 ; Restore R2
  441. addq 4, $acr
  442. move.d [$acr], $r3 ; Restore R3
  443. addq 4, $acr
  444. move.d [$acr], $r4 ; Restore R4
  445. addq 4, $acr
  446. move.d [$acr], $r5 ; Restore R5
  447. addq 4, $acr
  448. move.d [$acr], $r6 ; Restore R6
  449. addq 4, $acr
  450. move.d [$acr], $r7 ; Restore R7
  451. addq 4, $acr
  452. move.d [$acr], $r8 ; Restore R8
  453. addq 4, $acr
  454. move.d [$acr], $r9 ; Restore R9
  455. addq 4, $acr
  456. move.d [$acr], $r10 ; Restore R10
  457. addq 4, $acr
  458. move.d [$acr], $r11 ; Restore R11
  459. addq 4, $acr
  460. move.d [$acr], $r12 ; Restore R12
  461. addq 4, $acr
  462. move.d [$acr], $r13 ; Restore R13
  463. ;;
  464. ;; We restore all registers, even though some of them probably haven't changed.
  465. ;;
  466. addq 4, $acr
  467. move.d [$acr], $sp ; Restore SP (R14)
  468. ;; ACR cannot be restored just yet.
  469. addq 8, $acr
  470. ;; Skip BZ, VR.
  471. addq 2, $acr
  472. move [$acr], $pid ; Restore PID
  473. addq 4, $acr
  474. move [$acr], $srs ; Restore SRS
  475. nop
  476. nop
  477. nop
  478. addq 1, $acr
  479. ;; Skip WZ.
  480. addq 2, $acr
  481. move [$acr], $exs ; Restore EXS.
  482. addq 4, $acr
  483. move [$acr], $eda ; Restore EDA.
  484. addq 4, $acr
  485. move [$acr], $mof ; Restore MOF.
  486. ;; Skip DZ.
  487. addq 8, $acr
  488. move [$acr], $ebp ; Restore EBP.
  489. addq 4, $acr
  490. move [$acr], $erp ; Restore ERP.
  491. addq 4, $acr
  492. move [$acr], $srp ; Restore SRP.
  493. addq 4, $acr
  494. move [$acr], $nrp ; Restore NRP.
  495. addq 4, $acr
  496. move [$acr], $ccs ; Restore CCS like an ordinary register.
  497. addq 4, $acr
  498. move [$acr], $usp ; Restore USP
  499. addq 4, $acr
  500. move [$acr], $spc ; Restore SPC
  501. ; No restoration of pseudo-PC of course.
  502. move.d reg, $acr ; Reset ACR to point at the beginning of the register image
  503. add.d 15*4, $acr
  504. move.d [$acr], $acr ; Finally, restore ACR.
  505. rete ; Same as jump ERP
  506. rfe ; Shifts CCS