X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fmips32.c;h=bcf96147f13f149d15599ea9aae6505b51aff9ed;hb=27ad4524afc3262e64aff2ae917d10881e8d6823;hp=96e509c3b895ad42b3a47bd18b6ece9ee17b804f;hpb=ef1cfb23947bd32798077c6abb5c25a049460ae9;p=openocd.git diff --git a/src/target/mips32.c b/src/target/mips32.c index 96e509c3b8..bcf96147f1 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -4,6 +4,9 @@ * * * Copyright (C) 2008 by David T.L. Wong * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -32,10 +35,10 @@ char* mips32_core_reg_list[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", + "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra", "status", "lo", "hi", "badvaddr", "cause", "pc" }; @@ -286,7 +289,10 @@ reg_cache_t *mips32_build_reg_cache(target_t *target) if (mips32_core_reg_arch_type == -1) mips32_core_reg_arch_type = register_reg_arch_type(mips32_get_core_reg, mips32_set_core_reg); - + + register_init_dummy(&mips32_gdb_dummy_fsr_reg); + register_init_dummy(&mips32_gdb_dummy_fir_reg); + /* Build the process context cache */ cache->name = "mips32 registers"; cache->next = NULL; @@ -319,6 +325,10 @@ int mips32_init_arch_info(target_t *target, mips32_common_t *mips32, int chain_p target->arch_info = mips32; mips32->common_magic = MIPS32_COMMON_MAGIC; + /* has breakpoint/watchpint unit been scanned */ + mips32->bp_scanned = 0; + mips32->data_break_list = NULL; + mips32->ejtag_info.chain_pos = chain_pos; mips32->read_core_reg = mips32_read_core_reg; mips32->write_core_reg = mips32_write_core_reg; @@ -336,3 +346,82 @@ int mips32_run_algorithm(struct target_s *target, int num_mem_params, mem_param_ /*TODO*/ return ERROR_OK; } + +int mips32_examine(struct target_s *target) +{ + mips32_common_t *mips32 = target->arch_info; + + if (!target->type->examined) + { + target->type->examined = 1; + + /* we will configure later */ + mips32->bp_scanned = 0; + mips32->num_inst_bpoints = 0; + mips32->num_data_bpoints = 0; + mips32->num_inst_bpoints_avail = 0; + mips32->num_data_bpoints_avail = 0; + } + + return ERROR_OK; +} + +int mips32_configure_break_unit(struct target_s *target) +{ + /* get pointers to arch-specific information */ + mips32_common_t *mips32 = target->arch_info; + int retval; + u32 dcr, bpinfo; + int i; + + if (mips32->bp_scanned) + return ERROR_OK; + + /* get info about breakpoint support */ + if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK) + return retval; + + if (dcr & (1 << 16)) + { + /* get number of inst breakpoints */ + if ((retval = target_read_u32(target, EJTAG_IBS, &bpinfo)) != ERROR_OK) + return retval; + + mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F; + mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints; + mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(mips32_comparator_t)); + for (i = 0; i < mips32->num_inst_bpoints; i++) + { + mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i); + } + + /* clear IBIS reg */ + if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK) + return retval; + } + + if (dcr & (1 << 17)) + { + /* get number of data breakpoints */ + if ((retval = target_read_u32(target, EJTAG_DBS, &bpinfo)) != ERROR_OK) + return retval; + + mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F; + mips32->num_data_bpoints_avail = mips32->num_data_bpoints; + mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(mips32_comparator_t)); + for (i = 0; i < mips32->num_data_bpoints; i++) + { + mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i); + } + + /* clear DBIS reg */ + if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK) + return retval; + } + + LOG_DEBUG("DCR 0x%x numinst %i numdata %i", dcr, mips32->num_inst_bpoints, mips32->num_data_bpoints); + + mips32->bp_scanned = 1; + + return ERROR_OK; +}