[Openocd-development] ADIv5 handling proposal

2009-10-13 Thread Yauheni Kaliuta
Hi!

What about implementing more generic access to ADIv5 and APB-AP?
I see it like this but what gurus have in mind?
From 5e3072d911f89184d159232c0f410c0252161a25 Mon Sep 17 00:00:00 2001
From: Yauheni Kaliuta y.kali...@gmail.com
Date: Tue, 13 Oct 2009 12:47:05 +0300
Subject: [PATCH] More abstract interface to access ADIv5 debug components

Analyse romtables and access using addresses from rom tables
---
 src/target/arm_adi_v5.c |  426 ++-
 src/target/arm_adi_v5.h |   62 +++-
 src/target/cortex_a8.c  |2 +-
 src/target/cortex_m3.c  |2 +-
 4 files changed, 478 insertions(+), 14 deletions(-)

diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 90423f4..0384422 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -244,7 +244,7 @@ int swjdp_transaction_endcheck(swjdp_common_t *swjdp)
 		/* Check power to debug regions */
 		if ((ctrlstat  0xf000) != 0xf000)
 		{
-			 ahbap_debugport_init(swjdp);
+			 adiv5_debugport_init(swjdp);
 		}
 		else
 		{
@@ -950,18 +950,343 @@ int mem_ap_read_buf_u8(swjdp_common_t *swjdp, uint8_t *buffer, int count, uint32
 	return retval;
 }
 
-int ahbap_debugport_init(swjdp_common_t *swjdp)
+static struct adiv5_component *new_adiv5_component(void)
 {
-	uint32_t idreg, romaddr, dummy;
+	struct adiv5_component *comp;
+
+	comp = malloc(sizeof(*comp));
+	if (comp == NULL)
+		return NULL;
+
+	memset(comp, 0, sizeof(*comp));
+
+	return comp;
+}
+
+static void free_adiv5_component(struct adiv5_component *comp)
+{
+	free(comp);
+}
+
+static void list_add_tail_comp(struct adiv5_component **comps,
+			   struct adiv5_component *comp)
+{
+	struct adiv5_component *tmp;
+
+	if (*comps == NULL)
+	{
+		*comps = comp;
+		return;
+	}
+
+	for (tmp = *comps; tmp-next; tmp = tmp-next)
+		;
+
+	tmp-next = comp;
+}
+
+static void free_list_comp(struct adiv5_component **comps)
+{
+	struct adiv5_component *tmp, *tmp1;
+
+	for (tmp = *comps; tmp;)
+	{
+		tmp1 = tmp;
+		tmp = tmp-next;
+
+		free_adiv5_component(tmp1);
+	}
+	*comps = NULL;
+}
+
+static void show_component(struct adiv5_component *comp)
+{
+	LOG_DEBUG(Component %s, base 0x%08x, start 0x%08x, class %x, part %x,
+		  comp-name, comp-base, comp-start, comp-class, comp-part_num);
+
+}
+
+static void show_ap_components(struct adiv5_ap *ap)
+{
+	struct adiv5_component *comp;
+
+	comp = ap-components;
+
+	for(; comp; comp = comp-next)
+		show_component(comp);
+}
+
+static void show_ap(struct adiv5_ap *ap)
+{
+
+	LOG_DEBUG(AP number %d, %s ID Register 0x% PRIx32
+		  , Debug ROM Address 0x% PRIx32 ,
+		  ap-num, ap-name, ap-id, ap-debugbase);
+	show_ap_components(ap);
+}
+
+static int romtable_read_entry(struct adiv5_ap *ap, uint32_t base, int bit32,
+			   int *offset, uint32_t *entry)
+{
+	uint32_t tmp;
+	int r;
+	int i;
+
+	r = adiv5_ap_read_atomic_u32(ap, (base  0xF000) | *offset, tmp);
+	if (r  0)
+		return ERROR_FAIL;
+
+	*offset += 4;
+
+	if (bit32) {
+		*entry = tmp;
+		return ERROR_OK;
+	}
+
+	*entry = tmp  0x00FF;
+	for (i = 1; i  4; i++)
+	{
+		r = adiv5_ap_read_atomic_u32(ap, (base  0xF000) | *offset, tmp);
+		if (r  0)
+			return ERROR_FAIL;
+		*entry |= (tmp  0x00FF)  (8 * i);
+		offset += 4;
+	}
+	return ERROR_OK;
+}
+
+static int scan_memap_component(struct adiv5_ap *ap,
+struct adiv5_component **comps,
+uint32_t base);
+
+static int scan_memap_romtable(struct adiv5_ap *ap,
+struct adiv5_component *comp,
+struct adiv5_component **out_comps,
+uint32_t base)
+{
+	uint32_t tmp, entry, compbase;
+	int bit32;
+
+	int r;
+	int offset = 0;
+
+	r = adiv5_ap_read_atomic_u32(ap, (base  0xF000), tmp);
+	if (r  0)
+		return ERROR_FAIL;
+
+	if (tmp == 0)
+	{
+		LOG_DEBUG(Blank first romtable entry?);
+		return ERROR_OK;
+	}
+
+	/* IHI 0031A 14.2 ROM Entries */
+	bit32 = tmp  (1  1);
+
+	r = romtable_read_entry(ap, base, bit32, offset, entry);
+	if (r  0)
+		return ERROR_FAIL;
+
+	comp-name = ROMTable entry;
+	comp-start = base;
+
+	for (; entry; r = romtable_read_entry(ap, base, bit32, offset, entry))
+	{
+		if (r  0)
+			return ERROR_FAIL;
+
+		if (! (entry  (1  0))) /* check presense */
+			continue;
+
+		compbase = (base  0xF000) + (entry  0xF000);
+		r = scan_memap_component(ap, out_comps, compbase);
+		if (r  0)
+			return ERROR_FAIL;
+	}
+
+	return ERROR_OK;
+}
+
+static int scan_memap_debugcomp(struct adiv5_ap *ap,
+struct adiv5_component *comp,
+ uint32_t base)
+{
+	comp-start = base - 0x1000 * (comp-pid[4]  4);
+	comp-name = Coresight component;
+
+	return ERROR_OK;
+}
+
+static int scan_memap_component(struct adiv5_ap *ap,
+struct adiv5_component **comps,
+uint32_t base)
+{
+	struct adiv5_component *comp, *tablecomps = NULL;
+	int i, r;
+
+	uint32_t tmp;
+
+	comp = new_adiv5_component();
+	if (comp == NULL)
+	{
+		LOG_ERROR(No memory);
+		return ERROR_FAIL;
+	}
+
+	comp-base = base;
+	comp-ap = ap;
+
+	for (i = 0; i  4; i++)
+	{
+		r = 

Re: [Openocd-development] ADIv5 handling proposal

2009-10-13 Thread Magnus Lundin
Without looking deeply (lot of other work the coming weeks) I think this
is good, but I would like it in a separate file(module). Called
adiv5_component, adiv5_debug or coresight_component ??

So the adiv5 code talks to the MEMAP registers but does not handle the
memory mapped components that are accessed through the the MEMAP. This
includes the content of the ROMTABLE.

Best regards,
Magnus

 Hi!

 What about implementing more generic access to ADIv5 and APB-AP?
 I see it like this but what gurus have in mind?
 ___
 Openocd-development mailing list
 Openocd-development@lists.berlios.de
 https://lists.berlios.de/mailman/listinfo/openocd-development




___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] ADIv5 handling proposal

2009-10-13 Thread Yauheni Kaliuta
Hi!

On Tue, Oct 13, 2009 at 1:28 PM, Magnus Lundin lun...@mlu.mine.nu wrote:
 Without looking deeply (lot of other work the coming weeks) I think this
 is good, but I would like it in a separate file(module). Called
 adiv5_component, adiv5_debug or coresight_component ??

 So the adiv5 code talks to the MEMAP registers but does not handle the
 memory mapped components that are accessed through the the MEMAP. This
 includes the content of the ROMTABLE.

Hmm, I do not think so.

1) access to components is a part of the same ADIv5 specification IHI
0031A (shouldn't it be called then swjdp.c like it was?)

2) if you want to have the layer independent of ap and components
layers, then there should be no links in that direction, only from
components towards DP. As a result the cpu layer, which uses both
components and AP accesses should be aware of scanning, handling
(storing/freeing...) scanning results and so on.

Or I misunderstood your point?


 Best regards,
 Magnus

 Hi!

 What about implementing more generic access to ADIv5 and APB-AP?
 I see it like this but what gurus have in mind?
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] ADIv5 handling proposal

