X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFETARM7.py;h=f7f0b94de919f432deb1958058657100f2996888;hp=0864cb2019713a7138923945018ad66424b34f1d;hb=494cd04e27c3f437f55517c2de3f28b9b778ede4;hpb=c358276f31d141742a951112dc10bee4439a8b74 diff --git a/client/GoodFETARM7.py b/client/GoodFETARM7.py index 0864cb2..f7f0b94 100644 --- a/client/GoodFETARM7.py +++ b/client/GoodFETARM7.py @@ -32,9 +32,10 @@ IR_SHIFT = 0x80 DR_SHIFT = 0x81 RESETTAP = 0x82 RESETTARGET = 0x83 -GET_REGISTER = 0x87 -SET_REGISTER = 0x88 -DEBUG_INSTR = 0x89 +DR_SHIFT_MORE = 0x87 +GET_REGISTER = 0x8d +SET_REGISTER = 0x8e +DEBUG_INSTR = 0x8f # Really ARM specific stuff WAIT_DBG = 0x91 CHAIN0 = 0x93 @@ -122,6 +123,8 @@ 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... @@ -214,19 +217,38 @@ class GoodFETARM(GoodFET): """Move the FET into the JTAG ARM application.""" #print "Initializing ARM." self.writecmd(0x13,SETUP,0,self.data) - def getpc(self): - return self.ARMgetPC() def flash(self,file): """Flash an intel hex file to code memory.""" print "Flash not implemented."; - def dump(self,file,start=0,stop=0xffff): + def dump(self,fn,start=0,stop=0xffffffff): """Dump an intel hex file from code memory.""" + + print "Dumping from %04x to %04x as %s." % (start,stop,f); + # FIXME: get mcu state and return it to that state + self.halt() + + h = IntelHex(None); + i=start; + while i<=stop: + data=self.ARMreadChunk(i, 48, verbose=0); + print "Dumped %06x."%i; + for dword in data: + if i<=stop and dword != 0xdeadbeef: + h.puts( i, struct.pack(">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() @@ -282,6 +304,7 @@ class GoodFETARM(GoodFET): 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 @@ -373,6 +396,7 @@ class GoodFETARM(GoodFET): self.ARMset_register(15,self.storedPC&0xfffffffc) print "CPSR: (%s) %s"%(self.ARMget_regCPSRstr()) halt = ARMhaltcpu + def ARMreleasecpu(self): """Resume the CPU.""" # restore registers FIXME: DO THIS @@ -384,9 +408,10 @@ class GoodFETARM(GoodFET): self.ARMsetModeARM() # branch to the right address self.ARMset_register(15, self.storedPC) - print hex(self.storedPC) - print hex(self.ARMget_register(15)) - print hex(self.ARMchain0(self.storedPC,self.flags)[0]) + #print hex(self.storedPC) + #print hex(self.ARMget_register(15)) + #print hex(self.ARMchain0(self.storedPC,self.flags)[0]) + self.ARMchain0(self.storedPC,self.flags) self.ARM_nop(0) self.ARM_nop(1) self.ARMdebuginstr(ARM_INSTR_B_IMM | 0xfffff0,0) @@ -401,17 +426,18 @@ class GoodFETARM(GoodFET): self.ARMdebuginstr(THUMB_INSTR_MOV_PC_R0,0) self.ARM_nop(0) self.ARM_nop(1) - print hex(self.storedPC) - print hex(self.ARMget_register(15)) + #print hex(self.storedPC) + #print hex(self.ARMget_register(15)) print hex(self.ARMchain0(self.storedPC,self.flags)[0]) self.ARMdebuginstr(THUMB_INSTR_B_IMM | (0x7fc07fc),0) self.ARM_nop(0) self.ARMrestart() - resume = ARMreleasecpu + def resettap(self): self.writecmd(0x13, RESETTAP, 0,[]) + def ARMsetModeARM(self): r0 = None if ((self.current_dbgstate & DBG_TBIT)): @@ -423,6 +449,7 @@ class GoodFETARM(GoodFET): self.resettap() self.current_dbgstate = self.ARMget_dbgstate(); return self.current_dbgstate + def ARMsetModeThumb(self): # needs serious work and truing self.resettap() debugstr("=== Switching to THUMB mode ===") @@ -438,9 +465,11 @@ class GoodFETARM(GoodFET): self.ARMset_register(0,r0) self.current_dbgstate = self.ARMget_dbgstate(); return self.current_dbgstate + def ARMget_regCPSRstr(self): psr = self.ARMget_regCPSR() return hex(psr), PSRdecode(psr) + def ARMget_regCPSR(self): """Get an ARM's Register""" r0 = self.ARMget_register(0) @@ -451,6 +480,7 @@ class GoodFETARM(GoodFET): retval = self.ARMget_register(0) self.ARMset_register(0, r0) return retval + def ARMset_regCPSR(self, val): """Get an ARM's Register""" r0 = self.ARMget_register(0) @@ -461,6 +491,8 @@ class GoodFETARM(GoodFET): self.ARM_nop( 0) # push nop into pipeline - execute self.ARMset_register(0, r0) return(val) + + ''' def ARMreadMem(self, adr, wrdcount=1): retval = [] r0 = self.ARMget_register(0); # store R0 and R1 @@ -476,7 +508,7 @@ class GoodFETARM(GoodFET): self.ARM_nop(0) self.ARMrestart() self.ARMwaitDBG() - print hex(self.ARMget_register(1)) + #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]) @@ -490,16 +522,48 @@ class GoodFETARM(GoodFET): self.ARMset_register(1, r1); # restore R0 and R1 self.ARMset_register(0, r0); return retval - def ARMreadChunk(self, adr, wordcount): + ''' + + def ARMreadStream(self, addr, bytecount): + baseaddr = addr & 0xfffffffc + endaddr = ((addr + bytecount + 3) & 0xfffffffc) + diffstart = 4 - (addr - baseaddr) + diffend = 4 - (endaddr - (addr + bytecount )) + + + out = [] + data = [ x for x in self.ARMreadChunk( baseaddr, ((endaddr-baseaddr) / 4) ) ] + #print data, hex(baseaddr), hex(diffstart), hex(endaddr), hex(diffend) + if len(data) == 1: + #print "single dword" + out.append( struct.pack("0: + out.append( struct.pack(" 0): - if (wordcount%64 == 0): sys.stderr.write(".") + if (verbose and wordcount%64 == 0): sys.stderr.write(".") count = (wordcount, 0xe)[wordcount>0xd] bitmask = LDM_BITMASKS[count] self.ARMset_register(14,adr) @@ -508,17 +572,21 @@ class GoodFETARM(GoodFET): #FIXME: do we need the extra nop here? self.ARMrestart() self.ARMwaitDBG() - output.extend([self.ARMget_register(x) for x in xrange(count)]) + for x in range(count): + yield self.ARMget_register(x) 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): + #return output + + ARMreadMem = ARMreadChunk + peek = ARMreadMem + '''def ARMreadStream(self, adr, bytecount): data = [struct.unpack(">sys.stderr,("CPSR:\t%x"%self.ARMget_regCPSR()) @@ -553,13 +622,55 @@ 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 >>sys.stderr,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); + ''' + ARMwriteMem = ARMwriteChunk + + def ARMwriteStream(self, addr, datastr): + #bytecount = len(datastr) + #baseaddr = addr & 0xfffffffc + #diffstart = addr - baseaddr + #endaddr = ((addr + bytecount) & 0xfffffffc) + 4 + #diffend = 4 - (endaddr - (addr+bytecount)) + bytecount = len(datastr) + baseaddr = addr & 0xfffffffc + endaddr = ((addr + bytecount + 3) & 0xfffffffc) + diffstart = 4 - (addr - baseaddr) + diffend = 4 - (endaddr - (addr + bytecount )) + + print hex(baseaddr), hex(diffstart), hex(endaddr), hex(diffend) + out = [] + if diffstart: + dword = self.ARMreadChunk(baseaddr, 1)[0] & (0xffffffff>>(8*diffstart)) + dst = "\x00" * (4-diffstart) + datastr[:diffstart]; print hex(dword), repr(dst) + datachk = struct.unpack(">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 >>sys.stderr,(repr(bulk)) + #print >>sys.stderr,(repr(bulk)) self.writecmd(0x13,CHAIN0,16,bulk) d1,b1,a1 = struct.unpack("