From ebceb79b821ebdd7a68e07ff4488789f0bf68105 Mon Sep 17 00:00:00 2001 From: dodge-this Date: Tue, 5 Feb 2013 18:28:23 +0000 Subject: [PATCH] jtagarm7 abstractions to allow jtagarm9 to leverage much of this code. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1451 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFETARM7.py | 105 +++++++++++++--------------------- client/GoodFETARM9.py | 53 ++++++++--------- client/gplay-arm.py | 2 +- firmware/apps/jtag/jtagarm7.c | 14 ++++- firmware/include/jtagarm7.h | 4 ++ 5 files changed, 82 insertions(+), 96 deletions(-) diff --git a/client/GoodFETARM7.py b/client/GoodFETARM7.py index fcc2d77..5a23466 100644 --- a/client/GoodFETARM7.py +++ b/client/GoodFETARM7.py @@ -45,6 +45,8 @@ CHAIN0 = 0x93 SCANCHAIN1 = 0x94 EICE_READ = 0x95 EICE_WRITE = 0x96 +SCAN_N_SIZE = 0x9e +IR_SIZE = 0x9f IR_EXTEST = 0x0 IR_SCAN_N = 0x2 @@ -214,19 +216,23 @@ class GoodFETARM7(GoodFET): self.flags = 0xffffffff self.nothing = 0xffffffff self.stored_regs = [] + def __del__(self): try: if (self.ARMget_dbgstate()&9) == 9: self.resume() except: sys.excepthook(*sys.exc_info()) + def setup(self): """Move the FET into the JTAG ARM application.""" #print "Initializing ARM." self.writecmd(0x13,SETUP,0,self.data) + def flash(self,file): """Flash an intel hex file to code memory.""" print "Flash not implemented."; + def dump(self,fn,start=0,stop=0xffffffff): """Dump an intel hex file from code memory.""" @@ -248,48 +254,68 @@ class GoodFETARM7(GoodFET): h.write_hex_file(fn); print "Dump not implemented."; + + def ARMsetIRsize(self, size=4): + if size > 255: + raise Exception("IR size cannot be >255!!") + self.writecmd(0x13, IR_SIZE, 1, [size]) + + def ARMsetSCANsize(self, size=4): + if size > 255: + raise Exception("IR size cannot be >255!!") + self.writecmd(0x13, SCAN_N_SIZE, 1, [size]) + def ARMshift_IR(self, IR, noretidle=0): self.writecmd(0x13,IR_SHIFT,2, [IR, LSB|noretidle]) return self.data + def ARMshift_DR(self, data, bits, flags): self.writecmd(0x13,DR_SHIFT,14,[bits&0xff, flags&0xff, 0, 0, data&0xff,(data>>8)&0xff,(data>>16)&0xff,(data>>24)&0xff, (data>>32)&0xff,(data>>40)&0xff,(data>>48)&0xff,(data>>56)&0xff,(data>>64)&0xff,(data>>72)&0xff]) return self.data + def ARMshift_DR_more(self, data, bits, flags): self.writecmd(0x13,DR_SHIFT_MORE,14,[bits&0xff, flags&0xff, 0, 0, data&0xff,(data>>8)&0xff,(data>>16)&0xff,(data>>24)&0xff, (data>>32)&0xff,(data>>40)&0xff,(data>>48)&0xff,(data>>56)&0xff,(data>>64)&0xff,(data>>72)&0xff]) return self.data + def ARMwaitDBG(self, timeout=0xff): self.current_dbgstate = self.ARMget_dbgstate() while ( not ((self.current_dbgstate & 9L) == 9)): timeout -=1 self.current_dbgstate = self.ARMget_dbgstate() return timeout + def ARMident(self): """Get an ARM's ID.""" self.ARMshift_IR(IR_IDCODE,0) self.ARMshift_DR(0,32,LSB) retval = struct.unpack("> 28) partno = (ident >> 12) & 0xffff mfgid = (ident >> 1) & 0x7ff return "Chip IDCODE: 0x%x\tver: %x\tpartno: %x\tmfgid: %x" % (ident, ver, partno, mfgid); + def ARMeice_write(self, reg, val): data = chop(val,4) data.extend([reg]) retval = self.writecmd(0x13, EICE_WRITE, 5, data) return retval + def ARMeice_read(self, reg): self.writecmd(0x13, EICE_READ, 1, [reg]) retval, = struct.unpack(">8)&0xff, (val>>16)&0xff, val>>24, reg,0,0,0]) retval = struct.unpack(">sys.stderr,"Debug Status:\t%s\n" % self.statusstr() #print >>sys.stderr,"CPSR: (%s) %s"%(self.ARMget_regCPSRstr()) - #resume = ARMreleasecpu - def resettap(self): self.writecmd(0x13, RESETTAP, 0,[]) @@ -523,38 +559,6 @@ class GoodFETARM7(GoodFET): self.ARMset_register(0, r0) return(val) - ''' - def ARMreadMem(self, adr, wrdcount=1): - retval = [] - r0 = self.ARMget_register(0); # store R0 and R1 - r1 = self.ARMget_register(1); - #print >>sys.stderr,("CPSR:\t%x"%self.ARMget_regCPSR()) - self.ARMset_register(0, adr); # write address into R0 - self.ARMset_register(1, 0xdeadbeef) - for word in range(adr, adr+(wrdcount*4), 4): - #sys.stdin.readline() - self.ARM_nop(0) - self.ARM_nop(1) - self.ARMdebuginstr(ARM_READ_MEM, 0); # push LDR R1, [R0], #4 into instruction pipeline (autoincrements for consecutive reads) - self.ARM_nop(0) - self.ARMrestart() - self.ARMwaitDBG() - #print hex(self.ARMget_register(1)) - - # FIXME: this may end up changing te current debug-state. should we compare to current_dbgstate? - #print repr(self.data[4]) - if (len(self.data)>4 and self.data[4] == '\x00'): - print >>sys.stderr,("FAILED TO READ MEMORY/RE-ENTER DEBUG MODE") - raise Exception("FAILED TO READ MEMORY/RE-ENTER DEBUG MODE") - return (-1); - else: - retval.append( self.ARMget_register(1) ) # read memory value from R1 register - #print >>sys.stderr,("CPSR: %x\t\tR0: %x\t\tR1: %x"%(self.ARMget_regCPSR(),self.ARMget_register(0),self.ARMget_register(1))) - self.ARMset_register(1, r1); # restore R0 and R1 - self.ARMset_register(0, r0); - return retval - ''' - def ARMreadStream(self, addr, bytecount): baseaddr = addr & 0xfffffffc endaddr = ((addr + bytecount + 3) & 0xfffffffc) @@ -627,13 +631,6 @@ class GoodFETARM7(GoodFET): # FIXME: handle the rest of the wordcount here. self.ARMset_registers(regs,0xe) - '''def ARMreadStream(self, adr, bytecount): - #data = [struct.unpack(">sys.stderr,("CPSR:\t%x"%self.ARMget_regCPSR()) - for widx in xrange(len(wordarray)): - address = adr + (widx*4) - word = wordarray[widx] - self.ARMset_register(0, address); # write address into R0 - self.ARMset_register(1, word); # write address into R0 - self.ARM_nop(0) - self.ARM_nop(1) - self.ARMdebuginstr(instr, 0); # push STR R1, [R0], #4 into instruction pipeline (autoincrements for consecutive writes) - self.ARM_nop(0) - self.ARMrestart() - self.ARMwaitDBG() - #print >>sys.stderr,hex(self.ARMget_register(1)) - self.ARMset_register(1, r1); # restore R0 and R1 - self.ARMset_register(0, r0); - ''' ARMwriteMem = ARMwriteChunk def ARMwriteStream(self, addr, datastr): diff --git a/client/GoodFETARM9.py b/client/GoodFETARM9.py index a92fe57..dd565e9 100644 --- a/client/GoodFETARM9.py +++ b/client/GoodFETARM9.py @@ -12,41 +12,36 @@ import sys, binascii, struct, time import atlasutils.smartprint as asp from GoodFET import GoodFET -import GoodFETARM7 +from GoodFETARM7 import * from intelhex import IntelHex -#Global Commands -READ = 0x00 -WRITE = 0x01 -PEEK = 0x02 -POKE = 0x03 -SETUP = 0x10 -START = 0x20 -STOP = 0x21 -CALL = 0x30 -EXEC = 0x31 -NOK = 0x7E -OK = 0x7F - -# ARM JTAG commands -IR_SHIFT = 0x80 -DR_SHIFT = 0x81 -RESETTAP = 0x82 -RESETTARGET = 0x83 -GET_REGISTER = 0x87 -SET_REGISTER = 0x88 -DEBUG_INSTR = 0x89 -# Really ARM specific stuff -WAIT_DBG = 0x91 -CHAIN0 = 0x93 -SCANCHAIN1 = 0x94 -EICE_READ = 0x95 -EICE_WRITE = 0x96 + + + + + + + + + + + + + + + + + + class GoodFETARM9(GoodFETARM7.GoodFETARM7): - def ARM9readMem(self, adr, wordcount): + def __init__(self): + GoodFETARM7.GoodGETARM7.__init__(self) + self.ARMsetSCANsize(5) + + def ARMreadMem(self, adr, wordcount=0): """ Only works in ARM mode currently WARNING: Addresses must be word-aligned! """ diff --git a/client/gplay-arm.py b/client/gplay-arm.py index 70333d7..2ab3fe9 100755 --- a/client/gplay-arm.py +++ b/client/gplay-arm.py @@ -6,7 +6,7 @@ from intelhex import IntelHex data = [] -client=GoodFETARM(); +client=GoodFETARM7(); def init(): #Initailize FET and set baud rate print >>sys.stderr,"Connecting to goodfet..." diff --git a/firmware/apps/jtag/jtagarm7.c b/firmware/apps/jtag/jtagarm7.c index a023481..0e0fbc2 100644 --- a/firmware/apps/jtag/jtagarm7.c +++ b/firmware/apps/jtag/jtagarm7.c @@ -34,6 +34,8 @@ unsigned char last_sysstate = 0; unsigned char last_ir = -1; unsigned char last_scanchain = -1; unsigned char current_dbgstate = -1; +unsigned char g_jtag_ir_size = 4; +unsigned char g_jtagarm_scan_n_bitsize = 4; //unsigned char last_halt_debug_state = -1; //unsigned long last_halt_pc = -1; @@ -90,7 +92,7 @@ u8 jtagarm_shift_ir(u8 ir, u8 flags){ if (last_ir != ir){ jtag_capture_ir(); jtag_shift_register(); - retval = jtag_trans_n(ir, 4, LSB|flags); + retval = jtag_trans_n(ir, g_jtag_ir_size, LSB|flags); last_ir = ir; } return retval; @@ -110,7 +112,7 @@ state” to the “Select DR” state each time the “Update” state is reache last_scanchain = chain; jtag_capture_dr(); jtag_shift_register(); - retval = jtag_trans_n(chain, 4, LSB | NORETIDLE); + retval = jtag_trans_n(chain, g_jtagarm_scan_n_bitsize, LSB | NORETIDLE); } jtagarm_shift_ir(testmode, NORETIDLE); return(retval); @@ -304,6 +306,14 @@ void jtagarm7_handle_fn( uint8_t const app, jtagarm7tdmi_start(); txdata(app,verb,0); break; + case JTAGARM7_SCAN_N_SIZE: + g_jtagarm_scan_n_bitsize = cmddata[0]; + txdata(app,verb,1); + break; + case JTAGARM7_IR_SIZE: + g_jtag_ir_size = cmddata[0]; + txdata(app,verb,1); + break; case JTAG_IR_SHIFT: cmddataword[0] = jtagarm_shift_ir(cmddata[0], cmddata[1]); txdata(app,verb,1); diff --git a/firmware/include/jtagarm7.h b/firmware/include/jtagarm7.h index 40338bf..3af587f 100644 --- a/firmware/include/jtagarm7.h +++ b/firmware/include/jtagarm7.h @@ -113,6 +113,8 @@ The least significant bit of the instruction register is scanned in and scanned #define JTAGARM7_SCANCHAIN1 0x94 #define JTAGARM7_EICE_READ 0x95 #define JTAGARM7_EICE_WRITE 0x96 +#define JTAGARM7_IR_SIZE 0x9f +#define JTAGARM7_SCAN_N_SIZE 0x9e // for deeper understanding, read the instruction cycle timing section of: @@ -158,6 +160,8 @@ The least significant bit of the instruction register is scanned in and scanned #define JTAG_ARM7TDMI_DBG_TBIT 16 extern app_t const jtagarm7_app; +extern unsigned char g_jtag_ir_size; +extern unsigned char g_jtagarm_scan_n_bitsize; #endif // JTAGARM7_H -- 2.20.1