debug_handler.S 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /***************************************************************************
  2. * Copyright (C) 2006 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  17. ***************************************************************************/
  18. #include "protocol.h"
  19. .text
  20. .align 4
  21. @ Disable thumb mode
  22. .code 32
  23. @ send word to debugger
  24. .macro m_send_to_debugger reg
  25. 1:
  26. mrc p14, 0, r15, c14, c0, 0
  27. bvs 1b
  28. mcr p14, 0, \reg, c8, c0, 0
  29. .endm
  30. @ receive word from debugger
  31. .macro m_receive_from_debugger reg
  32. 1:
  33. mrc p14, 0, r15, c14, c0, 0
  34. bpl 1b
  35. mrc p14, 0, \reg, c9, c0, 0
  36. .endm
  37. @ save register on debugger, small
  38. .macro m_small_save_reg reg
  39. mov r0, \reg
  40. bl send_to_debugger
  41. .endm
  42. @ save status register on debugger, small
  43. .macro m_small_save_psr
  44. mrs r0, spsr
  45. bl send_to_debugger
  46. .endm
  47. @ wait for all outstanding coprocessor accesses to complete
  48. .macro m_cpwait
  49. mrc p15, 0, r0, c2, c0, 0
  50. mov r0, r0
  51. sub pc, pc, #4
  52. .endm
  53. .global reset_handler
  54. .global undef_handler
  55. .global swi_handler
  56. .global prefetch_abort_handler
  57. .global data_abort_handler
  58. .global irq_handler
  59. .global fiq_handler
  60. .section .part1 , "ax"
  61. reset_handler:
  62. @ read DCSR
  63. mrc p14, 0, r13, c10, c0
  64. @ check if global enable bit (GE) is set
  65. ands r13, r13, #0x80000000
  66. bne debug_handler
  67. @ set global enable bit (GE)
  68. mov r13, #0xc0000000
  69. mcr p14, 0, r13, c10, c0
  70. debug_handler:
  71. @ save r0 without modifying other registers
  72. m_send_to_debugger r0
  73. @ save lr (program PC) without branching (use macro)
  74. m_send_to_debugger r14
  75. @ save non-banked registers and spsr (program CPSR)
  76. m_small_save_reg r1
  77. m_small_save_reg r2
  78. m_small_save_reg r3
  79. m_small_save_reg r4
  80. m_small_save_reg r5
  81. m_small_save_reg r6
  82. m_small_save_reg r7
  83. m_small_save_psr
  84. mrs r0, spsr
  85. @ prepare program PSR for debug use (clear Thumb, set I/F to disable interrupts)
  86. bic r0, r0, #PSR_T
  87. orr r0, r0, #(PSR_I | PSR_F)
  88. @ examine mode bits
  89. and r1, r0, #MODE_MASK
  90. cmp r1, #MODE_USR
  91. bne not_user_mode
  92. @ replace USR mode with SYS
  93. bic r0, r0, #MODE_MASK
  94. orr r0, r0, #MODE_SYS
  95. not_user_mode:
  96. b save_banked_registers
  97. @ command loop
  98. @ wait for command from debugger, than execute desired function
  99. get_command:
  100. bl receive_from_debugger
  101. @ 0x0n - register access
  102. cmp r0, #0x0
  103. beq get_banked_registers
  104. cmp r0, #0x1
  105. beq set_banked_registers
  106. @ 0x1n - read memory
  107. cmp r0, #0x11
  108. beq read_byte
  109. cmp r0, #0x12
  110. beq read_half_word
  111. cmp r0, #0x14
  112. beq read_word
  113. @ 0x2n - write memory
  114. cmp r0, #0x21
  115. beq write_byte
  116. cmp r0, #0x22
  117. beq write_half_word
  118. cmp r0, #0x24
  119. beq write_word
  120. @ 0x3n - program execution
  121. cmp r0, #0x30
  122. beq resume
  123. cmp r0, #0x31
  124. beq resume_w_trace
  125. @ 0x4n - coprocessor access
  126. cmp r0, #0x40
  127. beq read_cp_reg
  128. cmp r0, #0x41
  129. beq write_cp_reg
  130. @ 0x5n - cache and mmu functions
  131. cmp r0, #0x50
  132. beq clean_d_cache
  133. cmp r0, #0x51
  134. beq invalidate_d_cache
  135. cmp r0, #0x52
  136. beq invalidate_i_cache
  137. cmp r0, #0x53
  138. beq cpwait
  139. @ 0x6n - misc functions
  140. cmp r0, #0x60
  141. beq clear_sa
  142. cmp r0, #0x61
  143. beq read_trace_buffer
  144. cmp r0, #0x62
  145. beq clean_trace_buffer
  146. @ return (back to get_command)
  147. b get_command
  148. @ ----
  149. @ resume program execution
  150. resume:
  151. @ restore CPSR (SPSR_dbg)
  152. bl receive_from_debugger
  153. msr spsr, r0
  154. @ restore registers (r7 - r0)
  155. bl receive_from_debugger @ r7
  156. mov r7, r0
  157. bl receive_from_debugger @ r6
  158. mov r6, r0
  159. bl receive_from_debugger @ r5
  160. mov r5, r0
  161. bl receive_from_debugger @ r4
  162. mov r4, r0
  163. bl receive_from_debugger @ r3
  164. mov r3, r0
  165. bl receive_from_debugger @ r2
  166. mov r2, r0
  167. bl receive_from_debugger @ r1
  168. mov r1, r0
  169. bl receive_from_debugger @ r0
  170. @ resume addresss
  171. m_receive_from_debugger lr
  172. @ branch back to application code, restoring CPSR
  173. subs pc, lr, #0
  174. @ get banked registers
  175. @ receive mode bits from host, then run into save_banked_registers to
  176. get_banked_registers:
  177. bl receive_from_debugger
  178. @ save banked registers
  179. @ r0[4:0]: desired mode bits
  180. save_banked_registers:
  181. @ backup CPSR
  182. mrs r7, cpsr
  183. msr cpsr_c, r0
  184. nop
  185. @ keep current mode bits in r1 for later use
  186. and r1, r0, #MODE_MASK
  187. @ backup banked registers
  188. m_send_to_debugger r8
  189. m_send_to_debugger r9
  190. m_send_to_debugger r10
  191. m_send_to_debugger r11
  192. m_send_to_debugger r12
  193. m_send_to_debugger r13
  194. m_send_to_debugger r14
  195. @ if not in SYS mode (or USR, which we replaced with SYS before)
  196. cmp r1, #MODE_SYS
  197. beq no_spsr_to_save
  198. @ backup SPSR
  199. mrs r0, spsr
  200. m_send_to_debugger r0
  201. no_spsr_to_save:
  202. @ restore CPSR for SDS
  203. msr cpsr_c, r7
  204. nop
  205. @ return
  206. b get_command
  207. @ ----
  208. @ set banked registers
  209. @ receive mode bits from host, then run into save_banked_registers to
  210. set_banked_registers:
  211. bl receive_from_debugger
  212. @ restore banked registers
  213. @ r0[4:0]: desired mode bits
  214. restore_banked_registers:
  215. @ backup CPSR
  216. mrs r7, cpsr
  217. msr cpsr_c, r0
  218. nop
  219. @ keep current mode bits in r1 for later use
  220. and r1, r0, #MODE_MASK
  221. @ set banked registers
  222. m_receive_from_debugger r8
  223. m_receive_from_debugger r9
  224. m_receive_from_debugger r10
  225. m_receive_from_debugger r11
  226. m_receive_from_debugger r12
  227. m_receive_from_debugger r13
  228. m_receive_from_debugger r14
  229. @ if not in SYS mode (or USR, which we replaced with SYS before)
  230. cmp r1, #MODE_SYS
  231. beq no_spsr_to_restore
  232. @ set SPSR
  233. m_receive_from_debugger r0
  234. msr spsr, r0
  235. no_spsr_to_restore:
  236. @ restore CPSR for SDS
  237. msr cpsr_c, r7
  238. nop
  239. @ return
  240. b get_command
  241. @ ----
  242. read_byte:
  243. @ r2: address
  244. bl receive_from_debugger
  245. mov r2, r0
  246. @ r1: count
  247. bl receive_from_debugger
  248. mov r1, r0
  249. rb_loop:
  250. ldrb r0, [r2], #1
  251. @ drain write- (and fill-) buffer to work around XScale errata
  252. mcr p15, 0, r8, c7, c10, 4
  253. bl send_to_debugger
  254. subs r1, r1, #1
  255. bne rb_loop
  256. @ return
  257. b get_command
  258. @ ----
  259. read_half_word:
  260. @ r2: address
  261. bl receive_from_debugger
  262. mov r2, r0
  263. @ r1: count
  264. bl receive_from_debugger
  265. mov r1, r0
  266. rh_loop:
  267. ldrh r0, [r2], #2
  268. @ drain write- (and fill-) buffer to work around XScale errata
  269. mcr p15, 0, r8, c7, c10, 4
  270. bl send_to_debugger
  271. subs r1, r1, #1
  272. bne rh_loop
  273. @ return
  274. b get_command
  275. @ ----
  276. read_word:
  277. @ r2: address
  278. bl receive_from_debugger
  279. mov r2, r0
  280. @ r1: count
  281. bl receive_from_debugger
  282. mov r1, r0
  283. rw_loop:
  284. ldr r0, [r2], #4
  285. @ drain write- (and fill-) buffer to work around XScale errata
  286. mcr p15, 0, r8, c7, c10, 4
  287. bl send_to_debugger
  288. subs r1, r1, #1
  289. bne rw_loop
  290. @ return
  291. b get_command
  292. @ ----
  293. write_byte:
  294. @ r2: address
  295. bl receive_from_debugger
  296. mov r2, r0
  297. @ r1: count
  298. bl receive_from_debugger
  299. mov r1, r0
  300. wb_loop:
  301. bl receive_from_debugger
  302. strb r0, [r2], #1
  303. @ drain write- (and fill-) buffer to work around XScale errata
  304. mcr p15, 0, r8, c7, c10, 4
  305. subs r1, r1, #1
  306. bne wb_loop
  307. @ return
  308. b get_command
  309. @ ----
  310. write_half_word:
  311. @ r2: address
  312. bl receive_from_debugger
  313. mov r2, r0
  314. @ r1: count
  315. bl receive_from_debugger
  316. mov r1, r0
  317. wh_loop:
  318. bl receive_from_debugger
  319. strh r0, [r2], #2
  320. @ drain write- (and fill-) buffer to work around XScale errata
  321. mcr p15, 0, r8, c7, c10, 4
  322. subs r1, r1, #1
  323. bne wh_loop
  324. @ return
  325. b get_command
  326. @ ----
  327. write_word:
  328. @ r2: address
  329. bl receive_from_debugger
  330. mov r2, r0
  331. @ r1: count
  332. bl receive_from_debugger
  333. mov r1, r0
  334. ww_loop:
  335. bl receive_from_debugger
  336. str r0, [r2], #4
  337. @ drain write- (and fill-) buffer to work around XScale errata
  338. mcr p15, 0, r8, c7, c10, 4
  339. subs r1, r1, #1
  340. bne ww_loop
  341. @ return
  342. b get_command
  343. @ ----
  344. clear_sa:
  345. @ read DCSR
  346. mrc p14, 0, r0, c10, c0
  347. @ clear SA bit
  348. bic r0, r0, #0x20
  349. @ write DCSR
  350. mcr p14, 0, r0, c10, c0
  351. @ return
  352. b get_command
  353. @ ----
  354. clean_d_cache:
  355. @ r0: cache clean area
  356. bl receive_from_debugger
  357. mov r1, #1024
  358. clean_loop:
  359. mcr p15, 0, r0, c7, c2, 5
  360. add r0, r0, #32
  361. subs r1, r1, #1
  362. bne clean_loop
  363. @ return
  364. b get_command
  365. @ ----
  366. invalidate_d_cache:
  367. mcr p15, 0, r0, c7, c6, 0
  368. @ return
  369. b get_command
  370. @ ----
  371. invalidate_i_cache:
  372. mcr p15, 0, r0, c7, c5, 0
  373. @ return
  374. b get_command
  375. @ ----
  376. cpwait:
  377. m_cpwait
  378. @return
  379. b get_command
  380. @ ----
  381. .section .part2 , "ax"
  382. read_cp_reg:
  383. @ requested cp register
  384. bl receive_from_debugger
  385. adr r1, read_cp_table
  386. add pc, r1, r0, lsl #3
  387. read_cp_table:
  388. mrc p15, 0, r0, c0, c0, 0 @ XSCALE_MAINID
  389. b read_cp_reg_reply
  390. mrc p15, 0, r0, c0, c0, 1 @ XSCALE_CACHETYPE
  391. b read_cp_reg_reply
  392. mrc p15, 0, r0, c1, c0, 0 @ XSCALE_CTRL
  393. b read_cp_reg_reply
  394. mrc p15, 0, r0, c1, c0, 1 @ XSCALE_AUXCTRL
  395. b read_cp_reg_reply
  396. mrc p15, 0, r0, c2, c0, 0 @ XSCALE_TTB
  397. b read_cp_reg_reply
  398. mrc p15, 0, r0, c3, c0, 0 @ XSCALE_DAC
  399. b read_cp_reg_reply
  400. mrc p15, 0, r0, c5, c0, 0 @ XSCALE_FSR
  401. b read_cp_reg_reply
  402. mrc p15, 0, r0, c6, c0, 0 @ XSCALE_FAR
  403. b read_cp_reg_reply
  404. mrc p15, 0, r0, c13, c0, 0 @ XSCALE_PID
  405. b read_cp_reg_reply
  406. mrc p15, 0, r0, c15, c0, 0 @ XSCALE_CP_ACCESS
  407. b read_cp_reg_reply
  408. mrc p15, 0, r0, c14, c8, 0 @ XSCALE_IBCR0
  409. b read_cp_reg_reply
  410. mrc p15, 0, r0, c14, c9, 0 @ XSCALE_IBCR1
  411. b read_cp_reg_reply
  412. mrc p15, 0, r0, c14, c0, 0 @ XSCALE_DBR0
  413. b read_cp_reg_reply
  414. mrc p15, 0, r0, c14, c3, 0 @ XSCALE_DBR1
  415. b read_cp_reg_reply
  416. mrc p15, 0, r0, c14, c4, 0 @ XSCALE_DBCON
  417. b read_cp_reg_reply
  418. mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG
  419. b read_cp_reg_reply
  420. mrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0
  421. b read_cp_reg_reply
  422. mrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1
  423. b read_cp_reg_reply
  424. mrc p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR
  425. b read_cp_reg_reply
  426. read_cp_reg_reply:
  427. bl send_to_debugger
  428. @ return
  429. b get_command
  430. @ ----
  431. write_cp_reg:
  432. @ requested cp register
  433. bl receive_from_debugger
  434. mov r1, r0
  435. @ value to be written
  436. bl receive_from_debugger
  437. adr r2, write_cp_table
  438. add pc, r2, r1, lsl #3
  439. write_cp_table:
  440. mcr p15, 0, r0, c0, c0, 0 @ XSCALE_MAINID (0x0)
  441. b get_command
  442. mcr p15, 0, r0, c0, c0, 1 @ XSCALE_CACHETYPE (0x1)
  443. b get_command
  444. mcr p15, 0, r0, c1, c0, 0 @ XSCALE_CTRL (0x2)
  445. b get_command
  446. mcr p15, 0, r0, c1, c0, 1 @ XSCALE_AUXCTRL (0x3)
  447. b get_command
  448. mcr p15, 0, r0, c2, c0, 0 @ XSCALE_TTB (0x4)
  449. b get_command
  450. mcr p15, 0, r0, c3, c0, 0 @ XSCALE_DAC (0x5)
  451. b get_command
  452. mcr p15, 0, r0, c5, c0, 0 @ XSCALE_FSR (0x6)
  453. b get_command
  454. mcr p15, 0, r0, c6, c0, 0 @ XSCALE_FAR (0x7)
  455. b get_command
  456. mcr p15, 0, r0, c13, c0, 0 @ XSCALE_PID (0x8)
  457. b get_command
  458. mcr p15, 0, r0, c15, c0, 0 @ XSCALE_CP_ACCESS (0x9)
  459. b get_command
  460. mcr p15, 0, r0, c14, c8, 0 @ XSCALE_IBCR0 (0xa)
  461. b get_command
  462. mcr p15, 0, r0, c14, c9, 0 @ XSCALE_IBCR1 (0xb)
  463. b get_command
  464. mcr p15, 0, r0, c14, c0, 0 @ XSCALE_DBR0 (0xc)
  465. b get_command
  466. mcr p15, 0, r0, c14, c3, 0 @ XSCALE_DBR1 (0xd)
  467. b get_command
  468. mcr p15, 0, r0, c14, c4, 0 @ XSCALE_DBCON (0xe)
  469. b get_command
  470. mcr p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG (0xf)
  471. b get_command
  472. mcr p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10)
  473. b get_command
  474. mcr p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11)
  475. b get_command
  476. mcr p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR (0x12)
  477. b get_command
  478. @ ----
  479. read_trace_buffer:
  480. @ dump 256 entries from trace buffer
  481. mov r1, #256
  482. read_tb_loop:
  483. mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG
  484. bl send_to_debugger
  485. subs r1, r1, #1
  486. bne read_tb_loop
  487. @ dump checkpoint register 0
  488. mrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10)
  489. bl send_to_debugger
  490. @ dump checkpoint register 1
  491. mrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11)
  492. bl send_to_debugger
  493. @ return
  494. b get_command
  495. @ ----
  496. clean_trace_buffer:
  497. @ clean 256 entries from trace buffer
  498. mov r1, #256
  499. clean_tb_loop:
  500. mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG
  501. subs r1, r1, #1
  502. bne clean_tb_loop
  503. @ return
  504. b get_command
  505. @ ----
  506. @ resume program execution with trace buffer enabled
  507. resume_w_trace:
  508. @ restore CPSR (SPSR_dbg)
  509. bl receive_from_debugger
  510. msr spsr, r0
  511. @ restore registers (r7 - r0)
  512. bl receive_from_debugger @ r7
  513. mov r7, r0
  514. bl receive_from_debugger @ r6
  515. mov r6, r0
  516. bl receive_from_debugger @ r5
  517. mov r5, r0
  518. bl receive_from_debugger @ r4
  519. mov r4, r0
  520. bl receive_from_debugger @ r3
  521. mov r3, r0
  522. bl receive_from_debugger @ r2
  523. mov r2, r0
  524. bl receive_from_debugger @ r1
  525. mov r1, r0
  526. bl receive_from_debugger @ r0
  527. @ resume addresss
  528. m_receive_from_debugger lr
  529. mrc p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR
  530. orr r13, r13, #1
  531. mcr p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR
  532. @ branch back to application code, restoring CPSR
  533. subs pc, lr, #0
  534. undef_handler:
  535. swi_handler:
  536. prefetch_abort_handler:
  537. data_abort_handler:
  538. irq_handler:
  539. fiq_handler:
  540. 1:
  541. b 1b
  542. send_to_debugger:
  543. m_send_to_debugger r0
  544. mov pc, lr
  545. receive_from_debugger:
  546. m_receive_from_debugger r0
  547. mov pc, lr