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