tweak here, tie there
[goodfet] / client / GoodFETARM7.py
index 4e03e50..9eb7d0d 100644 (file)
@@ -13,8 +13,8 @@
 #  * -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
-#  * thumb to arm mode
+#  * 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
@@ -133,7 +133,8 @@ ARM_INSTR_STR_R1_r0_4 =     0xe4801004L
 ARM_WRITE_MEM =             ARM_INSTR_STR_R1_r0_4
 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 +184,7 @@ DBGCTRLBITS = {
         1<<ENABLE:'ENABLE',
         }
 
+LDM_BITMASKS = [(1<<x)-1 for x in xrange(16)]
 #### TOTALLY BROKEN, NEED VALIDATION AND TESTING
 PCOFF_DBGRQ = 4 * 4
 PCOFF_WATCH = 4 * 4
@@ -311,9 +313,9 @@ class GoodFETARM(GoodFET):
         """Set ARM Registers"""
         for x in xrange(15):
           if (1<<x) & mask:
-            self.ARMset_register(x,regs.pop())
+            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())
+          self.ARMsetPC(regs.pop(0))
     def ARMdebuginstr(self,instr,bkpt):
         if type (instr) == int or type(instr) == long:
             instr = struct.pack("<L", instr)
@@ -497,7 +499,51 @@ class GoodFETARM(GoodFET):
         self.ARMset_register(1, r1);       # restore R0 and R1 
         self.ARMset_register(0, r0);
         return retval
-
+    def ARMreadChunk(self, adr, wordcount):         
+        """ Only works in ARM mode currently
+        WARNING: Addresses must be word-aligned!
+        """
+        regs = self.ARMget_registers()
+        output = []
+        count = wordcount
+        while (wordcount > 0):
+            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 ARMwriteChunk(self, adr, wordarray):         
+        """ Only works in ARM mode currently
+        WARNING: Addresses must be word-aligned!
+        """
+        regs = self.ARMget_registers()
+        wordcount = len(wordarray)
+        while (wordcount > 0):
+            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):
         r0 = self.ARMget_register(0);        # store R0 and R1
         r1 = self.ARMget_register(1);