From 68b97e4b5c40a70b42dc2a970f1b90b9a3e9f13d Mon Sep 17 00:00:00 2001
From: ntfreak <ntfreak@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Thu, 17 Jan 2008 12:45:06 +0000
Subject: - add support for cortex_m3 target_request debugmsgs - target request
 handler disabled by default until a target has been registered

git-svn-id: svn://svn.berlios.de/openocd/trunk@259 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/target/arm7_9_common.c  |  3 ++
 src/target/cortex_m3.c      | 93 +++++++++++++++++++++++++++++++++++++++++----
 src/target/cortex_m3.h      |  8 ++--
 src/target/cortex_swjdp.c   | 20 ++++++++--
 src/target/target.c         |  3 +-
 src/target/target.h         |  1 +
 src/target/target_request.c | 10 +++++
 7 files changed, 123 insertions(+), 15 deletions(-)

(limited to 'src')

diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index ee814ba9..af3b7b32 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -638,6 +638,9 @@ int arm7_9_handle_target_request(void *priv)
 	arm_jtag_t *jtag_info = &arm7_9->jtag_info; 
 	reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL];
 	
+	if (!target->dbg_msg_enabled)
+		return ERROR_OK;
+		
 	if (target->state == TARGET_RUNNING)
 	{
 		/* read DCC control register */
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index 4b383274..279d986a 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -30,6 +30,7 @@
 
 #include "register.h"
 #include "target.h"
+#include "target_request.h"
 #include "log.h"
 #include "jtag.h"
 #include "arm_jtag.h"
@@ -50,7 +51,8 @@ int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *ta
 int cortex_m3_quit();
 int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value);
 int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value);
-		
+int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer);
+
 target_type_t cortexm3_target =
 {
 	.name = "cortex_m3",
@@ -58,8 +60,8 @@ target_type_t cortexm3_target =
 	.poll = cortex_m3_poll,
 	.arch_state = armv7m_arch_state,
 
-	.target_request_data = NULL,
-
+	.target_request_data = cortex_m3_target_request_data,
+	
 	.halt = cortex_m3_halt,
 	.resume = cortex_m3_resume,
 	.step = cortex_m3_step,
@@ -168,6 +170,8 @@ int cortex_m3_endreset_event(target_t *target)
 	ahbap_read_system_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
 	DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr);
 	
+	ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
+	
 	/* Enable debug requests */
 	ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
 	if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
@@ -216,15 +220,15 @@ int cortex_m3_examine_debug_reason(target_t *target)
 	if ((target->debug_reason != DBG_REASON_DBGRQ)
 		&& (target->debug_reason != DBG_REASON_SINGLESTEP))
 	{
-		/*  INCOPMPLETE */
+		/*  INCOMPLETE */
 
-		if (cortex_m3->nvic_dfsr & 0x2)
+		if (cortex_m3->nvic_dfsr & DFSR_BKPT)
 		{
 			target->debug_reason = DBG_REASON_BREAKPOINT;
-			if (cortex_m3->nvic_dfsr & 0x4)
+			if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
 				target->debug_reason = DBG_REASON_WPTANDBKPT;
 		}
-		else if (cortex_m3->nvic_dfsr & 0x4)
+		else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
 			target->debug_reason = DBG_REASON_WATCHPOINT;
 	}
 
@@ -701,6 +705,8 @@ int cortex_m3_assert_reset(target_t *target)
 	
 	DEBUG("target->state: %s", target_state_strings[target->state]);
 	
+	ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
+	
 	if (target->reset_mode == RESET_RUN)
 	{
 		/* Set/Clear C_MASKINTS in a separate operation */
@@ -1353,6 +1359,77 @@ int cortex_m3_quit()
 	return ERROR_OK;
 }
 
+int cortex_m3_dcc_read(swjdp_common_t *swjdp, u8 *value, u8 *ctrl)
+{
+	u16 dcrdr;
+	
+	ahbap_read_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
+	*ctrl = (u8)dcrdr;
+	*value = (u8)(dcrdr >> 8);
+	
+	DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
+	
+	/* write ack back to software dcc register
+	 * signify we have read data */
+	dcrdr = 0;
+	ahbap_write_buf_u16( swjdp, (u8*)&dcrdr, 1, DCB_DCRDR);
+	return ERROR_OK;
+}
+
+int cortex_m3_target_request_data(target_t *target, u32 size, u8 *buffer)
+{
+	armv7m_common_t *armv7m = target->arch_info;
+	cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+	swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+	u8 data;
+	u8 ctrl;
+	int i;
+	
+	for (i = 0; i < (size * 4); i++)
+	{
+		cortex_m3_dcc_read(swjdp, &data, &ctrl);
+		buffer[i] = data;
+	}
+	
+	return ERROR_OK;
+}
+
+int cortex_m3_handle_target_request(void *priv)
+{
+	target_t *target = priv;
+	armv7m_common_t *armv7m = target->arch_info;
+	cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+	swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+	
+	if (!target->dbg_msg_enabled)
+		return ERROR_OK;
+	
+	if (target->state == TARGET_RUNNING)
+	{
+		u8 data;
+		u8 ctrl;
+				
+		cortex_m3_dcc_read(swjdp, &data, &ctrl);
+		
+		/* check if we have data */
+		if (ctrl & (1<<0))
+		{
+			u32 request;
+			
+			request = data;
+			cortex_m3_dcc_read(swjdp, &data, &ctrl);
+			request |= (data << 8);
+			cortex_m3_dcc_read(swjdp, &data, &ctrl);
+			request |= (data << 16);
+			cortex_m3_dcc_read(swjdp, &data, &ctrl);
+			request |= (data << 24);
+			target_request(target, request);
+		}
+	}
+	
+	return ERROR_OK;
+}
+
 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
 {
 	armv7m_common_t *armv7m;
@@ -1387,6 +1464,8 @@ int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, in
 	armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
 //	armv7m->full_context = cortex_m3_full_context;
 	
+	target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
+	
 	return ERROR_OK;
 }
 
