linux/arch/cris/arch-v32/kernel/kgdb_asm.S
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2004 Axis Communications AB
   3 *
   4 * Code for handling break 8, hardware breakpoint, single step, and serial
   5 * port exceptions for kernel debugging purposes.
   6 */
   7
   8#include <asm/arch/hwregs/intr_vect.h>
   9
  10        ;; Exported functions.
  11        .globl kgdb_handle_exception
  12
  13kgdb_handle_exception:
  14
  15;; Create a register image of the caller.
  16;;
  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.
  19
  20  subq     4, $sp
  21  move.d   $acr, [$sp]
  22
  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
  26;; register.
  27
  28  move.d   reg,  $acr
  29  move.d   $r0,  [$acr]        ; Save R0 (start of register struct)
  30  addq     4,    $acr
  31  move.d   $r1,  [$acr]        ; Save R1
  32  addq     4,    $acr
  33  move.d   $r2,  [$acr]        ; Save R2
  34  addq     4,    $acr
  35  move.d   $r3,  [$acr]        ; Save R3
  36  addq     4,    $acr
  37  move.d   $r4,  [$acr]        ; Save R4
  38  addq     4,    $acr
  39  move.d   $r5,  [$acr]        ; Save R5
  40  addq     4,    $acr
  41  move.d   $r6,  [$acr]        ; Save R6
  42  addq     4,    $acr
  43  move.d   $r7,  [$acr]        ; Save R7
  44  addq     4,    $acr
  45  move.d   $r8,  [$acr]        ; Save R8
  46  addq     4,    $acr
  47  move.d   $r9,  [$acr]        ; Save R9
  48  addq     4,    $acr
  49  move.d   $r10, [$acr]        ; Save R10
  50  addq     4,    $acr
  51  move.d   $r11, [$acr]        ; Save R11
  52  addq     4,    $acr
  53  move.d   $r12, [$acr]        ; Save R12
  54  addq     4,    $acr
  55  move.d   $r13, [$acr]        ; Save R13
  56  addq     4,    $acr
  57  move.d   $sp,  [$acr]        ; Save SP (R14)
  58  addq     4,    $acr
  59
  60  ;; The ACR register is already saved on the stack, so pop it from there.
  61  move.d   [$sp],$r0
  62  move.d   $r0,  [$acr]
  63  addq     4,    $acr
  64
  65  move     $bz,  [$acr]
  66  addq     1,    $acr
  67  move     $vr,  [$acr]
  68  addq     1,    $acr
  69  move     $pid, [$acr]
  70  addq     4,    $acr
  71  move     $srs, [$acr]
  72  addq     1,    $acr
  73  move     $wz,  [$acr]
  74  addq     2,    $acr
  75  move     $exs, [$acr]
  76  addq     4,    $acr
  77  move     $eda, [$acr]
  78  addq     4,    $acr
  79  move     $mof, [$acr]
  80  addq     4,    $acr
  81  move     $dz,  [$acr]
  82  addq     4,    $acr
  83  move     $ebp, [$acr]
  84  addq     4,    $acr
  85  move     $erp, [$acr]
  86  addq     4,    $acr
  87  move     $srp, [$acr]
  88  addq     4,    $acr
  89  move     $nrp, [$acr]
  90  addq     4,    $acr
  91  move     $ccs, [$acr]
  92  addq     4,    $acr
  93  move     $usp, [$acr]
  94  addq     4,    $acr
  95  move     $spc, [$acr]
  96  addq     4,     $acr
  97
  98;; Skip the pseudo-PC.
  99  addq     4,     $acr
 100
 101;; Save the support registers in bank 0 - 3.
 102  clear.d $r1 ; Bank counter
 103  move.d  sreg, $acr
 104
 105;; Bank 0
 106  move    $r1,  $srs
 107  nop
 108  nop
 109  nop
 110  move    $s0,   $r0
 111  move.d  $r0,   [$acr]
 112  addq    4,     $acr
 113  move    $s1,   $r0
 114  move.d  $r0,   [$acr]
 115  addq    4,     $acr
 116  move    $s2,   $r0
 117  move.d  $r0,   [$acr]
 118  addq    4,     $acr
 119  move    $s3,   $r0
 120  move.d  $r0,   [$acr]
 121  addq    4,     $acr
 122  move    $s4,   $r0
 123  move.d  $r0,   [$acr]
 124  addq    4,     $acr
 125  move    $s5,   $r0
 126  move.d  $r0,   [$acr]
 127  addq    4,     $acr
 128  move    $s6,   $r0
 129  move.d  $r0,   [$acr]
 130  addq    4,     $acr
 131  move    $s7,   $r0
 132  move.d  $r0,   [$acr]
 133  addq    4,     $acr
 134  move    $s8,   $r0
 135  move.d  $r0,   [$acr]
 136  addq    4,     $acr
 137  move    $s9,   $r0
 138  move.d  $r0,   [$acr]
 139  addq    4,     $acr
 140  move    $s10,  $r0
 141  move.d  $r0,   [$acr]
 142  addq    4,     $acr
 143  move    $s11,  $r0
 144  move.d  $r0,   [$acr]
 145  addq    4,     $acr
 146  move    $s12,  $r0
 147  move.d  $r0,   [$acr]
 148  addq    4,     $acr
 149
 150  ;; Nothing in S13 - S15, bank 0
 151  clear.d [$acr]
 152  addq    4,     $acr
 153  clear.d [$acr]
 154  addq    4,     $acr
 155  clear.d [$acr]
 156  addq    4,     $acr
 157
 158;; Bank 1 and bank 2 have the same layout, hence the loop.
 159  addq    1, $r1
 1601:
 161  move    $r1,  $srs
 162  nop
 163  nop
 164  nop
 165  move    $s0,   $r0
 166  move.d  $r0,   [$acr]
 167  addq    4,     $acr
 168  move    $s1,   $r0
 169  move.d  $r0,   [$acr]
 170  addq    4,     $acr
 171  move    $s2,   $r0
 172  move.d  $r0,   [$acr]
 173  addq    4,     $acr
 174  move    $s3,   $r0
 175  move.d  $r0,   [$acr]
 176  addq    4,     $acr
 177  move    $s4,   $r0
 178  move.d  $r0,   [$acr]
 179  addq    4,     $acr
 180  move    $s5,   $r0
 181  move.d  $r0,   [$acr]
 182  addq    4,     $acr
 183  move    $s6,   $r0
 184  move.d  $r0,   [$acr]
 185  addq    4,     $acr
 186
 187  ;; Nothing in S7 - S15, bank 1 and 2
 188  clear.d [$acr]
 189  addq    4,     $acr
 190  clear.d [$acr]
 191  addq    4,     $acr
 192  clear.d [$acr]
 193  addq    4,     $acr
 194  clear.d [$acr]
 195  addq    4,     $acr
 196  clear.d [$acr]
 197  addq    4,     $acr
 198  clear.d [$acr]
 199  addq    4,     $acr
 200  clear.d [$acr]
 201  addq    4,     $acr
 202  clear.d [$acr]
 203  addq    4,     $acr
 204  clear.d [$acr]
 205  addq    4,     $acr
 206
 207  addq 1, $r1
 208  cmpq 3, $r1
 209  bne 1b
 210  nop
 211
 212;; Bank 3
 213  move    $r1,  $srs
 214  nop
 215  nop
 216  nop
 217  move    $s0,   $r0
 218  move.d  $r0,   [$acr]
 219  addq    4,     $acr
 220  move    $s1,   $r0
 221  move.d  $r0,   [$acr]
 222  addq    4,     $acr
 223  move    $s2,   $r0
 224  move.d  $r0,   [$acr]
 225  addq    4,     $acr
 226  move    $s3,   $r0
 227  move.d  $r0,   [$acr]
 228  addq    4,     $acr
 229  move    $s4,   $r0
 230  move.d  $r0,   [$acr]
 231  addq    4,     $acr
 232  move    $s5,   $r0
 233  move.d  $r0,   [$acr]
 234  addq    4,     $acr
 235  move    $s6,   $r0
 236  move.d  $r0,   [$acr]
 237  addq    4,     $acr
 238  move    $s7,   $r0
 239  move.d  $r0,   [$acr]
 240  addq    4,     $acr
 241  move    $s8,   $r0
 242  move.d  $r0,   [$acr]
 243  addq    4,     $acr
 244  move    $s9,   $r0
 245  move.d  $r0,   [$acr]
 246  addq    4,     $acr
 247  move    $s10,  $r0
 248  move.d  $r0,   [$acr]
 249  addq    4,     $acr
 250  move    $s11,  $r0
 251  move.d  $r0,   [$acr]
 252  addq    4,     $acr
 253  move    $s12,  $r0
 254  move.d  $r0,   [$acr]
 255  addq    4,     $acr
 256  move    $s13,  $r0
 257  move.d  $r0,   [$acr]
 258  addq    4,     $acr
 259  move    $s14,  $r0
 260  move.d  $r0,   [$acr]
 261  addq    4,     $acr
 262;; Nothing in S15, bank 3
 263  clear.d [$acr]
 264  addq    4,     $acr
 265
 266;; Check what got us here: get IDX field of EXS.
 267  move $exs,    $r10
 268  and.d 0xff00, $r10
 269  lsrq 8,       $r10
 270#if defined(CONFIG_ETRAX_KGDB_PORT0)
 271  cmp.d SER0_INTR_VECT,   $r10 ; IRQ for serial port 0
 272  beq sigint
 273  nop
 274#elif defined(CONFIG_ETRAX_KGDB_PORT1)
 275  cmp.d SER1_INTR_VECT,   $r10 ; IRQ for serial port 1
 276  beq sigint
 277  nop
 278#elif defined(CONFIG_ETRAX_KGDB_PORT2)
 279  cmp.d SER2_INTR_VECT,   $r10 ; IRQ for serial port 2
 280  beq sigint
 281  nop
 282#elif defined(CONFIG_ETRAX_KGDB_PORT3)
 283  cmp.d SER3_INTR_VECT,   $r10 ; IRQ for serial port 3
 284  beq sigint
 285  nop
 286#endif
 287;; Multiple interrupt must be due to serial break.
 288  cmp.d 0x30,   $r10 ; Multiple interrupt
 289  beq sigint
 290  nop
 291;; Neither of those? Then it's a sigtrap.
 292  ba handle_comm
 293  moveq 5, $r10      ; Set SIGTRAP (delay slot)
 294
 295sigint:
 296  ;; Serial interrupt; get character
 297  jsr getDebugChar
 298  nop                ; Delay slot
 299  cmp.b 3, $r10      ; \003 (Ctrl-C)?
 300  bne return         ; No, get out of here
 301  nop
 302  moveq 2, $r10      ; Set SIGINT
 303
 304;;
 305;; Handle the communication
 306;;
 307handle_comm:
 308  move.d   internal_stack+1020, $sp ; Use the internal stack which grows upwards
 309  jsr      handle_exception         ; Interactive routine
 310  nop
 311
 312;;
 313;; Return to the caller
 314;;
 315return:
 316
 317;; First of all, write the support registers.
 318  clear.d $r1 ; Bank counter
 319  move.d  sreg, $acr
 320
 321;; Bank 0
 322  move    $r1,  $srs
 323  nop
 324  nop
 325  nop
 326  move.d  [$acr], $r0
 327  move    $r0,    $s0
 328  addq    4,      $acr
 329  move.d  [$acr], $r0
 330  move    $r0,    $s1
 331  addq    4,      $acr
 332  move.d  [$acr], $r0
 333  move    $r0,    $s2
 334  addq    4,      $acr
 335  move.d  [$acr], $r0
 336  move    $r0,    $s3
 337  addq    4,      $acr
 338  move.d  [$acr], $r0
 339  move    $r0,    $s4
 340  addq    4,      $acr
 341  move.d  [$acr], $r0
 342  move    $r0,    $s5
 343  addq    4,      $acr
 344
 345;; Nothing in S6 - S7, bank 0.
 346  addq    4,      $acr
 347  addq    4,      $acr
 348
 349  move.d  [$acr], $r0
 350  move    $r0,    $s8
 351  addq    4,      $acr
 352  move.d  [$acr], $r0
 353  move    $r0,    $s9
 354  addq    4,      $acr
 355  move.d  [$acr], $r0
 356  move    $r0,    $s10
 357  addq    4,      $acr
 358  move.d  [$acr], $r0
 359  move    $r0,    $s11
 360  addq    4,      $acr
 361  move.d  [$acr], $r0
 362  move    $r0,    $s12
 363  addq    4,      $acr
 364
 365;; Nothing in S13 - S15, bank 0
 366  addq    4,      $acr
 367  addq    4,      $acr
 368  addq    4,      $acr
 369
 370;; Bank 1 and bank 2 have the same layout, hence the loop.
 371  addq    1, $r1
 3722:
 373  move    $r1,  $srs
 374  nop
 375  nop
 376  nop
 377  move.d  [$acr], $r0
 378  move    $r0,    $s0
 379  addq    4,      $acr
 380  move.d  [$acr], $r0
 381  move    $r0,    $s1
 382  addq    4,      $acr
 383  move.d  [$acr], $r0
 384  move    $r0,    $s2
 385  addq    4,      $acr
 386
 387;; S3 (MM_CAUSE) is read-only.
 388  addq    4,      $acr
 389
 390  move.d  [$acr], $r0
 391  move    $r0,    $s4
 392  addq    4,      $acr
 393
 394;; FIXME: Actually write S5/S6? (Affects MM_CAUSE.)
 395  addq    4,      $acr
 396  addq    4,      $acr
 397
 398;; Nothing in S7 - S15, bank 1 and 2
 399  addq    4,      $acr
 400  addq    4,      $acr
 401  addq    4,      $acr
 402  addq    4,      $acr
 403  addq    4,      $acr
 404  addq    4,      $acr
 405  addq    4,      $acr
 406  addq    4,      $acr
 407  addq    4,      $acr
 408
 409  addq 1, $r1
 410  cmpq 3, $r1
 411  bne 2b
 412  nop
 413
 414;; Bank 3
 415  move    $r1,  $srs
 416  nop
 417  nop
 418  nop
 419  move.d  [$acr], $r0
 420  move    $r0,    $s0
 421  addq    4,      $acr
 422  move.d  [$acr], $r0
 423  move    $r0,    $s1
 424  addq    4,      $acr
 425  move.d  [$acr], $r0
 426  move    $r0,    $s2
 427  addq    4,      $acr
 428  move.d  [$acr], $r0
 429  move    $r0,    $s3
 430  addq    4,      $acr
 431  move.d  [$acr], $r0
 432  move    $r0,    $s4
 433  addq    4,      $acr
 434  move.d  [$acr], $r0
 435  move    $r0,    $s5
 436  addq    4,      $acr
 437  move.d  [$acr], $r0
 438  move    $r0,    $s6
 439  addq    4,      $acr
 440  move.d  [$acr], $r0
 441  move    $r0,    $s7
 442  addq    4,      $acr
 443  move.d  [$acr], $r0
 444  move    $r0,    $s8
 445  addq    4,      $acr
 446  move.d  [$acr], $r0
 447  move    $r0,    $s9
 448  addq    4,      $acr
 449  move.d  [$acr], $r0
 450  move    $r0,    $s10
 451  addq    4,      $acr
 452  move.d  [$acr], $r0
 453  move    $r0,    $s11
 454  addq    4,      $acr
 455  move.d  [$acr], $r0
 456  move    $r0,    $s12
 457  addq    4,      $acr
 458  move.d  [$acr], $r0
 459  move    $r0,    $s13
 460  addq    4,      $acr
 461  move.d  [$acr], $r0
 462  move    $r0,    $s14
 463  addq    4,      $acr
 464
 465;; Nothing in S15, bank 3
 466  addq    4,      $acr
 467
 468;; Now, move on to the regular register restoration process.
 469
 470   move.d  reg,    $acr   ; Reset ACR to point at the beginning of the register image
 471   move.d  [$acr], $r0    ; Restore R0
 472   addq    4,      $acr
 473   move.d  [$acr], $r1    ; Restore R1
 474   addq    4,      $acr
 475   move.d  [$acr], $r2    ; Restore R2
 476   addq    4,      $acr
 477   move.d  [$acr], $r3    ; Restore R3
 478   addq    4,      $acr
 479   move.d  [$acr], $r4    ; Restore R4
 480   addq    4,      $acr
 481   move.d  [$acr], $r5    ; Restore R5
 482   addq    4,      $acr
 483   move.d  [$acr], $r6    ; Restore R6
 484   addq    4,      $acr
 485   move.d  [$acr], $r7    ; Restore R7
 486   addq    4,      $acr
 487   move.d  [$acr], $r8    ; Restore R8
 488   addq    4,      $acr
 489   move.d  [$acr], $r9    ; Restore R9
 490   addq    4,      $acr
 491   move.d  [$acr], $r10   ; Restore R10
 492   addq    4,      $acr
 493   move.d  [$acr], $r11   ; Restore R11
 494   addq    4,      $acr
 495   move.d  [$acr], $r12   ; Restore R12
 496   addq    4,      $acr
 497   move.d  [$acr], $r13   ; Restore R13
 498
 499;;
 500;; We restore all registers, even though some of them probably haven't changed.
 501;;
 502
 503   addq    4,      $acr
 504   move.d  [$acr], $sp    ; Restore SP (R14)
 505
 506   ;; ACR cannot be restored just yet.
 507   addq    8,      $acr
 508
 509   ;; Skip BZ, VR.
 510   addq    2,      $acr
 511
 512   move    [$acr], $pid   ; Restore PID
 513   addq    4,      $acr
 514   move    [$acr], $srs   ; Restore SRS
 515   nop
 516   nop
 517   nop
 518   addq    1,      $acr
 519
 520   ;; Skip WZ.
 521   addq    2,      $acr
 522
 523   move    [$acr], $exs    ; Restore EXS.
 524   addq    4,      $acr
 525   move    [$acr], $eda    ; Restore EDA.
 526   addq    4,      $acr
 527   move    [$acr], $mof    ; Restore MOF.
 528
 529   ;; Skip DZ.
 530   addq    8,      $acr
 531
 532   move    [$acr], $ebp    ; Restore EBP.
 533   addq    4,      $acr
 534   move    [$acr], $erp    ; Restore ERP.
 535   addq    4,      $acr
 536   move    [$acr], $srp    ; Restore SRP.
 537   addq    4,      $acr
 538   move    [$acr], $nrp    ; Restore NRP.
 539   addq    4,      $acr
 540   move    [$acr], $ccs    ; Restore CCS like an ordinary register.
 541   addq    4,      $acr
 542   move    [$acr], $usp    ; Restore USP
 543   addq    4,      $acr
 544   move    [$acr], $spc    ; Restore SPC
 545                           ; No restoration of pseudo-PC of course.
 546
 547   move.d  reg,    $acr    ; Reset ACR to point at the beginning of the register image
 548   add.d   15*4,   $acr
 549   move.d  [$acr], $acr    ; Finally, restore ACR.
 550   rete                    ; Same as jump ERP
 551   rfe                     ; Shifts CCS
 552