target/arc: introduce arc_read/write_instruction functions
[fw/openocd] / src / target / arc.c
index 396bf8a4742dcd4eccfe0eaea249426b770fe29e..5bc6134d0cd76da867182dadbea28923f5c95997 100644 (file)
@@ -1285,6 +1285,62 @@ static int arc_target_create(struct target *target, Jim_Interp *interp)
        return ERROR_OK;
 }
 
+/**
+ * Write 4-byte instruction to memory. This is like target_write_u32, however
+ * in case of little endian ARC instructions are in middle endian format, not
+ * little endian, so different type of conversion should be done.
+ * Middle endinan: instruction "aabbccdd", stored as "bbaaddcc"
+ */
+int arc_write_instruction_u32(struct target *target, uint32_t address,
+       uint32_t instr)
+{
+       uint8_t value_buf[4];
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
+
+       LOG_DEBUG("Address: 0x%08" PRIx32 ", value: 0x%08" PRIx32, address,
+               instr);
+
+       if (target->endianness == TARGET_LITTLE_ENDIAN)
+               arc_h_u32_to_me(value_buf, instr);
+       else
+               h_u32_to_be(value_buf, instr);
+
+       CHECK_RETVAL(target_write_buffer(target, address, 4, value_buf));
+
+       return ERROR_OK;
+}
+
+/**
+ * Read 32-bit instruction from memory. It is like target_read_u32, however in
+ * case of little endian ARC instructions are in middle endian format, so
+ * different type of conversion should be done.
+ */
+int arc_read_instruction_u32(struct target *target, uint32_t address,
+               uint32_t *value)
+{
+       uint8_t value_buf[4];
+
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_FAIL;
+       }
+
+       *value = 0;
+       CHECK_RETVAL(target_read_buffer(target, address, 4, value_buf));
+
+       if (target->endianness == TARGET_LITTLE_ENDIAN)
+               *value = arc_me_to_h_u32(value_buf);
+       else
+               *value = be_to_h_u32(value_buf);
+
+       LOG_DEBUG("Address: 0x%08" PRIx32 ", value: 0x%08" PRIx32, address,
+               *value);
+
+       return ERROR_OK;
+}
 
 /* Helper function which swiches core to single_step mode by
  * doing aux r/w operations.  */