Hi,

        Attached is a patch for the jtag/src/ejtag.c file that enables memory
writes which allows the BCM6348 to work in PrAcc mode. It should work
for all EJTAG 2.0 or less compliant chips and should not affect any
others.
        On my Inventel Livebox, once the chip has been placed into debug mode I
need to disable the watchdog if Linux is running, otherwise it reboots.
This can be done by writing 0 to address 0xb8000080.
        I have managed to backup the flash with this patch but have not written
to flash as the flashdetect routine currently fails.


Cheers

        AndyP
--- jtag.org/src/bus/ejtag.c	2008-11-15 20:55:44.000000000 +0000
+++ jtag/src/bus/ejtag.c	2008-11-13 21:05:33.000000000 +0000
@@ -53,19 +53,59 @@
 #define EJTAG_20	0
 #define EJTAG_25	1
 #define EJTAG_26	2
+#define EJTAG_31	3
 
-/* EJTAG control register bits */
-#define PerRst		20
-#define PRnW		19
-#define PrAcc		18
-#define PrRst		16
-#define ProbEn		15
-#define JtagBrk		12
-#define BrkSt		 3
-
-/* EJTAG 2.6 */
-#define Rocc		31
-#define ProbTrap	14
+/* EJTAG 3.1 Control Register Bits */
+#define VPED		23	/* R	*/
+/* EJTAG 2.6 Control Register Bits */
+#define Rocc		31	/* R/W0 */
+#define Psz1		30	/* R    */
+#define Psz0		29	/* R    */
+#define Doze		22	/* R    */
+#define ProbTrap	14	/* R/W  */
+#define DebugMode	 3	/* R	*/
+/* EJTAG 1.5.3 Control Register Bits */
+#define Dnm		28 /* */
+#define Sync		23	/* R/W  */
+#define Run		21	/* R    */
+#define PerRst		20	/* R/W  */
+#define PRnW		19	/* R    0 = Read, 1 = Write */
+#define PrAcc		18	/* R/W0 */
+#define DmaAcc		17	/* R/W  */
+#define PrRst		16	/* R/W  */
+#define ProbEn		15	/* R/W  */
+#define SetDev		14	/* R    */
+#define JtagBrk		12	/* R/W1 */
+#define DStrt		11	/* R/W1 */
+#define DeRR		10	/* R    */
+#define DrWn		 9	/* R/W  */
+#define Dsz1		 8	/* R/W  */
+#define Dsz0		 7	/* R/W  */
+#define DLock		 5	/* R/W  */
+#define BrkSt		 3	/* R    */
+#define TIF		 2	/* W0/R	*/
+#define TOF		 1	/* W0/R */
+#define ClkEn		 0	/* R/W  */
+
+/* EJTAG 3.1 Debug Control Register at drseg 0xFF300000 */
+#define PCS			 9	/* R	*/
+#define PCR2		 8	/* R/W	*/
+#define PCR1		 7	/* R/W	*/
+#define PCR0		 6	/* R/W	*/
+/* EJTAG 2.X Debug Control Register at drseg 0xFF300000 */
+#define	DataBrk		17	/* R	*/
+#define	InstBrk		16	/* R	*/
+#define	NMIPend		 2	/* R	*/
+#define	SRstE		 1	/* R/W	*/
+#define	DCRProbeEn	 0	/* R	*/
+/* EJTAG 1.5.3 Debug Control Register at drseg 0xFF300000*/
+#define HIS			30	/* R	*/
+#define ENM			29	/* R 0=Little End,1=Big Endian */
+#define MIntE		4	/* R/W	*/
+#define MNmiE		3	/* R/W	*/
+#define MemProt		2	/* R/W 0=WriteOK,1=Protected */
+#define MRst		1	/* R/W	*/
+#define TraceMode	0	/* R/W	*/
 
 /**
  * bus->driver->(*new_bus)
@@ -148,7 +188,7 @@
 		chain_shift_data_registers( CHAIN, 0 );
 		chain_shift_data_registers( CHAIN, 1 );
 
-		// printf( "ctrl=%s\n", register_get_string( ejctrl->out ) );
+//		printf( "ctrl=%s\n", register_get_string( ejctrl->out ) );
 
 		if (ejctrl->out->data[Rocc]) {
 			printf( _("%s(%d) Reset occurred, ctrl=%s\n"),
@@ -225,7 +265,7 @@
 static int
 ejtag_bus_init( bus_t *bus )
 {
-	data_register *ejctrl, *ejimpl;
+	data_register *ejctrl, *ejimpl, *ejaddr, *ejdata, *ejall;
 	uint32_t code[4] = {
 		0x3c04ff20,				// lui $4,0xff20
 		0x349f0200,				// ori $31,$4,0x0200
@@ -235,6 +275,9 @@
 
 	ejctrl = part_find_data_register( PART, "EJCONTROL" );
 	ejimpl = part_find_data_register( PART, "EJIMPCODE" );
+	ejaddr = part_find_data_register( PART, "EJADDRESS" );
+	ejdata = part_find_data_register( PART, "EJDATA"    );
+	ejall  = part_find_data_register( PART, "EJALL"     );
 	if (!(ejctrl && ejimpl)) {
 		printf( _("%s(%d) EJCONTROL or EJIMPCODE register not found\n"),
 			__FILE__, __LINE__ );
@@ -243,15 +286,16 @@
 
 	part_set_instruction( PART, "EJTAG_IMPCODE" );
 	chain_shift_instructions( CHAIN );
-	chain_shift_data_registers( CHAIN, 0 );
-	chain_shift_data_registers( CHAIN, 1 );
-	printf( "ImpCode=%s\n", register_get_string( ejimpl->out ) );
+	chain_shift_data_registers( CHAIN, 0 );//Write
+	chain_shift_data_registers( CHAIN, 1 );//Read
+	printf( "ImpCode=%s %08X\n", register_get_string( ejimpl->out ), reg_value( ejimpl->out ) );
 	BP->impcode = reg_value( ejimpl->out );
 
 	switch (EJTAG_VER) {
 	case EJTAG_20: printf( "EJTAG version: <= 2.0\n"); break;
 	case EJTAG_25: printf( "EJTAG version: 2.5\n"); break;
 	case EJTAG_26: printf( "EJTAG version: 2.6\n"); break;
+	case EJTAG_31: printf( "EJTAG version: 3.1\n"); break;
 	default:
 		printf( "EJTAG version: unknown (%d)\n", EJTAG_VER );
 	}
@@ -261,27 +305,151 @@
 		(BP->impcode & (1 << 22)) ? " ASID_8"	: "",
 		(BP->impcode & (1 << 21)) ? " ASID_6"	: "",
 		(BP->impcode & (1 << 16)) ? " MIPS16"	: "",
-		(BP->impcode & (1 << 14)) ? " NoDMA"	: "",
+		(BP->impcode & (1 << 14)) ? " NoDMA"	: " DMA",
 		(BP->impcode & (1      )) ? " MIPS64"	: " MIPS32" );
 
 	if (EJTAG_VER >= EJTAG_25) {
 		part_set_instruction( PART, "EJTAGBOOT" );
 		chain_shift_instructions( CHAIN );
 	}
-
 	part_set_instruction( PART, "EJTAG_CONTROL" );
 	chain_shift_instructions( CHAIN );
-
+	//Reset
 	register_fill( ejctrl->in, 0 );
-
 	ejctrl->in->data[PrRst] = 1;
 	ejctrl->in->data[PerRst] = 1;
-	chain_shift_data_registers( CHAIN, 0 );
-
+	chain_shift_data_registers( CHAIN, 0 );//Write
 	ejctrl->in->data[PrRst] = 0;
 	ejctrl->in->data[PerRst] = 0;
-	chain_shift_data_registers( CHAIN, 0 );
+	chain_shift_data_registers( CHAIN, 0 );//Write
+//
+	if (EJTAG_VER == EJTAG_20)
+	{
+		// Try enabling memory write on EJTAG_20 (BCM6348)
+		// Badly Copied from HairyDairyMaid V4.8
+		//ejtag_dma_write(0xff300000, (ejtag_dma_read(0xff300000) & ~(1<<2)) );
+//		printf("Set Address to READ from\n");
+//		printf("Select EJTAG ADDRESS Register\n");
+		part_set_instruction( PART, "EJTAG_ADDRESS" );
+		chain_shift_instructions ( CHAIN );
+		//Set to Debug Control Register Address, 0xFF300000
+		register_init( ejaddr->in, "11111111001100000000000000000000");
+//		printf("Write to ejaddr->in     =%s %08X\n",register_get_string( ejaddr->in ),reg_value( ejaddr->in ) );
+		chain_shift_data_registers (CHAIN, 0);//Write
+//		printf("Select EJTAG CONTROL Register\n");
+		part_set_instruction( PART, "EJTAG_CONTROL" );
+		chain_shift_instructions( CHAIN );
+		//Set some bits in CONTROL Register 0x00068B00
+		register_fill( ejctrl->in, 0 ); // Clear Register
+		ejctrl->in->data[PrAcc]    = 1; // 18----|||
+		ejctrl->in->data[DmaAcc]   = 1; // 17----|||
+		ejctrl->in->data[ProbEn]   = 1; // 15-----||
+		ejctrl->in->data[DStrt]    = 1; // 11------|
+		ejctrl->in->data[DrWn]     = 1; // 9-------|
+		ejctrl->in->data[Dsz1]     = 1; // 8-------| DMA_WORD = 0x00000100 = Bit8
+		chain_shift_data_registers( CHAIN, 1 );//WriteRead
+//		printf("Write To ejctrl->in     =%s %08X\n",register_get_string( ejctrl->in ), reg_value( ejctrl->in ) );
+//		printf("Read From ejctrl->out   =%s %08X\n",register_get_string( ejctrl->out ),reg_value( ejctrl->out ) );
+		do {
+//		    printf("Wait for DStrt to clear\n");
+		    part_set_instruction( PART, "EJTAG_CONTROL" );
+		    chain_shift_instructions( CHAIN );
+		    register_fill( ejctrl->in, 0 );
+		    //Set some bits in CONTROL Register 0x00068000
+		    ejctrl->in->data[PrAcc]    = 1; // 18----||
+		    ejctrl->in->data[DmaAcc]   = 1; // 17----||
+		    ejctrl->in->data[ProbEn]   = 1; // 15-----|
+		    chain_shift_data_registers( CHAIN, 1 );//WriteRead
+//			printf("Write To ejctrl->in     =%s %08X\n",register_get_string( ejctrl->in ), reg_value( ejctrl->in ) );
+//			printf("Read From ejctrl->out   =%s %08X\n",register_get_string( ejctrl->out ),reg_value( ejctrl->out ) );
+		} while ( ejctrl->out->data[DStrt]==1 );
+//		printf("Select EJTAG DATA Register\n");
+		part_set_instruction( PART, "EJTAG_DATA" );
+		chain_shift_instructions (CHAIN );
+		register_fill( ejdata->in, 0 ); // Clear Register
+		chain_shift_data_registers( CHAIN, 1 );//WriteRead
+//		printf( "Write To ejdata->in    =%s %08X\n", register_get_string( ejdata->in ), reg_value( ejdata->in ) );
+//		printf( "Read From ejdata->out  =%s %08X\n", register_get_string( ejdata->out ),reg_value( ejdata->out ) );
+//		printf("Select EJTAG CONTROL Register\n");
+		part_set_instruction( PART, "EJTAG_CONTROL" );
+		chain_shift_instructions( CHAIN );
+		register_fill( ejctrl->in, 0 );
+		//Set some bits in CONTROL Register 0x00048000
+		ejctrl->in->data[PrAcc]    = 1; // 18----||
+		ejctrl->in->data[ProbEn]   = 1; // 15-----|
+		chain_shift_data_registers( CHAIN, 1 );//WriteRead
+//		printf("Write To ejctrl->in     =%s %08X\n",register_get_string( ejctrl->in ), reg_value( ejctrl->in ) );
+//		printf("Read From ejctrl->out   =%s %08X\n",register_get_string( ejctrl->out ),reg_value( ejctrl->out ) );
+		if (ejctrl->out->data[DeRR]==1)
+		{
+			printf("DMA READ ERROR\n");
+		}
+		//Now have data from DCR, need to reset the MP Bit (2) and write it back out
+		register_init( ejdata->in, register_get_string( ejdata->out ) );
+		ejdata->in->data[MemProt] = 0;
+//		printf( "Need to Write ejdata-> =%s %08X\n", register_get_string( ejdata->in ),reg_value( ejdata->in ) );
+
+	// Now the Write
+//		printf("Set Address To Write To\n");
+//		printf("Select EJTAG ADDRESS Register\n");
+		part_set_instruction( PART, "EJTAG_ADDRESS" );
+		chain_shift_instructions ( CHAIN );
+		register_init( ejaddr->in, "11111111001100000000000000000000" );
+//		printf("Write to ejaddr->in     =%s %08X\n",register_get_string( ejaddr->in ), reg_value( ejaddr->in ) );
+		//This appears to be a write with NO Read
+		chain_shift_data_registers ( CHAIN, 0 );//Write
+//		printf("Select EJTAG DATA Register\n");
+		part_set_instruction( PART, "EJTAG_DATA" );
+		chain_shift_instructions ( CHAIN );
+		//The value is already in ejdata->in, so write it
+//		printf("Write To ejdata->in     =%s %08X\n", register_get_string( ejdata->in ),reg_value( ejdata->in ) );
+		chain_shift_data_registers( CHAIN, 0 );//Write
+//		printf("Select EJTAG CONTROL Register\n");
+		part_set_instruction( PART, "EJTAG_CONTROL" );
+		chain_shift_instructions( CHAIN );
+
+		//Set some bits in CONTROL Register
+		register_fill( ejctrl->in, 0 ); // Clear Register
+		ejctrl->in->data[DmaAcc]   = 1; // 17
+		ejctrl->in->data[Dsz1]     = 1; // DMA_WORD = 0x00000100 = Bit8
+		ejctrl->in->data[DStrt]    = 1; // 11
+		ejctrl->in->data[ProbEn]   = 1; // 15
+		ejctrl->in->data[PrAcc]    = 1; // 18
+		chain_shift_data_registers( CHAIN, 1 );//Write/Read
+//		printf("Write to ejctrl->in     =%s %08X\n",register_get_string( ejctrl->in ),  reg_value( ejctrl->in ) );
+//		printf("Read from ejctrl->out   =%s %08X\n",register_get_string( ejctrl->out ), reg_value( ejctrl->out ) );
+		do {
+//		    printf("Wait for DStrt to clear\n");
+		    //Might not need these 2 lines
+		    part_set_instruction( PART, "EJTAG_CONTROL" );
+		    chain_shift_instructions( CHAIN );
+		    ejctrl->in->data[DmaAcc]   = 1; // 17
+		    ejctrl->in->data[ProbEn]   = 1; // 15
+		    ejctrl->in->data[PrAcc]    = 1; // 18
+		    chain_shift_data_registers( CHAIN, 1 );//Write/Read
+//		    printf("Write to ejctrl->in     =%s %08X\n",register_get_string( ejctrl->in ),  reg_value( ejctrl->in ) );
+//		    printf("Read from ejctrl->out   =%s %08X\n",register_get_string( ejctrl->out ), reg_value( ejctrl->out ) );
+		} while ( ejctrl->out->data[DStrt]==1 );
+//		printf("Select EJTAG CONTROL Register\n");
+		part_set_instruction( PART, "EJTAG_CONTROL" );
+		chain_shift_instructions( CHAIN );
+		register_fill( ejctrl->in, 0 );
+		//Set some bits in CONTROL Register 0x00048000
+		ejctrl->in->data[PrAcc]    = 1; // 18----||
+		ejctrl->in->data[ProbEn]   = 1; // 15-----|
+		chain_shift_data_registers( CHAIN, 1 );//Write/Read
+//		printf("Write To ejctrl->in     =%s %08X\n",register_get_string( ejctrl->in ),reg_value( ejctrl->in ) );
+//		printf("Read From ejctrl->out   =%s %08X\n",register_get_string( ejctrl->out ),reg_value( ejctrl->out ) );
+		if ( ejctrl->out->data[DeRR]==1 )
+		{
+			printf("DMA WRITE ERROR\n");
+		}
+	}
+
+	part_set_instruction( PART, "EJTAG_CONTROL" );
+	chain_shift_instructions( CHAIN );
 
+	register_fill( ejctrl->in, 0 );
 	ejctrl->in->data[PrAcc] = 1;
 	ejctrl->in->data[ProbEn] = 1;
 	if (EJTAG_VER >= EJTAG_25) {
@@ -290,7 +458,11 @@
 	}
 	chain_shift_data_registers( CHAIN, 0 );
 
+	ejctrl->in->data[PrAcc] = 1;
+	ejctrl->in->data[ProbEn] = 1;
+	ejctrl->in->data[ProbTrap] = 1;
 	ejctrl->in->data[JtagBrk] = 1;
+
 	chain_shift_data_registers( CHAIN, 0 );
 
 	ejctrl->in->data[JtagBrk] = 0;
@@ -302,7 +474,10 @@
 			register_get_string( ejctrl->out ) );
 		return URJTAG_STATUS_FAIL;
 	}
-
+	else
+	{
+		printf("Processor entered Debug Mode.\n");
+	}
 	if (ejctrl->out->data[Rocc]) {
 		ejctrl->in->data[Rocc] = 0;
 		chain_shift_data_registers( CHAIN, 0 );
@@ -310,6 +485,9 @@
 		chain_shift_data_registers( CHAIN, 1 );
 	}
 
+	//HDM now Clears Watchdog
+
+
 	ejtag_run_pracc( bus, code, 4 );
 	BP->adr_hi = 0;
 	INITIALIZED = 1;
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to