That looks very interesting.
Here is a new patch against head that should give very much information.
It is tested on a STM32 CortexM3.
Looking at the code you can se how I think we must read the ROMTABLE
information structure.
The command syntax is now
>dap info n
>dap select n
If there are no problems found I will commit to head.
Regards,
Magnus
Index: src/target/cortex_m3.c
===================================================================
--- src/target/cortex_m3.c (revision 1527)
+++ src/target/cortex_m3.c (working copy)
@@ -45,6 +45,8 @@
/* cli handling */
int cortex_m3_register_commands(struct command_context_s *cmd_ctx);
int handle_cortex_m3_mask_interrupts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_cortex_dap_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_cortex_dap_apsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
/* forward declarations */
void cortex_m3_enable_breakpoints(struct target_s *target);
@@ -1576,11 +1578,15 @@
{
int retval;
command_t *cortex_m3_cmd;
+ command_t *cortex_dap_cmd;
retval = armv7m_register_commands(cmd_ctx);
cortex_m3_cmd = register_command(cmd_ctx, NULL, "cortex_m3", NULL, COMMAND_ANY, "cortex_m3 specific commands");
register_command(cmd_ctx, cortex_m3_cmd, "maskisr", handle_cortex_m3_mask_interrupts_command, COMMAND_EXEC, "mask cortex_m3 interrupts ['on'|'off']");
+ cortex_dap_cmd = register_command(cmd_ctx, NULL, "dap", NULL, COMMAND_ANY, "cortex dap specific commands");
+ register_command(cmd_ctx, cortex_dap_cmd, "info", handle_cortex_dap_info_command, COMMAND_EXEC, "dap info for ap [num] (default 0)");
+ register_command(cmd_ctx, cortex_dap_cmd, "apsel", handle_cortex_dap_apsel_command, COMMAND_EXEC, "select a different AP [num] (default 0)");
return retval;
}
@@ -1618,3 +1624,112 @@
return ERROR_OK;
}
+
+int handle_cortex_dap_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ target_t *target = get_current_target(cmd_ctx);
+ armv7m_common_t *armv7m = target->arch_info;
+ cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+ swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+
+ u32 dbgbase,apid;
+ u32 apsel,apselold;
+ int romtable_present = 0;
+ u8 mem_ap;
+
+ apsel = 0;
+ apselold = swjdp->apsel;
+ if (argc > 0)
+ {
+ apsel = strtoul(args[0], NULL, 0);
+ }
+
+
+ swjdp_apselect(swjdp, apsel);
+ ahbap_read_reg_u32(swjdp, 0xF8, &dbgbase);
+ ahbap_read_reg_u32(swjdp, 0xFC, &apid);
+ swjdp_transaction_endcheck(swjdp);
+// swjdp_apselect(swjdp, apselold);
+ /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
+ command_print(cmd_ctx, "ap debugbase 0x%8.8x", dbgbase);
+ command_print(cmd_ctx, "ap identification register 0x%8.8x", apid);
+ romtable_present = (((dbgbase&0x3)==0x3)&&(dbgbase != 0xFFFFFFFF));
+ if (romtable_present)
+ {
+ u32 cid0,cid1,cid2,cid3,memtype,romentry;
+ u16 entry_offset;
+ swjdp_apselect(swjdp, apsel);
+ /* bit 16 of apid indicates a memory access port */
+ mem_ap = (apid>>16)&0x1;
+ if (mem_ap)
+ {
+ command_print(cmd_ctx, "\tValid ap debugbase entry - type is mem-ap");
+ }
+ else
+ {
+ command_print(cmd_ctx, "\tValid ap debugbase entry - type is UNKNOWN (JTAG-AP? )" );
+ }
+ /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
+ ahbap_read_system_u32(swjdp, (dbgbase&0xFFFFF000)|0xFF0, &cid0);
+ ahbap_read_system_u32(swjdp, (dbgbase&0xFFFFF000)|0xFF4, &cid1);
+ ahbap_read_system_u32(swjdp, (dbgbase&0xFFFFF000)|0xFF8, &cid2);
+ ahbap_read_system_u32(swjdp, (dbgbase&0xFFFFF000)|0xFFC, &cid3);
+ ahbap_read_system_u32(swjdp, (dbgbase&0xFFFFF000)|0xFCC, &memtype);
+ swjdp_transaction_endcheck(swjdp);
+ command_print(cmd_ctx, "\tCID3 0x%x, CID2 0x%x, CID1 0x%x, CID0, 0x%x",cid3,cid2,cid1,cid0);
+ if (memtype&0x01)
+ {
+ command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
+ }
+ else
+ {
+ command_print(cmd_ctx, "\tMEMTYPE system memory not present. Dedicated debug bus" );
+ }
+
+ /* Now we read ROM table entries from dbgbase&0xFFFFF000)|0x000 until we get 0x00000000 */
+ entry_offset = 0;
+ do
+ {
+ ahbap_read_system_atomic_u32(swjdp, (dbgbase&0xFFFFF000)|entry_offset, &romentry);
+ command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%x",entry_offset,romentry);
+ if (romentry>0)
+ {
+ u32 component_base = (u32)((dbgbase&0xFFFFF000)+(int)(romentry&0xFFFFF000));
+ command_print(cmd_ctx, "\tComponent base address 0x%x",component_base);
+ }
+ entry_offset += 4;
+ } while (romentry>0);
+ }
+ else
+ {
+ command_print(cmd_ctx, "\tNo ROM table present");
+ }
+ swjdp_apselect(swjdp, apselold);
+
+ return ERROR_OK;
+
+}
+
+int handle_cortex_dap_apsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+ target_t *target = get_current_target(cmd_ctx);
+ armv7m_common_t *armv7m = target->arch_info;
+ cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
+ swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
+
+ u32 apsel,apid;
+
+ apsel = 0;
+ if (argc > 0)
+ {
+ apsel = strtoul(args[0], NULL, 0);
+ }
+
+ swjdp_apselect(swjdp, apsel);
+ ahbap_read_reg_u32(swjdp, (apsel<<24)|0xFC, &apid);
+ swjdp_transaction_endcheck(swjdp);
+ command_print(cmd_ctx, "ap %i selected, identification register 0x%8.8x", apsel, apid);
+
+ return ERROR_OK;
+
+}
Index: src/target/cortex_swjdp.c
===================================================================
--- src/target/cortex_swjdp.c (revision 1527)
+++ src/target/cortex_swjdp.c (working copy)
@@ -245,10 +245,13 @@
}
else
{
+#if 0
u32 dcb_dhcsr,nvic_shcsr, nvic_bfar, nvic_cfsr;
+#endif
+ u32 ahbap_csv;
/* Print information about last AHBAP access */
- LOG_ERROR("AHBAP: dp_select 0x%x, ap_csw 0x%x, ap_tar 0x%x", swjdp->dp_select_value, swjdp->ap_csw_value, swjdp->ap_tar_value);
+ LOG_ERROR("AHBAP Cached values: dp_select 0x%x, ap_csw 0x%x, ap_tar 0x%x", swjdp->dp_select_value, swjdp->ap_csw_value, swjdp->ap_tar_value);
if (ctrlstat & SSTICKYORUN)
LOG_ERROR("SWJ-DP OVERRUN - check clock or reduce jtag speed");
@@ -263,12 +266,20 @@
LOG_DEBUG("swjdp: status 0x%x", ctrlstat);
+ ahbap_read_reg_u32(swjdp, AHBAP_CSW, &ahbap_csv);
+ if ((retval=jtag_execute_queue())!=ERROR_OK)
+ return retval;
+ LOG_ERROR("Read AHBAP_CSW 0x%x", ahbap_csv);
+
+#if 0
/* Can we find out the reason for the error ?? */
+ /* WARNING This creates an infinite loop when memorymapped core registers cannot be accessed, and no info about SWJDP communicaton problems, REMOVE!!? */
ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
ahbap_read_system_atomic_u32(swjdp, NVIC_SHCSR, &nvic_shcsr);
ahbap_read_system_atomic_u32(swjdp, NVIC_CFSR, &nvic_cfsr);
ahbap_read_system_atomic_u32(swjdp, NVIC_BFAR, &nvic_bfar);
LOG_ERROR("dcb_dhcsr 0x%x, nvic_shcsr 0x%x, nvic_cfsr 0x%x, nvic_bfar 0x%x", dcb_dhcsr, nvic_shcsr, nvic_cfsr, nvic_bfar);
+#endif
}
if ((retval=jtag_execute_queue())!=ERROR_OK)
return retval;
@@ -294,14 +305,31 @@
return scan_inout_check_u32(swjdp, SWJDP_IR_DPACC, reg_addr, DPAP_READ, 0, value);
}
+int swjdp_apselect(swjdp_common_t *swjdp,u8 apsel)
+{
+ u32 select;
+ select = (apsel<<24) & 0xFF000000;
+
+ if (select != swjdp->apsel)
+ {
+ swjdp->apsel = select;
+ /* Switchin AP invalidates cached values */
+ swjdp->dp_select_value = -1;
+ swjdp->ap_csw_value = -1;
+ swjdp->ap_tar_value = -1;
+ }
+
+ return ERROR_OK;
+}
+
int swjdp_bankselect_apacc(swjdp_common_t *swjdp,u32 reg_addr)
{
u32 select;
- select = (reg_addr & 0xFF0000F0);
+ select = (reg_addr & 0x000000F0);
if (select != swjdp->dp_select_value)
{
- swjdp_write_dpacc(swjdp, select, DP_SELECT);
+ swjdp_write_dpacc(swjdp, select | swjdp->apsel, DP_SELECT);
swjdp->dp_select_value = select;
}
@@ -686,7 +714,7 @@
* *
* ahbap_read_buf_u32(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address) *
* *
-* Read block fast in target order (little endian) into a buffer *
+* Read block of memory fast in target order (little endian) into a buffer *
* *
**********************************************************************************/
int ahbap_read_buf_u32(swjdp_common_t *swjdp, u8 *buffer, int count, u32 address)
@@ -922,6 +950,15 @@
return retval;
}
+/*****************************************************************************
+* *
+* ahbap_read_coreregister_u32(swjdp_common_t *swjdp, u32 *value, int regnum) *
+* *
+* Read a u32 value from a processor core register using the NVIC/DCB *
+* core debug component *
+* *
+*****************************************************************************/
+
int ahbap_read_coreregister_u32(swjdp_common_t *swjdp, u32 *value, int regnum)
{
int retval;
@@ -981,6 +1018,7 @@
LOG_DEBUG(" ");
+ swjdp->apsel = 0;
swjdp->ap_csw_value = -1;
swjdp->ap_tar_value = -1;
swjdp->trans_mode = TRANS_MODE_ATOMIC;
Index: src/target/cortex_swjdp.h
===================================================================
--- src/target/cortex_swjdp.h (revision 1527)
+++ src/target/cortex_swjdp.h (working copy)
@@ -87,6 +87,8 @@
arm_jtag_t *jtag_info;
/* Control config */
u32 dp_ctrl_stat;
+ /* Support for several AP's in one DAP */
+ u32 apsel;
/* Register select cache */
u32 dp_select_value;
u32 ap_csw_value;
@@ -102,8 +104,11 @@
/* extern int swjdp_write_apacc(swjdp_common_t *swjdp, u32 value, u8 reg_addr); */
extern int swjdp_read_dpacc(swjdp_common_t *swjdp, u32 *value, u8 reg_addr);
/* extern int swjdp_read_apacc(swjdp_common_t *swjdp, u32 *value, u8 reg_addr); */
+int swjdp_apselect(swjdp_common_t *swjdp,u8 apsel);
+
extern int ahbap_write_reg(swjdp_common_t *swjdp, u32 reg_addr, u8* out_value_buf);
extern int ahbap_read_reg(swjdp_common_t *swjdp, u32 reg_addr, u8 *in_value_buf);
+extern int ahbap_read_reg_u32(swjdp_common_t *swjdp, u32 reg_addr, u32 *value);
/* External interface, partial operations must be completed with swjdp_transaction_endcheck() */
extern int ahbap_read_system_u32(swjdp_common_t *swjdp, u32 address, u32 *value);
_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development