X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Faarch64.c;h=e9c822d64d7b13275a867c9c2f53f326fc53cf52;hp=bcfce659244af6ca099623c1a8dc277e3f1d7877;hb=f444c57bf2d692171b7b50a6ce477265f951f77e;hpb=a640f139baa9fe4f44d428b1e4e1a9da245532ca diff --git a/src/target/aarch64.c b/src/target/aarch64.c index bcfce65924..e9c822d64d 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -40,6 +40,10 @@ enum halt_mode { HALT_SYNC, }; +struct aarch64_private_config { + struct arm_cti *cti; +}; + static int aarch64_poll(struct target *target); static int aarch64_debug_entry(struct target *target); static int aarch64_restore_context(struct target *target, bool bpwp); @@ -452,7 +456,7 @@ static int update_halt_gdb(struct target *target, enum target_debug_reason debug struct target *curr; if (debug_reason == DBG_REASON_NOTHALTED) { - LOG_INFO("Halting remaining targets in SMP group"); + LOG_DEBUG("Halting remaining targets in SMP group"); aarch64_halt_smp(target, true); } @@ -642,9 +646,11 @@ static int aarch64_prepare_restart_one(struct target *target) armv8->debug_base + CPUV8_DBG_DSCR, dscr); } - /* clear sticky bits in PRSR, SDR is now 0 */ - retval = mem_ap_read_atomic_u32(armv8->debug_ap, - armv8->debug_base + CPUV8_DBG_PRSR, &tmp); + if (retval == ERROR_OK) { + /* clear sticky bits in PRSR, SDR is now 0 */ + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_PRSR, &tmp); + } return retval; } @@ -1084,7 +1090,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres if (retval != ERROR_OK) return retval; - if (target->smp && !handle_breakpoints) { + if (target->smp && (current == 1)) { /* * isolate current target so that it doesn't get resumed * together with the others @@ -1815,6 +1821,8 @@ static int aarch64_write_cpu_memory(struct target *target, dscr = (dscr & ~DSCR_MA); retval = mem_ap_write_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DSCR, dscr); + if (retval != ERROR_OK) + return retval; if (arm->core_state == ARM_STATE_AARCH64) { /* Write X0 with value 'address' using write procedure */ @@ -1826,10 +1834,13 @@ static int aarch64_write_cpu_memory(struct target *target, /* Write R0 with value 'address' using write procedure */ /* Step 1.a+b - Write the address for read access into DBGDTRRX */ /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */ - dpm->instr_write_data_dcc(dpm, + retval = dpm->instr_write_data_dcc(dpm, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address); } + if (retval != ERROR_OK) + return retval; + if (size == 4 && (address % 4) == 0) retval = aarch64_write_cpu_memory_fast(target, count, buffer, &dscr); else @@ -1854,7 +1865,7 @@ static int aarch64_write_cpu_memory(struct target *target, if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) { /* Abort occurred - clear it and exit */ LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr); - armv8_dpm_handle_exception(dpm); + armv8_dpm_handle_exception(dpm, true); return ERROR_FAIL; } @@ -1941,13 +1952,21 @@ static int aarch64_read_cpu_memory_fast(struct target *target, retval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 0, 0, 5, 0)); } + if (retval != ERROR_OK) + return retval; + /* Step 1.e - Change DCC to memory mode */ *dscr |= DSCR_MA; retval = mem_ap_write_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DSCR, *dscr); + if (retval != ERROR_OK) + return retval; + /* Step 1.f - read DBGDTRTX and discard the value */ retval = mem_ap_read_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DTRTX, &value); + if (retval != ERROR_OK) + return retval; count--; /* Read the data - Each read of the DTRTX register causes the instruction to be reissued @@ -2011,28 +2030,35 @@ static int aarch64_read_cpu_memory(struct target *target, /* Read DSCR */ retval = mem_ap_read_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DSCR, &dscr); + if (retval != ERROR_OK) + return retval; /* This algorithm comes from DDI0487A.g, chapter J9.1 */ /* Set Normal access mode */ dscr &= ~DSCR_MA; - retval += mem_ap_write_atomic_u32(armv8->debug_ap, + retval = mem_ap_write_atomic_u32(armv8->debug_ap, armv8->debug_base + CPUV8_DBG_DSCR, dscr); + if (retval != ERROR_OK) + return retval; if (arm->core_state == ARM_STATE_AARCH64) { /* Write X0 with value 'address' using write procedure */ /* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */ /* Step 1.c - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */ - retval += dpm->instr_write_data_dcc_64(dpm, + retval = dpm->instr_write_data_dcc_64(dpm, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address); } else { /* Write R0 with value 'address' using write procedure */ /* Step 1.a+b - Write the address for read access into DBGDTRRXint */ /* Step 1.c - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */ - retval += dpm->instr_write_data_dcc(dpm, + retval = dpm->instr_write_data_dcc(dpm, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), address); } + if (retval != ERROR_OK) + return retval; + if (size == 4 && (address % 4) == 0) retval = aarch64_read_cpu_memory_fast(target, count, buffer, &dscr); else @@ -2058,7 +2084,7 @@ static int aarch64_read_cpu_memory(struct target *target, if (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) { /* Abort occurred - clear it and exit */ LOG_ERROR("abort occurred - dscr = 0x%08" PRIx32, dscr); - armv8_dpm_handle_exception(dpm); + armv8_dpm_handle_exception(dpm, true); return ERROR_FAIL; } @@ -2176,7 +2202,7 @@ static int aarch64_examine_first(struct target *target) struct aarch64_common *aarch64 = target_to_aarch64(target); struct armv8_common *armv8 = &aarch64->armv8_common; struct adiv5_dap *swjdp = armv8->arm.dap; - uint32_t cti_base; + struct aarch64_private_config *pc; int i; int retval = ERROR_OK; uint64_t debug, ttypr; @@ -2267,17 +2293,15 @@ static int aarch64_examine_first(struct target *target) LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr); LOG_DEBUG("debug = 0x%08" PRIx64, debug); - if (target->ctibase == 0) { - /* assume a v8 rom table layout */ - cti_base = armv8->debug_base + 0x10000; - LOG_INFO("Target ctibase is not set, assuming 0x%0" PRIx32, cti_base); - } else - cti_base = target->ctibase; + if (target->private_config == NULL) + return ERROR_FAIL; - armv8->cti = arm_cti_create(armv8->debug_ap, cti_base); - if (armv8->cti == NULL) + pc = (struct aarch64_private_config *)target->private_config; + if (pc->cti == NULL) return ERROR_FAIL; + armv8->cti = pc->cti; + retval = aarch64_dpm_setup(aarch64, debug); if (retval != ERROR_OK) return retval; @@ -2383,6 +2407,63 @@ static int aarch64_virt2phys(struct target *target, target_addr_t virt, return armv8_mmu_translate_va_pa(target, virt, phys, 1); } +static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi) +{ + struct aarch64_private_config *pc; + const char *arg; + int e; + + /* check if argv[0] is for us */ + arg = Jim_GetString(goi->argv[0], NULL); + if (strcmp(arg, "-cti")) + return JIM_CONTINUE; + + /* pop the argument from argv */ + e = Jim_GetOpt_String(goi, &arg, NULL); + if (e != JIM_OK) + return e; + + /* check if we have another option */ + if (goi->argc == 0) { + Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-cti ?cti-name?"); + return JIM_ERR; + } + + pc = (struct aarch64_private_config *)target->private_config; + + if (goi->isconfigure) { + Jim_Obj *o_cti; + struct arm_cti *cti; + e = Jim_GetOpt_Obj(goi, &o_cti); + if (e != JIM_OK) + return e; + cti = cti_instance_by_jim_obj(goi->interp, o_cti); + if (cti == NULL) + return JIM_ERR; + + if (pc == NULL) { + pc = calloc(1, sizeof(struct aarch64_private_config)); + target->private_config = pc; + } + pc->cti = cti; + } else { + if (goi->argc != 0) { + Jim_WrongNumArgs(goi->interp, + goi->argc, goi->argv, + "NO PARAMS"); + return JIM_ERR; + } + + if (pc == NULL || pc->cti == NULL) { + Jim_SetResultString(goi->interp, "CTI not configured", -1); + return JIM_ERR; + } + Jim_SetResultString(goi->interp, arm_cti_name(pc->cti), -1); + } + + return JIM_OK; +} + COMMAND_HANDLER(aarch64_handle_cache_info_command) { struct target *target = get_current_target(CMD_CTX); @@ -2548,6 +2629,7 @@ struct target_type aarch64_target = { .commands = aarch64_command_handlers, .target_create = aarch64_target_create, + .target_jim_configure = aarch64_jim_configure, .init_target = aarch64_init_target, .examine = aarch64_examine,