* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the *
- * Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
return ERROR_FAIL;
}
+ /* avoid filling log waiting for fileio reply */
+ if (arm->semihosting_hit_fileio)
+ return ERROR_OK;
+
LOG_USER("target halted in %s state due to %s, current mode: %s\n"
- "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s",
+ "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s%s",
arm_state_strings[arm->core_state],
debug_reason_name(target),
arm_mode_name(arm->core_mode),
buf_get_u32(arm->cpsr->value, 0, 32),
buf_get_u32(arm->pc->value, 0, 32),
- arm->is_semihosting ? ", semihosting" : "");
+ arm->is_semihosting ? ", semihosting" : "",
+ arm->is_semihosting_fileio ? " fileio" : "");
return ERROR_OK;
}
}
struct arm *arm = target_to_arm(target);
- uint32_t address;
+ target_addr_t address;
int count = 1;
int thumb = 0;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
/* FALL THROUGH */
case 1:
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
+ COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
if (address & 0x01) {
if (!thumb) {
command_print(CMD_CTX, "Disassemble as Thumb");
return ERROR_OK;
}
+COMMAND_HANDLER(handle_arm_semihosting_fileio_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+
+ if (target == NULL) {
+ LOG_ERROR("No target selected");
+ return ERROR_FAIL;
+ }
+
+ struct arm *arm = target_to_arm(target);
+
+ if (!is_arm(arm)) {
+ command_print(CMD_CTX, "current target isn't an ARM");
+ return ERROR_FAIL;
+ }
+
+ if (!arm->is_semihosting) {
+ command_print(CMD_CTX, "semihosting is not enabled");
+ return ERROR_FAIL;
+ }
+
+ if (CMD_ARGC > 0)
+ COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm->is_semihosting_fileio);
+
+ command_print(CMD_CTX, "semihosting fileio is %s",
+ arm->is_semihosting_fileio
+ ? "enabled" : "disabled");
+
+ return ERROR_OK;
+}
+
static const struct command_registration arm_exec_command_handlers[] = {
{
.name = "reg",
.usage = "['enable'|'disable']",
.help = "activate support for semihosting operations",
},
+ {
+ "semihosting_fileio",
+ .handler = handle_arm_semihosting_fileio_command,
+ .mode = COMMAND_EXEC,
+ .usage = "['enable'|'disable']",
+ .help = "activate support for semihosting fileio operations",
+ },
COMMAND_REGISTRATION_DONE
};
struct mem_param *mem_params,
int num_reg_params,
struct reg_param *reg_params,
- uint32_t entry_point,
- uint32_t exit_point,
+ target_addr_t entry_point,
+ target_addr_t exit_point,
int timeout_ms,
void *arch_info)
{
mem_params,
num_reg_params,
reg_params,
- entry_point,
- exit_point,
+ (uint32_t)entry_point,
+ (uint32_t)exit_point,
timeout_ms,
arch_info,
armv4_5_run_algorithm_completion);
*
*/
int arm_checksum_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *checksum)
+ target_addr_t address, uint32_t count, uint32_t *checksum)
{
struct working_area *crc_algorithm;
struct arm_algorithm arm_algo;
uint32_t i;
uint32_t exit_var = 0;
- /* see contrib/loaders/checksum/armv4_5_crc.s for src */
-
- static const uint32_t arm_crc_code[] = {
- 0xE1A02000, /* mov r2, r0 */
- 0xE3E00000, /* mov r0, #0xffffffff */
- 0xE1A03001, /* mov r3, r1 */
- 0xE3A04000, /* mov r4, #0 */
- 0xEA00000B, /* b ncomp */
- /* nbyte: */
- 0xE7D21004, /* ldrb r1, [r2, r4] */
- 0xE59F7030, /* ldr r7, CRC32XOR */
- 0xE0200C01, /* eor r0, r0, r1, asl 24 */
- 0xE3A05000, /* mov r5, #0 */
- /* loop: */
- 0xE3500000, /* cmp r0, #0 */
- 0xE1A06080, /* mov r6, r0, asl #1 */
- 0xE2855001, /* add r5, r5, #1 */
- 0xE1A00006, /* mov r0, r6 */
- 0xB0260007, /* eorlt r0, r6, r7 */
- 0xE3550008, /* cmp r5, #8 */
- 0x1AFFFFF8, /* bne loop */
- 0xE2844001, /* add r4, r4, #1 */
- /* ncomp: */
- 0xE1540003, /* cmp r4, r3 */
- 0x1AFFFFF1, /* bne nbyte */
- /* end: */
- 0xe1200070, /* bkpt #0 */
- /* CRC32XOR: */
- 0x04C11DB7 /* .word 0x04C11DB7 */
+ static const uint8_t arm_crc_code_le[] = {
+#include "../../contrib/loaders/checksum/armv4_5_crc.inc"
};
+ assert(sizeof(arm_crc_code_le) % 4 == 0);
+
retval = target_alloc_working_area(target,
- sizeof(arm_crc_code), &crc_algorithm);
+ sizeof(arm_crc_code_le), &crc_algorithm);
if (retval != ERROR_OK)
return retval;
/* convert code into a buffer in target endianness */
- for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
+ for (i = 0; i < ARRAY_SIZE(arm_crc_code_le) / 4; i++) {
retval = target_write_u32(target,
crc_algorithm->address + i * sizeof(uint32_t),
- arm_crc_code[i]);
+ le_to_h_u32(&arm_crc_code_le[i * 4]));
if (retval != ERROR_OK)
goto cleanup;
}
/* armv4 must exit using a hardware breakpoint */
if (arm->is_armv4)
- exit_var = crc_algorithm->address + sizeof(arm_crc_code) - 8;
+ exit_var = crc_algorithm->address + sizeof(arm_crc_code_le) - 8;
retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
crc_algorithm->address,
*
*/
int arm_blank_check_memory(struct target *target,
- uint32_t address, uint32_t count, uint32_t *blank)
+ target_addr_t address, uint32_t count, uint32_t *blank, uint8_t erased_value)
{
struct working_area *check_algorithm;
struct reg_param reg_params[3];
assert(sizeof(check_code_le) % 4 == 0);
+ if (erased_value != 0xff) {
+ LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for ARMv4/v5 targets",
+ erased_value);
+ return ERROR_FAIL;
+ }
+
/* make sure we have a working area */
retval = target_alloc_working_area(target,
sizeof(check_code_le), &check_algorithm);
buf_set_u32(reg_params[1].value, 0, 32, count);
init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT);
- buf_set_u32(reg_params[2].value, 0, 32, 0xff);
+ buf_set_u32(reg_params[2].value, 0, 32, erased_value);
/* armv4 must exit using a hardware breakpoint */
if (arm->is_armv4)