diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 47c4955b..16038698 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,3 +1,7 @@ +2008-11-16 Kolja Waschk + + * src/bus/ejtag.c: Support BCM6348/EJTAG 3.1 (by Andy Potter/livebox) + 2008-10-30 Arnim Laeuger * src/svf/svf_bison.y, src/svf/svf.c, src/svf/svf.h: diff --git a/jtag/src/bus/ejtag.c b/jtag/src/bus/ejtag.c index 3a65ca43..49c324fb 100644 --- a/jtag/src/bus/ejtag.c +++ b/jtag/src/bus/ejtag.c @@ -53,19 +53,59 @@ typedef struct { #define EJTAG_20 0 #define EJTAG_25 1 #define EJTAG_26 2 - -/* 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 +#define EJTAG_31 3 + +/* 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 @@ ejtag_run_pracc( bus_t *bus, const uint32_t *code, unsigned int len ) 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 @@ ejtag_run_pracc( bus_t *bus, const uint32_t *code, unsigned int len ) 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 @@ ejtag_bus_init( bus_t *bus ) 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 @@ ejtag_bus_init( bus_t *bus ) 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 @@ ejtag_bus_init( bus_t *bus ) (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 @@ ejtag_bus_init( bus_t *bus ) } 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 @@ ejtag_bus_init( bus_t *bus ) 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 @@ ejtag_bus_init( bus_t *bus ) chain_shift_data_registers( CHAIN, 1 ); } + //HDM now Clears Watchdog + + ejtag_run_pracc( bus, code, 4 ); BP->adr_hi = 0; INITIALIZED = 1;