static void arm9tdmi_build_reg_cache(struct target *target) { struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); struct arm *arm = target_to_arm(target); (*cache_p) = arm_build_reg_cache(target, arm); }
/** * Hooks up this DPM to its associated target; call only once. * Initially this only covers the register cache. * * Oh, and watchpoints. Yeah. */ int arm_dpm_setup(struct arm_dpm *dpm) { struct arm *arm = dpm->arm; struct target *target = arm->target; struct reg_cache *cache; arm->dpm = dpm; /* register access setup */ arm->full_context = arm_dpm_full_context; arm->read_core_reg = arm_dpm_read_core_reg; arm->write_core_reg = arm_dpm_write_core_reg; cache = arm_build_reg_cache(target, arm); if (!cache) return ERROR_FAIL; *register_get_last_cache_p(&target->reg_cache) = cache; /* coprocessor access setup */ arm->mrc = dpm_mrc; arm->mcr = dpm_mcr; /* breakpoint setup -- optional until it works everywhere */ if (!target->type->add_breakpoint) { target->type->add_breakpoint = dpm_add_breakpoint; target->type->remove_breakpoint = dpm_remove_breakpoint; } /* watchpoint setup */ target->type->add_watchpoint = dpm_add_watchpoint; target->type->remove_watchpoint = dpm_remove_watchpoint; /* FIXME add vector catch support */ dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf); dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp); dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf); dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp); if (!dpm->dbp || !dpm->dwp) { free(dpm->dbp); free(dpm->dwp); return ERROR_FAIL; } LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints", target_name(target), dpm->nbp, dpm->nwp); /* REVISIT ... and some of those breakpoints could match * execution context IDs... */ return ERROR_OK; }