diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 100615300..75d43fd8a 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -53,6 +53,8 @@ int arm926ejs_arch_state(struct target_s *target); int arm926ejs_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer); int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer); int arm926ejs_soft_reset_halt(struct target_s *target); +static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical); +static int arm926ejs_mmu(struct target_s *target, int *enabled); target_type_t arm926ejs_target = { @@ -89,7 +91,9 @@ target_type_t arm926ejs_target = .register_commands = arm926ejs_register_commands, .target_command = arm926ejs_target_command, .init_target = arm926ejs_init_target, - .quit = arm926ejs_quit + .quit = arm926ejs_quit, + .virt2phys = arm926ejs_virt2phys, + .mmu = arm926ejs_mmu }; @@ -899,3 +903,42 @@ int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu); } +static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical) +{ + int retval; + int type; + u32 cb; + int domain; + u32 ap; + + armv4_5_common_t *armv4_5; + arm7_9_common_t *arm7_9; + arm9tdmi_common_t *arm9tdmi; + arm926ejs_common_t *arm926ejs; + retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs); + if (retval != ERROR_OK) + { + return retval; + } + u32 ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap); + if (type == -1) + { + return ret; + } + *physical = ret; + return ERROR_OK; +} + +static int arm926ejs_mmu(struct target_s *target, int *enabled) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + arm926ejs_common_t *arm926ejs = armv4_5->arch_info; + + if (target->state != TARGET_HALTED) + { + ERROR("Target not halted"); + return ERROR_TARGET_INVALID; + } + *enabled = arm926ejs->armv4_5_mmu.mmu_enabled; + return ERROR_OK; +} diff --git a/src/target/xscale.c b/src/target/xscale.c index 4e1115218..bfa0f9f9f 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -631,7 +631,6 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) scan_field_t fields[3]; u8 field0_out = 0x0; - u8 field0_in = 0x0; u8 field0_check_value = 0x2; u8 field0_check_mask = 0x6; u8 field2 = 0x1; @@ -646,8 +645,11 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) fields[0].num_bits = 3; fields[0].out_value = &field0_out; fields[0].out_mask = NULL; - fields[0].in_value = &field0_in; - jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); + fields[0].in_handler = NULL; + if (!xscale->fast_memory_access) + { + jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL); + } fields[1].device = xscale->jtag_info.chain_pos; fields[1].num_bits = 32; @@ -666,18 +668,43 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) fields[2].out_value = &field2; fields[2].out_mask = NULL; fields[2].in_value = NULL; - jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); - - while (done_count++ < count) + fields[2].in_handler = NULL; + if (!xscale->fast_memory_access) { + jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL); + } + + if (size==4) + { + int endianness = target->endianness; + while (done_count++ < count) + { + if (endianness == TARGET_LITTLE_ENDIAN) + { + output[0]=buffer[0]; + output[1]=buffer[1]; + output[2]=buffer[2]; + output[3]=buffer[3]; + } else + { + output[0]=buffer[3]; + output[1]=buffer[2]; + output[2]=buffer[1]; + output[3]=buffer[0]; + } + jtag_add_dr_scan(3, fields, TAP_RTI, NULL); + buffer += size; + } + + } else + { + while (done_count++ < count) + { /* extract sized element from target-endian buffer, and put it * into little-endian output buffer */ switch (size) { - case 4: - buf_set_u32(output, 0, 32, target_buffer_get_u32(target, buffer)); - break; case 2: buf_set_u32(output, 0, 32, target_buffer_get_u16(target, buffer)); break; @@ -693,6 +720,8 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size) buffer += size; } + } + if ((retval = jtag_execute_queue()) != ERROR_OK) { ERROR("JTAG error while sending data to debug handler"); @@ -3101,6 +3130,8 @@ int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_p xscale->armv4_5_mmu.has_tiny_pages = 1; xscale->armv4_5_mmu.mmu_enabled = 0; + xscale->fast_memory_access = 0; + return ERROR_OK; } @@ -3700,6 +3731,41 @@ int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int a return ERROR_OK; } +int handle_xscale_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + target_t *target = get_current_target(cmd_ctx); + armv4_5_common_t *armv4_5; + xscale_common_t *xscale; + + if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK) + { + return ERROR_OK; + } + + if (argc == 1) + { + if (strcmp("enable", args[0]) == 0) + { + xscale->fast_memory_access = 1; + } + else if (strcmp("disable", args[0]) == 0) + { + xscale->fast_memory_access = 0; + } + else + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + } else if (argc!=0) + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + + command_print(cmd_ctx, "fast memory access is %s", (xscale->fast_memory_access) ? "enabled" : "disabled"); + + return ERROR_OK; +} + int xscale_register_commands(struct command_context_s *cmd_ctx) { command_t *xscale_cmd; @@ -3724,6 +3790,8 @@ int xscale_register_commands(struct command_context_s *cmd_ctx) COMMAND_EXEC, "load image from [base address]"); register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 [value]"); + register_command(cmd_ctx, xscale_cmd, "fast_memory_access", handle_xscale_fast_memory_access_command, + COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses "); armv4_5_register_commands(cmd_ctx); diff --git a/src/target/xscale.h b/src/target/xscale.h index 8d1c25cca..62285abb0 100644 --- a/src/target/xscale.h +++ b/src/target/xscale.h @@ -143,6 +143,8 @@ typedef struct xscale_common_s /* possible future enhancements that go beyond XScale common stuff */ void *arch_info; + + int fast_memory_access; } xscale_common_t; typedef struct xscale_reg_s