2009-10-13 Thread Magnus Lundin
Yauheni Kaliuta wrote:
 Hi!

 On Tue, Oct 13, 2009 at 1:28 PM, Magnus Lundin lun...@mlu.mine.nu wrote:
   
 Without looking deeply (lot of other work the coming weeks) I think this
 is good, but I would like it in a separate file(module). Called
 adiv5_component, adiv5_debug or coresight_component ??

 So the adiv5 code talks to the MEMAP registers but does not handle the
 memory mapped components that are accessed through the the MEMAP. This
 includes the content of the ROMTABLE.
 

 Hmm, I do not think so.

 1) access to components is a part of the same ADIv5 specification IHI
 0031A (shouldn't it be called then swjdp.c like it was?)

   
I will expand my ideas a bit more.

No, IHI0031A does not contain the full component specification,  Arm ADI is
the debug interface, and it does not specify the componets. The 
specification contains
some  information about the rom table structure and peripherial 
identification registers.
These are specified in the CoreSight Architecture Specification ARM IHI 
0029B.
The actual debug comonents are specified in the ArmV7A TRM and Cortex A8 
TRM.

The importatnt distinction is that debug components are accesed through 
a memeory space,
from a target level using memory reads and writes to the relevant memory 
space/bus.
These components can also be accesed from the processor core over the 
memory bus.
The Arm debug interface is just the set of DP and AP registers that the 
(recommended)
external access implementation uses for access to this memory range. SWJ 
is the method
to talk to DP and AP through JTAG or SW access.

So the only target property that the component needs is the memory 
read/write, for the
components the rest of adiv5 is irrelevant. For a target that controls 
the components using a
swjdp interface it is also important to use the correct memap port if 
there are several, and
to make sure that direct memory access is used with no cache or virtual 
addressing handling.

Perhaps we need a taget level structure that describes a memory port, 
something that can
be read and written like memory.
The attributes would be
* valid memory range
* Physical/Virtual memory addressing
* Cache handling
* Pointer to a memory port driver that does the actual
For a Cortex A8 we would have one memory port for each SWJDP-MEMAP 
port for
direct physical access and one memory port for program memory that 
uses virtual
addressing whem MMU is active and also controls cache cleaning and 
invalidation.
We can have a separate memory port that accesses memory through the CPU.
Of course twe some work on how to create a user/tcl interface for this 
structure.
 
 
 2) if you want to have the layer independent of ap and components
 layers, then there should be no links in that direction, only from
 components towards DP. As a result the cpu layer, which uses both
 components and AP accesses should be aware of scanning, handling
 (storing/freeing...) scanning results and so on.
   
Well, the target layer must be aware that scanning should be done and 
that there are
components handled by the coresight component layer.  Components do 
their stuff
by reading and writing to memory.

Even if we let the componets use the swjdp structure to access memory, I 
think
it should be placed in a seperate file.

Best regards,
Magnus

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] ADIv5 handling proposal

2009-10-13 Thread David Brownell
On Tuesday 13 October 2009, Magnus Lundin wrote:
 The actual debug comonents are specified in the ArmV7A TRM and Cortex A8 
 TRM.

Not for Cortex M3 they aren't!  :)

(Which doesn't negate your point that the ADI arch doc doesn't
specify those components; it does highlight *why* the arch doc
isn't doing that.)

No comments on the rest of the discussion, for now; except the
obvious reminder not to do anything that makes trouble for CM3.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development