2
* Copyright (C) 2004 Axis Communications AB
4
* Code for handling break 8, hardware breakpoint, single step, and serial
5
* port exceptions for kernel debugging purposes.
8
#include <hwregs/intr_vect.h>
10
;; Exported functions.
11
.globl kgdb_handle_exception
13
kgdb_handle_exception:
15
;; Create a register image of the caller.
17
;; First of all, save the ACR on the stack since we need it for address calculations.
18
;; We put it into the register struct later.
23
;; Now we are free to use ACR all we want.
24
;; If we were running this handler with interrupts on, we would have to be careful
25
;; to save and restore CCS manually, but since we aren't we treat it like every other
29
move.d $r0, [$acr] ; Save R0 (start of register struct)
31
move.d $r1, [$acr] ; Save R1
33
move.d $r2, [$acr] ; Save R2
35
move.d $r3, [$acr] ; Save R3
37
move.d $r4, [$acr] ; Save R4
39
move.d $r5, [$acr] ; Save R5
41
move.d $r6, [$acr] ; Save R6
43
move.d $r7, [$acr] ; Save R7
45
move.d $r8, [$acr] ; Save R8
47
move.d $r9, [$acr] ; Save R9
49
move.d $r10, [$acr] ; Save R10
51
move.d $r11, [$acr] ; Save R11
53
move.d $r12, [$acr] ; Save R12
55
move.d $r13, [$acr] ; Save R13
57
move.d $sp, [$acr] ; Save SP (R14)
60
;; The ACR register is already saved on the stack, so pop it from there.
98
;; Skip the pseudo-PC.
101
;; Save the support registers in bank 0 - 3.
102
clear.d $r1 ; Bank counter
150
;; Nothing in S13 - S15, bank 0
158
;; Bank 1 and bank 2 have the same layout, hence the loop.
187
;; Nothing in S7 - S15, bank 1 and 2
262
;; Nothing in S15, bank 3
266
;; Check what got us here: get IDX field of EXS.
270
#if defined(CONFIG_ETRAX_KGDB_PORT0)
271
cmp.d SER0_INTR_VECT, $r10 ; IRQ for serial port 0
274
#elif defined(CONFIG_ETRAX_KGDB_PORT1)
275
cmp.d SER1_INTR_VECT, $r10 ; IRQ for serial port 1
278
#elif defined(CONFIG_ETRAX_KGDB_PORT2)
279
cmp.d SER2_INTR_VECT, $r10 ; IRQ for serial port 2
282
#elif defined(CONFIG_ETRAX_KGDB_PORT3)
283
cmp.d SER3_INTR_VECT, $r10 ; IRQ for serial port 3
287
;; Multiple interrupt must be due to serial break.
288
cmp.d 0x30, $r10 ; Multiple interrupt
291
;; Neither of those? Then it's a sigtrap.
293
moveq 5, $r10 ; Set SIGTRAP (delay slot)
296
;; Serial interrupt; get character
299
cmp.b 3, $r10 ; \003 (Ctrl-C)?
300
bne return ; No, get out of here
302
moveq 2, $r10 ; Set SIGINT
305
;; Handle the communication
308
move.d internal_stack+1020, $sp ; Use the internal stack which grows upwards
309
jsr handle_exception ; Interactive routine
313
;; Return to the caller
317
;; First of all, write the support registers.
318
clear.d $r1 ; Bank counter
345
;; Nothing in S6 - S7, bank 0.
365
;; Nothing in S13 - S15, bank 0
370
;; Bank 1 and bank 2 have the same layout, hence the loop.
387
;; S3 (MM_CAUSE) is read-only.
394
;; FIXME: Actually write S5/S6? (Affects MM_CAUSE.)
398
;; Nothing in S7 - S15, bank 1 and 2
465
;; Nothing in S15, bank 3
468
;; Now, move on to the regular register restoration process.
470
move.d reg, $acr ; Reset ACR to point at the beginning of the register image
471
move.d [$acr], $r0 ; Restore R0
473
move.d [$acr], $r1 ; Restore R1
475
move.d [$acr], $r2 ; Restore R2
477
move.d [$acr], $r3 ; Restore R3
479
move.d [$acr], $r4 ; Restore R4
481
move.d [$acr], $r5 ; Restore R5
483
move.d [$acr], $r6 ; Restore R6
485
move.d [$acr], $r7 ; Restore R7
487
move.d [$acr], $r8 ; Restore R8
489
move.d [$acr], $r9 ; Restore R9
491
move.d [$acr], $r10 ; Restore R10
493
move.d [$acr], $r11 ; Restore R11
495
move.d [$acr], $r12 ; Restore R12
497
move.d [$acr], $r13 ; Restore R13
500
;; We restore all registers, even though some of them probably haven't changed.
504
move.d [$acr], $sp ; Restore SP (R14)
506
;; ACR cannot be restored just yet.
512
move [$acr], $pid ; Restore PID
514
move [$acr], $srs ; Restore SRS
523
move [$acr], $exs ; Restore EXS.
525
move [$acr], $eda ; Restore EDA.
527
move [$acr], $mof ; Restore MOF.
532
move [$acr], $ebp ; Restore EBP.
534
move [$acr], $erp ; Restore ERP.
536
move [$acr], $srp ; Restore SRP.
538
move [$acr], $nrp ; Restore NRP.
540
move [$acr], $ccs ; Restore CCS like an ordinary register.
542
move [$acr], $usp ; Restore USP
544
move [$acr], $spc ; Restore SPC
545
; No restoration of pseudo-PC of course.
547
move.d reg, $acr ; Reset ACR to point at the beginning of the register image
549
move.d [$acr], $acr ; Finally, restore ACR.
550
rete ; Same as jump ERP