X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFETARM7.py;h=01e929c0227f975cf024f15bb7dd89c49752d36a;hp=83fc5160e1412911bc0b6495b460087e3ed790aa;hb=f7fdc48f01ada713d5034763a2f3395fe2a7c51b;hpb=3fbd4830f8d8dc3011415f1aab574561f603cd6e diff --git a/client/GoodFETARM7.py b/client/GoodFETARM7.py index 83fc516..01e929c 100644 --- a/client/GoodFETARM7.py +++ b/client/GoodFETARM7.py @@ -1,8 +1,6 @@ #!/usr/bin/env python # GoodFET ARM Client Library # -# -# Good luck with alpha / beta code. # Contributions and bug reports welcome. # # todo: @@ -10,15 +8,8 @@ # * ensure correct PC handling # * flash manipulation (probably need to get the specific chip for this one) # * set security (chip-specific) -# * -ancilary/faster- ldm/stm versions of memory access (had trouble in past, possibly also due to haphazard abuse of DCLK) -# -# fixme now stuff: -# * thumb mode get/set_register - DONE! -# * thumb to arm mode - DONE! -# * rethink the whole python/c trade-off for cross-python session debugging import sys, binascii, struct, time -import atlasutils.smartprint as asp from GoodFET import GoodFET from intelhex import IntelHex @@ -40,10 +31,11 @@ OK = 0x7F IR_SHIFT = 0x80 DR_SHIFT = 0x81 RESETTAP = 0x82 -RESETTARGET = 0x86 -GET_REGISTER = 0x87 -SET_REGISTER = 0x88 -DEBUG_INSTR = 0x89 +RESETTARGET = 0x83 +DR_SHIFT_MORE = 0x87 +GET_REGISTER = 0x8d +SET_REGISTER = 0x8e +DEBUG_INSTR = 0x8f # Really ARM specific stuff WAIT_DBG = 0x91 CHAIN0 = 0x93 @@ -131,9 +123,12 @@ ARM_INSTR_LDR_R1_r0_4 = 0xe4901004L ARM_READ_MEM = ARM_INSTR_LDR_R1_r0_4 ARM_INSTR_STR_R1_r0_4 = 0xe4801004L ARM_WRITE_MEM = ARM_INSTR_STR_R1_r0_4 +ARM_INSTR_STRB_R1_r0_1 = 0xe4c01001L +ARM_WRITE_MEM_BYTE = ARM_INSTR_STRB_R1_r0_1 ARM_INSTR_MRS_R0_CPSR = 0xe10f0000L ARM_INSTR_MSR_cpsr_cxsf_R0 =0xe12ff000L -ARM_INSTR_STMIA_R14_r0_rx = 0xE88E0000L # add up to 65k to indicate which registers... +ARM_INSTR_STMIA_R14_r0_rx = 0xE88e0000L # add up to 65k to indicate which registers... +ARM_INSTR_LDMIA_R14_r0_rx = 0xE89e0000L # add up to 65k to indicate which registers... ARM_STORE_MULTIPLE = ARM_INSTR_STMIA_R14_r0_rx ARM_INSTR_SKANKREGS = 0xE88F7fffL ARM_INSTR_CLOBBEREGS = 0xE89F7fffL @@ -183,6 +178,7 @@ DBGCTRLBITS = { 1<>8)&0xff,(data>>16)&0xff,(data>>24)&0xff]) + 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() @@ -249,10 +248,10 @@ class GoodFETARM(GoodFET): return retval def ARMidentstr(self): ident=self.ARMident() - ver = ident >> 28 - partno = (ident >> 12) & 0x10 - mfgid = ident & 0xfff - return "mfg: %x\npartno: %x\nver: %x\n(%x)" % (ver, partno, mfgid, ident); + ver = (ident >> 28) + partno = (ident >> 12) & 0xffff + mfgid = (ident >> 1) & 0x7ff + return "Chip IDCODE: 0x%x\n\tver: %x\n\tpartno: %x\n\tmfgid: %x\n" % (ident, ver, partno, mfgid); def ARMeice_write(self, reg, val): data = chop(val,4) data.extend([reg]) @@ -304,20 +303,16 @@ class GoodFETARM(GoodFET): return retval def ARMget_registers(self): """Get ARM Registers""" - # FIXME: should we clobber r15 first? if results get wonky, we will. - self.ARMdebuginstr(ARM_INSTR_SKANKREGS,0) - self.ARM_nop(0) - self.ARM_nop(0) - regs = [ struct.unpack(" 0): + if (wordcount%64 == 0): sys.stderr.write(".") + count = (wordcount, 0xe)[wordcount>0xd] + bitmask = LDM_BITMASKS[count] + self.ARMset_register(14,adr) + self.ARM_nop(1) + self.ARMdebuginstr(ARM_INSTR_LDMIA_R14_r0_rx | bitmask ,0) + #FIXME: do we need the extra nop here? + self.ARMrestart() + self.ARMwaitDBG() + output.extend([self.ARMget_register(x) for x in xrange(count)]) + wordcount -= count + adr += count*4 + #print hex(adr) + # FIXME: handle the rest of the wordcount here. + self.ARMset_registers(regs,0xe) + return output + def ARMreadStream(self, adr, bytecount): + data = [struct.unpack(" 0): + if (wordcount%64 == 0): sys.stderr.write(".") + count = (wordcount, 0xe)[wordcount>0xd] + bitmask = LDM_BITMASKS[count] + self.ARMset_register(14,adr) + #print len(wordarray),bin(bitmask) + self.ARMset_registers(wordarray[:count],bitmask) + self.ARM_nop(1) + self.ARMdebuginstr(ARM_INSTR_STMIA_R14_r0_rx | bitmask ,0) + #FIXME: do we need the extra nop here? + self.ARMrestart() + self.ARMwaitDBG() + wordarray = wordarray[count:] + wordcount -= count + 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()) @@ -513,13 +559,16 @@ class GoodFETARM(GoodFET): self.ARMset_register(1, word); # write address into R0 self.ARM_nop(0) self.ARM_nop(1) - self.ARMdebuginstr(ARM_WRITE_MEM, 0); # push STR R1, [R0], #4 into instruction pipeline (autoincrements for consecutive writes) + 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 hex(self.ARMget_register(1)) + print >>sys.stderr,hex(self.ARMget_register(1)) self.ARMset_register(1, r1); # restore R0 and R1 self.ARMset_register(0, r0); + def writeMemByte(self, adr, byte): + self.ARMwriteMem(adr, byte, ARM_WRITE_MEM_BYTE) + ARMstatusbits={ 0x10 : "TBIT", @@ -533,22 +582,24 @@ class GoodFETARM(GoodFET): 0x02 : "force dbgrq", 0x01 : "force dbgack" } - + def ARMresettarget(self, delay=10): + return self.writecmd(0x13,RESETTARGET,2, [ delay&0xff, (delay>>8)&0xff ] ) def ARMchain0(self, address, bits=0x819684c054, data=0): bulk = chop(address,4) bulk.extend(chop(bits,8)) bulk.extend(chop(data,4)) - print (repr(bulk)) + print >>sys.stderr,(repr(bulk)) self.writecmd(0x13,CHAIN0,16,bulk) d1,b1,a1 = struct.unpack(">sys.stderr,"Identifying Target:" ident=self.ARMidentstr() - print "Target identifies as %s." % ident - print "Debug Status: %s." % self.statusstr() - #print "System State: %x." % self.ARMget_regCPSRstr() + print >>sys.stderr,ident + print >>sys.stderr,"Debug Status:\t%s\n" % self.statusstr() + def stop(self): """Stop debugging.""" self.writecmd(0x13,STOP,0,self.data)