diff --git a/src/target/cortex_m3.h b/src/target/cortex_m3.h
index d51c4a49..7932dff8 100644
--- a/src/target/cortex_m3.h
+++ b/src/target/cortex_m3.h
@@ -101,10 +101,10 @@ extern char* cortex_m3_state_strings[];
 /* NVIC_SHCSR bits */
 #define SHCSR_BUSFAULTENA	(1<<17)
 /* NVIC_DFSR bits */
-#define DFSR_HALTED	1
-#define DFSR_BKPT	2
-#define DFSR_DWTTRAP	4
-#define DFSR_VCATCH	8
+#define DFSR_HALTED			1
+#define DFSR_BKPT			2
+#define DFSR_DWTTRAP		4
+#define DFSR_VCATCH			8
 
 #define FPCR_CODE 0
 #define FPCR_LITERAL 1
diff --git a/src/target/cortex_swjdp.c b/src/target/cortex_swjdp.c
index 85a2abc3..8cefcbfd 100644
--- a/src/target/cortex_swjdp.c
+++ b/src/target/cortex_swjdp.c
@@ -613,6 +613,11 @@ int ahbap_block_read_u32(swjdp_common_t *swjdp, u32 *buffer, int count, u32 addr
 
 int ahbap_read_coreregister_u32(swjdp_common_t *swjdp, u32 *value, int regnum)
 {
+	int retval;
+	u32 dcrdr;
+	
+	ahbap_read_system_atomic_u32(swjdp, DCB_DCRDR, &dcrdr);
+	
 	swjdp->trans_mode = TRANS_MODE_COMPOSITE;
 
 	/* ahbap_write_system_u32(swjdp, DCB_DCRSR, regnum); */
@@ -623,11 +628,18 @@ int ahbap_read_coreregister_u32(swjdp_common_t *swjdp, u32 *value, int regnum)
 	ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
 	ahbap_read_reg_u32(swjdp, AHBAP_BD0 | (DCB_DCRDR & 0xC), value );
 	
-	return swjdp_transaction_endcheck(swjdp);
+	retval = swjdp_transaction_endcheck(swjdp);
+	ahbap_write_system_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+	return retval;
 }
 
 int ahbap_write_coreregister_u32(swjdp_common_t *swjdp, u32 value, int regnum)
 {
+	int retval;
+	u32 dcrdr;
+	
+	ahbap_read_system_atomic_u32(swjdp, DCB_DCRDR, &dcrdr);
+	
 	swjdp->trans_mode = TRANS_MODE_COMPOSITE;
 	
 	/* ahbap_write_system_u32(swjdp, DCB_DCRDR, core_regs[i]); */
@@ -637,8 +649,10 @@ int ahbap_write_coreregister_u32(swjdp_common_t *swjdp, u32 value, int regnum)
 	/* ahbap_write_system_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR	); */
 	ahbap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
 	ahbap_write_reg_u32(swjdp, AHBAP_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR );
-
-	return swjdp_transaction_endcheck(swjdp);
+	
+	retval = swjdp_transaction_endcheck(swjdp);
+	ahbap_write_system_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
+	return retval;
 }
 
 int ahbap_debugport_init(swjdp_common_t *swjdp)
diff --git a/src/target/target.c b/src/target/target.c
index 01084512..47e3358c 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1065,7 +1065,8 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
 				(*last_target_p)->trace_info->trace_history_overflowed = 0;
 				
 				(*last_target_p)->dbgmsg = NULL;
-								
+				(*last_target_p)->dbg_msg_enabled = 0;
+				
 				(*last_target_p)->type->target_command(cmd_ctx, cmd, args, argc, *last_target_p);
 				
 				found = 1;
diff --git a/src/target/target.h b/src/target/target.h
index e15a2c8e..46aaa7ae 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -170,6 +170,7 @@ typedef struct target_s
 	struct watchpoint_s *watchpoints;	/* list of watchpoints */
 	struct trace_s *trace_info;			/* generic trace information */
 	struct debug_msg_receiver_s *dbgmsg;/* list of debug message receivers */
+	u32 dbg_msg_enabled;				/* debug message status */
 	void *arch_info;					/* architecture specific information */
 	struct target_s *next;				/* next target in list */
 } target_t;
diff --git a/src/target/target_request.c b/src/target/target_request.c
index 9dc58607..e23a0f7d 100644
--- a/src/target/target_request.c
+++ b/src/target/target_request.c
@@ -83,6 +83,8 @@ int target_hexmsg(target_t *target, int size, u32 length)
 		
 		if ((i%8 == 7) || (i == length - 1))
 		{
+			DEBUG("%s", line);
+			
 			while (c)
 			{
 				command_print(c->cmd_ctx, "%s", line);
@@ -153,6 +155,9 @@ int add_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
 	(*p)->cmd_ctx = cmd_ctx;
 	(*p)->next = NULL;
 	
+	/* enable callback */
+	target->dbg_msg_enabled = 1;
+	
 	return ERROR_OK;
 }
 
@@ -217,6 +222,11 @@ int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *targe
 			{
 				*p = next;
 				free(c);
+				if (*p == NULL)
+				{
+					/* disable callback */
+					target->dbg_msg_enabled = 0;
+				}
 				return ERROR_OK;
 			}
 			else
-- 
cgit v1.2.3