[Openocd-development] ADIv5 handling proposal
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
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
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
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
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