Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible bug in CPU identification #1712

Open
jharwell opened this issue Jan 3, 2024 · 25 comments
Open

Possible bug in CPU identification #1712

jharwell opened this issue Jan 3, 2024 · 25 comments

Comments

@jharwell
Copy link

jharwell commented Jan 3, 2024

In adiv5.c, there is the following code on the latest tip:

595 │                 if (recursion == 0) {                                                                                                                                                                       
 596 │                   DEBUG_INFO("%s designer code: 0x%x partno: 0x%x\n", __FUNCTION__, designer_code, part_number);                                                                                            
 597 │                         ap->designer_code = designer_code;                                                                                                                                                  
 598 │                         ap->partno = part_number;                                                                                                                                                           
 599 │                                                                                                                                                                                                             
 600 │                         if (ap->designer_code == JEP106_MANUFACTURER_ATMEL && ap->partno == 0xcd0U) {                                                                                                       
 601 │                                 uint32_t ctrlstat = adiv5_mem_read32(ap, SAMX5X_DSU_CTRLSTAT);                                                                                                              
 602 │                                 if (ctrlstat & SAMX5X_STATUSB_PROT) {                                                                                                                                       
 603 │                                         /* A protected SAMx5x device is found.                                                                                                                              
 604 │                                          * Handle it here, as access only to limited memory region                                                                                                          
 605 │                                          * is allowed                                                                                                                                                       
 606 │                                          */                                                                                                                                                                 
 607 │                                         cortexm_probe(ap);                                                                                                                                                  
 608 │                                         return;                                                                                                                                                             
 609 │                                 }                                                                                                                                                                           
 610 │                         }                        

which effectively results (I think) in the ap->designer_code and ap->partno being set to whatever is parsed out of the read PIDR register for the first thing that is probed on the DAP bus. For a cortex M7 system I'm working on, the actual CPU shows up as the 4th thing to be probed, resulting in 0 for the designer code and partno when cortexm_probe() is called. In that function we have:

 522 │         if (ap->dp->version >= 2 && ap->dp->target_designer_code != 0) {                                                                                                                                    
 523 │                 /* Use TARGETID register to identify target */                                                                                                                                              
 524 │                 target->designer_code = ap->dp->target_designer_code;                                                                                                                                       
 525 │                 target->part_id = ap->dp->target_partno;                                                                                                                                                    
 526 │         } else {                                                                                                                                                                                            
 527 │                 /* Use AP DESIGNER and AP PARTNO to identify target */                                                                                                                                      
 528 │                 target->designer_code = ap->designer_code;                                                                                                                                                  
 529 │                 target->part_id = ap->partno;                                                                                                                                                               
 530 │         }    

and it just so happens that ap->dp->version is 1 for our M7, which results in a target->designer_code and target->part_id of 0, making it impossible to call the correct probe function without inserting a hacky 0 case in the big switch() later in the function. Is this a bug, or am I not understanding something/using things correctly?

FWIW, removing the above lines and inserting the following later in the cortexm_probe() function fixes the error and doesn't cause obvious problems, but I have no idea if it would break things elsewhere:

                                                                                                                                                                                     
 693 │                           ap->designer_code = designer_code;                                                                                                                                                
 694 │                           ap->partno = part_number;                                                                                                                                                         
 695 │                                                                                                                                                                                                             
 696 │                           if (ap->designer_code == JEP106_MANUFACTURER_ATMEL && ap->partno == 0xcd0U) {                                                                                                     
 697 │                             uint32_t ctrlstat = adiv5_mem_read32(ap, SAMX5X_DSU_CTRLSTAT);                                                                                                                  
 698 │                             if (ctrlstat & SAMX5X_STATUSB_PROT) {                                                                                                                                           
 699 │                               /* A protected SAMx5x device is found.                                                                                                                                        
 700 │                                * Handle it here, as access only to limited memory region                                                                                                                    
 701 │                                * is allowed                                                                                                                                                                 
 702 │                                */                                                                                                                                                                           
 703 │                               cortexm_probe(ap);                                                                                                                                                            
 704 │                               return;                                                                                                                                                                       
 705 │                             }                                                                                                                                                                               
 706 │                           }                                                                                                                                                                                 
 707 │                         switch (arm_component_lut[i].arch) {                                                                   
@dragonmux
Copy link
Member

Hello fellow bat user! So, in relation to your analysis.. ROM tables are structured in a nested manner and to accommodate how that works the ap's manufacturer information must necessarily be the outer most table's information (we can only use on table per AP for this information, it must stay constant through discovery) - however, you make a good point about the inner table layer's information when there are multiple cores attached to an AP.

For Cortex-M parts, this isn't actually normally a problem in any way because only one part is allowed per AP due to the required memory layout on the debug bus (one AP is one debug bus), so the outer most table for that AP on a conforming implementation has the core's information and that's fine (inner tables should be the ARM-specific information such as what the core type is. This will always have designer_code == JEP106_MANUFACTUER_ARM, and the part_number will always be a core ID value such as 4c4 (M4), 4c7 (M7), 4c0 (M0), etc).

For Cortex-A/R parts this is more of a problem (multiple cores per AP are ok), though a very similar thing happens with the sub-table designer and part codes - which is why this logic is how it is. For most parts it's the outer-most table that's Vendor-provided and defines their ID information.

What we suspect you've actually hit here is that for DPv2 parts, we want to use the DP's information (from TARGETID), and it's this which is causing problems for you.

NB: The AP information is from the ROM tables PIDR not the DP PIDR register. DP PIDR only exists for DPv2+ parts and is used only in the ap->dp path - it's the TARGETID register that matters though here.

Here are some example tables from some parts on our desk showing how this generally winds up working:

ROM: Table BASE=0xe00ff000 SYSMEM=0x00000001, Manufacturer 020 Partno 411
0 0xe000e000: Generic IP component - Cortex-M4 SCS (System Control Space) (PIDR = 0x00000004000bb00c DEVTYPE = 0x00 ARCHID = 0x0000)
-> cortexm_probe
CPUID 0x410fc241 (M4 var 0 rev 1)
Calling stm32f1_probe
Calling stm32f4_probe
1 0xe0001000: Generic IP component - Cortex-M3 DWT (Data Watchpoint and Trace) (PIDR = 0x00000004003bb002 DEVTYPE = 0x00 ARCHID = 0x0000)
2 0xe0002000: Generic IP component - Cortex-M3 FBP (Flash Patch and Breakpoint) (PIDR = 0x00000004002bb003 DEVTYPE = 0x00 ARCHID = 0x0000)
3 0xe0000000: Generic IP component - Cortex-M3 ITM (Instrumentation Trace Module) (PIDR = 0x00000004003bb001 DEVTYPE = 0x00 ARCHID = 0x0000)
4 0xe0040000: Debug component - Cortex-M4 TPIU (Trace Port Interface Unit) (PIDR = 0x00000004000bb9a1 DEVTYPE = 0x11 ARCHID = 0x0000)
5 0xe0041000: Debug component - Cortex-M4 ETM (Embedded Trace) (PIDR = 0x00000004000bb925 DEVTYPE = 0x13 ARCHID = 0x0000)
ROM: Table END
DP DPIDR 0x0bc12477 (v2 MINDP rev0) designer 0x43b partno 0xbc
TARGETID 0x01002927 designer 0x913 partno 0x1002
[...]
ROM: Table BASE=0xe00ff000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c0
0 0xe000e000: Generic IP component - Cortex-M0 SCS (System Control Space) (PIDR = 0x00000004000bb008 DEVTYPE = 0x00 ARCHID = 0x0000)
-> cortexm_probe
CPUID 0x410cc601 (M0+ var 0 rev 1)
Calling rp_probe
Old Bootrom Version 1!
1 0xe0001000: Generic IP component - Cortex-M0 DWT (Data Watchpoint and Trace) (PIDR = 0x00000004000bb00a DEVTYPE = 0x00 ARCHID = 0x0000)
2 0xe0002000: Generic IP component - Cortex-M0 BPU (Breakpoint Unit) (PIDR = 0x00000004000bb00b DEVTYPE = 0x00 ARCHID = 0x0000)
ROM: Table END
DP DPIDR 0x6ba02477 (v2 rev0) designer 0x43b partno 0xba
TARGETID 0x14740041 designer 0x20 partno 0x4740
[...]
ROM: Table BASE=0xe00e0000 SYSMEM=0x00000000, Manufacturer 020 Partno 474
 0xe00e4000: 0x00000000000a0000 Non ARM component ignored
ROM: Table END
AP   1: IDR=84770001 CFG=00000000 BASE=e00fe003 CSW=83800040 (AHB3-AP var0 rev8)
ROM: Table BASE=0xe00fe000 SYSMEM=0x00000001, Manufacturer 020 Partno 474
ROM: Table BASE=0xe00ff000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c9
 0 0xe000e000: Debug component - Cortex-M33 (System Control Space) (PIDR = 0x00000004000bbd21 DEVTYPE = 0x00 ARCHID = 0x2a04)
 -> cortexm_probe
CPUID 0x410fd214 (M33 var 0 rev 4)
Calling stm32f1_probe
Calling stm32f4_probe
Calling stm32h5_probe
 1 0xe0001000: Debug component - Cortex-M33 (Data Watchpoint and Trace) (PIDR = 0x00000004000bbd21 DEVTYPE = 0x00 ARCHID = 0x1a02)
 2 0xe0002000: Debug component - Cortex-M33 (Breakpoint Unit) (PIDR = 0x00000004000bbd21 DEVTYPE = 0x00 ARCHID = 0x1a03)
 3 0xe0000000: Debug component - Cortex-M33 (Instrumentation Trace Macrocell) (PIDR = 0x00000004000bbd21 DEVTYPE = 0x43 ARCHID = 0x1a01)
 4 Entry 0xfff41002 -> Not present
 5 0xe0041000: Debug component - Cortex-M33 (Embedded Trace) (PIDR = 0x00000004001bbd21 DEVTYPE = 0x13 ARCHID = 0x4a13)
 6 0xe0042000: Debug component - Cortex-M33 (Cross Trigger) (PIDR = 0x00000004000bbd21 DEVTYPE = 0x14 ARCHID = 0x1a14)
 7 Entry 0xfff44002 -> Not present
 ROM: Table END
 1 0xe0040000: 0x00000000 <- does not match preamble (0xb105000d)
2 Entry 0x1ff02002 -> Not present
3 Entry 0x1ff02002 -> Not present
ROM: Table END

@jharwell
Copy link
Author

jharwell commented Jan 4, 2024

ooo interesting--so it sounds like I'm hitting an issue which shouldn't exist for M7 parts? Here's the output when I run against my M7 system with the change I mentioned above in place (and some more debugging info):

Switching out of dormant state into SWD
DP DPIDR 0x0bd11477 (v1 MINDP rev0) designer 0x43b partno 0xbd
AP   0: IDR=04770041 CFG=00000000 BASE=e00fd003 CSW=83000040 (AHB3-AP var4 rev0)
Halt via DHCSR(01030003): success after 0ms
adiv5_component_probe designer code: 0x0 partno: 0x0
  0 0xe000e000: Generic IP component - Cortex-M4 SCS (System Control Space) (PIDR = 0x00000004000bb00c DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0xc
  -> CPUID 0x411fc272 (M7 var 1 rev 2)
Probe ARM cortex: Designer code: 0x43bCPUID: 0x411fc272
Probing for XXX...
  1 0xe0001000: Generic IP component - Cortex-M3 DWT (Data Watchpoint and Trace) (PIDR = 0x00000004000bb002 DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x2
  2 0xe0002000: Generic IP component - Cortex-M7 FBP (Flash Patch and Breakpoint) (PIDR = 0x00000004000bb00e DEVTYPE = 0x00 ARCHID = 0x0000)
  3 0xe0000000: Generic IP component - Cortex-M3 ITM (Instrumentation Trace Module) (PIDR = 0x00000004000bb001 DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x1
  4 Entry 0xfff41002 -> Not present
  5 Entry 0xfff42002 -> Not present
  ROM: Table END
 1 0xe0041000: Debug component - Cortex-M7 ETM (Embedded Trace) (PIDR = 0x00000004001bb975 DEVTYPE = 0x13 ARCHID = 0x4a13)
Parsed designer code: 0x43b, parsed partno: 0x975
 2 Entry 0xfff44002 -> Not present
 3 Entry 0x1ff02002 -> Not present
 ROM: Table END
1 0xe0040000: Debug component - Cortex-M7 TPIU (Trace Port Interface Unit) (PIDR = 0x00000004000bb9a9 DEVTYPE = 0x11 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x9a9
2 Entry 0x1ff03002 -> Not present
3 Entry 0x1ff03002 -> Not present
ROM: Table END

Given your comments above and what I'm seeing, does that mean that my custom system is a non-conforming system in some way? Specifically, you say above that for an M7 I should see a partno of 0x4c7, but I see 0xc.

@dragonmux
Copy link
Member

dragonmux commented Jan 4, 2024

Interesting that the ROM table header is missing from that - was this BMDA built using feature/meson (PR #1528) prior to today's patch to fix that bug?

Anyway, yeah, those part numbers are all over the place - very strange! For a Cortex-M7 we'd expect something like this from the ROM tables:

DP DPIDR 0x6ba02477 (v2 rev0) designer 0x43b partno 0xba
TARGETID 0x04830041 designer 0x20 partno 0x4830
[...]
ROM: Table BASE=0xe00fe000 SYSMEM=0x00000001, Manufacturer  20 Partno 483
ROM: Table BASE=0xe00ff000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c7
 0 0xe000e000: Generic IP component - Cortex-M4 SCS (System Control Space) (PIDR = 0x00000004000bb00c  DEVTYPE = 0x00 ARCHID = 0x0000)
 -> cortexm_probe
CPUID 0x411fc272 (M7 var 1 rev 2)
Calling stm32f1_probe
Calling stm32f4_probe
Calling stm32h7_probe
 1 0xe0001000: Generic IP component - Cortex-M3 DWT (Data Watchpoint and Trace) (PIDR = 0x00000004000bb002  DEVTYPE = 0x00 ARCHID = 0x0000)
 2 0xe0002000: Generic IP component - Cortex-M7 FBP (Flash Patch and Breakpoint) (PIDR = 0x00000004000bb00e  DEVTYPE = 0x00 ARCHID = 0x0000)
 3 0xe0000000: Generic IP component - Cortex-M3 ITM (Instrumentation Trace Module) (PIDR = 0x00000004000bb001  DEVTYPE = 0x00 ARCHID = 0x0000)
 4 Entry 0xfff41002 -> Not present
 5 Entry 0xfff42002 -> Not present
 ROM: Table END
1 0xe0041000: Debug component - Cortex-M7 ETM (Embedded Trace) (PIDR = 0x00000004001bb975  DEVTYPE = 0x13 ARCHID = 0x4a13)
2 0xe0043000: Debug component - CoreSight CTI (Cross Trigger) (PIDR = 0x00000004004bb906  DEVTYPE = 0x14 ARCHID = 0x0000)
3 Entry 0x1ff02002 -> Not present
ROM: Table END
AP   1: IDR=84770001 CFG=00000000 BASE=00000002 CSW=c3800040 (AHB-AP var0 rev8)
AP   2: IDR=54770002 CFG=00000000 BASE=e00e0003 CSW=80000040 (AHB-AP var0 rev5)
ROM: Table BASE=0xe00e0000 SYSMEM=0x00000000, Manufacturer  20 Partno 483
 0xe00e1000: 0x00000000000a0000 Non ARM component ignored
1 Entry 0x2002 -> Not present
 2 0xe00e3000: 0x00000000 <- does not match preamble (0xb105000d)
3 Entry 0x4002 -> Not present
4 Entry 0x5002 -> Not present
ROM: Table BASE=0xe00f0000 SYSMEM=0x00000000, Manufacturer  20 Partno   1
 0 0xe00f1000: Debug component - CoreSight CTI (Cross Trigger) (PIDR = 0x00000004005bb906  DEVTYPE = 0x14 ARCHID = 0x0000)
 1 Entry 0x2002 -> Not present
 2 0xe00f3000: Debug component - CoreSight CSTF (Trace Funnel) (PIDR = 0x00000004003bb908  DEVTYPE = 0x12 ARCHID = 0x0000)
 3 0xe00f4000: Debug component - CoreSight TMC (Trace Memory Controller) (PIDR = 0x00000004001bb961  DEVTYPE = 0x32 ARCHID = 0x0000)
 4 0xe00f5000: Debug component - CoreSight TPIU (Trace Port Interface Unit) (PIDR = 0x00000004005bb912  DEVTYPE = 0x11 ARCHID = 0x0000)
 5 Entry 0x6002 -> Not present
 6 Entry 0x7002 -> Not present
 7 Entry 0x8002 -> Not present
 ROM: Table END
ROM: Table END

(edit: please excuse our accidentally closing the issue while trying to copy that trace in)

@dragonmux dragonmux reopened this Jan 4, 2024
@jharwell
Copy link
Author

jharwell commented Jan 5, 2024

this was built from tip b44bbf04b3ee8a73be5d8432b94e185e7dd8c302. I wasn't using the debug app (couldn't get that to work), but was using firmware loaded onto the probe with dfu-util. Hmm it looks like you only get the ROM BASE=... lines when compiling the debug app--that seems like a useful thing to have enabled when building the firmware too? After poking things to get those lines, I now get:

Switching out of dormant state into SWD                                                                                        
DP DPIDR 0x0bd11477 (v1 MINDP rev0) designer 0x43b partno 0xbd                                                                 
AP   0: IDR=04770041 CFG=00000000 BASE=e00fd003 CSW=83000040 (AHB3-AP var4 rev0)                                               
Halt via DHCSR(01030003): success after 0ms                                  
adiv5_component_probe: designer code: 0x0 partno: 0x0                        
ROM: Table BASE=0xe00fd000 SYSMEM=0x00000001, Manufacturer 000 Partno 000
ROM: Table BASE=0xe00fe000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c8
ROM: Table BASE=0xe00ff000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c7
  0 0xe000e000: Generic IP component - Cortex-M4 SCS (System Control Space) (PIDR = 0x00000004000bb00c DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0xc
  -> cortexm_probe
CPUID 0x411fc272 (M7 var 1 rev 2)
Probe ARM cortex: Designer code: 0x43b, CPUID: 0x411fc272
Probing for orca7090...
  1 0xe0001000: Generic IP component - Cortex-M3 DWT (Data Watchpoint and Trace) (PIDR = 0x00000004000bb002 DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x2
  2 0xe0002000: Generic IP component - Cortex-M7 FBP (Flash Patch and Breakpoint) (PIDR = 0x00000004000bb00e DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0xe
  3 0xe0000000: Generic IP component - Cortex-M3 ITM (Instrumentation Trace Module) (PIDR = 0x00000004000bb001 DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x1
  4 Entry 0xfff41002 -> Not present
  5 Entry 0xfff42002 -> Not present
  ROM: Table END
 1 0xe0041000: Debug component - Cortex-M7 ETM (Embedded Trace) (PIDR = 0x00000004001bb975 DEVTYPE = 0x13 ARCHID = 0x4a13)
Parsed designer code: 0x43b, parsed partno: 0x975
 2 Entry 0xfff44002 -> Not present
 3 Entry 0x1ff02002 -> Not present
 ROM: Table END
1 0xe0040000: Debug component - Cortex-M7 TPIU (Trace Port Interface Unit) (PIDR = 0x00000004000bb9a9 DEVTYPE = 0x11 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x9a9
2 Entry 0x1ff03002 -> Not present
3 Entry 0x1ff03002 -> Not present
ROM: Table END

Am I correct in saying that the root of my issues is that the first detected device has a manufacturer and partno of 0 ?

@dragonmux
Copy link
Member

dragonmux commented Jan 5, 2024

Ok, so you're building from main a few commits back - what's your probe? It looks like one of them (but not native - we know that's correct) is misconfigured and not defining PLATFORM_HAS_DEBUG correctly. This is fixed in c5c05bc for this particular case (this is not a general fix for that problem though) but it sounds like a platform needs adjustment in its platform.h

To answer the main question though - yes, looks like whoever's chip this is failed to configure the IDs in their part of the ROM tables, leaving them decidedly blank. Interesting that the second table in the set defines a would-be Cortex-M8 but is empty before finally defining a Cortex-M7

@ALTracer
Copy link
Contributor

ALTracer commented Jan 5, 2024

It looks like one of them (but not native - we know that's correct) is misconfigured and not defining PLATFORM_HAS_DEBUG correctly. This is fixed in c5c05bc for this particular case (this is not a general fix for that problem though) but it sounds like a platform needs adjustment in its platform.h

That doesn't matter, because I decoupled platform.h from general.h and missed this file (adiv5.c) wanting it for the PLATFORM_HAS_DEBUG macro. It was not a hard build error, and the logs are optional. See #1530
In this case I suggest dropping the second part of macro condition (which was hanging here since c456fc7 ) or re-introducing #include "platform.h" for this one line (which is IMO worse).

#if ENABLE_DEBUG == 1 && defined(PLATFORM_HAS_DEBUG)

diff --git a/src/target/adiv5.c b/src/target/adiv5.c
index 137162f8..962f0ded 100644
--- a/src/target/adiv5.c
+++ b/src/target/adiv5.c
@@ -608,7 +608,7 @@ static void adiv5_component_probe(
 			}
 		}
 
-#if ENABLE_DEBUG == 1 && defined(PLATFORM_HAS_DEBUG)
+#if ENABLE_DEBUG == 1
 		/* Check SYSMEM bit */
 		const uint32_t memtype = adiv5_mem_read32(ap, addr | ADIV5_ROM_MEMTYPE) & ADIV5_ROM_MEMTYPE_SYSMEM;
 

The memtype variable is otherwise unused and still has to be hidden behind ENABLE_DEBUG=1. I am not bothering to check sizediff yet, but it builds for both cases, asking for / omitting debug logging.

To the topicstarter: visualising links between CoreSight discoverable ROM tables is crucial to verify that the implementer did it correctly and that debugger-projects like BMD (and OpenOCD etc.) can sensibly use this information. You can use a BMP for this. I saw a couple chips which have useless ROM tables and are impossible to discover dynamically, which is one of main features of BMD.
If you have problems getting BMDA to build on your setup, and other issues & discussions don't help you, then please post details on that (what you attempted and what is missing) -- not all environments are supported (easily).

@dragonmux
Copy link
Member

dragonmux commented Jan 5, 2024

That doesn't matter, because I decoupled platform.h from general.h and missed this file (adiv5.c)

Ah, ok, that explains it!

Regarding the rest of your reply on that point - see the linked commit from our previous post, which is fast becoming our preferred way to fix these problems

@jharwell
Copy link
Author

jharwell commented Jan 8, 2024

@dragonmux my probe is the one I bought from here: https://1bitsquared.com/collections/embedded-hardware/products/black-magic-probe. I'm able to build he debug app with ENABLE_DEBUG=1 PROBE_HOST=hosted, and run it via sudo ./src/blackmagic -d /dev/blackmagic/ttyGDB build/main.elf. I was not able to get any of the debugging to come out (-v with 1 2 4 8 16 32 64) did not seem to do anything, so i hardcoded the debug level to 127, and then got the following output:

Black Magic Debug App v1.10.0-278-g7e90d1f3
 for Black Magic Probe, ST-Link v2 and v3, CMSIS-DAP, J-Link and FTDI (MPSSE)
Remote is v1.10.0-278-g7e90d1f3-dirty
Target voltage: 1.8V Volt
Speed set to 1.951MHz for SWD
remote_swd_init
Switching out of dormant state into SWD
remote_v0_swd_seq_out 32 clock_cycles: ffffffff
remote_v0_swd_seq_out 28 clock_cycles: 0fffffff
remote_v0_swd_seq_out 32 clock_cycles: 6209f392
remote_v0_swd_seq_out 32 clock_cycles: 86852d95
remote_v0_swd_seq_out 32 clock_cycles: e3ddafe9
remote_v0_swd_seq_out 32 clock_cycles: 19bc0ea2
remote_v0_swd_seq_out 12 clock_cycles: 000001a0
remote_v0_swd_seq_out 32 clock_cycles: ffffffff
remote_v0_swd_seq_out 32 clock_cycles: 0fffffff
remote_v0_swd_seq_out 8 clock_cycles: 000000a5
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: 0bd11477 OK
Read DPIDR: 0x0bd11477
Abort: 00000004
Write ABORT: 0x00000004
remote_v0_swd_seq_out 8 clock_cycles: 00000081
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_out_parity 32 clock_cycles: 00000004
remote_v0_swd_seq_out 8 clock_cycles: 00000000
remote_v3_adiv5_raw_access: addr 0000 -> 0bd11477
Read DPIDR: 0x0bd11477
DP DPIDR 0x0bd11477 (v1 MINDP rev0) designer 0x43b partno 0xbd
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
Write CTRL: 0x00000000
remote_v3_adiv5_raw_access: addr 0004 <- 00000000 -> 00000000
remote_v3_adiv5_dp_read: addr 0004 -> 00000000
Read STATUS: 0x00000000
Write CTRL: 0x50000000
remote_v3_adiv5_raw_access: addr 0004 <- 50000000 -> 00000000
remote_v3_adiv5_dp_read: addr 0004 -> f0000000
Read STATUS: 0xf0000000
remote_v3_adiv5_ap_read: addr 01fc -> 04770041
Read AP 0 IDR: 0x04770041
remote_v3_adiv5_ap_read: addr 01f8 -> e00fd003
Read AP 0 BASE: 0xe00fd003
remote_v3_adiv5_ap_read: addr 0100 -> 03000040
Read AP 0 CSW: 0x03000040
remote_v3_adiv5_ap_read: addr 01f4 -> 00000000
Read AP 0 CFG: 0x00000000
AP   0: IDR=04770041 CFG=00000000 BASE=e00fd003 CSW=83000040 (AHB3-AP var4 rev0)
remote_v3_adiv5_dp_read: addr 0004 -> f0000040
Read STATUS: 0xf0000040
Write AP 0 CSW: 0x83000042
remote_v3_adiv5_ap_write: addr 0100 <- 83000042
remote_v3_adiv5_raw_access: addr 0104 <- e000edf0 -> 00000000
Write AP 0 TAR: 0xe000edf0
remote_v3_adiv5_raw_access: addr 010c <- a05f0001 -> 00000000
Write AP 0 DRW: 0xa05f0001
remote_v3_adiv5_dp_read: addr 000c -> 00000000
Read RDBUFF: 0x00000000
remote_v3_adiv5_raw_access: addr 010c <- a05f0003 -> 00000000
Write AP 0 DRW: 0xa05f0003
remote_v3_adiv5_raw_access: addr 010c -> 00000000
Read AP 0 DRW: 0x00000000
remote_v3_adiv5_raw_access: addr 000c -> 02030003
Read RDBUFF: 0x02030003
remote_v3_adiv5_raw_access: addr 010c <- a05f0003 -> 00000000
Write AP 0 DRW: 0xa05f0003
remote_v3_adiv5_raw_access: addr 010c -> 00000000
Read AP 0 DRW: 0x00000000
remote_v3_adiv5_raw_access: addr 000c -> 00030003
Read RDBUFF: 0x00030003
Halt via DHCSR(00030003): success after 1ms
remote_v3_adiv5_mem_read_bytes: @e000edfc+4
ap_memread @ e000edfc len 4: 00 00 00 00
ap_mem_write_sized @ e000edfc len 4, align 4: 01 04 00 01
remote_v3_adiv5_mem_write_bytes: @e000edfc+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 03 00 03 00
remote_v3_adiv5_mem_read_bytes: @e00fdff0+10
ap_memread @ e00fdff0 len 16: 0d 00 00 00 10 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fdfd0+10
ap_memread @ e00fdfd0 len 16: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e00fdfe0+10
ap_memread @ e00fdfe0 len 16: 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00
adiv5_component_probe: designer code: 0x0 partno: 0x0
remote_v3_adiv5_mem_read_bytes: @e00fdfcc+4
ap_memread @ e00fdfcc len 4: 01 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
ROM: Table BASE=0xe00fd000 SYSMEM=0x00000001, Manufacturer 000 Partno 000
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fd000+4
ap_memread @ e00fd000 len 4: 03 10 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00feff0+10
ap_memread @ e00feff0 len 16: 0d 00 00 00 10 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fefd0+10
ap_memread @ e00fefd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e00fefe0+10
ap_memread @ e00fefe0 len 16: c8 00 00 00 b4 00 00 00 0b 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e00fefcc+4
ap_memread @ e00fefcc len 4: 01 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
ROM: Table BASE=0xe00fe000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c8
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fe000+4
ap_memread @ e00fe000 len 4: 03 10 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ffff0+10
ap_memread @ e00ffff0 len 16: 0d 00 00 00 10 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fffd0+10
ap_memread @ e00fffd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e00fffe0+10
ap_memread @ e00fffe0 len 16: c7 00 00 00 b4 00 00 00 0b 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e00fffcc+4
ap_memread @ e00fffcc len 4: 01 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
ROM: Table BASE=0xe00ff000 SYSMEM=0x00000001, Manufacturer 43b Partno 4c7
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff000+4
ap_memread @ e00ff000 len 4: 03 f0 f0 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e000eff0+10
ap_memread @ e000eff0 len 16: 0d 00 00 00 e0 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e000efd0+10
ap_memread @ e000efd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e000efe0+10
ap_memread @ e000efe0 len 16: 0c 00 00 00 b0 00 00 00 0b 00 00 00 00 00 00 00
  0 0xe000e000: Generic IP component - Cortex-M4 SCS (System Control Space) (PIDR = 0x00000004000bb00c DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0xc
  -> cortexm_probe
remote_v3_adiv5_mem_read_bytes: @e000ed00+4
ap_memread @ e000ed00 len 4: 72 c2 1f 41
CPUID 0x411fc272 (M7 var 1 rev 2)
remote_v3_adiv5_mem_read_bytes: @e000ed88+4
ap_memread @ e000ed88 len 4: 00 00 00 00
ap_mem_write_sized @ e000ed88 len 4, align 4: 00 00 f0 00
remote_v3_adiv5_mem_write_bytes: @e000ed88+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @e000ed88+4
ap_memread @ e000ed88 len 4: 00 00 f0 00
remote_v3_adiv5_mem_read_bytes: @e000ed7c+4
ap_memread @ e000ed7c len 4: 03 c0 03 83
Probe ARM cortex: Designer code: 0x43b, CPUID: 0x411fc272
Calling mychip_probe
Probing for mychip...
remote_v3_adiv5_mem_read_bytes: @e000ed00+4
ap_memread @ e000ed00 len 4: 72 c2 1f 41
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff004+4
ap_memread @ e00ff004 len 4: 03 20 f0 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0001ff0+10
ap_memread @ e0001ff0 len 16: 0d 00 00 00 e0 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0001fd0+10
ap_memread @ e0001fd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0001fe0+10
ap_memread @ e0001fe0 len 16: 02 00 00 00 b0 00 00 00 0b 00 00 00 00 00 00 00
  1 0xe0001000: Generic IP component - Cortex-M3 DWT (Data Watchpoint and Trace) (PIDR = 0x00000004000bb002 DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x2
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff008+4
ap_memread @ e00ff008 len 4: 03 30 f0 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0002ff0+10
ap_memread @ e0002ff0 len 16: 0d 00 00 00 e0 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0002fd0+10
ap_memread @ e0002fd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0002fe0+10
ap_memread @ e0002fe0 len 16: 0e 00 00 00 b0 00 00 00 0b 00 00 00 00 00 00 00
  2 0xe0002000: Generic IP component - Cortex-M7 FBP (Flash Patch and Breakpoint) (PIDR = 0x00000004000bb00e DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0xe
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff00c+4
ap_memread @ e00ff00c len 4: 03 10 f0 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0000ff0+10
ap_memread @ e0000ff0 len 16: 0d 00 00 00 e0 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0000fd0+10
ap_memread @ e0000fd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0000fe0+10
ap_memread @ e0000fe0 len 16: 01 00 00 00 b0 00 00 00 0b 00 00 00 00 00 00 00
  3 0xe0000000: Generic IP component - Cortex-M3 ITM (Instrumentation Trace Module) (PIDR = 0x00000004000bb001 DEVTYPE = 0x00 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x1
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff010+4
ap_memread @ e00ff010 len 4: 02 10 f4 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
  4 Entry 0xfff41002 -> Not present
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff014+4
ap_memread @ e00ff014 len 4: 02 20 f4 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
  5 Entry 0xfff42002 -> Not present
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00ff018+4
ap_memread @ e00ff018 len 4: 00 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
  ROM: Table END
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fe004+4
ap_memread @ e00fe004 len 4: 03 30 f4 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0041ff0+10
ap_memread @ e0041ff0 len 16: 0d 00 00 00 90 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0041fd0+10
ap_memread @ e0041fd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0041fe0+10
ap_memread @ e0041fe0 len 16: 75 00 00 00 b9 00 00 00 1b 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0041fcc+4
ap_memread @ e0041fcc len 4: 13 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0041fbc+4
ap_memread @ e0041fbc len 4: 13 4a 70 47
 1 0xe0041000: Debug component - Cortex-M7 ETM (Embedded Trace) (PIDR = 0x00000004001bb975 DEVTYPE = 0x13 ARCHID = 0x4a13)
Parsed designer code: 0x43b, parsed partno: 0x975
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fe008+4
ap_memread @ e00fe008 len 4: 02 40 f4 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
 2 Entry 0xfff44002 -> Not present
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fe00c+4
ap_memread @ e00fe00c len 4: 02 20 f0 1f
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
 3 Entry 0x1ff02002 -> Not present
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fe010+4
ap_memread @ e00fe010 len 4: 00 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
 ROM: Table END
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fd004+4
ap_memread @ e00fd004 len 4: 03 30 f4 ff
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0040ff0+10
ap_memread @ e0040ff0 len 16: 0d 00 00 00 90 00 00 00 05 00 00 00 b1 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e0040fd0+10
ap_memread @ e0040fd0 len 16: 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0040fe0+10
ap_memread @ e0040fe0 len 16: a9 00 00 00 b9 00 00 00 0b 00 00 00 00 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0040fcc+4
ap_memread @ e0040fcc len 4: 11 00 00 00
remote_v3_adiv5_mem_read_bytes: @e0040fbc+4
ap_memread @ e0040fbc len 4: 00 00 00 00
1 0xe0040000: Debug component - Cortex-M7 TPIU (Trace Port Interface Unit) (PIDR = 0x00000004000bb9a9 DEVTYPE = 0x11 ARCHID = 0x0000)
Parsed designer code: 0x43b, parsed partno: 0x9a9
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fd008+4
ap_memread @ e00fd008 len 4: 02 30 f0 1f
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
2 Entry 0x1ff03002 -> Not present
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fd00c+4
ap_memread @ e00fd00c len 4: 02 30 f0 1f
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
3 Entry 0x1ff03002 -> Not present
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
remote_v3_adiv5_mem_read_bytes: @e00fd010+4
ap_memread @ e00fd010 len 4: 00 00 00 00
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
ROM: Table END
ap_mem_write_sized @ e000ef50 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000ef50+4 alignment 2
ap_mem_write_sized @ e000edf0 len 4, align 4: 01 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 1 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 1 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 2 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 2 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 3 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 3 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 4 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 4 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 5 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 5 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 6 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 6 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 7 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 7 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
remote_v3_adiv5_ap_read: addr 01fc -> 00000000
Read AP 8 IDR: 0x00000000
remote_v3_adiv5_ap_read: addr 01f8 -> 00000000
Read AP 8 BASE: 0x00000000
Abort: 00000004
Write ABORT: 0x00000004
remote_v3_adiv5_raw_access: addr 0000 <- 00000004 -> 00000000
***  1   MyChip M7
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
ap_mem_write_sized @ e000edf0 len 4, align 4: 03 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2
ap_mem_write_sized @ e000edfc len 4, align 4: 01 04 00 01
remote_v3_adiv5_mem_write_bytes: @e000edfc+4 alignment 2
ap_mem_write_sized @ e000ed30 len 4, align 4: 1f 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000ed30+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @e0002000+4
ap_memread @ e0002000 len 4: 80 00 00 10
remote_v3_adiv5_mem_read_bytes: @e0001000+4
ap_memread @ e0001000 len 4: 00 00 00 40
ap_mem_write_sized @ e0002008 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002008+4 alignment 2
ap_mem_write_sized @ e000200c len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000200c+4 alignment 2
ap_mem_write_sized @ e0002010 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002010+4 alignment 2
ap_mem_write_sized @ e0002014 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002014+4 alignment 2
ap_mem_write_sized @ e0002018 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002018+4 alignment 2
ap_mem_write_sized @ e000201c len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000201c+4 alignment 2
ap_mem_write_sized @ e0002020 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002020+4 alignment 2
ap_mem_write_sized @ e0002024 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002024+4 alignment 2
ap_mem_write_sized @ e0001028 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001028+4 alignment 2
ap_mem_write_sized @ e0001038 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001038+4 alignment 2
ap_mem_write_sized @ e0001048 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001048+4 alignment 2
ap_mem_write_sized @ e0001058 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001058+4 alignment 2
ap_mem_write_sized @ e0002000 len 4, align 4: 03 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002000+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 03 00 03 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 03 00 03 00
RAM   Start: 0x30000000 length = 0x200000
RAM   Start: 0x10000000 length = 0x100000
RAM   Start: 0x00000000 length = 0x1020000
Erasing 177560 bytes at 0xffffffff
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 03 00 03 00
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
remote_v3_adiv5_mem_read_bytes error around 0xe000edf0
ap_memread @ e000edf0 len 4: 00 00 00 00
ap_mem_write_sized @ e000ed0c len 4, align 4: 04 00 fa 05
remote_v3_adiv5_mem_write_bytes: @e000ed0c+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000ed0c
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
remote_v3_adiv5_mem_read_bytes error around 0xe000edf0
ap_memread @ e000edf0 len 4: 00 00 00 00
ap_mem_write_sized @ e000ed30 len 4, align 4: 1f 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000ed30+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000ed30
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000007
remote_v0_swd_seq_in_parity 32 clock_cycles: ffffffff ERR
Read STATUS: 0x00000000
DP Error 0x00000000
Flash erase failed!
ap_mem_write_sized @ e0002008 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002008+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0002008
ap_mem_write_sized @ e000200c len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000200c+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000200c
ap_mem_write_sized @ e0002010 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002010+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0002010
ap_mem_write_sized @ e0002014 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002014+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0002014
ap_mem_write_sized @ e0002018 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002018+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0002018
ap_mem_write_sized @ e000201c len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000201c+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000201c
ap_mem_write_sized @ e0002020 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002020+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0002020
ap_mem_write_sized @ e0002024 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0002024+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0002024
ap_mem_write_sized @ e0001028 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001028+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0001028
ap_mem_write_sized @ e0001038 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001038+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0001038
ap_mem_write_sized @ e0001048 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001048+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0001048
ap_mem_write_sized @ e0001058 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e0001058+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe0001058
ap_mem_write_sized @ e000edfc len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000edfc+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000edfc
ap_mem_write_sized @ e000edf0 len 4, align 4: 03 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000edf0
ap_mem_write_sized @ e000edf0 len 4, align 4: 01 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000edf0
ap_mem_write_sized @ e000edf0 len 4, align 4: 00 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2
remote_v3_adiv5_mem_write_bytes error around 0xe000edf0

When running the debug app, everything works fine up until the app tries to erase FLASH (which our chip doesn't have) which fails. If I try to run the debug app again, I get:

Black Magic Debug App v1.10.0-278-g7e90d1f3
 for Black Magic Probe, ST-Link v2 and v3, CMSIS-DAP, J-Link and FTDI (MPSSE)
Remote is v1.10.0-278-g7e90d1f3-dirty
Target voltage: 1.8V Volt
Speed set to 1.951MHz for SWD
remote_swd_init
Switching out of dormant state into SWD
remote_v0_swd_seq_out 32 clock_cycles: ffffffff
remote_v0_swd_seq_out 28 clock_cycles: 0fffffff
remote_v0_swd_seq_out 32 clock_cycles: 6209f392
remote_v0_swd_seq_out 32 clock_cycles: 86852d95
remote_v0_swd_seq_out 32 clock_cycles: e3ddafe9
remote_v0_swd_seq_out 32 clock_cycles: 19bc0ea2
remote_v0_swd_seq_out 12 clock_cycles: 000001a0
remote_v0_swd_seq_out 32 clock_cycles: ffffffff
remote_v0_swd_seq_out 32 clock_cycles: 0fffffff
remote_v0_swd_seq_out 8 clock_cycles: 000000a5
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: 0bd11477 OK
Read DPIDR: 0x0bd11477
Abort: 00000004
Write ABORT: 0x00000004
remote_v0_swd_seq_out 8 clock_cycles: 00000081
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_out_parity 32 clock_cycles: 00000004
remote_v0_swd_seq_out 8 clock_cycles: 00000000
Read DPIDR: 0x00000000
Failed to read DPIDR
No target found

and have to unplug and re-plug the probe to get the first output again. Why would running the debug app not work, but running the firmware on the probe work ? It seems like the debug app always tries to erase FLASH, and assumes that connected M7 chips have FLASH even if they don't register any, as is the case in my probe() function:

+bool mychip_probe(target_s *target) {
+  DEBUG_INFO("Probing for mychip...\n");
+  uint32_t cpuid = target_mem_read32(target, CORTEX_M7_CPUID);
+
+  if (CORTEX_M7_CPUID_VAL != cpuid) {
+    DEBUG_ERROR("Not a Cortex M7: Expected CPUID=0x%x, got 0x%" PRIx32 "\n",
+               CORTEX_M7_CPUID_VAL,
+               cpuid);
+    return false;
+  }
+
+  target->driver = "mychip";
+  target->cpuid = MYCHIP_CPUTAPID;
+  target->designer_code = 0x43b;
+
+  /* Add memory mappings */
+  target_add_ram(target, 0x30000000, 2 * MiB);
+  target_add_ram(target, 0x10000000, 1 * MiB);
+  target_add_ram(target, 0x0, 16 * MiB + 128 * KiB);
+  return true;
+}

@dragonmux
Copy link
Member

dragonmux commented Jan 9, 2024

Ok, that's a fair bit to unpack, so.. here goes:

I'm able to build he debug app with ENABLE_DEBUG=1 PROBE_HOST=hosted, and run it via sudo ./src/blackmagic -d /dev/blackmagic/ttyGDB build/main.elf. I was not able to get any of the debugging to come out (-v with 1 2 4 8 16 32 64) did not seem to do anything, so i hardcoded the debug level to 127

make PROBE_HOST=hosted always implies ENABLE_DEBUG=1. You should not need to run as sudo - please use the project's udev rules appropriate to your flavour of Linux. Likewise you do not need to specify the device node - this is all automatic as part of BMDA's function - src/blackmagic -l to get a list of probes, src/blackmagic -s <serial> to select one by serial number - if you only have the one attached, no options are needed to select it, it will automatically be selected.

With regards the verbosity level, it's combining. -v 5 is levels 1 + 4 (INFO + TARGET) and because BMDA spins up a GDB server, you won't see much of anything till you interact with the GDB server. Any odd verbosity level will give you a banner at least. If you want to just try a test scan, you can run as src/blackmagic -tv 5 or w/e other verbosity level to do enter into test-mode which will: scan for targets (include j as in -tjv 5 for JTAG); attach to the first found target; print the memory map; detach; exit.

The banner for all INFO-enabled verbosity combinations should look like:

Black Magic Debug App v1.10.0-428-gd3a23481e-dirty
 for Black Magic Probe, ST-Link v2 and v3, CMSIS-DAP, J-Link and FTDI (MPSSE)
Using 1d50:6018 8BB20695 Black Magic Debug
 Black Magic Probe v1.10.0-279-gbc3822923-dirty

Please do not hard code the verbosity level, and especially not to 127 - for most of your needs we're best served with a verbosity level of 13 or 29 (INFO + TARGET + PROTO [+ PROBE]).
WARN and ERROR are always enabled in debug-enabled builds.

When running the debug app, everything works fine up until the app tries to erase FLASH (which our chip doesn't have) which fails. If I try to run the debug app again, I get:

What was the command line you used to attempt that? If you used the command-line Flash manipulation options like -E/-w then yes, it can and probably will go wrong for targets that fail to register any Flash. If you're going through the GDB interface then this shouldn't be a problem at all.

and have to unplug and re-plug the probe to get the first output again. Why would running the debug app not work, but running the firmware on the probe work ? It seems like the debug app always tries to erase FLASH, and assumes that connected M7 chips have FLASH even if they don't register any, as is the case in my probe() functio

The firmware can only be talked to via the GDB interface or its remote protocol. The only way for the probe itself to attempt to erase Flash of its own volition is if you ask for it to from GDB via load - and the vFlashErase handling takes care of making this a no-op. This is true too for BMDA if using it only from GDB, but if you're using the Flash operation commands then other rules specific to BMDA come into effect. src/platforms/hosted/cli.c is a bundle of code that needs near complete ground-up rewriting but which we've not yet had the time to dig into.

@jharwell
Copy link
Author

Sorry for the long post! I'll keep this one short.

The command I used to try and connect to our board via the BMDA was ./src/blackmagic -d /dev/blackmagic/ttyGDB build/main.elf. From your comments above, this cmd shouldn't be trying to erase FLASH, right? It should just connect to the board and wait for me to connect to the GDB server and issue a load cmd, but that isn't what I'm seeing. :-/

@dragonmux
Copy link
Member

Ah, no, you're giving BMDA the .elf file name for the firmware so you're invoking Flash operations - specifically write mode, and BMDA's trying to byte-for-byte blast your target's (non-existent) Flash with the file's contents (BMDA doesn't understand what an ELF file is for now). This is the behaviour selected by doing src/blackmagic <file> specifically - check the src/blackmagic --help output, and specifically the final two sections on Flash operations.

If you just want to connect to the board (with or without verbosity flags) it's just src/blackmagic - it will automatically figure out how to find your BMP's device node, and you do not want to give it a file name. If you want to pass verbosity flags to see what it's doing more, that's src/blackmagic -v N where N is a number - we'd suggest 5 for most usage. When used this way it will spin up a GDB server on port 2000, which you can connect to from GDB with tar ext :2000.

@jharwell
Copy link
Author

DOH! i didn't think that providing the filename would implicitly put me into FLASH programming mode, but that makes sense. When I remove that argument and connect to BDMA via GDB, I'm able to connect to the board, and load my executable. But when I put a breakpoint on main() and do continue, the breakpoint is never hit, and GDB hangs (not in a not-responsive way, but doesn't output anything as it is "running" the program). In BDMA, I see the following:

gdb_putpacket: OK
gdb_getpacket: vCont?
gdb_putpacket: vCont;c;C;s;t
gdb_getpacket: vCont;c
ap_mem_write_sized @ e000ef50 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000ef50+4 alignment 2
ap_mem_write_sized @ e000edf0 len 4, align 4: 01 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01
remote_v3_adiv5_mem_read_bytes: @e000edf0+4
ap_memread @ e000edf0 len 4: 01 00 01 01

so BDMA is trying to read the debug halt and status register over and over, and presumably failing? There's no error printed though, even at maximum verbosity. I have two questions:

  • Is this another effect of our chip's bad ROM tables somehow?
  • Since our chip IS an M7, and the BMDA is using the M7 driver, I shouldn't need to add any more logic to my custom driver to handle reset, stop, halt, etc requests from the BMDA, right? That's the only thing I can think of other than our bad ROM tables as being the cause of this error.

@dragonmux
Copy link
Member

dragonmux commented Jan 10, 2024

The reads aren't failing, they're just not showing a halted processor - 0x01010001 is the value it's getting back (the bytewise value has to be read little endian), which corresponds with: CORTEXM_DHCSR_C_DEBUGEN | CORTEXM_DHCSR_S_REGRDY | CORTEXM_DHCSR_S_RETIRE_ST.

For a halted processor that's hit a breakpoint, we'd anticipate 0x01030001 - CORTEXM_DHCSR_C_DEBUGEN | CORTEXM_DHCSR_S_REGRDY | CORTEXM_DHCSR_S_HALT | CORTEXM_DHCSR_S_RETIRE_ST (possibly with some of the other bits set).

Your target is just never hitting the breakpoint you have set for some reason, or if it would, the breakpoint unit is not armed and so never triggering and making the target halt.

Indeed, BMD is using the Cortex-M architecture implementation (cortexm.c) which provides all the bits for debug and halt, assuming working breakpoint units.

@jharwell
Copy link
Author

jharwell commented Jan 10, 2024

Digging into what happens after load, it looks like all the registers are properly set up:

r0             0x0                 0
r1             0x3001d224          805425700
r2             0x30011fac          805380012
r3             0x30011fac          805380012
r4             0x3001d47c          805426300
r5             0x301ffd91          807402897
r6             0x301ffd91          807402897
r7             0x301ffd78          807402872
r8             0x300121d4          805380564
r9             0x0                 0
r10            0x300121d8          805380568
r11            0x30011fbc          805380028
r12            0xa                 10
sp             0x301fffdc          0x301fffdc
lr             0x3000654b          0x3000654b <Reset_Handler+54>
pc             0x30002eb0          0x30002eb0 <main()+0>
xpsr           0x61030003          1627586563
fpscr          0x0                 0
msp            0x301fffdc          0x301fffdc
psp            0x0                 0x0
primask        0x0                 0 '\000'
basepri        0x0                 0 '\000'
faultmask      0x0                 0 '\000'
control        0x4                 4 '\004'
>>> p main
$2 = {int (void)} 0x30002eb0 <main()>
>>> info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x30002eb0 in main() at src_arm_test/test_basic.cpp:303
>>> 

Yet when I do continue the processor fails to hit the breakpoint which should be on the very first instruction which the PC is pointing at. Where can I look for where/how the breakpoint gets set in hw/sw by GDB? I looked here: https://developer.arm.com/documentation/ddi0489/f/debug/about-debug/debug-register-summary but there wasn't anything helpful.

My application IS running as far as I can tell, but skips over the breakpoint if it is set (some of the time). Other times, if I Ctrl-C GDB after runs for few seconds, I see the same thing as above, which implies that the CPU isn't doing anything I think, because the PC hasn't moved.

Even weirder, stepi also causes GDB to hang as it waits for the correct response from the debug registers, BUT if I Ctrl-C the code I can see it stepping through instructions, and the PC updating.

@dragonmux
Copy link
Member

dragonmux commented Jan 10, 2024

On the GDB side of things, you're looking for the z/Z packet documentation which describes how GDB requests we set a breakpoint.

From there, BMD handles the packet in the state machine:

blackmagic/src/gdb_main.c

Lines 355 to 360 in 476017e

/* These packet implement hardware break-/watchpoints */
case 'Z': /* Z type,addr,len: Set breakpoint packet */
case 'z': /* z type,addr,len: Clear breakpoint packet */
ERROR_IF_NO_TARGET();
handle_z_packet(pbuf, size);
break;

Which hands off to a helper that vectors into the target layer:

blackmagic/src/gdb_main.c

Lines 783 to 787 in 476017e

int ret = 0;
if (packet[0] == 'Z')
ret = target_breakwatch_set(cur_target, type, addr, len);
else
ret = target_breakwatch_clear(cur_target, type, addr, len);

That winds up calling the Cortex-M functions to set up:

case TARGET_BREAK_HARD:
if (priv->flash_patch_revision == 0) {
val &= 0x1ffffffcU;
val |= (breakwatch->addr & 2U) ? 0x80000000U : 0x40000000U;
}
val |= 1U;
/* Find the first available breakpoint slot */
for (i = 0; i < priv->base.breakpoints_available; i++) {
if (!(priv->base.breakpoints_mask & (1U << i)))
break;
}
if (i == priv->base.breakpoints_available)
return -1;
priv->base.breakpoints_mask |= 1U << i;
target_mem_write32(target, CORTEXM_FPB_COMP(i), val);
breakwatch->reserved[0] = i;
return 0;

and clear:

case TARGET_BREAK_HARD:
priv->base.breakpoints_mask &= ~(1U << i);
target_mem_write32(target, CORTEXM_FPB_COMP(i), 0);
return 0;

breakpoints against the target's hardware FPB (Flash Patch and Breakpoint unit). The DWT (Data Watch and Trace unit) is similarly used for watchpoints.

It is possible under some situations for BMD to use a software breakpoint using the Flash Patch part of the FPB, but usually it'll use a hardware breakpoint. We do not know what will happen if the FPB revision check fails and it winds up setting breakpoints wrong per the unit you actually have.

Single-stepping uses the same machinery (DHCSR single-step bit then resume the processor and wait for halt again), so it is not surprising if one is broken that both are.

@jharwell
Copy link
Author

Getting weirder: A breakpoint on cortexm_breakwatch_set(), or even on gdb_main.c:355 is never hit. The debug output from BMDA when I do b main in the attached GDB is:

gdb_getpacket: m30002eb0,2
m packet: addr = 30002eb0, len = 2
ap_mem_write_sized @ e000ef68 len 4, align 4: a0 2e 00 30
remote_v3_adiv5_mem_write_bytes: @e000ef68+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @30002eb0+2
ap_memread @ 30002eb0 len 2: 2d e9
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
gdb_putpacket: 2DE9
gdb_getpacket: m30002eb0,4
m packet: addr = 30002eb0, len = 4
ap_mem_write_sized @ e000ef68 len 4, align 4: a0 2e 00 30
remote_v3_adiv5_mem_write_bytes: @e000ef68+4 alignment 2
remote_v3_adiv5_mem_read_bytes: @30002eb0+4
ap_memread @ 30002eb0 len 4: 2d e9 f0 4f
remote_v0_swd_seq_out 8 clock_cycles: 0000008d
remote_v0_swd_seq_in 3 clock_cycles: 00000001
remote_v0_swd_seq_in_parity 32 clock_cycles: f0000040 OK
Read STATUS: 0xf0000040
DP Error 0x00000000
gdb_putpacket: 2DE9F04F

0xe000ef68 is the "Data cache clean by address" register, according to https://developer.arm.com/documentation/ddi0489/b/BABCIIIA, so if that's the right reference for the M7, then the request to set a breakpoint is not being handled properly (which is probably not BMDA's fault, but rather our non-conforming chip). It seems odd that the "m" command is being sent into BMDA on a breakpoint set request, as that maps to :

 149 │         case 'm': { /* 'm addr,len': Read len bytes from addr */                                                                                                                                            
 150 │                 uint32_t addr, len;                                                                                                                                                                         
 151 │                 ERROR_IF_NO_TARGET();                                                                                                                                                                       
 152 │                 sscanf(pbuf, "m%" SCNx32 ",%" SCNx32, &addr, &len);                                                                                                                                         
 153 │                 if (len > pbuf_size / 2U) {                                                                                                                                                                 
 154 │                         gdb_putpacketz("E02");                                                                                                                                                              
 155 │                         break;                                                                                                                                                                              
 156 │                 }                                                                                                                                                                                           
 157 │                 DEBUG_GDB("m packet: addr = %" PRIx32 ", len = %" PRIx32 "\n", addr, len);                                                                                                                  
 158 │                 uint8_t *mem = alloca(len);                                                                                                                                                                 
 159 │                 if (target_mem_read(cur_target, mem, addr, len))                                                                                                                                            
 160 │                         gdb_putpacketz("E01");                                                                                                                                                              
 161 │                 else                                                                                                                                                                                        
 162 │                         gdb_putpacket(hexify(pbuf, mem, len), len * 2U);                                                                                                                                    
 163 │                 break;                                                                                                                                                                                      
 164 │         }         

which has nothing to do with setting a breakpoint as far as I can tell. Can you shed some light?

@dragonmux
Copy link
Member

When you actually ask GDB to set a breakpoint it does things in two steps - the first is to read the target memory so it knows what instruction is going to get hit.. the second is to then, when you run continue, send the Z command packet to configure the breakpoint before running vCont to continue execution. You'll probably want to put a breakpoint on the Z packet handling so you can catch this happening - should be the preamble to

gdb_putpacket: OK
gdb_getpacket: vCont?
gdb_putpacket: vCont;c;C;s;t
gdb_getpacket: vCont;c
ap_mem_write_sized @ e000ef50 len 4, align 4: 00 00 00 00
remote_v3_adiv5_mem_write_bytes: @e000ef50+4 alignment 2
ap_mem_write_sized @ e000edf0 len 4, align 4: 01 00 5f a0
remote_v3_adiv5_mem_write_bytes: @e000edf0+4 alignment 2

@jharwell
Copy link
Author

jharwell commented Jan 10, 2024

Ah got it. When I step through the code, the breakpoint type passed to cortexm_breakwatch_set() is TARGET_BREAK_SOFT, which is not handled in the switch() in that function, so the breakpoint is actually never being set. That type is parsed out of the packet received from the GDB client: gdb_getpacket: Z0,30002eb0,3: the "0" in "Z0" is parsed as a target_breakwatch enum value, which is TARGET_BREAK_SOFT. Why would the GDB client send a soft breakpoint request?

If I manually change the type of the breakpoint request to TARGET_BREAK_HARD, and load my program again, then the breakpoint is hit! I then get this from the GDB client:

Ignoring packet error, continuing...                                                                                                                                                                               
Ignoring packet error, continuing...                                                                     
warning: Invalid remote reply: vCont;c;C;s;t                                                             
warning: Invalid remote reply: vCont;c;C;s;t                                                                                                                                                                       
warning: Invalid remote reply: vCont;c;C;s;t                                                             
warning: Invalid remote reply: vCont;c;C;s;t                                                                                                                                                                       
warning: Invalid remote reply: vCont;c;C;s;t       
warning: Invalid remote reply: vCont;c;C;s;t                                                                                                                                                                       
warning: Invalid remote reply: vCont;c;C;s;t                                                                                                                                                                       
warning: Invalid remote reply: vCont;c;C;s;t                                                             
^C                                                                                                       
Program received signal SIGINT, Interrupt.      
Cannot remove breakpoints because program is no longer writable.                                                                                                                                                   
Further execution is probably impossible. 

and i have to restart the GDB client to get a usable prompt back, and my code is no longer running/outputting anything.

@dragonmux
Copy link
Member

dragonmux commented Jan 10, 2024

How interesting - that sounds like the Cortex-M code, when trying to inspect the breakpoints configuration of the target, is seeing no valid breakpoint slots and reporting 0 back to GDB.. in which case with no hardware breakpoints to use, GDB's only option is soft breakpoints.

Need to think then on how to get software breakpoints done in cortexm_breakwatch_set() using Flash patching and the bkpt opcode as that's the obvious "fix" here.

Edit: it would be very interesting if you could inspect what the FPB control value winds up reading as here:

/* size the break/watchpoint units */
priv->base.breakpoints_available = CORTEX_MAX_BREAKPOINTS;
const uint32_t flash_break_cfg = target_mem_read32(target, CORTEXM_FPB_CTRL);
const uint32_t breakpoints = ((flash_break_cfg >> 4U) & 0xfU);
if (breakpoints < priv->base.breakpoints_available) /* only look at NUM_COMP1 */
priv->base.breakpoints_available = breakpoints;
priv->flash_patch_revision = flash_break_cfg >> 28U;

@jharwell
Copy link
Author

That register reads as 0x10000080, and the DWT_CTRL reg reads as 0x40000000. So there should be 8 breakpoints and 4 watchpoints in hw, which looks reasonable. AFAICT, the GDB client has no reason to request a sw breakpoint via the Z0 packet, instead of a hw breakpoint via a Z1 packet, but yet it does. If I set remote debug 1 in the client GDB, and then do a b main followed by continue, this is what I get:

>>> b main
Sending packet: $m30002eb0,2#b7...Ack
Packet received: F0F7
Sending packet: $m30002eb0,4#b9...Ack
Packet received: F0F700A0
Breakpoint 4 at 0x30002eb0: file src_arm_test/test_basic.cpp, line 303.
>>> continue
Sending packet: $m30002eb0,2#b7...Ack
Packet received: 2DE9
Sending packet: $Z0,30002eb0,3#01...Ack
Packet received: 
Packet Z0 (software-breakpoint) is NOT supported
Sending packet: $m30002eb0,4#b9...Ack
Packet received: 2DE9F04F
Sending packet: $X30002eb0,0:#da...Ack
Packet received: OK
binary downloading supported by target
Sending packet: $X30002eb0,4:\000#65...Ack
Packet received: OK
Sending packet: $vCont?#49...Ack
Packet received: vCont;c;C;s;t
Packet vCont (verbose-resume) is supported
Sending packet: $vCont;c#a8...Ack

Which bizzarely says that sw breakpoints are not supported by the running BMDA? But yet it still sends a sw breakpoint request later???

If I run the usual connect, scan and attach sequence with a fresh GDB client with remote debug enabled, I get:

>>> tar ext :2000
Remote debugging using :2000
Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a...Ack
Packet received: PacketSize=400;qXfer:memory-map:read+;qXfer:features:read+;vContSupported+
Packet qSupported (supported-packets) is supported
Sending packet: $vMustReplyEmpty#3a...Ack
Packet received: 
Sending packet: $!#21...Ack
Packet received: OK
Sending packet: $Hg0#df...Ack
Packet received: OK
Sending packet: $qXfer:features:read:target.xml:0,3fb#46...Ack
Packet received: E01
Sending packet: $qTStatus#49...Ack
Packet received: 
Packet qTStatus (trace-status) is NOT supported
Sending packet: $?#3f...Ack
Packet received: W00
>>> mon swd_scan
Sending packet: $qRcmd,7377645f7363616e#d5...Ack
Packet received: O54617267657420766F6C746167653A20312E38560A
Target voltage: 1.8V
Packet received: O417661696C61626C6520546172676574733A0A
Available Targets:
Packet received: O4E6F2E20417474204472697665720A
No. Att Driver
Packet received: O20312020202020206F72636137303930204D370A
 1      mychip M7
Packet received: OK
>>> att 1                                                                                                                                                                                                          
Attaching to program: /opt/jharwell/satelles/orca7090/workspace/algorithm/build/arm/test_basic, Remote target                                                                                                      
Sending packet: $vAttach;1#37...Ack                                                                                                                                                                                
Packet received: T05thread:1;                                                                                                                                                                                      
Packet vAttach (attach) is supported                                                                                                                                                                               
Sending packet: $qC#b4...Ack                                                                                                                                                                                       
Packet received: QC1                                                                                                                                                                                               
Sending packet: $Hg1#e0...Ack                                                                                                                                                                                      
Packet received: OK     
Sending packet: $qXfer:features:read:target.xml:0,3fb#46...Ack                                                                                                                                                     
Packet received: m<?xml version="1.0"?><!DOCTYPE target SYSTEM "gdb-target.dtd"><target>  <architecture>arm</architecture> <feature name="org.gnu.gdb.arm.m-profile"><reg name="r0" bitsize="32"/><reg name="r1" bi
tsize="32"/><reg name="r2" bitsize="32"/><reg name="r3" bitsize="32"/><reg name="r4" bitsize="32"/><reg name="r5" bitsize="32"/><reg name="r6" bitsize="32"/><reg name="r7" bitsize="32"/><reg name="r8" bitsize="3
2"/><reg name="r9" bitsize="32"/><reg name="r10" bitsize="32"/><reg name="r11" bitsize="32"/><reg name="r12[508 bytes omitted]
Sending packet: $qXfer:features:read:target.xml:3fb,3fb#11...Ack
Packet received: me="no"/></feature><feature name="org.gnu.gdb.arm.vfp"><reg name="fpscr" bitsize="32"/><reg name="d0" bitsize="64" type="float"/><reg name="d1" bitsize="64" type="float"/><reg name="d2" bitsize=
"64" type="float"/><reg name="d3" bitsize="64" type="float"/><reg name="d4" bitsize="64" type="float"/><reg name="d5" bitsize="64" type="float"/><reg name="d6" bitsize="64" type="float"/><reg name="d7" bitsize="
64" type="float"/><reg name="d8" bitsize="64" type="float"/><reg name="d9" bitsize="64" type="float"/><reg [272 bytes omitted]
Sending packet: $qXfer:features:read:target.xml:70a,3fb#de...Ack
Packet received: l
Sending packet: $g#67...Ack
Packet received: 140000000A00000014000000A603000044E71F30000000000000000090FE1F3000000000000000000000000000000000FFFFFFFF88FE1F30F73F0000462700000000030188FE1F3000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000FFFFFFFF
Sending packet: $qOffsets#4b...Ack
Packet received: 
Sending packet: $qSymbol::#5b...Ack
Packet received: 
Packet qSymbol (symbol-lookup) is NOT supported
Sending packet: $qXfer:memory-map:read::0,3fb#e5...Ack
Packet received: m<memory-map><memory type="ram" start="0x00000000" length="0x1020000"/><memory type="ram" start="0x10000000" length="0x100000"/><memory type="ram" start="0x30000000" length="0x200000"/></memory-
map>
Sending packet: $qXfer:memory-map:read::c5,3fb#4d...Ack
Packet received: l
Sending packet: $m30002eb0,2#b7...Ack                                                                                                                                                                     
Packet received: F0F7
Sending packet: $m30002eb0,4#b9...Ack
Packet received: F0F700A0
Sending packet: $m30002eb0,2#b7...Ack
Packet received: F0F7
Sending packet: $m30002eb0,4#b9...Ack
Packet received: F0F700A0
Sending packet: $m30006d74,2#93...Ack
Packet received: 7047
Sending packet: $m30006d74,2#93...Ack
Packet received: 7047
Sending packet: $qfThreadInfo#bb...Ack
Packet received: m1
Sending packet: $qsThreadInfo#c8...Ack
Packet received: l
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2742,4#9c...Ack
Packet received: 3B68FB60
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2742,4#9c...Ack
Packet received: 3B68FB60
Sending packet: $m2746,2#9e...Ack
Packet received: FAE7
Sending packet: $m2744,2#9c...Ack
Packet received: FB60
Sending packet: $m2742,2#9a...Ack
Packet received: 3B68
Sending packet: $m2746,2#9e...Ack
Packet received: FAE7
Sending packet: $m2744,2#9c...Ack
Packet received: FB60
Sending packet: $m2742,2#9a...Ack
Packet received: 3B68
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2742,4#9c...Ack
Packet received: 3B68FB60
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2742,4#9c...Ack
Packet received: 3B68FB60
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2746,4#a0...Ack
Packet received: FAE748BC
Sending packet: $m2746,2#9e...Ack
Packet received: FAE7

Which all looks OK to me.

@ALTracer
Copy link
Contributor

Have you declared any flash regions via BMD to GDB so that it understands that hardware breakpoints via FPB are preferred to overwriting insns in RAM (sw bp)? I see a 16 MiB plus something region at 0x0 in your declarations, but it's ram.
GDB has intelligence to select/substitute hbreak when user asks for a break in flash. Try its options as well.
I always have requested "hb main" and it just worked for me. Btw BMD doesn't support overwriting flash to force breakpoints, only RAM (I never used that though)

@jharwell
Copy link
Author

jharwell commented Jan 12, 2024

No I haven't declared any flash regions; my probe() function is just this:

  33 │ bool mychip(target_s *target) {                                                                                                                                                                     
  34 │   DEBUG_INFO("Probing for mychip...\n");                                                                                                                                                                  
  35 │   uint32_t cpuid = target_mem_read32(target, CORTEX_M7_CPUID);                                                                                                                                              
  36 │                                                                                                                                                                                                             
  37 │   if (CORTEX_M7_CPUID_VAL != cpuid) {                                                                                                                                                                       
  38 │     DEBUG_ERROR("Not a Cortex M7: Expected CPUID=0x%x, got 0x%" PRIx32 "\n",                                                                                                                                
  39 │                CORTEX_M7_CPUID_VAL,                                                                                                                                                                         
  40 │                cpuid);                                                                                                                                                                                      
  41 │     return true;                                                                                                                                                                                            
  42 │   }                                                                                                                                                                                                         
  43 │                                                                                                                                                                                                             
  44 │   target->driver = "mychip";                                                                                                                                                                              
  45 │   target->cpuid = MYCHIP_CPUTAPID;                                                                                                                                                                        
  46 │   target->designer_code = 0x43b;                                                                                                                                                                            
  47 │                                                                                                                                                                                                             
  48 │   /* Add memory mappings */                                                                                                                                                                                 
  49 │   target_add_ram(target, 0x30000000, 2 * MiB);                                                                                                                                                              
  50 │   target_add_ram(target, 0x10000000, 1 * MiB);                                                                                                                                                              
  51 │   target_add_ram(target, 0x0, 16 * MiB + 128 * KiB);                                                                                                                                                        
  52 │   return true;                                                                                                                                                                                              
  53 │ }                                                                                                                                                                                                           
              ```
              
I'm a little confused on how declaring FLASH vs RAM regions in our system would change the default you get when you do 'b main`. Can you elaborate?

@ALTracer
Copy link
Contributor

I'm a little confused on how declaring FLASH vs RAM regions in our system would change the default you get when you do 'b main`. Can you elaborate?

Please experiment with set breakpoints auto-hw off and read https://sourceware.org/gdb/wiki/Internals/Breakpoint%20Handling
GDB will mangle target RAM via m-/M-packets to insert a trapping instruction (breakpoint) if you tell it to set a normal default software breakpoint. And it also saves and shadows original contents (on every halt/continue). GDB only refuses to touch non-writable Flash and then resorts to asking the gdbserver to try to set up a hardware breakpoint -- in cortexm case, FPB slots are limited (RAM is not).

@dragonmux
Copy link
Member

Think the clarification needed here is that GDB, not knowing you're trying to set a breakpoint in Flash as no Flash is defined, assumes it's working with RAM and does its RAM breakpoint routine - which, of course, doesn't work here because Flash is non-mutable without using the controller for it or Flash patching via the FPB.

In regards the limitations on slots, @ALTracer - if we actually used the Flash Patch part of the unit, we can insert a breakpoint instruction and get the proper behaviour for any number of additional breakpoints if memory serves.. or at least some significant number more than the normal hardware breakpoints part of the unit provides. It's something we've been meaning to play with.

@jharwell
Copy link
Author

jharwell commented Jan 17, 2024

Ok I think I understand how BMDA interacts with hw vs. sw breakpoints now--thanks! I can reliably hit a breakpoint on main() now, which is good, thanks to @ALTracer's GDB config suggestion. The last thing I'm working on to get debugging up and running with our board is to be able to hit a breakpoint on main(), then step in GDB, and stop on the next line. When I try to do that, sometimes it works, and sometimes I get:

Packet received: l   
                                                    
Program received signal SIGSEGV, Segmentation fault. 

After getting this msg, execution jumps to 0x0 (or maybe it jumping to 0x0 causes the segfault; not sure at this point), and trying to continue always immediately ends up back at 0x0 for the PC. I've never encountered a segfault with an embedded target, and am not sure what might cause the GDB server to send such a packet--any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants