kgdb_asm.S 12 KB

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