Remove FSF address from GPL notices
[fw/openocd] / src / target / xscale / debug_handler.S
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
20     .text
21     .align  4
22
23 @ Disable thumb mode
24     .code 32
25
26 @ send word to debugger
27 .macro m_send_to_debugger reg
28 1:
29         mrc p14, 0, r15, c14, c0, 0
30         bvs 1b
31         mcr p14, 0, \reg, c8, c0, 0
32 .endm
33
34 @ receive word from debugger
35 .macro m_receive_from_debugger reg
36 1:
37         mrc p14, 0, r15, c14, c0, 0
38         bpl 1b
39         mrc p14, 0, \reg, c9, c0, 0
40 .endm
41
42 @ save register on debugger, small
43 .macro m_small_save_reg reg
44         mov r0, \reg
45         bl send_to_debugger
46 .endm
47
48 @ save status register on debugger, small
49 .macro m_small_save_psr
50         mrs r0, spsr
51         bl send_to_debugger
52 .endm
53
54 @ wait for all outstanding coprocessor accesses to complete
55 .macro m_cpwait
56         mrc p15, 0, r0, c2, c0, 0
57         mov r0, r0
58         sub pc, pc, #4
59 .endm
60
61 .global reset_handler
62 .global undef_handler
63 .global swi_handler
64 .global prefetch_abort_handler
65 .global data_abort_handler
66 .global irq_handler
67 .global fiq_handler
68
69 .section .part1 , "ax"
70
71 reset_handler:
72         @ read DCSR
73         mrc p14, 0, r13, c10, c0
74         @ check if global enable bit (GE) is set
75         ands r13, r13, #0x80000000
76
77         bne debug_handler
78
79         @ set global enable bit (GE)
80         mov r13, #0xc0000000
81         mcr p14, 0, r13, c10, c0
82
83 debug_handler:
84
85         @ save r0 without modifying other registers
86         m_send_to_debugger r0
87
88         @ save lr (program PC) without branching (use macro)
89         m_send_to_debugger r14
90
91         @ save non-banked registers and spsr (program CPSR)
92         m_small_save_reg r1
93         m_small_save_reg r2
94         m_small_save_reg r3
95         m_small_save_reg r4
96         m_small_save_reg r5
97         m_small_save_reg r6
98         m_small_save_reg r7
99         m_small_save_psr
100
101         mrs r0, spsr
102
103         @ prepare program PSR for debug use (clear Thumb, set I/F to disable interrupts)
104         bic r0, r0, #PSR_T
105         orr r0, r0, #(PSR_I | PSR_F)
106
107         @ examine mode bits
108         and r1, r0, #MODE_MASK
109         cmp r1, #MODE_USR
110
111         bne not_user_mode
112
113         @ replace USR mode with SYS
114         bic r0, r0, #MODE_MASK
115         orr r0, r0, #MODE_SYS
116
117 not_user_mode:
118
119         b save_banked_registers
120
121 @ command loop
122 @ wait for command from debugger, than execute desired function
123 get_command:
124         bl receive_from_debugger
125
126         @ 0x0n - register access
127         cmp r0, #0x0
128         beq get_banked_registers
129
130         cmp r0, #0x1
131         beq set_banked_registers
132
133         @ 0x1n - read memory
134         cmp r0, #0x11
135         beq read_byte
136
137         cmp r0, #0x12
138         beq read_half_word
139
140         cmp r0, #0x14
141         beq read_word
142
143         @ 0x2n - write memory
144         cmp r0, #0x21
145         beq write_byte
146
147         cmp r0, #0x22
148         beq write_half_word
149
150         cmp r0, #0x24
151         beq write_word
152
153         @ 0x3n - program execution
154         cmp r0, #0x30
155         beq resume
156
157         cmp r0, #0x31
158         beq resume_w_trace
159
160         @ 0x4n - coprocessor access
161         cmp r0, #0x40
162         beq read_cp_reg
163
164         cmp r0, #0x41
165         beq write_cp_reg
166
167         @ 0x5n - cache and mmu functions
168         cmp r0, #0x50
169         beq clean_d_cache
170
171         cmp r0, #0x51
172         beq invalidate_d_cache
173
174         cmp r0, #0x52
175         beq invalidate_i_cache
176
177         cmp r0, #0x53
178         beq cpwait
179
180         @ 0x6n - misc functions
181         cmp r0, #0x60
182         beq clear_sa
183
184         cmp r0, #0x61
185         beq read_trace_buffer
186
187         cmp r0, #0x62
188         beq clean_trace_buffer
189
190         @ return (back to get_command)
191         b get_command
192
193 @ ----
194
195 @ resume program execution
196 resume:
197         @ restore CPSR (SPSR_dbg)
198         bl receive_from_debugger
199         msr spsr, r0
200
201         @ restore registers (r7 - r0)
202         bl receive_from_debugger @ r7
203         mov r7, r0
204         bl receive_from_debugger @ r6
205         mov r6, r0
206         bl receive_from_debugger @ r5
207         mov r5, r0
208         bl receive_from_debugger @ r4
209         mov r4, r0
210         bl receive_from_debugger @ r3
211         mov r3, r0
212         bl receive_from_debugger @ r2
213         mov r2, r0
214         bl receive_from_debugger @ r1
215         mov r1, r0
216         bl receive_from_debugger @ r0
217
218         @ resume addresss
219         m_receive_from_debugger lr
220
221         @ branch back to application code, restoring CPSR
222         subs pc, lr, #0
223
224 @ get banked registers
225 @ receive mode bits from host, then run into save_banked_registers to
226
227 get_banked_registers:
228         bl receive_from_debugger
229
230 @ save banked registers
231 @ r0[4:0]: desired mode bits
232 save_banked_registers:
233         @ backup CPSR
234         mrs r7, cpsr
235         msr cpsr_c, r0
236         nop
237
238         @ keep current mode bits in r1 for later use
239         and r1, r0, #MODE_MASK
240
241         @ backup banked registers
242         m_send_to_debugger r8
243         m_send_to_debugger r9
244         m_send_to_debugger r10
245         m_send_to_debugger r11
246         m_send_to_debugger r12
247         m_send_to_debugger r13
248         m_send_to_debugger r14
249
250         @ if not in SYS mode (or USR, which we replaced with SYS before)
251         cmp r1, #MODE_SYS
252
253         beq no_spsr_to_save
254
255         @ backup SPSR
256         mrs r0, spsr
257         m_send_to_debugger r0
258
259 no_spsr_to_save:
260
261         @ restore CPSR for SDS
262         msr cpsr_c, r7
263         nop
264
265         @ return
266         b get_command
267
268 @ ----
269
270
271 @ set banked registers
272 @ receive mode bits from host, then run into save_banked_registers to
273
274 set_banked_registers:
275         bl receive_from_debugger
276
277 @ restore banked registers
278 @ r0[4:0]: desired mode bits
279 restore_banked_registers:
280         @ backup CPSR
281         mrs r7, cpsr
282         msr cpsr_c, r0
283         nop
284
285         @ keep current mode bits in r1 for later use
286         and r1, r0, #MODE_MASK
287
288         @ set banked registers
289         m_receive_from_debugger r8
290         m_receive_from_debugger r9
291         m_receive_from_debugger r10
292         m_receive_from_debugger r11
293         m_receive_from_debugger r12
294         m_receive_from_debugger r13
295         m_receive_from_debugger r14
296
297         @ if not in SYS mode (or USR, which we replaced with SYS before)
298         cmp r1, #MODE_SYS
299
300         beq no_spsr_to_restore
301
302         @ set SPSR
303         m_receive_from_debugger r0
304         msr spsr, r0
305
306 no_spsr_to_restore:
307
308         @ restore CPSR for SDS
309         msr cpsr_c, r7
310         nop
311
312         @ return
313         b get_command
314
315 @ ----
316
317 read_byte:
318         @ r2: address
319         bl receive_from_debugger
320         mov r2, r0
321
322         @ r1: count
323         bl receive_from_debugger
324         mov r1, r0
325
326 rb_loop:
327         ldrb r0, [r2], #1
328
329         @ drain write- (and fill-) buffer to work around XScale errata
330         mcr p15, 0, r8, c7, c10, 4
331
332         bl send_to_debugger
333
334         subs r1, r1, #1
335         bne rb_loop
336
337         @ return
338         b get_command
339
340 @ ----
341
342 read_half_word:
343         @ r2: address
344         bl receive_from_debugger
345         mov r2, r0
346
347         @ r1: count
348         bl receive_from_debugger
349         mov r1, r0
350
351 rh_loop:
352         ldrh r0, [r2], #2
353
354         @ drain write- (and fill-) buffer to work around XScale errata
355         mcr p15, 0, r8, c7, c10, 4
356
357         bl send_to_debugger
358
359         subs r1, r1, #1
360         bne rh_loop
361
362         @ return
363         b get_command
364
365 @ ----
366
367 read_word:
368         @ r2: address
369         bl receive_from_debugger
370         mov r2, r0
371
372         @ r1: count
373         bl receive_from_debugger
374         mov r1, r0
375
376 rw_loop:
377         ldr r0, [r2], #4
378
379         @ drain write- (and fill-) buffer to work around XScale errata
380         mcr p15, 0, r8, c7, c10, 4
381
382         bl send_to_debugger
383
384         subs r1, r1, #1
385         bne rw_loop
386
387         @ return
388         b get_command
389
390 @ ----
391
392 write_byte:
393         @ r2: address
394         bl receive_from_debugger
395         mov r2, r0
396
397         @ r1: count
398         bl receive_from_debugger
399         mov r1, r0
400
401 wb_loop:
402         bl receive_from_debugger
403         strb r0, [r2], #1
404
405         @ drain write- (and fill-) buffer to work around XScale errata
406         mcr p15, 0, r8, c7, c10, 4
407
408         subs r1, r1, #1
409         bne wb_loop
410
411         @ return
412         b get_command
413
414 @ ----
415
416 write_half_word:
417         @ r2: address
418         bl receive_from_debugger
419         mov r2, r0
420
421         @ r1: count
422         bl receive_from_debugger
423         mov r1, r0
424
425 wh_loop:
426         bl receive_from_debugger
427         strh r0, [r2], #2
428
429         @ drain write- (and fill-) buffer to work around XScale errata
430         mcr p15, 0, r8, c7, c10, 4
431
432         subs r1, r1, #1
433         bne wh_loop
434
435         @ return
436         b get_command
437
438 @ ----
439
440 write_word:
441         @ r2: address
442         bl receive_from_debugger
443         mov r2, r0
444
445         @ r1: count
446         bl receive_from_debugger
447         mov r1, r0
448
449 ww_loop:
450         bl receive_from_debugger
451         str r0, [r2], #4
452
453         @ drain write- (and fill-) buffer to work around XScale errata
454         mcr p15, 0, r8, c7, c10, 4
455
456         subs r1, r1, #1
457         bne ww_loop
458
459         @ return
460         b get_command
461
462 @ ----
463
464 clear_sa:
465         @ read DCSR
466         mrc p14, 0, r0, c10, c0
467
468         @ clear SA bit
469         bic r0, r0, #0x20
470
471         @ write DCSR
472         mcr p14, 0, r0, c10, c0
473
474         @ return
475         b get_command
476
477 @ ----
478
479 clean_d_cache:
480         @ r0: cache clean area
481         bl receive_from_debugger
482
483         mov r1, #1024
484 clean_loop:
485         mcr p15, 0, r0, c7, c2, 5
486         add r0, r0, #32
487         subs r1, r1, #1
488         bne clean_loop
489
490         @ return
491         b get_command
492
493 @ ----
494
495 invalidate_d_cache:
496         mcr p15, 0, r0, c7, c6, 0
497
498         @ return
499         b get_command
500
501 @ ----
502
503 invalidate_i_cache:
504         mcr p15, 0, r0, c7, c5, 0
505
506         @ return
507         b get_command
508
509 @ ----
510
511 cpwait:
512         m_cpwait
513
514         @return
515         b get_command
516
517 @ ----
518
519 .section .part2 , "ax"
520
521 read_cp_reg:
522         @ requested cp register
523         bl receive_from_debugger
524
525         adr r1, read_cp_table
526         add pc, r1, r0, lsl #3
527
528 read_cp_table:
529         mrc p15, 0, r0, c0, c0, 0  @ XSCALE_MAINID
530         b read_cp_reg_reply
531         mrc p15, 0, r0, c0, c0, 1  @ XSCALE_CACHETYPE
532         b read_cp_reg_reply
533         mrc p15, 0, r0, c1, c0, 0  @ XSCALE_CTRL
534         b read_cp_reg_reply
535         mrc p15, 0, r0, c1, c0, 1  @ XSCALE_AUXCTRL
536         b read_cp_reg_reply
537         mrc p15, 0, r0, c2, c0, 0  @ XSCALE_TTB
538         b read_cp_reg_reply
539         mrc p15, 0, r0, c3, c0, 0  @ XSCALE_DAC
540         b read_cp_reg_reply
541         mrc p15, 0, r0, c5, c0, 0  @ XSCALE_FSR
542         b read_cp_reg_reply
543         mrc p15, 0, r0, c6, c0, 0  @ XSCALE_FAR
544         b read_cp_reg_reply
545         mrc p15, 0, r0, c13, c0, 0  @ XSCALE_PID
546         b read_cp_reg_reply
547         mrc p15, 0, r0, c15, c0, 0  @ XSCALE_CP_ACCESS
548         b read_cp_reg_reply
549         mrc p15, 0, r0, c14, c8, 0  @ XSCALE_IBCR0
550         b read_cp_reg_reply
551         mrc p15, 0, r0, c14, c9, 0  @ XSCALE_IBCR1
552         b read_cp_reg_reply
553         mrc p15, 0, r0, c14, c0, 0  @ XSCALE_DBR0
554         b read_cp_reg_reply
555         mrc p15, 0, r0, c14, c3, 0  @ XSCALE_DBR1
556         b read_cp_reg_reply
557         mrc p15, 0, r0, c14, c4, 0  @ XSCALE_DBCON
558         b read_cp_reg_reply
559         mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG
560         b read_cp_reg_reply
561         mrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0
562         b read_cp_reg_reply
563         mrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1
564         b read_cp_reg_reply
565         mrc p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR
566         b read_cp_reg_reply
567
568 read_cp_reg_reply:
569         bl send_to_debugger
570
571         @ return
572         b get_command
573
574 @ ----
575
576 write_cp_reg:
577         @ requested cp register
578         bl receive_from_debugger
579         mov r1, r0
580
581         @ value to be written
582         bl receive_from_debugger
583
584         adr r2, write_cp_table
585         add pc, r2, r1, lsl #3
586
587 write_cp_table:
588         mcr p15, 0, r0, c0, c0, 0  @ XSCALE_MAINID (0x0)
589         b get_command
590         mcr p15, 0, r0, c0, c0, 1  @ XSCALE_CACHETYPE (0x1)
591         b get_command
592         mcr p15, 0, r0, c1, c0, 0  @ XSCALE_CTRL (0x2)
593         b get_command
594         mcr p15, 0, r0, c1, c0, 1  @ XSCALE_AUXCTRL (0x3)
595         b get_command
596         mcr p15, 0, r0, c2, c0, 0  @ XSCALE_TTB (0x4)
597         b get_command
598         mcr p15, 0, r0, c3, c0, 0  @ XSCALE_DAC (0x5)
599         b get_command
600         mcr p15, 0, r0, c5, c0, 0  @ XSCALE_FSR (0x6)
601         b get_command
602         mcr p15, 0, r0, c6, c0, 0  @ XSCALE_FAR (0x7)
603         b get_command
604         mcr p15, 0, r0, c13, c0, 0  @ XSCALE_PID (0x8)
605         b get_command
606         mcr p15, 0, r0, c15, c0, 0  @ XSCALE_CP_ACCESS (0x9)
607         b get_command
608         mcr p15, 0, r0, c14, c8, 0  @ XSCALE_IBCR0 (0xa)
609         b get_command
610         mcr p15, 0, r0, c14, c9, 0  @ XSCALE_IBCR1 (0xb)
611         b get_command
612         mcr p15, 0, r0, c14, c0, 0  @ XSCALE_DBR0 (0xc)
613         b get_command
614         mcr p15, 0, r0, c14, c3, 0  @ XSCALE_DBR1 (0xd)
615         b get_command
616         mcr p15, 0, r0, c14, c4, 0  @ XSCALE_DBCON (0xe)
617         b get_command
618         mcr p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG (0xf)
619         b get_command
620         mcr p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10)
621         b get_command
622         mcr p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11)
623         b get_command
624         mcr p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR (0x12)
625         b get_command
626
627 @ ----
628
629 read_trace_buffer:
630
631         @ dump 256 entries from trace buffer
632         mov     r1, #256
633 read_tb_loop:
634         mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG
635         bl send_to_debugger
636         subs r1, r1, #1
637         bne read_tb_loop
638
639         @ dump checkpoint register 0
640         mrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10)
641         bl send_to_debugger
642
643         @ dump checkpoint register 1
644         mrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11)
645         bl send_to_debugger
646
647         @ return
648         b get_command
649
650 @ ----
651
652 clean_trace_buffer:
653
654         @ clean 256 entries from trace buffer
655         mov     r1, #256
656 clean_tb_loop:
657         mrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG
658         subs r1, r1, #1
659         bne clean_tb_loop
660
661         @ return
662         b get_command
663
664 @ ----
665
666
667 @ resume program execution with trace buffer enabled
668 resume_w_trace:
669         @ restore CPSR (SPSR_dbg)
670         bl receive_from_debugger
671         msr spsr, r0
672
673         @ restore registers (r7 - r0)
674         bl receive_from_debugger @ r7
675         mov r7, r0
676         bl receive_from_debugger @ r6
677         mov r6, r0
678         bl receive_from_debugger @ r5
679         mov r5, r0
680         bl receive_from_debugger @ r4
681         mov r4, r0
682         bl receive_from_debugger @ r3
683         mov r3, r0
684         bl receive_from_debugger @ r2
685         mov r2, r0
686         bl receive_from_debugger @ r1
687         mov r1, r0
688         bl receive_from_debugger @ r0
689
690         @ resume addresss
691         m_receive_from_debugger lr
692
693         mrc p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR
694         orr r13, r13, #1
695         mcr p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR
696
697         @ branch back to application code, restoring CPSR
698         subs pc, lr, #0
699
700 undef_handler:
701 swi_handler:
702 prefetch_abort_handler:
703 data_abort_handler:
704 irq_handler:
705 fiq_handler:
706 1:
707         b 1b
708
709 send_to_debugger:
710         m_send_to_debugger r0
711         mov pc, lr
712
713 receive_from_debugger:
714         m_receive_from_debugger r0
715         mov pc, lr
716