[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openocd-development
Subject:    [OpenOCD-devel] [PATCH]: 60249bf target/arc: introduce initial set/unset bp functions
From:       gerrit () openocd ! org (gerrit)
Date:       2020-04-30 19:51:49
Message-ID: 20200430195149.8BEF34A02DA () mail ! openocd ! org
[Download RAW message or body]

This is an automated email from Gerrit.

Evgeniy Didin (didin@synopsys.com) just uploaded a new patch set to Gerrit, which you \
can find at http://openocd.zylin.com/5641

-- gerrit

commit 60249bfe35ec6666c307f4414480358e930bebe1
Author: Evgeniy Didin <didin@synopsys.com>
Date:   Mon Mar 16 20:38:00 2020 +0300

    target/arc: introduce initial set/unset bp functions
    
    With this patch we introduce set/unset breakpoints
    routines, which will be used in future.
    Currently soft breakpoints are only supported.
    
    Change-Id: Ib10ccdb02fd1606e4f407f012b1bee106a8ffccd
    Signed-off-by: Evgeniy Didin <didin@synopsys.com>

diff --git a/src/target/arc.c b/src/target/arc.c
index b4c5f5d..2e053d0 100644
--- a/src/target/arc.c
+++ b/src/target/arc.c
@@ -1342,6 +1342,133 @@ int arc_read_instruction_u32(struct target *target, uint32_t \
address,  return ERROR_OK;
 }
 
+static int arc_set_breakpoint(struct target *target,
+		struct breakpoint *breakpoint)
+{
+
+	if (breakpoint->set) {
+		LOG_WARNING("breakpoint already set");
+		return ERROR_OK;
+	}
+
+	if (breakpoint->type == BKPT_SOFT) {
+		LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
+
+		if (breakpoint->length == 4) {
+			uint32_t verify = 0xffffffff;
+
+			CHECK_RETVAL(target_read_buffer(target, breakpoint->address, breakpoint->length,
+					breakpoint->orig_instr));
+
+			CHECK_RETVAL(arc_write_instruction_u32(target, breakpoint->address,
+					ARC_SDBBP_32));
+
+			CHECK_RETVAL(arc_read_instruction_u32(target, breakpoint->address, &verify));
+
+			if (verify != ARC_SDBBP_32) {
+				LOG_ERROR("Unable to set 32bit breakpoint at address @0x%" TARGET_PRIxADDR
+						" - check that memory is read/writable", breakpoint->address);
+				return ERROR_FAIL;
+			}
+		} else if (breakpoint->length == 2) {
+			uint16_t verify = 0xffff;
+
+			CHECK_RETVAL(target_read_buffer(target, breakpoint->address, breakpoint->length,
+					breakpoint->orig_instr));
+			CHECK_RETVAL(target_write_u16(target, breakpoint->address, ARC_SDBBP_16));
+
+			CHECK_RETVAL(target_read_u16(target, breakpoint->address, &verify));
+			if (verify != ARC_SDBBP_16) {
+				LOG_ERROR("Unable to set 16bit breakpoint at address @0x%" TARGET_PRIxADDR
+						" - check that memory is read/writable", breakpoint->address);
+				return ERROR_FAIL;
+			}
+		} else {
+			LOG_ERROR("Invalid breakpoint length: target supports only 2 or 4");
+			return ERROR_COMMAND_ARGUMENT_INVALID;
+		}
+
+		breakpoint->set = 64; /* Any nice value but 0 */
+	} else if (breakpoint->type == BKPT_HARD) {
+		LOG_DEBUG("Hardware breakpoints are not supported yet!");
+		return ERROR_FAIL;
+	} else {
+		LOG_DEBUG("ERROR: setting unknown breakpoint type");
+		return ERROR_FAIL;
+	}
+	/* core instruction cache is now invalid,
+	 * TODO: add cache invalidation function here (when implemented). */
+
+	return ERROR_OK;
+}
+
+static int arc_unset_breakpoint(struct target *target,
+		struct breakpoint *breakpoint)
+{
+	int retval = ERROR_OK;
+
+	if (!breakpoint->set) {
+		LOG_WARNING("breakpoint not set");
+		return ERROR_OK;
+	}
+
+	if (breakpoint->type == BKPT_SOFT) {
+		/* restore original instruction (kept in target endianness) */
+		LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
+		if (breakpoint->length == 4) {
+			uint32_t current_instr;
+
+			/* check that user program has not modified breakpoint instruction */
+			CHECK_RETVAL(arc_read_instruction_u32(target, breakpoint->address, \
&current_instr)); +
+			if (current_instr == ARC_SDBBP_32) {
+				retval = target_write_buffer(target, breakpoint->address,
+					breakpoint->length, breakpoint->orig_instr);
+				if (retval != ERROR_OK)
+					return retval;
+			} else {
+				LOG_WARNING("Software breakpoint @0x%" TARGET_PRIxADDR
+					" has been overwritten outside of debugger."
+					"Expected: @0x%" PRIx32 ", got: @0x%" PRIx32,
+					breakpoint->address, ARC_SDBBP_32, current_instr);
+			}
+		} else if (breakpoint->length == 2) {
+			uint16_t current_instr;
+
+			/* check that user program has not modified breakpoint instruction */
+			CHECK_RETVAL(target_read_u16(target, breakpoint->address, &current_instr));
+			if (current_instr == ARC_SDBBP_16) {
+				retval = target_write_buffer(target, breakpoint->address,
+					breakpoint->length, breakpoint->orig_instr);
+				if (retval != ERROR_OK)
+					return retval;
+			} else {
+				LOG_WARNING("Software breakpoint @0x%" TARGET_PRIxADDR
+					" has been overwritten outside of debugger. "
+					"Expected: 0x%04" PRIx16 ", got: 0x%04" PRIx16,
+					breakpoint->address, ARC_SDBBP_16, current_instr);
+			}
+		} else {
+			LOG_ERROR("Invalid breakpoint length: target supports only 2 or 4");
+			return ERROR_COMMAND_ARGUMENT_INVALID;
+		}
+		breakpoint->set = 0;
+
+	}	else if (breakpoint->type == BKPT_HARD) {
+			LOG_WARNING("Hardware breakpoints are not supported yet!");
+			return ERROR_FAIL;
+	} else {
+			LOG_DEBUG("ERROR: unsetting unknown breakpoint type");
+			return ERROR_FAIL;
+	}
+
+	/* core instruction cache is now invalid.
+	 * TODO: Add cache invalidation function */
+
+	return retval;
+}
+
+
 /* ARC v2 target */
 struct target_type arcv2_target = {
 	.name = "arcv2",
diff --git a/src/target/arc.h b/src/target/arc.h
index d175738..0ce6d9c 100644
--- a/src/target/arc.h
+++ b/src/target/arc.h
@@ -49,6 +49,12 @@
 /* Limit reg_type/reg_type_field  name to 20 symbols */
 #define REG_TYPE_MAX_NAME_LENGTH	20
 
+/* ARC 32bits opcodes */
+#define ARC_SDBBP_32 0x256F003F  /* BRK */
+
+/* ARC 16bits opcodes */
+#define ARC_SDBBP_16 0x7FFF      /* BRK_S */
+
 struct arc_reg_bitfield {
 	struct reg_data_type_bitfield bitfield;
 	char name[REG_TYPE_MAX_NAME_LENGTH];

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic