/** Execute one instruction via ITR repeatedly while * reading data from the core via DTR on each execution. * * The executed instruction \em must write data to DTR. * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode ARM opcode * \param data Pointer to an array that receives the data words from the core * \param count Number of data words and instruction repetitions * */ void arm11_run_instr_data_from_core(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, -1); arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE); arm11_add_IR(arm11, ARM11_INTEST, -1); scan_field_t chain5_fields[3]; u32 Data; u8 Ready; u8 nRetry; arm11_setup_field(arm11, 32, NULL, &Data, chain5_fields + 0); arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2); while (count--) { do { arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, count ? TAP_IDLE : TAP_DRPAUSE); jtag_execute_queue(); JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", Data, Ready, nRetry); } while (!Ready); *data++ = Data; } }
/** Execute one instruction via ITR repeatedly while * passing data to the core via DTR on each execution. * * No Ready check during transmission. * * The executed instruction \em must read data from DTR. * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode ARM opcode * \param data Pointer to the data words to be passed to the core * \param count Number of data words and instruction repetitions * */ void arm11_run_instr_data_to_core_noack(arm11_common_t * arm11, u32 opcode, u32 * data, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, -1); arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); arm11_add_IR(arm11, ARM11_EXTEST, -1); scan_field_t chain5_fields[3]; arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0); arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); u8 Readies[count + 1]; u8 * ReadyPos = Readies; while (count--) { chain5_fields[0].out_value = (void *)(data++); chain5_fields[1].in_value = ReadyPos++; if (count) { jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE); jtag_add_pathmove(asizeof(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); } else { jtag_add_dr_scan(asizeof(chain5_fields), chain5_fields, TAP_IDLE); } } arm11_add_IR(arm11, ARM11_INTEST, -1); chain5_fields[0].out_value = 0; chain5_fields[1].in_value = ReadyPos++; arm11_add_dr_scan_vc(asizeof(chain5_fields), chain5_fields, TAP_DRPAUSE); jtag_execute_queue(); size_t error_count = 0; {size_t i; for (i = 0; i < asizeof(Readies); i++) { if (Readies[i] != 1) { error_count++; } }} if (error_count) LOG_ERROR("Transfer errors " ZU, error_count); }
/** * Execute one or more instructions via ITR. * Caller guarantees that processor is in debug state, that DSCR_ITR_EN * is set, the ITR Ready flag is set (as seen on the previous entry to * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode Pointer to sequence of ARM opcodes * \param count Number of opcodes to execute * */ static int arm11_run_instr_no_data(struct arm11_common * arm11, uint32_t * opcode, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); while (count--) { arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_IDLE); int i = 0; while (1) { uint8_t flag; arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_IDLE : TAP_DRPAUSE); CHECK_RETVAL(jtag_execute_queue()); if (flag) break; long long then = 0; if (i == 1000) { then = timeval_ms(); } if (i >= 1000) { if ((timeval_ms()-then) > 1000) { LOG_WARNING("Timeout (1000ms) waiting for instructions to complete"); return ERROR_FAIL; } } i++; } } return ERROR_OK; }
/** Execute one instruction via ITR repeatedly while * reading data from the core via DTR on each execution. * * Caller guarantees that processor is in debug state, that DSCR_ITR_EN * is set, the ITR Ready flag is set (as seen on the previous entry to * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. * * The executed instruction \em must write data to DTR. * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode ARM opcode * \param data Pointer to an array that receives the data words from the core * \param count Number of data words and instruction repetitions * */ int arm11_run_instr_data_from_core(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); arm11_add_debug_INST(arm11, opcode, NULL, TAP_IDLE); arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); struct scan_field chain5_fields[3]; uint32_t Data; uint8_t Ready; uint8_t nRetry; arm11_setup_field(arm11, 32, NULL, &Data, chain5_fields + 0); arm11_setup_field(arm11, 1, NULL, &Ready, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, &nRetry, chain5_fields + 2); while (count--) { int i = 0; do { arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, count ? TAP_IDLE : TAP_DRPAUSE); CHECK_RETVAL(jtag_execute_queue()); JTAG_DEBUG("DTR Data %08x Ready %d nRetry %d", (unsigned) Data, Ready, nRetry); long long then = 0; if (i == 1000) { then = timeval_ms(); } if (i >= 1000) { if ((timeval_ms()-then) > 1000) { LOG_WARNING("Timeout (1000ms) waiting for instructions to complete"); return ERROR_FAIL; } } i++; } while (!Ready); *data++ = Data; } return ERROR_OK; }
/** Execute one or multiple instructions via ITR * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode Pointer to sequence of ARM opcodes * \param count Number of opcodes to execute * */ void arm11_run_instr_no_data(arm11_common_t * arm11, u32 * opcode, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, -1); while (count--) { arm11_add_debug_INST(arm11, *opcode++, NULL, TAP_IDLE); while (1) { u8 flag; arm11_add_debug_INST(arm11, 0, &flag, count ? TAP_IDLE : TAP_DRPAUSE); jtag_execute_queue(); if (flag) break; } } }
/** Execute one instruction via ITR repeatedly while * passing data to the core via DTR on each execution. * * Caller guarantees that processor is in debug state, that DSCR_ITR_EN * is set, the ITR Ready flag is set (as seen on the previous entry to * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. * * No Ready check during transmission. * * The executed instruction \em must read data from DTR. * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode ARM opcode * \param data Pointer to the data words to be passed to the core * \param count Number of data words and instruction repetitions * */ int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); int retval = arm11_run_instr_data_to_core_noack_inner(arm11->arm.target->tap, opcode, data, count); if (retval != ERROR_OK) return retval; arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); struct scan_field chain5_fields[3]; arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0); arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); uint8_t ready_flag; chain5_fields[1].in_value = &ready_flag; arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE); retval = jtag_execute_queue(); if (retval == ERROR_OK) { if (ready_flag != 1) { LOG_ERROR("last word not transferred"); retval = ERROR_FAIL; } } return retval; }
/** Execute one instruction via ITR repeatedly while * passing data to the core via DTR on each execution. * * Caller guarantees that processor is in debug state, that DSCR_ITR_EN * is set, the ITR Ready flag is set (as seen on the previous entry to * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear. * * No Ready check during transmission. * * The executed instruction \em must read data from DTR. * * \pre arm11_run_instr_data_prepare() / arm11_run_instr_data_finish() block * * \param arm11 Target state variable. * \param opcode ARM opcode * \param data Pointer to the data words to be passed to the core * \param count Number of data words and instruction repetitions * */ int arm11_run_instr_data_to_core_noack(struct arm11_common * arm11, uint32_t opcode, uint32_t * data, size_t count) { arm11_add_IR(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT); arm11_add_debug_INST(arm11, opcode, NULL, TAP_DRPAUSE); arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT); struct scan_field chain5_fields[3]; arm11_setup_field(arm11, 32, NULL/*&Data*/, NULL, chain5_fields + 0); arm11_setup_field(arm11, 1, NULL, NULL /*&Ready*/, chain5_fields + 1); arm11_setup_field(arm11, 1, NULL, NULL, chain5_fields + 2); uint8_t *Readies; unsigned readiesNum = count + 1; unsigned bytes = sizeof(*Readies)*readiesNum; Readies = (uint8_t *) malloc(bytes); if (Readies == NULL) { LOG_ERROR("Out of memory allocating %u bytes", bytes); return ERROR_FAIL; } uint8_t * ReadyPos = Readies; while (count--) { chain5_fields[0].out_value = (void *)(data++); chain5_fields[1].in_value = ReadyPos++; if (count) { jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_DRPAUSE)); jtag_add_pathmove(ARRAY_SIZE(arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay), arm11_MOVE_DRPAUSE_IDLE_DRPAUSE_with_delay); } else { jtag_add_dr_scan(ARRAY_SIZE(chain5_fields), chain5_fields, jtag_set_end_state(TAP_IDLE)); } } arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT); chain5_fields[0].out_value = 0; chain5_fields[1].in_value = ReadyPos++; arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE); int retval = jtag_execute_queue(); if (retval == ERROR_OK) { unsigned error_count = 0; for (size_t i = 0; i < readiesNum; i++) { if (Readies[i] != 1) { error_count++; } } if (error_count > 0 ) LOG_ERROR("%u words out of %u not transferred", error_count, readiesNum); } free(Readies); return retval; }