Support for BCM6348/EJTAG 3.1 (by Andy Potter/livebox)

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1387 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Kolja Waschk 16 years ago
parent 15c619f21d
commit fca58d9d22

@ -1,3 +1,7 @@
2008-11-16 Kolja Waschk <kawk>
* src/bus/ejtag.c: Support BCM6348/EJTAG 3.1 (by Andy Potter/livebox)
2008-10-30 Arnim Laeuger <arniml@users.sourceforge.net>
* src/svf/svf_bison.y, src/svf/svf.c, src/svf/svf.h:

@ -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;

Loading…
Cancel
Save