From a4a1de4dd1ec3e17fa7da0f8f82c4c2854d39d5d Mon Sep 17 00:00:00 2001 From: Øyvind Harboe Date: Wed, 21 Oct 2009 13:07:44 +0200 Subject: First cut at implementing software breakpoints for mmu read only memory --- src/target/arm926ejs.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 3c808021..5d7f1e30 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -2,6 +2,9 @@ * Copyright (C) 2007 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2009 by Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -681,8 +684,40 @@ int arm926ejs_write_memory(struct target_s *target, uint32_t address, uint32_t s arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; arm926ejs_common_t *arm926ejs = arm9tdmi->arch_info; - if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK) - return retval; + /* FIX!!!! this should be cleaned up and made much more general. The + * plan is to write up and test on arm926ejs specifically and + * then generalize and clean up afterwards. */ + if ((count == 1) && ((size==2) || (size==4))) + { + /* special case the handling of single word writes to bypass MMU + * to allow implementation of breakpoints in memory marked read only + * by MMU */ + if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) + { + /* flush and invalidate data cache + * + * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address + * + */ + retval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3); + if (retval != ERROR_OK) + return retval; + } + + uint32_t pa; + retval = target->type->virt2phys(target, address, &pa); + if (retval != ERROR_OK) + return retval; + + /* write directly to physical memory bypassing any read only MMU bits, etc. */ + retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer); + if (retval != ERROR_OK) + return retval; + } else + { + if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK) + return retval; + } /* If ICache is enabled, we have to invalidate affected ICache lines * the DCache is forced to write-through, so we don't have to clean it here -- cgit v1.2.3 From e895246966e3aa6e78f9d0816c72c6fbb9160122 Mon Sep 17 00:00:00 2001 From: Øyvind Harboe Date: Wed, 21 Oct 2009 13:10:32 +0200 Subject: Retire obsolete and superfluous implementations of virt2phys in each target. This is done in a polymorphic implementation in target.c --- src/target/arm720t.c | 28 ---------------------------- src/target/arm920t.c | 28 ---------------------------- src/target/arm926ejs.c | 28 ---------------------------- src/target/armv4_5_mmu.c | 45 --------------------------------------------- 4 files changed, 129 deletions(-) (limited to 'src') diff --git a/src/target/arm720t.c b/src/target/arm720t.c index a5916aae..2ebd83a3 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -34,7 +34,6 @@ int arm720t_register_commands(struct command_context_s *cmd_ctx); int arm720t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int arm720t_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm720t_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm720t_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -487,7 +486,6 @@ int arm720t_register_commands(struct command_context_s *cmd_ctx) arm720t_cmd = register_command(cmd_ctx, NULL, "arm720t", NULL, COMMAND_ANY, "arm720t specific commands"); register_command(cmd_ctx, arm720t_cmd, "cp15", arm720t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register [value]"); - register_command(cmd_ctx, arm720t_cmd, "virt2phys", arm720t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa "); register_command(cmd_ctx, arm720t_cmd, "mdw_phys", arm720t_handle_md_phys_command, COMMAND_EXEC, "display memory words [count]"); register_command(cmd_ctx, arm720t_cmd, "mdh_phys", arm720t_handle_md_phys_command, COMMAND_EXEC, "display memory half-words [count]"); @@ -560,32 +558,6 @@ int arm720t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, ch return ERROR_OK; } -int arm720t_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc) -{ - target_t *target = get_current_target(cmd_ctx); - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; - arm7tdmi_common_t *arm7tdmi; - arm720t_common_t *arm720t; - arm_jtag_t *jtag_info; - - if (arm720t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm7tdmi, &arm720t) != ERROR_OK) - { - command_print(cmd_ctx, "current target isn't an ARM720t target"); - return ERROR_OK; - } - - jtag_info = &arm7_9->jtag_info; - - if (target->state != TARGET_HALTED) - { - command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd); - return ERROR_OK; - } - - return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm720t->armv4_5_mmu); -} - int arm720t_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 3d119bd6..5ade82bc 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -33,7 +33,6 @@ /* cli handling */ int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int arm920t_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm920t_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm920t_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -700,7 +699,6 @@ int arm920t_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, arm920t_cmd, "cp15", arm920t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register [value]"); register_command(cmd_ctx, arm920t_cmd, "cp15i", arm920t_handle_cp15i_command, COMMAND_EXEC, "display/modify cp15 (interpreted access) [value] [address]"); register_command(cmd_ctx, arm920t_cmd, "cache_info", arm920t_handle_cache_info_command, COMMAND_EXEC, "display information about target caches"); - register_command(cmd_ctx, arm920t_cmd, "virt2phys", arm920t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa "); register_command(cmd_ctx, arm920t_cmd, "mdw_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory words [count]"); register_command(cmd_ctx, arm920t_cmd, "mdh_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory half-words [count]"); @@ -1402,32 +1400,6 @@ int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *c return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache); } -int arm920t_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc) -{ - target_t *target = get_current_target(cmd_ctx); - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; - arm9tdmi_common_t *arm9tdmi; - arm920t_common_t *arm920t; - arm_jtag_t *jtag_info; - - if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK) - { - command_print(cmd_ctx, "current target isn't an ARM920t target"); - return ERROR_OK; - } - - jtag_info = &arm7_9->jtag_info; - - if (target->state != TARGET_HALTED) - { - command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd); - return ERROR_OK; - } - - return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu); -} - int arm920t_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index 5d7f1e30..c3c5097a 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -36,7 +36,6 @@ /* cli handling */ int arm926ejs_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm926ejs_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int arm926ejs_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm926ejs_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int arm926ejs_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -810,7 +809,6 @@ int arm926ejs_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, arm926ejs_cmd, "cp15", arm926ejs_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register [value]"); register_command(cmd_ctx, arm926ejs_cmd, "cache_info", arm926ejs_handle_cache_info_command, COMMAND_EXEC, "display information about target caches"); - register_command(cmd_ctx, arm926ejs_cmd, "virt2phys", arm926ejs_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa "); register_command(cmd_ctx, arm926ejs_cmd, "mdw_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory words [count]"); register_command(cmd_ctx, arm926ejs_cmd, "mdh_phys", arm926ejs_handle_md_phys_command, COMMAND_EXEC, "display memory half-words [count]"); @@ -905,32 +903,6 @@ int arm926ejs_handle_cache_info_command(struct command_context_s *cmd_ctx, char return armv4_5_handle_cache_info_command(cmd_ctx, &arm926ejs->armv4_5_mmu.armv4_5_cache); } -int arm926ejs_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc) -{ - target_t *target = get_current_target(cmd_ctx); - armv4_5_common_t *armv4_5; - arm7_9_common_t *arm7_9; - arm9tdmi_common_t *arm9tdmi; - arm926ejs_common_t *arm926ejs; - arm_jtag_t *jtag_info; - - if (arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs) != ERROR_OK) - { - command_print(cmd_ctx, "current target isn't an ARM926EJ-S target"); - return ERROR_OK; - } - - jtag_info = &arm7_9->jtag_info; - - if (target->state != TARGET_HALTED) - { - command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd); - return ERROR_OK; - } - - return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu); -} - int arm926ejs_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc) { target_t *target = get_current_target(cmd_ctx); diff --git a/src/target/armv4_5_mmu.c b/src/target/armv4_5_mmu.c index e64021e8..33800122 100644 --- a/src/target/armv4_5_mmu.c +++ b/src/target/armv4_5_mmu.c @@ -170,51 +170,6 @@ int armv4_5_mmu_write_physical(target_t *target, armv4_5_mmu_common_t *armv4_5_m return retval; } -int armv4_5_mmu_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc, target_t *target, armv4_5_mmu_common_t *armv4_5_mmu) -{ - uint32_t va; - uint32_t pa; - int type; - uint32_t cb; - int domain; - uint32_t ap; - - if (target->state != TARGET_HALTED) - { - command_print(cmd_ctx, "target must be stopped for \"virt2phys\" command"); - return ERROR_OK; - } - - if (argc == 0) - { - command_print(cmd_ctx, "usage: virt2phys "); - return ERROR_OK; - } - - if (argc == 1) - { - va = strtoul(args[0], NULL, 0); - pa = armv4_5_mmu_translate_va(target, armv4_5_mmu, va, &type, &cb, &domain, &ap); - if (type == -1) - { - switch (pa) - { - case ERROR_TARGET_TRANSLATION_FAULT: - command_print(cmd_ctx, "no valid translation for 0x%8.8" PRIx32 "", va); - break; - default: - command_print(cmd_ctx, "unknown translation error"); - } - return ERROR_OK; - } - - command_print(cmd_ctx, "0x%8.8" PRIx32 " -> 0x%8.8" PRIx32 ", type: %s, cb: %i, domain: %d, ap: %2.2x", - va, pa, armv4_5_mmu_page_type_names[type], (int)cb, domain, (int)ap); - } - - return ERROR_OK; -} - int armv4_5_mmu_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc, target_t *target, armv4_5_mmu_common_t *armv4_5_mmu) { int count = 1; -- cgit v1.2.3