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

Reply via email to