Hey,

today Matt Hsu and me sat together to look into why OpenOCD does not work on 
the beagle board. We have found and fixed some issues with the code, it should 
make it more robust and we have fixed the root cause for us.

cortex_a8_dap_read_coreregister_u32 only returned 0x0 for the registers, this 
was due the instruction written to the ITR register was not executed. We will 
have to enable bit 13 of DSCR to enable the execution of ITR.

The attached patch series fixes the problem for me and matt. The patches were 
done in teamwork..

regards
        z.


From 7a5bd75f349b76d86a720ca37b58cf62985c35ef Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:49:39 +0200
Subject: [PATCH 7/7] cortex-a8: Wait for the CPU to be halted/started

With DCCR we are asking the CPU to halt, we should wait until
the CPU has halted before proceeding with the operation.

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/cortex_a8.c |   28 +++++++++++++++++++++++-----
 1 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index 9efd4e4..829bf3d 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -413,6 +413,8 @@ int cortex_a8_poll(target_t *target)
 int cortex_a8_halt(target_t *target)
 {
 	int retval = ERROR_OK;
+	uint32_t dscr;
+
 	/* get pointers to arch-specific information */
 	armv4_5_common_t *armv4_5 = target->arch_info;
 	armv7a_common_t *armv7a = armv4_5->arch_info;
@@ -421,13 +423,25 @@ int cortex_a8_halt(target_t *target)
 	uint8_t saved_apsel = dap_ap_get_select(swjdp);
 	dap_ap_select(swjdp, swjdp_debugap);
 
-	/* Perhaps we should do a read-modify-write here */
+	/*
+	 * Tell the core to be halted by writing DRCR with 0x1
+	 * and then wait for the core to be halted.
+	 */
 	retval = mem_ap_write_atomic_u32(swjdp,
 			OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x1);
 
+	if (retval != ERROR_OK)
+		goto out;
+
+	do {
+		mem_ap_read_atomic_u32(swjdp,
+			OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+	} while ((dscr & (1 << 0)) == 0);
+
 	target->debug_reason = DBG_REASON_DBGRQ;
-	dap_ap_select(swjdp, saved_apsel);
 
+out:
+	dap_ap_select(swjdp, saved_apsel);
 	return retval;
 }
 
@@ -441,7 +455,7 @@ int cortex_a8_resume(struct target_s *target, int current,
 	swjdp_common_t *swjdp = &armv7a->swjdp_info;
 
 //	breakpoint_t *breakpoint = NULL;
-	uint32_t resume_pc;
+	uint32_t resume_pc, dscr;
 
 	uint8_t saved_apsel = dap_ap_get_select(swjdp);
 	dap_ap_select(swjdp, swjdp_debugap);
@@ -515,10 +529,14 @@ int cortex_a8_resume(struct target_s *target, int current,
 	}
 
 #endif
-	/* Restart core */
-	/* Perhaps we should do a read-modify-write here */
+	/* Restart core and wait for it to be started */
 	mem_ap_write_atomic_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DRCR, 0x2);
 
+	do {
+		mem_ap_read_atomic_u32(swjdp,
+			OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+	} while ((dscr & (1 << 1)) == 0);
+
 	target->debug_reason = DBG_REASON_NOTHALTED;
 	target->state = TARGET_RUNNING;
 
-- 
1.6.3.3

From 3dec0999159dffed678a6fc0436831152c9af97d Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:32:54 +0200
Subject: [PATCH 2/7] cortex-a8: Wait until the DTRRX is full before reading it

Wait for the DTRRX to be full before reading it. Remove the
trans_mode change as it is done in the mem_ap_read_atomic_u32
function.

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/cortex_a8.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index dcf246f..fd80723 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -259,14 +259,13 @@ int cortex_a8_dap_read_coreregister_u32(target_t *target,
 {
 	int retval = ERROR_OK;
 	uint8_t reg = regnum&0xFF;
+	uint32_t dscr;
 
 	/* get pointers to arch-specific information */
 	armv4_5_common_t *armv4_5 = target->arch_info;
 	armv7a_common_t *armv7a = armv4_5->arch_info;
 	swjdp_common_t *swjdp = &armv7a->swjdp_info;
 
-	swjdp->trans_mode = TRANS_MODE_COMPOSITE;
-
 	if (reg > 16)
 		return retval;
 
@@ -286,10 +285,16 @@ int cortex_a8_dap_read_coreregister_u32(target_t *target,
 		cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
 	}
 
-	/* Read DCCTX */
+	/* Read DTRRTX */
+	do
+	{
+		retval = mem_ap_read_atomic_u32(swjdp,
+				OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+	}
+	while ((dscr & (1 << 29)) == 0); /* Wait for DTRRXfull */
+
 	retval = mem_ap_read_atomic_u32(swjdp,
 			OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
-//	retval = mem_ap_read_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_DTRTX, value);
 
 	return retval;
 }
-- 
1.6.3.3

From d88ef91ca5309507711bf64d9735fb3d5b29619d Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:37:46 +0200
Subject: [PATCH 4/7] cortex-a8: Copy some more registers from the documentation

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/cortex_a8.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/target/cortex_a8.h b/src/target/cortex_a8.h
index c1610d5..bb57b13 100644
--- a/src/target/cortex_a8.h
+++ b/src/target/cortex_a8.h
@@ -42,6 +42,7 @@ extern char* cortex_a8_state_strings[];
 /* Debug Control Block */
 #define CPUDBG_DIDR		0x000
 #define CPUDBG_WFAR		0x018
+#define CPUDBG_VCR	0x01C
 #define CPUDBG_DSCCR	0x028
 #define CPUDBG_DTRRX	0x080
 #define CPUDBG_ITR	0x084
@@ -52,6 +53,13 @@ extern char* cortex_a8_state_strings[];
 #define CPUDBG_BCR_BASE	0x140
 #define CPUDBG_WVR_BASE	0x180
 
+#define CPUDBG_OSLAR	0x300
+#define CPUDBG_OSLSR	0x304
+#define CPUDBG_OSSRR	0x308
+
+#define CPUDBG_PRCR	0x310
+#define CPUDBG_PRSR	0x314
+
 #define CPUDBG_CPUID	0xD00
 #define CPUDBG_CTYPR	0xD04
 #define CPUDBG_TTYPR	0xD0C
-- 
1.6.3.3

From 894f592b4ceb2e0be8ce29f96e2575e54d012971 Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:30:21 +0200
Subject: [PATCH 1/7] cortex-a8: Wait for the previous instruction to finish

Before executing a new instruction wait for the previous
instruction to be finished. This comes from the pseudo code
of the cortex a8 trm.

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/cortex_a8.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index 84ace67..dcf246f 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -161,7 +161,15 @@ int cortex_a8_exec_opcode(target_t *target, uint32_t opcode)
 	swjdp_common_t *swjdp = &armv7a->swjdp_info;
 
 	LOG_DEBUG("exec opcode 0x%08" PRIx32, opcode);
+	do
+	{
+		retvalue = mem_ap_read_atomic_u32(swjdp,
+				OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+	}
+	while ((dscr & (1 << 24)) == 0); /* Wait for InstrCompl bit to be set */
+
 	mem_ap_write_u32(swjdp, OMAP3530_DEBUG_BASE + CPUDBG_ITR, opcode);
+
 	do
 	{
 		retvalue = mem_ap_read_atomic_u32(swjdp,
-- 
1.6.3.3

From 7211c3183eca42ac8bed33023a57e6ef4fb8ee62 Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:34:46 +0200
Subject: [PATCH 3/7] cortex-a8: Enable the execution from the ITR

cortex_a8_exec_opcode is writing the ARM instruction into
the ITR register but it will only be executed when the DSCR[13]
bit is set. The documentation is a bit weird as it classifies
the DSCR as read-only but the pseudo code is writing to it as
well. This is working on a beagleboard.

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/cortex_a8.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index fd80723..9585b35 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -546,7 +546,7 @@ int cortex_a8_resume(struct target_s *target, int current,
 int cortex_a8_debug_entry(target_t *target)
 {
 	int i;
-	uint32_t regfile[16], pc, cpsr;
+	uint32_t regfile[16], pc, cpsr, dscr;
 	int retval = ERROR_OK;
 	working_area_t *regfile_working_area = NULL;
 
@@ -561,6 +561,14 @@ int cortex_a8_debug_entry(target_t *target)
 
 	LOG_DEBUG("dscr = 0x%08" PRIx32, cortex_a8->cpudbg_dscr);
 
+	/* Enable the ITR execution once we are in debug mode */
+	mem_ap_read_atomic_u32(swjdp,
+				OMAP3530_DEBUG_BASE + CPUDBG_DSCR, &dscr);
+	dscr |= (1 << 13);
+	retval = mem_ap_write_atomic_u32(swjdp,
+			OMAP3530_DEBUG_BASE + CPUDBG_DSCR, dscr);
+
+
 	/* Examine debug reason */
 	switch ((cortex_a8->cpudbg_dscr >> 2)&0xF)
 	{
-- 
1.6.3.3

From 9ae587086785a0825568651fa7997652f0528368 Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:39:56 +0200
Subject: [PATCH 5/7] cortex-a8: Move the dap_select for memoryap into the memory branch

Only dap_ap_select when we are going to do a memory access
in the fast reg case.

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/cortex_a8.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index 9585b35..9efd4e4 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -589,7 +589,6 @@ int cortex_a8_debug_entry(target_t *target)
 	}
 
 	/* Examine target state and mode */
-	dap_ap_select(swjdp, swjdp_memoryap);
 	if (cortex_a8->fast_reg_read)
 		target_alloc_working_area(target, 64, &regfile_working_area);
 
@@ -602,6 +601,7 @@ int cortex_a8_debug_entry(target_t *target)
 	}
 	else
 	{
+		dap_ap_select(swjdp, swjdp_memoryap);
 		cortex_a8_read_regs_through_mem(target,
 				regfile_working_area->address, regfile);
 		dap_ap_select(swjdp, swjdp_memoryap);
-- 
1.6.3.3

From 222025df25349af193cc206f77e4caf5aeba8b4f Mon Sep 17 00:00:00 2001
From: Holger Hans Peter Freyther <[email protected]>
Date: Wed, 26 Aug 2009 14:47:51 +0200
Subject: [PATCH 6/7] armv7a: Print the value that the method didn't like

Signed-off-by: Matt Hsu <[email protected]>
Signed-off-by: Holger Hans Peter Freyther <[email protected]>
---
 src/target/armv7a.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/target/armv7a.h b/src/target/armv7a.h
index d92e5bc..12b6625 100644
--- a/src/target/armv7a.h
+++ b/src/target/armv7a.h
@@ -148,7 +148,7 @@ static inline int armv7a_mode_to_number(enum armv7a_mode mode)
 		case ARMV7A_MODE_MON: return 7; break;
 		case ARMV7A_MODE_ANY: return 0; break;	/* map MODE_ANY to user mode */
 		default:
-			LOG_ERROR("invalid mode value encountered");
+			LOG_ERROR("invalid mode value encountered, val %d", mode);
 			return -1;
 	}
 }
-- 
1.6.3.3

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to