target/arm_adi_v5: fix sync CSW cache on apreg write
[fw/openocd] / src / target / feroceon.c
index d3037c5433ade42e126698da5b57ca31bb8da282..6b14ab6a8679eadbb7e2fb24ba38588c7f5c19a7 100644 (file)
@@ -16,9 +16,7 @@
  *   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/>. *
  ***************************************************************************/
 
 /*
@@ -64,6 +62,13 @@ static int feroceon_assert_reset(struct target *target)
        struct arm7_9_common *arm7_9 = arm->arch_info;
        int ud = arm7_9->use_dbgrq;
 
+       /* TODO: apply hw reset signal in not examined state */
+       if (!(target_was_examined(target))) {
+               LOG_WARNING("Reset is not asserted because the target is not examined.");
+               LOG_WARNING("Use a reset button or power cycle the target.");
+               return ERROR_TARGET_NOT_EXAMINED;
+       }
+
        arm7_9->use_dbgrq = 0;
        if (target->reset_halt)
                arm7_9_halt(target);
@@ -88,7 +93,7 @@ static int feroceon_dummy_clock_out(struct arm_jtag *jtag_info, uint32_t instr)
        if (retval != ERROR_OK)
                return retval;
 
-       retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
+       retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
        if (retval != ERROR_OK)
                return retval;
 
@@ -455,7 +460,7 @@ static int feroceon_examine_debug_reason(struct target *target)
 }
 
 static int feroceon_bulk_write_memory(struct target *target,
-               uint32_t address, uint32_t count, const uint8_t *buffer)
+               target_addr_t address, uint32_t count, const uint8_t *buffer)
 {
        int retval;
        struct arm *arm = target->arch_info;
@@ -493,8 +498,11 @@ static int feroceon_bulk_write_memory(struct target *target,
 
        uint32_t dcc_size = sizeof(dcc_code);
 
+       if (address % 4 != 0)
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+
        if (!arm7_9->dcc_downloads)
-               return target_write_memory(target, address, 4, count, buffer);
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 
        /* regrab previously allocated working_area, or allocate a new one */
        if (!arm7_9->dcc_working_area) {
@@ -503,15 +511,15 @@ static int feroceon_bulk_write_memory(struct target *target,
                /* make sure we have a working area */
                if (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK) {
                        LOG_INFO("no working area available, falling back to memory writes");
-                       return target_write_memory(target, address, 4, count, buffer);
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
 
                /* copy target instructions to target endianness */
-               for (i = 0; i < dcc_size/4; i++)
-                       target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]);
+               target_buffer_set_u32_array(target, dcc_code_buf, ARRAY_SIZE(dcc_code), dcc_code);
 
-               /* write DCC code to working area */
-               retval = target_write_memory(target,
+               /* write DCC code to working area, using the non-optimized
+                * memory write to avoid ending up here again */
+               retval = arm7_9_write_memory_no_opt(target,
                                arm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf);
                if (retval != ERROR_OK)
                        return retval;
@@ -557,7 +565,7 @@ static int feroceon_bulk_write_memory(struct target *target,
                        buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);
                if (endaddress != address + count*4) {
                        LOG_ERROR("DCC write failed,"
-                               " expected end address 0x%08" PRIx32
+                               " expected end address 0x%08" TARGET_PRIxADDR
                                " got 0x%0" PRIx32 "",
                                address + count*4, endaddress);
                        retval = ERROR_FAIL;
@@ -627,6 +635,10 @@ static int feroceon_target_create(struct target *target, Jim_Interp *interp)
        arm926ejs_init_arch_info(target, arm926ejs, target->tap);
        feroceon_common_setup(target);
 
+       struct arm *arm = target->arch_info;
+       struct arm7_9_common *arm7_9 = arm->arch_info;
+       arm7_9->write_memory = arm926ejs_write_memory;
+
        /* the standard ARM926 methods don't always work (don't ask...) */
        arm926ejs->read_cp15 = feroceon_read_cp15;
        arm926ejs->write_cp15 = feroceon_write_cp15;
@@ -641,6 +653,10 @@ static int dragonite_target_create(struct target *target, Jim_Interp *interp)
        arm966e_init_arch_info(target, arm966e, target->tap);
        feroceon_common_setup(target);
 
+       struct arm *arm = target->arch_info;
+       struct arm7_9_common *arm7_9 = arm->arch_info;
+       arm7_9->write_memory = arm7_9_write_memory;
+
        return ERROR_OK;
 }
 
@@ -697,7 +713,7 @@ struct target_type feroceon_target = {
        .get_gdb_reg_list = arm_get_gdb_reg_list,
 
        .read_memory = arm7_9_read_memory,
-       .write_memory = arm926ejs_write_memory_opt,
+       .write_memory = arm7_9_write_memory_opt,
 
        .checksum_memory = arm_checksum_memory,
        .blank_check_memory = arm_blank_check_memory,