jtagarm7 abstractions to allow jtagarm9 to leverage much of this code.
authordodge-this <dodge-this@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 5 Feb 2013 18:28:23 +0000 (18:28 +0000)
committerdodge-this <dodge-this@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 5 Feb 2013 18:28:23 +0000 (18:28 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1451 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETARM7.py
client/GoodFETARM9.py
client/gplay-arm.py
firmware/apps/jtag/jtagarm7.c
firmware/include/jtagarm7.h

index fcc2d77..5a23466 100644 (file)
@@ -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("<L", "".join(self.data[0:4]))[0]
         return retval
+
     def ARMidentstr(self):
         ident=self.ARMident()
         ver     = (ident >> 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("<L",self.data)
         return retval
+
     def ARMget_dbgstate(self):
         """Read the config register of an ARM."""
         self.ARMeice_read(EICE_DBGSTATUS)
         self.current_dbgstate = struct.unpack("<L", self.data[:4])[0]
         return self.current_dbgstate
     status = ARMget_dbgstate
+
     def statusstr(self):
         """Check the status as a string."""
         status=self.status()
@@ -300,36 +326,44 @@ class GoodFETARM7(GoodFET):
                 str="%s %s" %(self.ARMstatusbits[i],str)
             i*=2
         return str
+
     def ARMget_dbgctrl(self):
         """Read the config register of an ARM."""
         self.ARMeice_read(EICE_DBGCTRL)
         retval = struct.unpack("<L", self.data[:4])[0]
         return retval
+
     def ARMset_dbgctrl(self,config):
         """Write the config register of an ARM."""
         self.ARMeice_write(EICE_DBGCTRL, config&7)
+
     def ARMgetPC(self):
         """Get an ARM's PC. Note: real PC gets all wonky in debug mode, this is the "saved" PC"""
         return self.storedPC
     getpc = ARMgetPC
+    
     def ARMsetPC(self, val):
         """Set an ARM's PC.  Note: real PC gets all wonky in debug mode, this changes the "saved" PC which is used when exiting debug mode"""
         self.storedPC = val
+
     def ARMget_register(self, reg):
         """Get an ARM's Register"""
         self.writecmd(0x13,GET_REGISTER,1,[reg&0xf])
         retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
         return retval
+
     def ARMset_register(self, reg, val):
         """Get an ARM's Register"""
         self.writecmd(0x13,SET_REGISTER,8,[val&0xff, (val>>8)&0xff, (val>>16)&0xff, val>>24, reg,0,0,0])
         retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
         return retval
+
     def ARMget_registers(self):
         """Get ARM Registers"""
         regs = [ self.ARMget_register(x) for x in range(15) ]
         regs.append(self.ARMgetPC())            # make sure we snag the "static" version of PC
         return regs
+
     def ARMset_registers(self, regs, mask):
         """Set ARM Registers"""
         for x in xrange(15):
@@ -337,6 +371,7 @@ class GoodFETARM7(GoodFET):
             self.ARMset_register(x,regs.pop(0))
         if (1<<15) & mask:                      # make sure we set the "static" version of PC or changes will be lost
           self.ARMsetPC(regs.pop(0))
+
     def ARMdebuginstr(self,instr,bkpt):
         if type (instr) == int or type(instr) == long:
             instr = struct.pack("<L", instr)
@@ -344,12 +379,15 @@ class GoodFETARM7(GoodFET):
         instr.extend([bkpt])
         self.writecmd(0x13,DEBUG_INSTR,len(instr),instr)
         return (self.data)
+
     def ARM_nop(self, bkpt=0):
         if self.status() & DBG_TBIT:
             return self.ARMdebuginstr(THUMB_INSTR_NOP, bkpt)
         return self.ARMdebuginstr(ARM_INSTR_NOP, bkpt)
+
     def ARMrestart(self):
         self.ARMshift_IR(IR_RESTART)
+
     def ARMset_watchpoint0(self, addr, addrmask, data, datamask, ctrl, ctrlmask):
         self.ARMeice_write(EICE_WP0ADDR, addr);           # write 0 in watchpoint 0 address
         self.ARMeice_write(EICE_WP0ADDRMASK, addrmask);   # write 0xffffffff in watchpoint 0 address mask
@@ -358,6 +396,7 @@ class GoodFETARM7(GoodFET):
         self.ARMeice_write(EICE_WP0CTRL, ctrl);           # write 0x00000100 in watchpoint 0 control value register (enables watchpoint)
         self.ARMeice_write(EICE_WP0CTRLMASK, ctrlmask);   # write 0xfffffff7 in watchpoint 0 control mask - only detect the fetch instruction
         return self.data
+
     def ARMset_watchpoint1(self, addr, addrmask, data, datamask, ctrl, ctrlmask):
         self.ARMeice_write(EICE_WP1ADDR, addr);           # write 0 in watchpoint 1 address
         self.ARMeice_write(EICE_WP1ADDRMASK, addrmask);   # write 0xffffffff in watchpoint 1 address mask
@@ -366,6 +405,7 @@ class GoodFETARM7(GoodFET):
         self.ARMeice_write(EICE_WP1CTRL, ctrl);           # write 0x00000100 in watchpoint 1 control value register (enables watchpoint)
         self.ARMeice_write(EICE_WP1CTRLMASK, ctrlmask);   # write 0xfffffff7 in watchpoint 1 control mask - only detect the fetch instruction
         return self.data
+
     def THUMBgetPC(self):
         THUMB_INSTR_STR_R0_r0 =     0x60006000L
         THUMB_INSTR_MOV_R0_PC =     0x46b846b8L
@@ -377,6 +417,7 @@ class GoodFETARM7(GoodFET):
         retval = self.ARMget_register(0)
         self.ARMset_register(0,r0)
         return retval
+
     def ARMcapture_system_state(self, pcoffset):
         self.c0Data, self.flags, self.c0Addr = self.ARMchain0(0)
         if self.ARMget_dbgstate() & DBG_TBIT:
@@ -388,7 +429,6 @@ class GoodFETARM7(GoodFET):
         self.cpsr = self.ARMget_regCPSR()
         #print "ARMcapture_system_state: stored pc: 0x%x  last_dbg_state: 0x%x" % (self.storedPC, self.last_dbg_state)
 
-    #def ARMhaltcpu(self):
     def halt(self):
         """Halt the CPU."""
         if self.ARMget_dbgstate()&DBG_DBGACK:
@@ -413,9 +453,7 @@ class GoodFETARM7(GoodFET):
         #print "stored regs: " + repr(self.stored_regs)
         #print self.print_stored_registers()
         #print "CPSR: (%s) %s"%(self.ARMget_regCPSRstr())
-    #halt = ARMhaltcpu
 
-    #def ARMreleasecpu(self):
     def resume(self):
         """Resume the CPU."""
         # FIXME: restore CPSR
@@ -464,8 +502,6 @@ class GoodFETARM7(GoodFET):
         #print >>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("<L", x) for x in self.ARMreadChunk(adr, (bytecount-1/4)+1)]
-        diff = adr % 4
-        address = adr - diff
-        data = [ struct.pack("<L", x) for x in self.ARMreadChunk(address, (bytecount-1/4)+1) ]
-        return "".join(data)[diff:bytecount]'''
-    
     ARMreadMem = ARMreadChunk
     peek = ARMreadMem
 
@@ -660,26 +657,6 @@ class GoodFETARM7(GoodFET):
             adr += count*4
             #print hex(adr)
         # FIXME: handle the rest of the wordcount here.
-        '''
-    def ARMwriteMem(self, adr, wordarray, instr=ARM_WRITE_MEM):
-        r0 = self.ARMget_register(0);        # store R0 and R1
-        r1 = self.ARMget_register(1);
-        #print >>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):
index a92fe57..dd565e9 100644 (file)
 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!
         """
index 70333d7..2ab3fe9 100755 (executable)
@@ -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..."
index a023481..0e0fbc2 100644 (file)
@@ -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);
index 40338bf..3af587f 100644 (file)
@@ -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