played around with different inputs to change the temperature display
[goodfet] / client / GoodFETADIv5.py
1 #!/usr/bin/env python
2 # GoodFET ARM Debugging Interface v5 (ADIv5) Client Library.
3 # the ideal interface to pwning ARM Cortex
4
5 # Contributions and bug reports welcome.
6 #
7
8
9 import sys, binascii, struct, time
10 import atlasutils.smartprint as asp
11 from GoodFET import GoodFET
12 from intelhex import IntelHex
13
14
15 #Global Commands
16 READ  = 0x00
17 WRITE = 0x01
18 PEEK  = 0x02
19 POKE  = 0x03
20 SETUP = 0x10
21 START = 0x20
22 STOP  = 0x21
23 CALL  = 0x30
24 EXEC  = 0x31
25 NOK   = 0x7E
26 OK    = 0x7F
27
28 # ARM7TDMI JTAG commands
29 IR_SHIFT =              0x80
30 DR_SHIFT =              0x81
31 RESETTAP =              0x82
32 RESETTARGET =           0x83
33 GET_REGISTER =          0x87
34 SET_REGISTER =          0x88
35 DEBUG_INSTR =           0x89
36 # Really ARM specific stuff
37 WAIT_DBG =              0x91
38 CHAIN0 =                0x93
39 SCANCHAIN1 =            0x94
40 EICE_READ =             0x95
41 EICE_WRITE =            0x96
42
43 #4-bit ARM JTAG INSTRUCTIONS - STANDARD
44 IR_ABORT =              0x8
45 IR_RESERVED1 =          0x9
46 IR_DPACC =              0xA
47 IR_APACC =              0xB
48 IR_RESERVED2 =          0xC
49 IR_RESERVED3 =          0xD
50 IR_IDCODE =             0xE
51 IR_BYPASS =             0xF
52 #4-bit ARM JTAG INSTRUCTIONS - IMPLEMENTATION-DEFINED
53 IR_EXTEST =             0x0
54 IR_SAMPLE =             0x1
55 IR_PRELOAD =            0x2
56 IR_RESERVED =           0x3
57 IR_INTEST =             0x4
58 IR_CLAMP =              0x5
59 IR_HIGHZ =              0x6
60 IR_CLAMPZ =             0x7
61
62 DP_CTRLSTAT_OFF =       0x4
63 DP_SELECT_OFF =         0x8
64 DP_RDBUFF_OFF =         0xC
65
66 MAX_AP_COUNT = 16
67
68 PM_usr = 0b10000
69 PM_fiq = 0b10001
70 PM_irq = 0b10010
71 PM_svc = 0b10011
72 PM_abt = 0b10111
73 PM_und = 0b11011
74 PM_sys = 0b11111
75 proc_modes = {
76     0:      ("UNKNOWN, MESSED UP PROCESSOR MODE","fsck", "This should Never happen.  MCU is in funky state!"),
77     PM_usr: ("User Processor Mode", "usr", "Normal program execution mode"),
78     PM_fiq: ("FIQ Processor Mode", "fiq", "Supports a high-speed data transfer or channel process"),
79     PM_irq: ("IRQ Processor Mode", "irq", "Used for general-purpose interrupt handling"),
80     PM_svc: ("Supervisor Processor Mode", "svc", "A protected mode for the operating system"),
81     PM_abt: ("Abort Processor Mode", "abt", "Implements virtual memory and/or memory protection"),
82     PM_und: ("Undefined Processor Mode", "und", "Supports software emulation of hardware coprocessor"),
83     PM_sys: ("System Processor Mode", "sys", "Runs privileged operating system tasks (ARMv4 and above)"),
84 }
85
86 PSR_bits = [ 
87     None, None, None, None, None, "Thumb", "nFIQ_int", "nIRQ_int", 
88     "nImprDataAbort_int", "BIGendian", None, None, None, None, None, None, 
89     "GE_0", "GE_1", "GE_2", "GE_3", None, None, None, None, 
90     "Jazelle", None, None, "Q (DSP-overflow)", "oVerflow", "Carry", "Zero", "Neg",
91     ]
92
93 ARM_INSTR_NOP =             0xe1a00000L
94 ARM_INSTR_BX_R0 =           0xe12fff10L
95 ARM_INSTR_STR_Rx_r14 =      0xe58f0000L # from atmel docs
96 ARM_READ_REG =              ARM_INSTR_STR_Rx_r14
97 ARM_INSTR_LDR_Rx_r14 =      0xe59f0000L # from atmel docs
98 ARM_WRITE_REG =             ARM_INSTR_LDR_Rx_r14
99 ARM_INSTR_LDR_R1_r0_4 =     0xe4901004L
100 ARM_READ_MEM =              ARM_INSTR_LDR_R1_r0_4
101 ARM_INSTR_STR_R1_r0_4 =     0xe4801004L
102 ARM_WRITE_MEM =             ARM_INSTR_STR_R1_r0_4
103 ARM_INSTR_MRS_R0_CPSR =     0xe10f0000L
104 ARM_INSTR_MSR_cpsr_cxsf_R0 =0xe12ff000L
105 ARM_INSTR_STMIA_R14_r0_rx = 0xE88e0000L      # add up to 65k to indicate which registers...
106 ARM_INSTR_LDMIA_R14_r0_rx = 0xE89e0000L      # add up to 65k to indicate which registers...
107 ARM_STORE_MULTIPLE =        ARM_INSTR_STMIA_R14_r0_rx
108 ARM_INSTR_SKANKREGS =       0xE88F7fffL
109 ARM_INSTR_CLOBBEREGS =      0xE89F7fffL
110
111 ARM_INSTR_B_IMM =           0xea000000L
112 ARM_INSTR_B_PC =            0xea000000L
113 ARM_INSTR_BX_PC =           0xe1200010L      # need to set r0 to the desired address
114 THUMB_INSTR_LDR_R0_r0 =     0x68006800L
115 THUMB_WRITE_REG =           THUMB_INSTR_LDR_R0_r0
116 THUMB_INSTR_STR_R0_r0 =     0x60006000L
117 THUMB_READ_REG =            THUMB_INSTR_STR_R0_r0
118 THUMB_INSTR_MOV_R0_PC =     0x46b846b8L
119 THUMB_INSTR_MOV_PC_R0 =     0x46474647L
120 THUMB_INSTR_BX_PC =         0x47784778L
121 THUMB_INSTR_NOP =           0x1c001c00L
122 THUMB_INSTR_B_IMM =         0xe000e000L
123 ARM_REG_PC =                15
124
125
126 LDM_BITMASKS = [(1<<x)-1 for x in xrange(16)]
127
128 CSYSPWRUPACK =              1<<31
129 CSYSPWRUPACK_BIT =          31
130 CSYSPWRUPREQ =              1<<30
131 CSYSPWRUPREQ_BIT =          30
132 CDBGPWRUPACK =              1<<29
133 CDBGPWRUPACK_BIT =          29
134 CDBGPWRUPREQ =              1<<28
135 CDBGPWRUPREQ_BIT =          28
136 CSYSRSTACK =                1<<27
137 CSYSRSTACK_BIT =            27
138 CSYSRSTREQ =                1<<26
139 CSYSRSTREQ_BIT =            26
140 TRNCNT =                    0x3ff<<12
141 TRNCNT_BIT =                12
142 MASKLANE =                  0xf<<8
143 MASKLANE_BIT =              8
144 WDATAERR =                  1<<7
145 WDATAERR =                  1<<7
146 READOK =                    1<<6
147 READOK =                    1<<6
148 STICKYERR =                 1<<5
149 STICKYERR =                 1<<5
150 STICKYCMP =                 1<<4
151 STICKYCMP =                 1<<4
152 TRNMODE =                   3<<2
153 TRNMODE =                   3<<2
154 STICKYORUN =                1<<1
155 STICKYORUN =                1<<1
156 ORUNDETECT =                1<<0
157 ORUNDETECT =                1<<0
158
159
160 def debugstr(strng):
161     print >>sys.stderr,(strng)
162 def PSRdecode(psrval):
163     output = [ "(%s mode)"%proc_modes[psrval&0x1f][1] ]
164     for x in xrange(5,32):
165         if psrval & (1<<x):
166             output.append(PSR_bits[x])
167     return " ".join(output)
168    
169 fmt = ["B", "B", "<H", "<L", "<L", "<Q", "<Q", "<Q", "<Q"]
170 def chop(val,byts):
171     s = struct.pack(fmt[byts], val)
172     return [ord(b) for b in s ][:byts]
173         
174 class GoodFETADIv5(GoodFET):
175     """A GoodFET variant for use with ARM7TDMI microprocessor."""
176     def __init__(self):
177         GoodFET.__init__(self)
178         self.storedPC =         0xffffffff
179         self.current_dbgstate = 0xffffffff
180         self.flags =            0xffffffff
181         self.nothing =          0xffffffff
182         self.ir_status =        None
183         self.ap_selected =      None
184         self.ap_bank =          0
185         self.aps =              None
186
187     def __del__(self):
188         pass
189
190     def setup(self):
191         """Move the FET into the JTAG ARM application."""
192         #print "Initializing ARM."
193         self.writecmd(0x14,SETUP,0,self.data)
194
195     def getpc(self):
196         return self.ADIgetPC()
197
198     def flash(self,file):
199         """Flash an intel hex file to code memory."""
200         print "Flash not implemented.";
201
202     def dump(self,file,start=0,stop=0xffff):
203         """Dump an intel hex file from code memory."""
204         print "Dump not implemented.";
205
206     def ADIident(self):
207         """Get an ARM's ID."""
208         raise Exception("Not Implemented.  Abstract base class method called.")
209     def ADIidentstr(self):
210         ident=self.ADIident()
211         ver     = (ident >> 28)
212         partno  = (ident >> 12) & 0xffff
213         mfgid   = (ident >> 1)  & 0x7ff
214         return "Chip IDCODE: 0x%x\n\tver: %x\n\tpartno: %x\n\tmfgid: %x\n" % (ident, ver, partno, mfgid); 
215
216     def ADIget_register(self, reg):
217         """Get an ARM's Register"""
218         self.writecmd(0x14,GET_REGISTER,1,[reg&0xf])
219         retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
220         return retval
221     def ADIset_register(self, reg, val):
222         """Get an ARM's Register"""
223         self.writecmd(0x14,SET_REGISTER,8,[val&0xff, (val>>8)&0xff, (val>>16)&0xff, val>>24, reg,0,0,0])
224         retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
225         return retval
226     def ADIget_registers(self):
227         """Get ARM Registers"""
228         regs = [ self.ADIget_register(x) for x in range(15) ]
229         regs.append(self.ADIgetPC())            # make sure we snag the "static" version of PC
230         return regs
231     def ADIset_registers(self, regs, mask):
232         """Set ARM Registers"""
233         for x in xrange(15):
234           if (1<<x) & mask:
235             self.ADIset_register(x,regs.pop(0))
236         if (1<<15) & mask:                      # make sure we set the "static" version of PC or changes will be lost
237           self.ADIsetPC(regs.pop(0))
238
239     def ADIrestart(self):
240         raise Exception("Not Implemented.  Abstract base class method called.")
241
242     ####### Common DP features #######
243     def ADIgetAPACC(self, addr, flags):         # candidate for firmware.  not sure the intelligence wants to be there, but performance may want it.
244         raise Exception("Not Implemented.  Abstract base class method called.")
245     def ADIsetAPACC(self, addr, val):
246         raise Exception("Not Implemented.  Abstract base class method called.")
247     def ADIgetDPACC(self, addr, flags):         # candidate for firmware.  not sure the intelligence wants to be there, but performance may want it.
248         raise Exception("Not Implemented.  Abstract base class method called.")
249     def ADIsetDPACC(self, addr, val):
250         raise Exception("Not Implemented.  Abstract base class method called.")
251     def ADIsetABORT(self):
252         """ ONLY use if the debugger has received WAIT responses over an extended period"""
253         raise Exception("Not Implemented.  Abstract base class method called.")
254
255     def ADIsetSELECT(self, num):
256         return self.ADIsetDPACC(0x8, num)
257     def ADIgetSELECT(self):
258         return self.ADIgetDPACC(0x8)
259     def ADIgetSELECTrepr(self):
260         raw = self.ADIgetSELECT()
261         swdp_ctrlsel = raw&1
262         apbanksel = (raw>>4) & 0xf
263         apsel = raw>>24
264         return "SWDP_CTRLSEL = %d\nAPBANKSEL = %d\nAPSEL = %d\n"
265
266     def ADIgetAccessPorts(self):
267         if self.aps == None:
268             self.aps = [createAP(self, x) for x in xrange(MAX_AP_COUNT)]
269         return self.aps
270
271     def ADIgetWCR(self):        # SWDP only
272         raise Exception("IMPLEMENT ME: ADIgetWCR")
273
274     def ADIgetRESEND(self):     # SWDP only
275         raise Exception("IMPLEMENT ME: ADIgetRESEND")
276
277 class GoodFETADIjtag(GoodFETADIv5):
278     """A GoodFET variant for use with ARM7TDMI microprocessor."""
279     def ADIshift_IR(self, IR, noretidle=0):
280         if (self.ir_status != IR):
281             self.writecmd(0x14,IR_SHIFT,2, [IR, LSB|noretidle])
282             self.ir_status = IR
283         return self.data
284     def ADIshift_DR(self, bignum, bits, flags=0):
285         data = [bits&0xff, flags&0xff,0,0]
286         data.extend(chop(data, bits/4))
287         self.writecmd(0x14,DR_SHIFT, len(data), data)
288         return self.data
289     def ADIident(self):
290         """Get an ARM's ID."""
291         self.ADIshift_IR(IR_IDCODE,0)
292         self.ADIshift_DR(0,32,LSB)
293         retval = struct.unpack("<L", "".join(self.data[0:4]))[0]
294         return retval
295
296     def ADIdebuginstr(self,instr,bkpt):
297         """if type (instr) == int or type(instr) == long:
298             instr = struct.pack("<L", instr)
299         instr = [int("0x%x"%ord(x),16) for x in instr]
300         instr.extend([bkpt])
301         self.writecmd(0x14,DEBUG_INSTR,len(instr),instr)
302         return (self.data)"""
303         pass
304     def ADI_nop(self, bkpt=0):
305         """if self.status() & DBG_TBIT:
306             return self.ADIdebuginstr(THUMB_INSTR_NOP, bkpt)
307         return self.ADIdebuginstr(ARM_INSTR_NOP, bkpt)"""
308         pass
309
310     def ADIrestart(self):
311         self.ADIshift_IR(IR_RESTART)
312
313     ####### Common DP features #######
314     def ADIgetAPACC(self, addr):                # candidate for firmware.  not sure the intelligence wants to be there, but performance may want it.
315         self.ADIshift_IR(IR_APACC)
316         data = 1 | (addr>>1)                    # addr[3:2] goes in bits [2:1].  this *must* be a multiple of 4.
317         return self.ADIshift_DR(data, 35, LSB)
318     def ADIsetAPACC(self, addr, val):
319         """
320         0 < val < 0xffffffff
321         addr == 4*n   (ie.  multiple of four, returns the word at that register)
322         """
323         self.ADIshift_IR(IR_APACC)
324         data = (val<<3) | (addr>>1)             # addr[3:2] goes in bits [2:1].  this *must* be a multiple of 4.
325         self.ADIshift_DR(data, 35, LSB)
326     def ADIgetDPACC(self, addr, flags):         # candidate for firmware.  not sure the intelligence wants to be there, but performance may want it.
327         self.ADIshift_IR(IR_DPACC)
328         data = 1 | (addr>>1)                    # addr[3:2] goes in bits [2:1].  this *must* be a multiple of 4.
329         return self.ADIshift_DR(data, 35, LSB)
330     def ADIsetDPACC(self, addr, val):
331         """
332         0 < val < 0xffffffff
333         addr == 4*n   (ie.  multiple of four, returns the word at that register)
334         """
335         self.ADIshift_IR(IR_DPACC)
336         data = (val<<3) | (addr>>1)             # addr[3:2] goes in bits [2:1].  this *must* be a multiple of 4.
337         self.ADIshift_DR(data, 35, LSB)
338
339     def ADIsetABORT(self):
340         """ ONLY use if the debugger has received WAIT responses over an extended period"""
341         self.ADIshift_IR(self, IR_ABORT)
342         self.ADIshift_DR(self, 1, 35)
343
344     def ADIsetSELECT(self, apnum, apbank, flags="ignored for jtag"):
345         if (apnum != self.ap_selected or apbank != self.ap_bank):
346             select = (apnum<<24) | (apbank<<4)
347             self.ADIsetDPACC(0x8, select)
348             self.ap_selected = apnum
349             self.ap_bank = apbank
350     def ADIgetSELECT(self, noncached=False):
351         if (noncached):
352             return self.ADIgetDPACC(0x8)
353         return self.ap_selected
354
355 def createAP(dp, apnum):
356     idr = 0xfc
357     bank = idr/16
358     self.dp.ADIsetSELECT(self.apnum, bank)
359     ident = self.dp.ADIgetAPACC(idr&0xf)
360     if ((ident>>16)&1):
361         return ADI_MEM_AP(dp, apnum)
362     return ADI_JTAG_AP(dp, apnum)
363
364 class ADI_AccessPort:           # define common AP calls
365     def __init__(self, DP, apnum):
366         self.dp = DP            # link to parent.  all calls should use this to access the underlying debug port.
367         self.apnum = apnum      # which AP am i to this DP?
368
369     def getRegister(self, bank, off):
370         self.dp.ADIsetSELECT(self.apnum, bank)
371         return self.dp.ADIgetAPACC(off)
372
373     def getRegisterByAddr(self, addr):
374         bank = addr/16
375         self.dp.ADIsetSELECT(self.apnum, bank)
376         return self.dp.ADIgetAPACC(addr&0xf)
377
378     def getIdentRegister(self):
379         ident = self.getRegisterByAddr(0xfc)
380         return ident
381
382     def getIdentRegisterrepr(self):
383         raw = self.getIdentRegister()
384         ap_rev = raw>>28
385         jep_cont = (raw>>24) & 0xf
386         jep_ident = (raw>>17) & 0x7f
387         ap_class = (raw>>16) & 1
388         ap_ident = raw & 0xff
389         return "AP Revision: 0x%x\nJEP-106 Continuation Code: 0x%x\nJEP-106 Identity Code: 0x%x\nAP Class: 0x%x\nAP Identification: %x (%s)\n"%(ap_rev,jep_cont,jep_ident,ap_class,ap_ident,AP_IDENT_TYPES[ap_ident&0xf])
390     #def 
391
392 class ADI_MEM_AP(ADI_AccessPort):
393     MEMAP_CSW_REG =             0x0
394     MEMAP_TAR_REG =             0x4
395     MEMAP_DRW_REG =             0xC
396     MEMAP_BD0 =                 0x10
397     MEMAP_BD1 =                 0x14
398     MEMAP_BD2 =                 0x18
399     MEMAP_BD3 =                 0x1C
400     MEMAP_CFG_REG =             0xF4
401     MEMAP_BASE_REG =            0xF8
402     MEMAP_IDR_REG =             0xFC
403
404     def __init__(self, DP, apnum):
405         ADI_AccessPort.__init__(self, DP, apnum)
406         self.cfg = self.getCFG()                    # necessary to cache endianness information
407         # FIXME: how do i determine if this adi supports multibyte access or just word?  or packed transfers?
408         self.setMemAccessSize(4)
409
410     def getCSW(self):
411         """ Control/Status Word reg  """
412         return self.getRegister(self.MEMAP_CSW_REG)
413     def setCSW(self, csw):
414         """ Control/Status Word reg.  Some bits are RO """
415         return self.setRegister(self.MEMAP_CSW_REG, csw)
416     def reprCSW(self):
417         csw = self.getCSW()
418         
419
420     def getTAR(self):
421         """ Transfer Address Register.  Used for both DRW and BDx accesses.  Autoinc (see CSW) only works for DRW accesses, not Banked Regs"""
422         return self.getRegister(self.MEMAP_TAR_REG)
423     def setTAR(self, tar):
424         """ Transfer Address Register.  Used for both DRW and BDx accesses.  Autoinc (see CSW) only works for DRW accesses, not Banked Regs"""
425         return self.setRegister(self.MEMAP_TAR_REG, tar)
426
427     def getDRW(self):
428         """ Data Read/Write reg. """
429         return self.getRegister(self.MEMAP_DRW_REG)
430     def setDRW(self, drw):
431         """ Data Read/Write reg. """
432         return self.setRegister(self.MEMAP_DRW_REG, drw)
433
434     #FIXME: use one set of accessors... either keep the indexed version or the individuals.
435     def getBDReg(self, index):
436         return self.getRegister(self.MEMAP_BD0_REG + (index*4))
437     def setBDReg(self, index, bd):
438         return self.setRegister(self.MEMAP_BD0_REG + (index*4), bd0)
439
440     def getBD0(self):
441         return self.getRegister(self.MEMAP_BD0_REG)
442     def setBD0(self, bd0):
443         return self.setRegister(self.MEMAP_BD0_REG, bd0)
444
445     def getBD1(self):
446         return self.getRegister(self.MEMAP_BD1_REG)
447     def setBD1(self, bd1):
448         return self.setRegister(self.MEMAP_BD1_REG, bd1)
449
450     def getBD2(self):
451         return self.getRegister(self.MEMAP_BD2_REG)
452     def setBD2(self, bd2):
453         return self.setRegister(self.MEMAP_BD2_REG, bd2)
454
455     def getBD3(self):
456         return self.getRegister(self.MEMAP_BD3_REG)
457     def setBD3(self, bd3):
458         return self.setRegister(self.MEMAP_BD3_REG, bd3)
459
460     def getCFG(self):
461         return self.getRegister(self.MEMAP_CFG_REG)
462     def setCFG(self, cfg):
463         return self.setRegister(self.MEMAP_CFG_REG, cfg)
464
465     def getBASE(self):
466         """ BASE debug address.  RO """
467         return self.getRegister(self.MEMAP_BASE_REG)
468     def setBASE(self, base):
469         """ BASE debug address.  RO """
470         return self.setRegister(self.MEMAP_BASE_REG, base)
471
472     def getIDR(self):
473         return self.getRegister(self.MEMAP_IDR_REG)
474
475     # CFG accessors
476     CFG_DBGSWENABLE_BITS =      31
477     CFG_DBGSWENABLE =           1<<31
478     CFG_PROT_BITS =             24
479     CFG_PROT =               0x3f<<24
480     CFG_SPIDEN_BITS =           23
481     CFG_SPIDEN =                1<<23
482     CFG_MODE_BITS =             8
483     CFG_MODE =                0xf<<8
484     CFG_TRINPROG_BITS =         7
485     CFG_TRINPROG =              1<<7
486     CFG_DEVICEEN_BITS =         6
487     CFG_DEVICEEN =              1<<6
488     CFG_ADDRINC_BITS =          4
489     CFG_ADDRINC =               3<<4
490     CFG_SIZE_BITS =             0
491     CFG_SIZE =                  7
492     CFG_ADDRINC_off =           0b00
493     CFG_ADDRINC_single =        0b01
494     CFG_ADDRINC_packed =        0b10
495     CFG_MEM_8bits =             0b000
496     CFG_MEM_16bits =            0b001
497     CFG_MEM_32bits =            0b010
498     def CSWsetDbgSwEnable(self, bit):
499         cfg = self.getCFG() & self.CFG_DBGSWENABLE
500         cfg |= (bit<<self.CFG_DBGSWENABLE_BITS)
501     def CSWgetDbgSwEnable(self):
502         cfg = (self.getCFG() & self.CFG_DBGSWENABLE) >> self.CFG_DBGSWENABLE_BITS
503         return cfg
504
505     def CSWsetAddrInc(self, bits=CFG_ADDRINC_single):
506         cfg = (self.getCFG() & self.CFG_ADDRINC) >> self.CFG_ADDRINC_BITS
507         cfg |= (bit<<self.CFG_DBGSWENABLE_BITS)
508     def CSWsetMemAccessSize(self, bytecount=self.CSW_MEM_32bits):        # 0b010 == 32bit words, necessary if the implementation allows for variable sizes
509         csw = self.getCSW()
510         csw &= 0xfffffff8
511         csw |= (bytecount>>1)
512         self.setCSW(csw)
513
514
515