uboot/arch/blackfin/lib/kgdb.c
<<
>>
Prefs
   1/*
   2 * U-boot - architecture specific kgdb code
   3 *
   4 * Copyright 2009 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <common.h>
  10#include <command.h>
  11
  12#include <kgdb.h>
  13#include <asm/processor.h>
  14#include <asm/mach-common/bits/core.h>
  15#include "kgdb.h"
  16#include <asm/deferred.h>
  17#include <asm/traps.h>
  18#include <asm/signal.h>
  19
  20void kgdb_enter(struct pt_regs *regs, kgdb_data *kdp)
  21{
  22        /* disable interrupts */
  23        disable_interrupts();
  24
  25        /* reply to host that an exception has occurred */
  26        kdp->sigval = kgdb_trap(regs);
  27
  28        /* send the PC and the Stack Pointer */
  29        kdp->nregs = 2;
  30        kdp->regs[0].num = BFIN_PC;
  31        kdp->regs[0].val = regs->pc;
  32
  33        kdp->regs[1].num = BFIN_SP;
  34        kdp->regs[1].val = (unsigned long)regs;
  35
  36}
  37
  38void kgdb_exit(struct pt_regs *regs, kgdb_data *kdp)
  39{
  40        if (kdp->extype & KGDBEXIT_WITHADDR)
  41                printf("KGDBEXIT_WITHADDR\n");
  42
  43        switch (kdp->extype & KGDBEXIT_TYPEMASK) {
  44        case KGDBEXIT_KILL:
  45                printf("KGDBEXIT_KILL:\n");
  46                break;
  47        case KGDBEXIT_CONTINUE:
  48                /* Make sure the supervisor single step bit is clear */
  49                regs->syscfg &= ~1;
  50                break;
  51        case KGDBEXIT_SINGLE:
  52                /* set the supervisor single step bit */
  53                regs->syscfg |= 1;
  54                break;
  55        default:
  56                printf("KGDBEXIT : %d\n", kdp->extype);
  57        }
  58
  59        /* enable interrupts */
  60        enable_interrupts();
  61}
  62
  63int kgdb_trap(struct pt_regs *regs)
  64{
  65        /* ipend doesn't get filled in properly */
  66        switch (regs->seqstat & EXCAUSE) {
  67        case VEC_EXCPT01:
  68                return SIGTRAP;
  69        case VEC_EXCPT03:
  70                return SIGSEGV;
  71        case VEC_EXCPT02:
  72                return SIGTRAP;
  73        case VEC_EXCPT04 ... VEC_EXCPT15:
  74                return SIGILL;
  75        case VEC_STEP:
  76                return SIGTRAP;
  77        case VEC_OVFLOW:
  78                return SIGTRAP;
  79        case VEC_UNDEF_I:
  80                return SIGILL;
  81        case VEC_ILGAL_I:
  82                return SIGILL;
  83        case VEC_CPLB_VL:
  84                return SIGSEGV;
  85        case VEC_MISALI_D:
  86                return SIGBUS;
  87        case VEC_UNCOV:
  88                return SIGILL;
  89        case VEC_CPLB_MHIT:
  90                return SIGSEGV;
  91        case VEC_MISALI_I:
  92                return SIGBUS;
  93        case VEC_CPLB_I_VL:
  94                return SIGBUS;
  95        case VEC_CPLB_I_MHIT:
  96                return SIGSEGV;
  97        default:
  98                return SIGBUS;
  99        }
 100}
 101
 102/*
 103 * getregs - gets the pt_regs, and gives them to kgdb's buffer
 104 */
 105int kgdb_getregs(struct pt_regs *regs, char *buf, int max)
 106{
 107        unsigned long *gdb_regs = (unsigned long *)buf;
 108
 109        if (max < NUMREGBYTES)
 110                kgdb_error(KGDBERR_NOSPACE);
 111
 112        if ((unsigned long)gdb_regs & 3)
 113                kgdb_error(KGDBERR_ALIGNFAULT);
 114
 115        gdb_regs[BFIN_R0] = regs->r0;
 116        gdb_regs[BFIN_R1] = regs->r1;
 117        gdb_regs[BFIN_R2] = regs->r2;
 118        gdb_regs[BFIN_R3] = regs->r3;
 119        gdb_regs[BFIN_R4] = regs->r4;
 120        gdb_regs[BFIN_R5] = regs->r5;
 121        gdb_regs[BFIN_R6] = regs->r6;
 122        gdb_regs[BFIN_R7] = regs->r7;
 123        gdb_regs[BFIN_P0] = regs->p0;
 124        gdb_regs[BFIN_P1] = regs->p1;
 125        gdb_regs[BFIN_P2] = regs->p2;
 126        gdb_regs[BFIN_P3] = regs->p3;
 127        gdb_regs[BFIN_P4] = regs->p4;
 128        gdb_regs[BFIN_P5] = regs->p5;
 129        gdb_regs[BFIN_SP] = (unsigned long)regs;
 130        gdb_regs[BFIN_FP] = regs->fp;
 131        gdb_regs[BFIN_I0] = regs->i0;
 132        gdb_regs[BFIN_I1] = regs->i1;
 133        gdb_regs[BFIN_I2] = regs->i2;
 134        gdb_regs[BFIN_I3] = regs->i3;
 135        gdb_regs[BFIN_M0] = regs->m0;
 136        gdb_regs[BFIN_M1] = regs->m1;
 137        gdb_regs[BFIN_M2] = regs->m2;
 138        gdb_regs[BFIN_M3] = regs->m3;
 139        gdb_regs[BFIN_B0] = regs->b0;
 140        gdb_regs[BFIN_B1] = regs->b1;
 141        gdb_regs[BFIN_B2] = regs->b2;
 142        gdb_regs[BFIN_B3] = regs->b3;
 143        gdb_regs[BFIN_L0] = regs->l0;
 144        gdb_regs[BFIN_L1] = regs->l1;
 145        gdb_regs[BFIN_L2] = regs->l2;
 146        gdb_regs[BFIN_L3] = regs->l3;
 147        gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
 148        gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
 149        gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
 150        gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
 151        gdb_regs[BFIN_ASTAT] = regs->astat;
 152        gdb_regs[BFIN_RETS] = regs->rets;
 153        gdb_regs[BFIN_LC0] = regs->lc0;
 154        gdb_regs[BFIN_LT0] = regs->lt0;
 155        gdb_regs[BFIN_LB0] = regs->lb0;
 156        gdb_regs[BFIN_LC1] = regs->lc1;
 157        gdb_regs[BFIN_LT1] = regs->lt1;
 158        gdb_regs[BFIN_LB1] = regs->lb1;
 159        gdb_regs[BFIN_CYCLES] = 0;
 160        gdb_regs[BFIN_CYCLES2] = 0;
 161        gdb_regs[BFIN_USP] = regs->usp;
 162        gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
 163        gdb_regs[BFIN_SYSCFG] = regs->syscfg;
 164        gdb_regs[BFIN_RETI] = regs->pc;
 165        gdb_regs[BFIN_RETX] = regs->retx;
 166        gdb_regs[BFIN_RETN] = regs->retn;
 167        gdb_regs[BFIN_RETE] = regs->rete;
 168        gdb_regs[BFIN_PC] = regs->pc;
 169        gdb_regs[BFIN_CC] = 0;
 170        gdb_regs[BFIN_EXTRA1] = 0;
 171        gdb_regs[BFIN_EXTRA2] = 0;
 172        gdb_regs[BFIN_EXTRA3] = 0;
 173        gdb_regs[BFIN_IPEND] = regs->ipend;
 174
 175        return NUMREGBYTES;
 176}
 177
 178/*
 179 * putreg - put kgdb's reg (regno) into the pt_regs
 180 */
 181void kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
 182{
 183        unsigned long *ptr = (unsigned long *)buf;
 184
 185        if (regno < 0 || regno > BFIN_NUM_REGS)
 186                kgdb_error(KGDBERR_BADPARAMS);
 187
 188        if (length < 4)
 189                kgdb_error(KGDBERR_NOSPACE);
 190
 191        if ((unsigned long)ptr & 3)
 192                kgdb_error(KGDBERR_ALIGNFAULT);
 193
 194        switch (regno) {
 195        case BFIN_R0:
 196                regs->r0 = *ptr;
 197                break;
 198        case BFIN_R1:
 199                regs->r1 = *ptr;
 200                break;
 201        case BFIN_R2:
 202                regs->r2 = *ptr;
 203                break;
 204        case BFIN_R3:
 205                regs->r3 = *ptr;
 206                break;
 207        case BFIN_R4:
 208                regs->r4 = *ptr;
 209                break;
 210        case BFIN_R5:
 211                regs->r5 = *ptr;
 212                break;
 213        case BFIN_R6:
 214                regs->r6 = *ptr;
 215                break;
 216        case BFIN_R7:
 217                regs->r7 = *ptr;
 218                break;
 219        case BFIN_P0:
 220                regs->p0 = *ptr;
 221                break;
 222        case BFIN_P1:
 223                regs->p1 = *ptr;
 224                break;
 225        case BFIN_P2:
 226                regs->p2 = *ptr;
 227                break;
 228        case BFIN_P3:
 229                regs->p3 = *ptr;
 230                break;
 231        case BFIN_P4:
 232                regs->p4 = *ptr;
 233                break;
 234        case BFIN_P5:
 235                regs->p5 = *ptr;
 236                break;
 237        case BFIN_SP:
 238                regs->reserved = *ptr;
 239                break;
 240        case BFIN_FP:
 241                regs->fp = *ptr;
 242                break;
 243        case BFIN_I0:
 244                regs->i0 = *ptr;
 245                break;
 246        case BFIN_I1:
 247                regs->i1 = *ptr;
 248                break;
 249        case BFIN_I2:
 250                regs->i2 = *ptr;
 251                break;
 252        case BFIN_I3:
 253                regs->i3 = *ptr;
 254                break;
 255        case BFIN_M0:
 256                regs->m0 = *ptr;
 257                break;
 258        case BFIN_M1:
 259                regs->m1 = *ptr;
 260                break;
 261        case BFIN_M2:
 262                regs->m2 = *ptr;
 263                break;
 264        case BFIN_M3:
 265                regs->m3 = *ptr;
 266                break;
 267        case BFIN_B0:
 268                regs->b0 = *ptr;
 269                break;
 270        case BFIN_B1:
 271                regs->b1 = *ptr;
 272                break;
 273        case BFIN_B2:
 274                regs->b2 = *ptr;
 275                break;
 276        case BFIN_B3:
 277                regs->b3 = *ptr;
 278                break;
 279        case BFIN_L0:
 280                regs->l0 = *ptr;
 281                break;
 282        case BFIN_L1:
 283                regs->l1 = *ptr;
 284                break;
 285        case BFIN_L2:
 286                regs->l2 = *ptr;
 287                break;
 288        case BFIN_L3:
 289                regs->l3 = *ptr;
 290                break;
 291        case BFIN_A0_DOT_X:
 292                regs->a0x = *ptr;
 293                break;
 294        case BFIN_A0_DOT_W:
 295                regs->a0w = *ptr;
 296                break;
 297        case BFIN_A1_DOT_X:
 298                regs->a1x = *ptr;
 299                break;
 300        case BFIN_A1_DOT_W:
 301                regs->a1w = *ptr;
 302                break;
 303        case BFIN_ASTAT:
 304                regs->astat = *ptr;
 305                break;
 306        case BFIN_RETS:
 307                regs->rets = *ptr;
 308                break;
 309        case BFIN_LC0:
 310                regs->lc0 = *ptr;
 311                break;
 312        case BFIN_LT0:
 313                regs->lt0 = *ptr;
 314                break;
 315        case BFIN_LB0:
 316                regs->lb0 = *ptr;
 317                break;
 318        case BFIN_LC1:
 319                regs->lc1 = *ptr;
 320                break;
 321        case BFIN_LT1:
 322                regs->lt1 = *ptr;
 323                break;
 324        case BFIN_LB1:
 325                regs->lb1 = *ptr;
 326                break;
 327/*
 328  BFIN_CYCLES,
 329  BFIN_CYCLES2,
 330  BFIN_USP,
 331  BFIN_SEQSTAT,
 332  BFIN_SYSCFG,
 333*/
 334        case BFIN_RETX:
 335                regs->retx = *ptr;
 336                break;
 337        case BFIN_RETN:
 338                regs->retn = *ptr;
 339                break;
 340        case BFIN_RETE:
 341                regs->rete = *ptr;
 342                break;
 343        case BFIN_PC:
 344                regs->pc = *ptr;
 345                break;
 346
 347        default:
 348                kgdb_error(KGDBERR_BADPARAMS);
 349        }
 350}
 351
 352void kgdb_putregs(struct pt_regs *regs, char *buf, int length)
 353{
 354        unsigned long *gdb_regs = (unsigned long *)buf;
 355
 356        if (length != BFIN_NUM_REGS)
 357                kgdb_error(KGDBERR_NOSPACE);
 358
 359        if ((unsigned long)gdb_regs & 3)
 360                kgdb_error(KGDBERR_ALIGNFAULT);
 361
 362        regs->r0 = gdb_regs[BFIN_R0];
 363        regs->r1 = gdb_regs[BFIN_R1];
 364        regs->r2 = gdb_regs[BFIN_R2];
 365        regs->r3 = gdb_regs[BFIN_R3];
 366        regs->r4 = gdb_regs[BFIN_R4];
 367        regs->r5 = gdb_regs[BFIN_R5];
 368        regs->r6 = gdb_regs[BFIN_R6];
 369        regs->r7 = gdb_regs[BFIN_R7];
 370        regs->p0 = gdb_regs[BFIN_P0];
 371        regs->p1 = gdb_regs[BFIN_P1];
 372        regs->p2 = gdb_regs[BFIN_P2];
 373        regs->p3 = gdb_regs[BFIN_P3];
 374        regs->p4 = gdb_regs[BFIN_P4];
 375        regs->p5 = gdb_regs[BFIN_P5];
 376        regs->fp = gdb_regs[BFIN_FP];
 377/*      regs->sp = gdb_regs[BFIN_ ]; */
 378        regs->i0 = gdb_regs[BFIN_I0];
 379        regs->i1 = gdb_regs[BFIN_I1];
 380        regs->i2 = gdb_regs[BFIN_I2];
 381        regs->i3 = gdb_regs[BFIN_I3];
 382        regs->m0 = gdb_regs[BFIN_M0];
 383        regs->m1 = gdb_regs[BFIN_M1];
 384        regs->m2 = gdb_regs[BFIN_M2];
 385        regs->m3 = gdb_regs[BFIN_M3];
 386        regs->b0 = gdb_regs[BFIN_B0];
 387        regs->b1 = gdb_regs[BFIN_B1];
 388        regs->b2 = gdb_regs[BFIN_B2];
 389        regs->b3 = gdb_regs[BFIN_B3];
 390        regs->l0 = gdb_regs[BFIN_L0];
 391        regs->l1 = gdb_regs[BFIN_L1];
 392        regs->l2 = gdb_regs[BFIN_L2];
 393        regs->l3 = gdb_regs[BFIN_L3];
 394        regs->a0x = gdb_regs[BFIN_A0_DOT_X];
 395        regs->a0w = gdb_regs[BFIN_A0_DOT_W];
 396        regs->a1x = gdb_regs[BFIN_A1_DOT_X];
 397        regs->a1w = gdb_regs[BFIN_A1_DOT_W];
 398        regs->rets = gdb_regs[BFIN_RETS];
 399        regs->lc0 = gdb_regs[BFIN_LC0];
 400        regs->lt0 = gdb_regs[BFIN_LT0];
 401        regs->lb0 = gdb_regs[BFIN_LB0];
 402        regs->lc1 = gdb_regs[BFIN_LC1];
 403        regs->lt1 = gdb_regs[BFIN_LT1];
 404        regs->lb1 = gdb_regs[BFIN_LB1];
 405        regs->usp = gdb_regs[BFIN_USP];
 406        regs->syscfg = gdb_regs[BFIN_SYSCFG];
 407        regs->retx = gdb_regs[BFIN_PC];
 408        regs->retn = gdb_regs[BFIN_RETN];
 409        regs->rete = gdb_regs[BFIN_RETE];
 410        regs->pc = gdb_regs[BFIN_PC];
 411
 412#if 0   /* can't change these */
 413        regs->astat = gdb_regs[BFIN_ASTAT];
 414        regs->seqstat = gdb_regs[BFIN_SEQSTAT];
 415        regs->ipend = gdb_regs[BFIN_IPEND];
 416#endif
 417
 418}
 419
 420void kgdb_breakpoint(int argc, char * const argv[])
 421{
 422        asm volatile ("excpt 0x1\n");
 423}
 424