linux/arch/blackfin/kernel/kgdb.c
<<
>>
Prefs
   1/*
   2 * arch/blackfin/kernel/kgdb.c - Blackfin kgdb pieces
   3 *
   4 * Copyright 2005-2008 Analog Devices Inc.
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <linux/string.h>
  10#include <linux/kernel.h>
  11#include <linux/sched.h>
  12#include <linux/smp.h>
  13#include <linux/spinlock.h>
  14#include <linux/delay.h>
  15#include <linux/ptrace.h>               /* for linux pt_regs struct */
  16#include <linux/kgdb.h>
  17#include <linux/console.h>
  18#include <linux/init.h>
  19#include <linux/errno.h>
  20#include <linux/irq.h>
  21#include <linux/uaccess.h>
  22#include <asm/system.h>
  23#include <asm/traps.h>
  24#include <asm/blackfin.h>
  25#include <asm/dma.h>
  26
  27/* Put the error code here just in case the user cares.  */
  28int gdb_bfin_errcode;
  29/* Likewise, the vector number here (since GDB only gets the signal
  30   number through the usual means, and that's not very specific).  */
  31int gdb_bfin_vector = -1;
  32
  33#if KGDB_MAX_NO_CPUS != 8
  34#error change the definition of slavecpulocks
  35#endif
  36
  37void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
  38{
  39        gdb_regs[BFIN_R0] = regs->r0;
  40        gdb_regs[BFIN_R1] = regs->r1;
  41        gdb_regs[BFIN_R2] = regs->r2;
  42        gdb_regs[BFIN_R3] = regs->r3;
  43        gdb_regs[BFIN_R4] = regs->r4;
  44        gdb_regs[BFIN_R5] = regs->r5;
  45        gdb_regs[BFIN_R6] = regs->r6;
  46        gdb_regs[BFIN_R7] = regs->r7;
  47        gdb_regs[BFIN_P0] = regs->p0;
  48        gdb_regs[BFIN_P1] = regs->p1;
  49        gdb_regs[BFIN_P2] = regs->p2;
  50        gdb_regs[BFIN_P3] = regs->p3;
  51        gdb_regs[BFIN_P4] = regs->p4;
  52        gdb_regs[BFIN_P5] = regs->p5;
  53        gdb_regs[BFIN_SP] = regs->reserved;
  54        gdb_regs[BFIN_FP] = regs->fp;
  55        gdb_regs[BFIN_I0] = regs->i0;
  56        gdb_regs[BFIN_I1] = regs->i1;
  57        gdb_regs[BFIN_I2] = regs->i2;
  58        gdb_regs[BFIN_I3] = regs->i3;
  59        gdb_regs[BFIN_M0] = regs->m0;
  60        gdb_regs[BFIN_M1] = regs->m1;
  61        gdb_regs[BFIN_M2] = regs->m2;
  62        gdb_regs[BFIN_M3] = regs->m3;
  63        gdb_regs[BFIN_B0] = regs->b0;
  64        gdb_regs[BFIN_B1] = regs->b1;
  65        gdb_regs[BFIN_B2] = regs->b2;
  66        gdb_regs[BFIN_B3] = regs->b3;
  67        gdb_regs[BFIN_L0] = regs->l0;
  68        gdb_regs[BFIN_L1] = regs->l1;
  69        gdb_regs[BFIN_L2] = regs->l2;
  70        gdb_regs[BFIN_L3] = regs->l3;
  71        gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
  72        gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
  73        gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
  74        gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
  75        gdb_regs[BFIN_ASTAT] = regs->astat;
  76        gdb_regs[BFIN_RETS] = regs->rets;
  77        gdb_regs[BFIN_LC0] = regs->lc0;
  78        gdb_regs[BFIN_LT0] = regs->lt0;
  79        gdb_regs[BFIN_LB0] = regs->lb0;
  80        gdb_regs[BFIN_LC1] = regs->lc1;
  81        gdb_regs[BFIN_LT1] = regs->lt1;
  82        gdb_regs[BFIN_LB1] = regs->lb1;
  83        gdb_regs[BFIN_CYCLES] = 0;
  84        gdb_regs[BFIN_CYCLES2] = 0;
  85        gdb_regs[BFIN_USP] = regs->usp;
  86        gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
  87        gdb_regs[BFIN_SYSCFG] = regs->syscfg;
  88        gdb_regs[BFIN_RETI] = regs->pc;
  89        gdb_regs[BFIN_RETX] = regs->retx;
  90        gdb_regs[BFIN_RETN] = regs->retn;
  91        gdb_regs[BFIN_RETE] = regs->rete;
  92        gdb_regs[BFIN_PC] = regs->pc;
  93        gdb_regs[BFIN_CC] = 0;
  94        gdb_regs[BFIN_EXTRA1] = 0;
  95        gdb_regs[BFIN_EXTRA2] = 0;
  96        gdb_regs[BFIN_EXTRA3] = 0;
  97        gdb_regs[BFIN_IPEND] = regs->ipend;
  98}
  99
 100/*
 101 * Extracts ebp, esp and eip values understandable by gdb from the values
 102 * saved by switch_to.
 103 * thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp
 104 * prior to entering switch_to is 8 greater than the value that is saved.
 105 * If switch_to changes, change following code appropriately.
 106 */
 107void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 108{
 109        gdb_regs[BFIN_SP] = p->thread.ksp;
 110        gdb_regs[BFIN_PC] = p->thread.pc;
 111        gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat;
 112}
 113
 114void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 115{
 116        regs->r0 = gdb_regs[BFIN_R0];
 117        regs->r1 = gdb_regs[BFIN_R1];
 118        regs->r2 = gdb_regs[BFIN_R2];
 119        regs->r3 = gdb_regs[BFIN_R3];
 120        regs->r4 = gdb_regs[BFIN_R4];
 121        regs->r5 = gdb_regs[BFIN_R5];
 122        regs->r6 = gdb_regs[BFIN_R6];
 123        regs->r7 = gdb_regs[BFIN_R7];
 124        regs->p0 = gdb_regs[BFIN_P0];
 125        regs->p1 = gdb_regs[BFIN_P1];
 126        regs->p2 = gdb_regs[BFIN_P2];
 127        regs->p3 = gdb_regs[BFIN_P3];
 128        regs->p4 = gdb_regs[BFIN_P4];
 129        regs->p5 = gdb_regs[BFIN_P5];
 130        regs->fp = gdb_regs[BFIN_FP];
 131        regs->i0 = gdb_regs[BFIN_I0];
 132        regs->i1 = gdb_regs[BFIN_I1];
 133        regs->i2 = gdb_regs[BFIN_I2];
 134        regs->i3 = gdb_regs[BFIN_I3];
 135        regs->m0 = gdb_regs[BFIN_M0];
 136        regs->m1 = gdb_regs[BFIN_M1];
 137        regs->m2 = gdb_regs[BFIN_M2];
 138        regs->m3 = gdb_regs[BFIN_M3];
 139        regs->b0 = gdb_regs[BFIN_B0];
 140        regs->b1 = gdb_regs[BFIN_B1];
 141        regs->b2 = gdb_regs[BFIN_B2];
 142        regs->b3 = gdb_regs[BFIN_B3];
 143        regs->l0 = gdb_regs[BFIN_L0];
 144        regs->l1 = gdb_regs[BFIN_L1];
 145        regs->l2 = gdb_regs[BFIN_L2];
 146        regs->l3 = gdb_regs[BFIN_L3];
 147        regs->a0x = gdb_regs[BFIN_A0_DOT_X];
 148        regs->a0w = gdb_regs[BFIN_A0_DOT_W];
 149        regs->a1x = gdb_regs[BFIN_A1_DOT_X];
 150        regs->a1w = gdb_regs[BFIN_A1_DOT_W];
 151        regs->rets = gdb_regs[BFIN_RETS];
 152        regs->lc0 = gdb_regs[BFIN_LC0];
 153        regs->lt0 = gdb_regs[BFIN_LT0];
 154        regs->lb0 = gdb_regs[BFIN_LB0];
 155        regs->lc1 = gdb_regs[BFIN_LC1];
 156        regs->lt1 = gdb_regs[BFIN_LT1];
 157        regs->lb1 = gdb_regs[BFIN_LB1];
 158        regs->usp = gdb_regs[BFIN_USP];
 159        regs->syscfg = gdb_regs[BFIN_SYSCFG];
 160        regs->retx = gdb_regs[BFIN_PC];
 161        regs->retn = gdb_regs[BFIN_RETN];
 162        regs->rete = gdb_regs[BFIN_RETE];
 163        regs->pc = gdb_regs[BFIN_PC];
 164
 165#if 0                           /* can't change these */
 166        regs->astat = gdb_regs[BFIN_ASTAT];
 167        regs->seqstat = gdb_regs[BFIN_SEQSTAT];
 168        regs->ipend = gdb_regs[BFIN_IPEND];
 169#endif
 170}
 171
 172struct hw_breakpoint {
 173        unsigned int occupied:1;
 174        unsigned int skip:1;
 175        unsigned int enabled:1;
 176        unsigned int type:1;
 177        unsigned int dataacc:2;
 178        unsigned short count;
 179        unsigned int addr;
 180} breakinfo[HW_WATCHPOINT_NUM];
 181
 182int bfin_set_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 183{
 184        int breakno;
 185        int bfin_type;
 186        int dataacc = 0;
 187
 188        switch (type) {
 189        case BP_HARDWARE_BREAKPOINT:
 190                bfin_type = TYPE_INST_WATCHPOINT;
 191                break;
 192        case BP_WRITE_WATCHPOINT:
 193                dataacc = 1;
 194                bfin_type = TYPE_DATA_WATCHPOINT;
 195                break;
 196        case BP_READ_WATCHPOINT:
 197                dataacc = 2;
 198                bfin_type = TYPE_DATA_WATCHPOINT;
 199                break;
 200        case BP_ACCESS_WATCHPOINT:
 201                dataacc = 3;
 202                bfin_type = TYPE_DATA_WATCHPOINT;
 203                break;
 204        default:
 205                return -ENOSPC;
 206        }
 207
 208        /* Becasue hardware data watchpoint impelemented in current
 209         * Blackfin can not trigger an exception event as the hardware
 210         * instrction watchpoint does, we ignaore all data watch point here.
 211         * They can be turned on easily after future blackfin design
 212         * supports this feature.
 213         */
 214        for (breakno = 0; breakno < HW_INST_WATCHPOINT_NUM; breakno++)
 215                if (bfin_type == breakinfo[breakno].type
 216                        && !breakinfo[breakno].occupied) {
 217                        breakinfo[breakno].occupied = 1;
 218                        breakinfo[breakno].skip = 0;
 219                        breakinfo[breakno].enabled = 1;
 220                        breakinfo[breakno].addr = addr;
 221                        breakinfo[breakno].dataacc = dataacc;
 222                        breakinfo[breakno].count = 0;
 223                        return 0;
 224                }
 225
 226        return -ENOSPC;
 227}
 228
 229int bfin_remove_hw_break(unsigned long addr, int len, enum kgdb_bptype type)
 230{
 231        int breakno;
 232        int bfin_type;
 233
 234        switch (type) {
 235        case BP_HARDWARE_BREAKPOINT:
 236                bfin_type = TYPE_INST_WATCHPOINT;
 237                break;
 238        case BP_WRITE_WATCHPOINT:
 239        case BP_READ_WATCHPOINT:
 240        case BP_ACCESS_WATCHPOINT:
 241                bfin_type = TYPE_DATA_WATCHPOINT;
 242                break;
 243        default:
 244                return 0;
 245        }
 246        for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++)
 247                if (bfin_type == breakinfo[breakno].type
 248                        && breakinfo[breakno].occupied
 249                        && breakinfo[breakno].addr == addr) {
 250                        breakinfo[breakno].occupied = 0;
 251                        breakinfo[breakno].enabled = 0;
 252                }
 253
 254        return 0;
 255}
 256
 257void bfin_remove_all_hw_break(void)
 258{
 259        int breakno;
 260
 261        memset(breakinfo, 0, sizeof(struct hw_breakpoint)*HW_WATCHPOINT_NUM);
 262
 263        for (breakno = 0; breakno < HW_INST_WATCHPOINT_NUM; breakno++)
 264                breakinfo[breakno].type = TYPE_INST_WATCHPOINT;
 265        for (; breakno < HW_WATCHPOINT_NUM; breakno++)
 266                breakinfo[breakno].type = TYPE_DATA_WATCHPOINT;
 267}
 268
 269void bfin_correct_hw_break(void)
 270{
 271        int breakno;
 272        unsigned int wpiactl = 0;
 273        unsigned int wpdactl = 0;
 274        int enable_wp = 0;
 275
 276        for (breakno = 0; breakno < HW_WATCHPOINT_NUM; breakno++)
 277                if (breakinfo[breakno].enabled) {
 278                        enable_wp = 1;
 279
 280                        switch (breakno) {
 281                        case 0:
 282                                wpiactl |= WPIAEN0|WPICNTEN0;
 283                                bfin_write_WPIA0(breakinfo[breakno].addr);
 284                                bfin_write_WPIACNT0(breakinfo[breakno].count
 285                                        + breakinfo->skip);
 286                                break;
 287                        case 1:
 288                                wpiactl |= WPIAEN1|WPICNTEN1;
 289                                bfin_write_WPIA1(breakinfo[breakno].addr);
 290                                bfin_write_WPIACNT1(breakinfo[breakno].count
 291                                        + breakinfo->skip);
 292                                break;
 293                        case 2:
 294                                wpiactl |= WPIAEN2|WPICNTEN2;
 295                                bfin_write_WPIA2(breakinfo[breakno].addr);
 296                                bfin_write_WPIACNT2(breakinfo[breakno].count
 297                                        + breakinfo->skip);
 298                                break;
 299                        case 3:
 300                                wpiactl |= WPIAEN3|WPICNTEN3;
 301                                bfin_write_WPIA3(breakinfo[breakno].addr);
 302                                bfin_write_WPIACNT3(breakinfo[breakno].count
 303                                        + breakinfo->skip);
 304                                break;
 305                        case 4:
 306                                wpiactl |= WPIAEN4|WPICNTEN4;
 307                                bfin_write_WPIA4(breakinfo[breakno].addr);
 308                                bfin_write_WPIACNT4(breakinfo[breakno].count
 309                                        + breakinfo->skip);
 310                                break;
 311                        case 5:
 312                                wpiactl |= WPIAEN5|WPICNTEN5;
 313                                bfin_write_WPIA5(breakinfo[breakno].addr);
 314                                bfin_write_WPIACNT5(breakinfo[breakno].count
 315                                        + breakinfo->skip);
 316                                break;
 317                        case 6:
 318                                wpdactl |= WPDAEN0|WPDCNTEN0|WPDSRC0;
 319                                wpdactl |= breakinfo[breakno].dataacc
 320                                        << WPDACC0_OFFSET;
 321                                bfin_write_WPDA0(breakinfo[breakno].addr);
 322                                bfin_write_WPDACNT0(breakinfo[breakno].count
 323                                        + breakinfo->skip);
 324                                break;
 325                        case 7:
 326                                wpdactl |= WPDAEN1|WPDCNTEN1|WPDSRC1;
 327                                wpdactl |= breakinfo[breakno].dataacc
 328                                        << WPDACC1_OFFSET;
 329                                bfin_write_WPDA1(breakinfo[breakno].addr);
 330                                bfin_write_WPDACNT1(breakinfo[breakno].count
 331                                        + breakinfo->skip);
 332                                break;
 333                        }
 334                }
 335
 336        /* Should enable WPPWR bit first before set any other
 337         * WPIACTL and WPDACTL bits */
 338        if (enable_wp) {
 339                bfin_write_WPIACTL(WPPWR);
 340                CSYNC();
 341                bfin_write_WPIACTL(wpiactl|WPPWR);
 342                bfin_write_WPDACTL(wpdactl);
 343                CSYNC();
 344        }
 345}
 346
 347void kgdb_disable_hw_debug(struct pt_regs *regs)
 348{
 349        /* Disable hardware debugging while we are in kgdb */
 350        bfin_write_WPIACTL(0);
 351        bfin_write_WPDACTL(0);
 352        CSYNC();
 353}
 354
 355#ifdef CONFIG_SMP
 356void kgdb_passive_cpu_callback(void *info)
 357{
 358        kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
 359}
 360
 361void kgdb_roundup_cpus(unsigned long flags)
 362{
 363        smp_call_function(kgdb_passive_cpu_callback, NULL, 0);
 364}
 365
 366void kgdb_roundup_cpu(int cpu, unsigned long flags)
 367{
 368        smp_call_function_single(cpu, kgdb_passive_cpu_callback, NULL, 0);
 369}
 370#endif
 371
 372void kgdb_post_primary_code(struct pt_regs *regs, int eVector, int err_code)
 373{
 374        /* Master processor is completely in the debugger */
 375        gdb_bfin_vector = eVector;
 376        gdb_bfin_errcode = err_code;
 377}
 378
 379int kgdb_arch_handle_exception(int vector, int signo,
 380                               int err_code, char *remcom_in_buffer,
 381                               char *remcom_out_buffer,
 382                               struct pt_regs *regs)
 383{
 384        long addr;
 385        char *ptr;
 386        int newPC;
 387        int i;
 388
 389        switch (remcom_in_buffer[0]) {
 390        case 'c':
 391        case 's':
 392                if (kgdb_contthread && kgdb_contthread != current) {
 393                        strcpy(remcom_out_buffer, "E00");
 394                        break;
 395                }
 396
 397                kgdb_contthread = NULL;
 398
 399                /* try to read optional parameter, pc unchanged if no parm */
 400                ptr = &remcom_in_buffer[1];
 401                if (kgdb_hex2long(&ptr, &addr)) {
 402                        regs->retx = addr;
 403                }
 404                newPC = regs->retx;
 405
 406                /* clear the trace bit */
 407                regs->syscfg &= 0xfffffffe;
 408
 409                /* set the trace bit if we're stepping */
 410                if (remcom_in_buffer[0] == 's') {
 411                        regs->syscfg |= 0x1;
 412                        kgdb_single_step = regs->ipend;
 413                        kgdb_single_step >>= 6;
 414                        for (i = 10; i > 0; i--, kgdb_single_step >>= 1)
 415                                if (kgdb_single_step & 1)
 416                                        break;
 417                        /* i indicate event priority of current stopped instruction
 418                         * user space instruction is 0, IVG15 is 1, IVTMR is 10.
 419                         * kgdb_single_step > 0 means in single step mode
 420                         */
 421                        kgdb_single_step = i + 1;
 422                }
 423
 424                bfin_correct_hw_break();
 425
 426                return 0;
 427        }                       /* switch */
 428        return -1;              /* this means that we do not want to exit from the handler */
 429}
 430
 431struct kgdb_arch arch_kgdb_ops = {
 432        .gdb_bpt_instr = {0xa1},
 433#ifdef CONFIG_SMP
 434        .flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP,
 435#else
 436        .flags = KGDB_HW_BREAKPOINT,
 437#endif
 438        .set_hw_breakpoint = bfin_set_hw_break,
 439        .remove_hw_breakpoint = bfin_remove_hw_break,
 440        .remove_all_hw_break = bfin_remove_all_hw_break,
 441        .correct_hw_break = bfin_correct_hw_break,
 442};
 443
 444static int hex(char ch)
 445{
 446        if ((ch >= 'a') && (ch <= 'f'))
 447                return ch - 'a' + 10;
 448        if ((ch >= '0') && (ch <= '9'))
 449                return ch - '0';
 450        if ((ch >= 'A') && (ch <= 'F'))
 451                return ch - 'A' + 10;
 452        return -1;
 453}
 454
 455static int validate_memory_access_address(unsigned long addr, int size)
 456{
 457        if (size < 0 || addr == 0)
 458                return -EFAULT;
 459        return bfin_mem_access_type(addr, size);
 460}
 461
 462static int bfin_probe_kernel_read(char *dst, char *src, int size)
 463{
 464        unsigned long lsrc = (unsigned long)src;
 465        int mem_type;
 466
 467        mem_type = validate_memory_access_address(lsrc, size);
 468        if (mem_type < 0)
 469                return mem_type;
 470
 471        if (lsrc >= SYSMMR_BASE) {
 472                if (size == 2 && lsrc % 2 == 0) {
 473                        u16 mmr = bfin_read16(src);
 474                        memcpy(dst, &mmr, sizeof(mmr));
 475                        return 0;
 476                } else if (size == 4 && lsrc % 4 == 0) {
 477                        u32 mmr = bfin_read32(src);
 478                        memcpy(dst, &mmr, sizeof(mmr));
 479                        return 0;
 480                }
 481        } else {
 482                switch (mem_type) {
 483                        case BFIN_MEM_ACCESS_CORE:
 484                        case BFIN_MEM_ACCESS_CORE_ONLY:
 485                                return probe_kernel_read(dst, src, size);
 486                        /* XXX: should support IDMA here with SMP */
 487                        case BFIN_MEM_ACCESS_DMA:
 488                                if (dma_memcpy(dst, src, size))
 489                                        return 0;
 490                                break;
 491                        case BFIN_MEM_ACCESS_ITEST:
 492                                if (isram_memcpy(dst, src, size))
 493                                        return 0;
 494                                break;
 495                }
 496        }
 497
 498        return -EFAULT;
 499}
 500
 501static int bfin_probe_kernel_write(char *dst, char *src, int size)
 502{
 503        unsigned long ldst = (unsigned long)dst;
 504        int mem_type;
 505
 506        mem_type = validate_memory_access_address(ldst, size);
 507        if (mem_type < 0)
 508                return mem_type;
 509
 510        if (ldst >= SYSMMR_BASE) {
 511                if (size == 2 && ldst % 2 == 0) {
 512                        u16 mmr;
 513                        memcpy(&mmr, src, sizeof(mmr));
 514                        bfin_write16(dst, mmr);
 515                        return 0;
 516                } else if (size == 4 && ldst % 4 == 0) {
 517                        u32 mmr;
 518                        memcpy(&mmr, src, sizeof(mmr));
 519                        bfin_write32(dst, mmr);
 520                        return 0;
 521                }
 522        } else {
 523                switch (mem_type) {
 524                        case BFIN_MEM_ACCESS_CORE:
 525                        case BFIN_MEM_ACCESS_CORE_ONLY:
 526                                return probe_kernel_write(dst, src, size);
 527                        /* XXX: should support IDMA here with SMP */
 528                        case BFIN_MEM_ACCESS_DMA:
 529                                if (dma_memcpy(dst, src, size))
 530                                        return 0;
 531                                break;
 532                        case BFIN_MEM_ACCESS_ITEST:
 533                                if (isram_memcpy(dst, src, size))
 534                                        return 0;
 535                                break;
 536                }
 537        }
 538
 539        return -EFAULT;
 540}
 541
 542/*
 543 * Convert the memory pointed to by mem into hex, placing result in buf.
 544 * Return a pointer to the last char put in buf (null). May return an error.
 545 */
 546int kgdb_mem2hex(char *mem, char *buf, int count)
 547{
 548        char *tmp;
 549        int err;
 550
 551        /*
 552         * We use the upper half of buf as an intermediate buffer for the
 553         * raw memory copy.  Hex conversion will work against this one.
 554         */
 555        tmp = buf + count;
 556
 557        err = bfin_probe_kernel_read(tmp, mem, count);
 558        if (!err) {
 559                while (count > 0) {
 560                        buf = pack_hex_byte(buf, *tmp);
 561                        tmp++;
 562                        count--;
 563                }
 564
 565                *buf = 0;
 566        }
 567
 568        return err;
 569}
 570
 571/*
 572 * Copy the binary array pointed to by buf into mem.  Fix $, #, and
 573 * 0x7d escaped with 0x7d.  Return a pointer to the character after
 574 * the last byte written.
 575 */
 576int kgdb_ebin2mem(char *buf, char *mem, int count)
 577{
 578        char *tmp_old, *tmp_new;
 579        int size;
 580
 581        tmp_old = tmp_new = buf;
 582
 583        for (size = 0; size < count; ++size) {
 584                if (*tmp_old == 0x7d)
 585                        *tmp_new = *(++tmp_old) ^ 0x20;
 586                else
 587                        *tmp_new = *tmp_old;
 588                tmp_new++;
 589                tmp_old++;
 590        }
 591
 592        return bfin_probe_kernel_write(mem, buf, count);
 593}
 594
 595/*
 596 * Convert the hex array pointed to by buf into binary to be placed in mem.
 597 * Return a pointer to the character AFTER the last byte written.
 598 * May return an error.
 599 */
 600int kgdb_hex2mem(char *buf, char *mem, int count)
 601{
 602        char *tmp_raw, *tmp_hex;
 603
 604        /*
 605         * We use the upper half of buf as an intermediate buffer for the
 606         * raw memory that is converted from hex.
 607         */
 608        tmp_raw = buf + count * 2;
 609
 610        tmp_hex = tmp_raw - 1;
 611        while (tmp_hex >= buf) {
 612                tmp_raw--;
 613                *tmp_raw = hex(*tmp_hex--);
 614                *tmp_raw |= hex(*tmp_hex--) << 4;
 615        }
 616
 617        return bfin_probe_kernel_write(mem, tmp_raw, count);
 618}
 619
 620#define IN_MEM(addr, size, l1_addr, l1_size) \
 621({ \
 622        unsigned long __addr = (unsigned long)(addr); \
 623        (l1_size && __addr >= l1_addr && __addr + (size) <= l1_addr + l1_size); \
 624})
 625#define ASYNC_BANK_SIZE \
 626        (ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
 627         ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE)
 628
 629int kgdb_validate_break_address(unsigned long addr)
 630{
 631        int cpu = raw_smp_processor_id();
 632
 633        if (addr >= 0x1000 && (addr + BREAK_INSTR_SIZE) <= physical_mem_end)
 634                return 0;
 635        if (IN_MEM(addr, BREAK_INSTR_SIZE, ASYNC_BANK0_BASE, ASYNC_BANK_SIZE))
 636                return 0;
 637        if (cpu == 0 && IN_MEM(addr, BREAK_INSTR_SIZE, L1_CODE_START, L1_CODE_LENGTH))
 638                return 0;
 639#ifdef CONFIG_SMP
 640        else if (cpu == 1 && IN_MEM(addr, BREAK_INSTR_SIZE, COREB_L1_CODE_START, L1_CODE_LENGTH))
 641                return 0;
 642#endif
 643        if (IN_MEM(addr, BREAK_INSTR_SIZE, L2_START, L2_LENGTH))
 644                return 0;
 645
 646        return -EFAULT;
 647}
 648
 649int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
 650{
 651        int err = bfin_probe_kernel_read(saved_instr, (char *)addr,
 652                                         BREAK_INSTR_SIZE);
 653        if (err)
 654                return err;
 655        return bfin_probe_kernel_write((char *)addr, arch_kgdb_ops.gdb_bpt_instr,
 656                                       BREAK_INSTR_SIZE);
 657}
 658
 659int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)
 660{
 661        return bfin_probe_kernel_write((char *)addr, bundle, BREAK_INSTR_SIZE);
 662}
 663
 664int kgdb_arch_init(void)
 665{
 666        kgdb_single_step = 0;
 667
 668        bfin_remove_all_hw_break();
 669        return 0;
 670}
 671
 672void kgdb_arch_exit(void)
 673{
 674}
 675