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