/* read a word (16bit) from the netx to the pc */ int fn_read_data16(void *pvHandle, unsigned long ulNetxAddress, unsigned short *pusData) { command_context_t *cmd_ctx; target_t *target; int iResult; /* cast the handle to the command context */ cmd_ctx = (command_context_t*)pvHandle; /* get the target from the command context */ target = get_current_target(cmd_ctx); /* read the data from the netX */ iResult = target_read_u16(target, ulNetxAddress, pusData); if( iResult==ERROR_OK ) { iResult = 0; } else { iResult = 1; } wxMilliSleep(1); return iResult; }
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found) { struct armv7m_common *armv7m = target_to_armv7m(target); struct reg *r = armv7m->arm.pc; bool result = false; /* if we halted last time due to a bkpt instruction * then we have to manually step over it, otherwise * the core will break again */ if (target->debug_reason == DBG_REASON_BREAKPOINT) { uint16_t op; uint32_t pc = buf_get_u32(r->value, 0, 32); pc &= ~1; if (target_read_u16(target, pc, &op) == ERROR_OK) { if ((op & 0xFF00) == 0xBE00) { pc = buf_get_u32(r->value, 0, 32) + 2; buf_set_u32(r->value, 0, 32, pc); r->dirty = true; r->valid = true; result = true; LOG_DEBUG("Skipping over BKPT instruction"); } } } if (inst_found) *inst_found = result; return ERROR_OK; }
static int str9x_protect_check(struct flash_bank *bank) { int retval; struct str9x_flash_bank *str9x_info = bank->driver_priv; struct target *target = bank->target; int i; uint32_t adr; uint32_t status = 0; uint16_t hstatus = 0; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } /* read level one protection */ if (str9x_info->variant) { if (str9x_info->bank1) { adr = bank1start + 0x18; retval = target_write_u16(target, adr, 0x90); if (retval != ERROR_OK) return retval; retval = target_read_u16(target, adr, &hstatus); if (retval != ERROR_OK) return retval; status = hstatus; } else { adr = bank1start + 0x14; retval = target_write_u16(target, adr, 0x90); if (retval != ERROR_OK) return retval; retval = target_read_u32(target, adr, &status); if (retval != ERROR_OK) return retval; } } else { adr = bank1start + 0x10; retval = target_write_u16(target, adr, 0x90); if (retval != ERROR_OK) return retval; retval = target_read_u16(target, adr, &hstatus); if (retval != ERROR_OK) return retval; status = hstatus; } /* read array command */ retval = target_write_u16(target, adr, 0xFF); if (retval != ERROR_OK) return retval; for (i = 0; i < bank->num_sectors; i++) { if (status & str9x_info->sector_bits[i]) bank->sectors[i].is_protected = 1; else bank->sectors[i].is_protected = 0; } return ERROR_OK; }
static int stm32x_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32x_flash_bank *stm32x_info = bank->driver_priv; int i; uint16_t num_pages; uint32_t device_id; int page_size; uint32_t base_address = 0x08000000; stm32x_info->probed = 0; stm32x_info->register_offset = FLASH_OFFSET_B0; /* read stm32 device id register */ int retval = target_read_u32(target, 0xE0042000, &device_id); if (retval != ERROR_OK) return retval; LOG_INFO("device id = 0x%08" PRIx32 "", device_id); /* get flash size from target. */ retval = target_read_u16(target, 0x1FFFF7E0, &num_pages); if (retval != ERROR_OK) { LOG_WARNING("failed reading flash size, default to max target family"); /* failed reading flash size, default to max target family */ num_pages = 0xffff; } if ((device_id & 0x7ff) == 0x410) { /* medium density - we have 1k pages * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revA */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash"); num_pages = 128; } } else if ((device_id & 0x7ff) == 0x412) { /* low density - we have 1k pages * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revA */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 32k flash"); num_pages = 32; } } else if ((device_id & 0x7ff) == 0x414) { /* high density - we have 2k pages * 2 pages for a protection area */ page_size = 2048; stm32x_info->ppage_size = 2; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revZ */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 512k flash"); num_pages = 512; } } else if ((device_id & 0x7ff) == 0x418) { /* connectivity line density - we have 2k pages * 2 pages for a protection area */ page_size = 2048; stm32x_info->ppage_size = 2; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revZ */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 256k flash"); num_pages = 256; } } else if ((device_id & 0x7ff) == 0x420) { /* value line density - we have 1k pages * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors may be incorrrect on early silicon */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash"); num_pages = 128; } } else if ((device_id & 0x7ff) == 0x430) { /* xl line density - we have 2k pages * 2 pages for a protection area */ page_size = 2048; stm32x_info->ppage_size = 2; stm32x_info->has_dual_banks = true; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors may be incorrrect on early silicon */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 1024k flash"); num_pages = 1024; } /* split reported size into matching bank */ if (bank->base != 0x08080000) { /* bank 0 will be fixed 512k */ num_pages = 512; } else { num_pages -= 512; /* bank1 also uses a register offset */ stm32x_info->register_offset = FLASH_OFFSET_B1; base_address = 0x08080000; } } else { LOG_WARNING("Cannot identify target as a STM32 family."); return ERROR_FAIL; } LOG_INFO("flash size = %dkbytes", num_pages); /* calculate numbers of pages */ num_pages /= (page_size / 1024); if (bank->sectors) { free(bank->sectors); bank->sectors = NULL; } bank->base = base_address; bank->size = (num_pages * page_size); bank->num_sectors = num_pages; bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); for (i = 0; i < num_pages; i++) { bank->sectors[i].offset = i * page_size; bank->sectors[i].size = page_size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } stm32x_info->probed = 1; return ERROR_OK; }
/* Data polling algorithm */ static int fm3_busy_wait(struct target *target, uint32_t offset, int timeout_ms) { int retval = ERROR_OK; uint16_t state1, state2; int ms = 0; /* While(1) loop exit via "break" and "return" on error */ while(1) { /* dummy-read - see flash manual */ retval = target_read_u16(target, offset, &state1); if (retval != ERROR_OK) return retval; /* Data polling 1 */ retval = target_read_u16(target, offset, &state1); if (retval != ERROR_OK) return retval; /* Data polling 2 */ retval = target_read_u16(target, offset, &state2); if (retval != ERROR_OK) return retval; /* Flash command finished via polled data equal? */ if ( (state1 & FLASH_DQ6) == (state2 & FLASH_DQ6) ) { break; } /* Timeout Flag? */ else if (state1 & FLASH_DQ5) { /* Retry data polling */ /* Data polling 1 */ retval = target_read_u16(target, offset, &state1); if (retval != ERROR_OK) return retval; /* Data polling 2 */ retval = target_read_u16(target, offset, &state2); if (retval != ERROR_OK) return retval; /* Flash command finished via polled data equal? */ if ( (state1 & FLASH_DQ6) != (state2 & FLASH_DQ6) ) { return ERROR_FLASH_OPERATION_FAILED; } /* finish anyway */ break; } usleep(1000); ++ms; /* Polling time exceeded? */ if (ms > timeout_ms) { LOG_ERROR("Polling data reading timed out!"); return ERROR_FLASH_OPERATION_FAILED; } } if (retval == ERROR_OK) LOG_DEBUG("fm3_busy_wait(%x) needs about %d ms", offset, ms); return retval; }
static int uCOS_III_update_threads(struct rtos *rtos) { struct uCOS_III_params *params = rtos->rtos_specific_params; int retval; /* free previous thread details */ rtos_free_threadlist(rtos); /* verify RTOS is running */ uint8_t rtos_running; retval = target_read_u8(rtos->target, rtos->symbols[uCOS_III_VAL_OSRunning].address, &rtos_running); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read RTOS running"); return retval; } if (rtos_running != 1 && rtos_running != 0) { LOG_ERROR("uCOS-III: invalid RTOS running value"); return ERROR_FAIL; } if (!rtos_running) { rtos->thread_details = calloc(1, sizeof(struct thread_detail)); if (rtos->thread_details == NULL) { LOG_ERROR("uCOS-III: out of memory"); return ERROR_FAIL; } rtos->thread_count = 1; rtos->thread_details->threadid = 0; rtos->thread_details->exists = true; rtos->current_thread = 0; return ERROR_OK; } /* update thread offsets */ retval = uCOS_III_update_thread_offsets(rtos); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to update thread offsets"); return retval; } /* read current thread address */ symbol_address_t current_thread_address = 0; retval = target_read_memory(rtos->target, rtos->symbols[uCOS_III_VAL_OSTCBCurPtr].address, params->pointer_width, 1, (void *)¤t_thread_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read current thread address"); return retval; } /* read number of tasks */ retval = target_read_u16(rtos->target, rtos->symbols[uCOS_III_VAL_OSTaskQty].address, (void *)&rtos->thread_count); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread count"); return retval; } rtos->thread_details = calloc(rtos->thread_count, sizeof(struct thread_detail)); if (rtos->thread_details == NULL) { LOG_ERROR("uCOS-III: out of memory"); return ERROR_FAIL; } /* * uC/OS-III adds tasks in LIFO order; advance to the end of the * list and work backwards to preserve the intended order. */ symbol_address_t thread_address = 0; retval = uCOS_III_find_last_thread_address(rtos, &thread_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to find last thread address"); return retval; } for (int i = 0; i < rtos->thread_count; i++) { struct thread_detail *thread_detail = &rtos->thread_details[i]; char thread_str_buffer[UCOS_III_MAX_STRLEN + 1]; /* find or create new threadid */ retval = uCOS_III_find_or_create_thread(rtos, thread_address, &thread_detail->threadid); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to find or create thread"); return retval; } if (thread_address == current_thread_address) rtos->current_thread = thread_detail->threadid; thread_detail->exists = true; /* read thread name */ symbol_address_t thread_name_address = 0; retval = target_read_memory(rtos->target, thread_address + params->thread_name_offset, params->pointer_width, 1, (void *)&thread_name_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to name address"); return retval; } retval = target_read_buffer(rtos->target, thread_name_address, sizeof(thread_str_buffer), (void *)thread_str_buffer); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread name"); return retval; } thread_str_buffer[sizeof(thread_str_buffer) - 1] = '\0'; thread_detail->thread_name_str = strdup(thread_str_buffer); /* read thread extra info */ uint8_t thread_state; uint8_t thread_priority; retval = target_read_u8(rtos->target, thread_address + params->thread_state_offset, &thread_state); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread state"); return retval; } retval = target_read_u8(rtos->target, thread_address + params->thread_priority_offset, &thread_priority); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read thread priority"); return retval; } const char *thread_state_str; if (thread_state < ARRAY_SIZE(uCOS_III_thread_state_list)) thread_state_str = uCOS_III_thread_state_list[thread_state]; else thread_state_str = "Unknown"; snprintf(thread_str_buffer, sizeof(thread_str_buffer), "State: %s, Priority: %d", thread_state_str, thread_priority); thread_detail->extra_info_str = strdup(thread_str_buffer); /* read previous thread address */ retval = target_read_memory(rtos->target, thread_address + params->thread_prev_offset, params->pointer_width, 1, (void *)&thread_address); if (retval != ERROR_OK) { LOG_ERROR("uCOS-III: failed to read previous thread address"); return retval; } } return ERROR_OK; }
static int stm32lx_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv; int i; uint16_t flash_size_in_kb; uint16_t max_flash_size_in_kb; uint32_t device_id; uint32_t base_address = FLASH_BANK0_ADDRESS; uint32_t second_bank_base; uint32_t first_bank_size_in_kb; stm32lx_info->probed = 0; /* read stm32 device id register */ int retval = target_read_u32(target, DBGMCU_IDCODE, &device_id); if (retval != ERROR_OK) return retval; LOG_DEBUG("device id = 0x%08" PRIx32 "", device_id); /* set max flash size depending on family */ switch (device_id & 0xfff) { case 0x416: max_flash_size_in_kb = 128; break; case 0x427: /* single bank, high density */ max_flash_size_in_kb = 256; break; case 0x436: /* According to ST, the devices with id 0x436 have dual bank flash and comes with * a total flash size of 384k or 256kb. However, the first bank is always 192kb, * and second one holds the rest. The reason is that the 256kb version is actually * the same physical flash but only the first 256kb are verified. */ max_flash_size_in_kb = 384; first_bank_size_in_kb = 192; stm32lx_info->has_dual_banks = true; break; default: LOG_WARNING("Cannot identify target as a STM32L family."); return ERROR_FAIL; } /* Get the flash size from target. */ retval = target_read_u16(target, F_SIZE, &flash_size_in_kb); /* Failed reading flash size or flash size invalid (early silicon), * default to max target family */ if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) { LOG_WARNING("STM32L flash size failed, probe inaccurate - assuming %dk flash", max_flash_size_in_kb); flash_size_in_kb = max_flash_size_in_kb; } else if (flash_size_in_kb > max_flash_size_in_kb) { LOG_WARNING("STM32L probed flash size assumed incorrect since FLASH_SIZE=%dk > %dk, - assuming %dk flash", flash_size_in_kb, max_flash_size_in_kb, max_flash_size_in_kb); flash_size_in_kb = max_flash_size_in_kb; } if (stm32lx_info->has_dual_banks) { /* Use the configured base address to determine if this is the first or second flash bank. * Verify that the base address is reasonably correct and determine the flash bank size */ second_bank_base = base_address + first_bank_size_in_kb * 1024; if (bank->base == second_bank_base) { /* This is the second bank */ base_address = second_bank_base; flash_size_in_kb = flash_size_in_kb - first_bank_size_in_kb; } else if (bank->base == 0 || bank->base == base_address) { /* This is the first bank */ flash_size_in_kb = first_bank_size_in_kb; } else { LOG_WARNING("STM32L flash bank base address config is incorrect. 0x%x but should rather be 0x%x or 0x%x", bank->base, base_address, second_bank_base); return ERROR_FAIL; } LOG_INFO("STM32L flash has dual banks. Bank (%d) size is %dkb, base address is 0x%x", bank->bank_number, flash_size_in_kb, base_address); } else { LOG_INFO("STM32L flash size is %dkb, base address is 0x%x", flash_size_in_kb, base_address); } /* if the user sets the size manually then ignore the probed value * this allows us to work around devices that have a invalid flash size register value */ if (stm32lx_info->user_bank_size) { flash_size_in_kb = stm32lx_info->user_bank_size / 1024; LOG_INFO("ignoring flash probed value, using configured bank size: %dkbytes", flash_size_in_kb); } /* STM32L - we have 32 sectors, 16 pages per sector -> 512 pages * 16 pages for a protection area */ /* calculate numbers of sectors (4kB per sector) */ int num_sectors = (flash_size_in_kb * 1024) / FLASH_SECTOR_SIZE; if (bank->sectors) { free(bank->sectors); bank->sectors = NULL; } bank->size = flash_size_in_kb * 1024; bank->base = base_address; bank->num_sectors = num_sectors; bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); if (bank->sectors == NULL) { LOG_ERROR("failed to allocate bank sectors"); return ERROR_FAIL; } for (i = 0; i < num_sectors; i++) { bank->sectors[i].offset = i * FLASH_SECTOR_SIZE; bank->sectors[i].size = FLASH_SECTOR_SIZE; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } stm32lx_info->probed = 1; return ERROR_OK; }
static int stm32x_probe(struct flash_bank *bank) { struct target *target = bank->target; struct stm32x_flash_bank *stm32x_info = bank->driver_priv; int i; uint16_t num_pages; uint32_t device_id; int page_size; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); return ERROR_TARGET_NOT_HALTED; } stm32x_info->probed = 0; /* read stm32 device id register */ target_read_u32(target, 0xE0042000, &device_id); LOG_INFO("device id = 0x%08" PRIx32 "", device_id); /* get flash size from target */ if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK) { /* failed reading flash size, default to max target family */ num_pages = 0xffff; } if ((device_id & 0x7ff) == 0x410) { /* medium density - we have 1k pages * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revA */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash"); num_pages = 128; } } else if ((device_id & 0x7ff) == 0x412) { /* low density - we have 1k pages * 4 pages for a protection area */ page_size = 1024; stm32x_info->ppage_size = 4; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revA */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 32k flash"); num_pages = 32; } } else if ((device_id & 0x7ff) == 0x414) { /* high density - we have 2k pages * 2 pages for a protection area */ page_size = 2048; stm32x_info->ppage_size = 2; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revZ */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 512k flash"); num_pages = 512; } } else if ((device_id & 0x7ff) == 0x418) { /* connectivity line density - we have 2k pages * 2 pages for a protection area */ page_size = 2048; stm32x_info->ppage_size = 2; /* check for early silicon */ if (num_pages == 0xffff) { /* number of sectors incorrect on revZ */ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 256k flash"); num_pages = 256; } } else { LOG_WARNING("Cannot identify target as a STM32 family."); return ERROR_FLASH_OPERATION_FAILED; } LOG_INFO("flash size = %dkbytes", num_pages); /* calculate numbers of pages */ num_pages /= (page_size / 1024); bank->base = 0x08000000; bank->size = (num_pages * page_size); bank->num_sectors = num_pages; bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); for (i = 0; i < num_pages; i++) { bank->sectors[i].offset = i * page_size; bank->sectors[i].size = page_size; bank->sectors[i].is_erased = -1; bank->sectors[i].is_protected = 1; } stm32x_info->probed = 1; return ERROR_OK; }
/** * Checks for and processes an ARM semihosting request. This is meant * to be called when the target is stopped due to a debug mode entry. * If the value 0 is returned then there was nothing to process. A non-zero * return value signifies that a request was processed and the target resumed, * or an error was encountered, in which case the caller must return * immediately. * * @param target Pointer to the ARM target to process. This target must * not represent an ARMv6-M or ARMv7-M processor. * @param retval Pointer to a location where the return code will be stored * @return non-zero value if a request was processed or an error encountered */ int arm_semihosting(struct target *target, int *retval) { struct arm *arm = target_to_arm(target); uint32_t pc, lr, spsr; struct reg *r; if (!arm->is_semihosting) return 0; if (is_arm7_9(target_to_arm7_9(target))) { if (arm->core_mode != ARM_MODE_SVC) return 0; /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */ r = arm->pc; pc = buf_get_u32(r->value, 0, 32); if (pc != 0x00000008 && pc != 0xffff0008) return 0; r = arm_reg_current(arm, 14); lr = buf_get_u32(r->value, 0, 32); /* Core-specific code should make sure SPSR is retrieved * when the above checks pass... */ if (!arm->spsr->valid) { LOG_ERROR("SPSR not valid!"); *retval = ERROR_FAIL; return 1; } spsr = buf_get_u32(arm->spsr->value, 0, 32); /* check instruction that triggered this trap */ if (spsr & (1 << 5)) { /* was in Thumb (or ThumbEE) mode */ uint8_t insn_buf[2]; uint16_t insn; *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u16(target, insn_buf); /* SVC 0xab */ if (insn != 0xDFAB) return 0; } else if (spsr & (1 << 24)) { /* was in Jazelle mode */ return 0; } else { /* was in ARM mode */ uint8_t insn_buf[4]; uint32_t insn; *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u32(target, insn_buf); /* SVC 0x123456 */ if (insn != 0xEF123456) return 0; } } else if (is_armv7m(target_to_armv7m(target))) { uint16_t insn; if (target->debug_reason != DBG_REASON_BREAKPOINT) return 0; r = arm->pc; pc = buf_get_u32(r->value, 0, 32); pc &= ~1; *retval = target_read_u16(target, pc, &insn); if (*retval != ERROR_OK) return 1; /* bkpt 0xAB */ if (insn != 0xBEAB) return 0; } else { LOG_ERROR("Unsupported semi-hosting Target"); return 0; } *retval = do_semihosting(target); return 1; }
/** * Checks for and processes an ARM semihosting request. This is meant * to be called when the target is stopped due to a debug mode entry. * If the value 0 is returned then there was nothing to process. A non-zero * return value signifies that a request was processed and the target resumed, * or an error was encountered, in which case the caller must return * immediately. * * @param target Pointer to the ARM target to process. This target must * not represent an ARMv6-M or ARMv7-M processor. * @param retval Pointer to a location where the return code will be stored * @return non-zero value if a request was processed or an error encountered */ int arm_semihosting(struct target *target, int *retval) { struct arm *arm = target_to_arm(target); struct armv7a_common *armv7a = target_to_armv7a(target); uint32_t pc, lr, spsr; struct reg *r; if (!arm->is_semihosting) return 0; if (is_arm7_9(target_to_arm7_9(target)) || is_armv7a(armv7a)) { uint32_t vbar = 0x00000000; if (arm->core_mode != ARM_MODE_SVC) return 0; if (is_armv7a(armv7a)) { struct arm_dpm *dpm = armv7a->arm.dpm; *retval = dpm->prepare(dpm); if (*retval == ERROR_OK) { *retval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRC(15, 0, 0, 12, 0, 0), &vbar); dpm->finish(dpm); if (*retval != ERROR_OK) return 1; } else { return 1; } } /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */ r = arm->pc; pc = buf_get_u32(r->value, 0, 32); if (pc != (vbar + 0x00000008) && pc != 0xffff0008) return 0; r = arm_reg_current(arm, 14); lr = buf_get_u32(r->value, 0, 32); /* Core-specific code should make sure SPSR is retrieved * when the above checks pass... */ if (!arm->spsr->valid) { LOG_ERROR("SPSR not valid!"); *retval = ERROR_FAIL; return 1; } spsr = buf_get_u32(arm->spsr->value, 0, 32); /* check instruction that triggered this trap */ if (spsr & (1 << 5)) { /* was in Thumb (or ThumbEE) mode */ uint8_t insn_buf[2]; uint16_t insn; *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u16(target, insn_buf); /* SVC 0xab */ if (insn != 0xDFAB) return 0; } else if (spsr & (1 << 24)) { /* was in Jazelle mode */ return 0; } else { /* was in ARM mode */ uint8_t insn_buf[4]; uint32_t insn; *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u32(target, insn_buf); /* SVC 0x123456 */ if (insn != 0xEF123456) return 0; } } else if (is_armv7m(target_to_armv7m(target))) { uint16_t insn; if (target->debug_reason != DBG_REASON_BREAKPOINT) return 0; r = arm->pc; pc = buf_get_u32(r->value, 0, 32); pc &= ~1; *retval = target_read_u16(target, pc, &insn); if (*retval != ERROR_OK) return 1; /* bkpt 0xAB */ if (insn != 0xBEAB) return 0; } else { LOG_ERROR("Unsupported semi-hosting Target"); return 0; } /* Perform semihosting if we are not waiting on a fileio * operation to complete. */ if (!arm->semihosting_hit_fileio) { *retval = do_semihosting(target); if (*retval != ERROR_OK) { LOG_ERROR("Failed semihosting operation"); return 0; } } /* Post result to target if we are not waiting on a fileio * operation to complete: */ if (!arm->semihosting_hit_fileio) { *retval = post_result(target); if (*retval != ERROR_OK) { LOG_ERROR("Failed to post semihosting result"); return 0; } *retval = target_resume(target, 1, 0, 0, 0); if (*retval != ERROR_OK) { LOG_ERROR("Failed to resume target"); return 0; } return 1; } return 0; }