CVS: msp430simu core.py,1.18,1.19 gdbserver.py,1.2,1.3 testing.py,1.5,1.6

Chris Liechti <[email protected]>
Newsgroups gmane.comp.hardware.texas-instruments.msp430.gcc.cvs
Message-ID <[email protected]>
Update of /cvsroot/mspgcc/msp430simu
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28669/msp430simu

Modified Files:
	core.py gdbserver.py testing.py 
Log Message:
- improve gdb server, use signals
- code cleanups ans small performance improvements (it's still slow tough...)

Index: core.py
===================================================================
RCS file: /cvsroot/mspgcc/msp430simu/core.py,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -w -d -r1.18 -r1.19
--- core.py	31 Dec 2005 00:25:06 -0000	1.18
+++ core.py	31 Dec 2005 04:27:36 -0000	1.19
@@ -10,6 +10,13 @@
 import sys
 import logging
 
+try:
+    import psyco
+except ImportError:
+    pass
+else:
+    psyco.full()
+
 ##################################################################
 ## Observer Pattern
 ##################################################################
@@ -83,37 +90,37 @@
 
 class Register(Subject):
     """generic register"""
-    def __init__(self, core, reg=0, regnum=None):
+    def __init__(self, core, value=0, regnum=None):
         Subject.__init__(self)          #init model for observer pattern
         self.core = core
-        self.reg = reg
+        self.value = value
         self.regnum = regnum
         self.log = logging.getLogger('register')
-        self.log.debug('initiliaize R%02d -> 0x%04x' % (self.regnum, reg))
+        self.log.debug('initiliaize R%02d -> 0x%04x' % (self.regnum, value))
 
     def set(self, value, bytemode=0, am=0):
         """write value to register"""
         self.log.debug('write 0x%04x -> R%02d mode:%s' % (value, self.regnum, bytemode and 'b' or 'w'))
-        self.reg = value & (bytemode and 0xff or 0xffff)
+        self.value = value & (bytemode and 0xff or 0xffff)
         self.notify()
 
     def get(self, bytemode=0, am=0):
         """read register"""
-        value = self.reg & (bytemode and 0xff or 0xffff)
+        value = self.value & (bytemode and 0xff or 0xffff)
         self.log.debug('read R%02d -> 0x%04x mode:%s' % (self.regnum, value, bytemode and 'b' or 'w'))
         return value
     
     def __getitem__(self,index):
         """indexed memory access"""
-        return self.core.memory.get(bytemode=0, address=self.reg+index)
+        return self.core.memory.get(bytemode=0, address=self.value+index)
 
     def __int__(self):
         """return value of register as number"""
-        return self.reg
+        return self.value
 
     def __repr__(self):
         """return register name and contents"""
-        return "R%02d = 0x%04x" % (self.regnum, self.reg)
+        return "R%02d = 0x%04x" % (self.regnum, self.value)
 
     def __str__(self):
         """return register name"""
@@ -123,45 +130,51 @@
 class PC(Register):
     """Program counter"""
     
-    def __init__(self, core, reg=0):
-        Register.__init__(self, core, reg=reg, regnum=0)
+    def __init__(self, core, value=0):
+        Register.__init__(self, core, value, regnum=0)
 
     def next(self):
-        value = self.core.memory.get(bytemode=0, address=self.reg)
-        self.set( self.get() + 2)
-        if self.log: self.log.debug('next @PC, PC+')
+        """fetch a value and advance one word"""
+        if self.log: self.log.debug('next @PC+')
+        value = self.core.memory.get(bytemode=0, address=self.value)
+        self.set(self.value + 2)
         return value
 
     def __repr__(self):
         """return register name and contents"""
-        return "PC  = 0x%04x" % (self.reg)
+        return "PC  = 0x%04x" % (self.value)
 
     def __str__(self):
         return "PC"
 
+    def __iadd__(self, other):
+        """inplace add (+=)"""
+        self.set(self.value + int(other))
+        return self
+
 
 class SP(Register):
     """Stack pointer"""
     
-    def __init__(self, core, reg=0):
-        Register.__init__(self, core, reg=reg, regnum=1)
+    def __init__(self, core, value=0):
+        Register.__init__(self, core, value, regnum=1)
             
     def push(self,value):
-        self.reg -= 2
-        if self.log: self.log.debug('push @-SP, 0x%04x' % (value))
-        self.core.memory.set(bytemode=0, address=self.reg, value=value)
+        self.set(self.value - 2)
+        self.log.debug('push @-SP, 0x%04x' % (value))
+        self.core.memory.set(bytemode=0, address=self.value, value=value)
         self.notify()
     
     def pop(self):
-        value = self.core.memory.get(bytemode=0, address=self.reg)
-        self.reg += 2
-        if self.log: self.log.debug('pop @SP+ -> 0x%04x' % (value))
+        value = self.core.memory.get(bytemode=0, address=self.value)
+        self.set(self.value + 2)
+        self.log.debug('pop @SP+ -> 0x%04x' % (value))
         self.notify()
         return value
 
     def __repr__(self):
         """return register name and contents"""
-        return "SP  = 0x%04x" % (self.reg)
+        return "SP  = 0x%04x" % (self.value)
     
     def __str__(self):
         return "SP"
@@ -171,8 +184,8 @@
     """SR combined with Constant Generator Register 1"""
     consts = (None,None,4,8)
 
-    def __init__(self, core, reg=0):
-        Register.__init__(self, core, reg=reg, regnum=2)
+    def __init__(self, core, value=0):
+        Register.__init__(self, core, value, regnum=2)
 
     bits = {
         'C':      0x0001,
@@ -189,7 +202,7 @@
     def __getattr__(self, name):
         if self.bits.has_key(name):
             mask = self.bits[name]
-            return (self.reg & mask) != 0
+            return (self.value & mask) != 0
         else:
             return self.__dict__[name]
 
@@ -197,26 +210,26 @@
         if self.bits.has_key(name):
             mask = self.bits[name]
             if value:
-                self.reg  |= mask
+                self.value  |= mask
             else:
-                self.reg  &= ~mask
+                self.value  &= ~mask
             self.notify()
         else:
             self.__dict__[name] = value
 
     #custom get for CG1
     def get(self, bytemode=0, am=0):
-        if am == 0: return self.reg & (bytemode and 0xff or 0xffff)
+        if am == 0: return self.value & (bytemode and 0xff or 0xffff)
         value = self.consts[am] & (bytemode and 0xff or 0xffff)
-        if self.log: self.log.debug('REGSTR: read     R%02d -> 0x%04x mode:%s' % (self.regnum, value, bytemode and 'b' or 'w'))
+        self.log.debug('REGSTR: read     R%02d -> 0x%04x mode:%s' % (self.regnum, value, bytemode and 'b' or 'w'))
         return value
 
     def __repr__(self):
         """return register name and contents"""
-        res = "SR  = 0x%04x " % (self.reg)
+        res = "SR  = 0x%04x " % (self.value)
         #then append deatiled bit display
         for key in ('C', 'Z', 'N', 'V', 'GIE'):
-            res += '%s:%s ' % (key, (self.reg & self.bits[key]) and '1' or '0')
+            res += '%s:%s ' % (key, (self.value & self.bits[key]) and '1' or '0')
         return res
 
     def __str__(self):
@@ -227,12 +240,12 @@
     """Constant Generator Register 2"""
     consts = (0,1,2,0xffff)
 
-    def __init__(self, core, reg=0):
-        Register.__init__(self, core, reg=reg, regnum=3)
+    def __init__(self, core, value=0):
+        Register.__init__(self, core, value, regnum=3)
 
     def get(self, bytemode=0, am=0):
         value = self.consts[am] & (bytemode and 0xff or 0xffff)
-        if self.log: self.log.debug('read R%02d -> 0x%04x mode:%s' % (self.regnum, value, bytemode and 'b' or 'w'))
+        self.log.debug('read R%02d -> 0x%04x mode:%s' % (self.regnum, value, bytemode and 'b' or 'w'))
         return value
 
     def __repr__(self):
@@ -276,16 +289,26 @@
         Peripheral.__init__(self)  #calls self.reset()
         self.log = logging.getLogger('flash')
     
+    FCTL1 = 0x0128
+    FCTL2 = 0x012a
+    FCTL3 = 0x012c
+    #~ INFO_START = 0x1000
+    #~ INFO_END   = 0x10ff
+
     def __contains__(self, address):
         """return true if address is handled by this peripheral"""
-        return self.startaddress <= address <= self.endaddress
+        return self.startaddress <= address <= self.endaddress \
+            or self.FCTL1 <= address <= self.FCTL3+1
 
     def reset(self):
         """perform a power up reset"""
-        self.values = [0xff] * (self.endaddress - self.startaddress + 1)
+        #~ self.values = [0xff] * (self.endaddress - self.startaddress + 1)
 
     def set(self, address, value, bytemode=0):
         """write value to address"""
+        if self.FCTL1 <= address <= self.FCTL3+1:
+            pass #xxx handle flas write/erase etc
+        else:
         if bytemode:
             self.values[address-self.startaddress] = value & 0xff
         else:
@@ -294,6 +317,9 @@
 
     def get(self, address, bytemode=0):
         """read from address"""
+        if self.FCTL1 <= address <= self.FCTL3+1:
+            value = 0
+        else:
         if bytemode:
             value = self.values[address-self.startaddress]
         else:
@@ -318,7 +344,7 @@
 
     def reset(self):
         """perform a power up reset"""
-        self.values = [0] * (self.endaddress - self.startaddress + 1)
+        #~ self.values = [0] * (self.endaddress - self.startaddress + 1)
 
     def set(self, address, value, bytemode=0):
         """write value to address"""
@@ -709,7 +735,7 @@
         return res
 
     def set(self, value):
-        raise "not possible as destination"
+        raise ValueError("not possible as destination")
 
     def __repr__(self):
         return '@%s+' % (self.reg)
@@ -725,7 +751,7 @@
         return self.value
 
     def set(self, value):
-        raise "not possible as destination"
+        raise ValueError("not possible as destination")
 
     def __repr__(self):
         return '#0x%04x' % (self.value)
@@ -758,7 +784,7 @@
         return self.offset
 
     def __repr__(self):
-        return '0x%04x' % (self.address+self.offset)
+        return '$%+d {->0x%04x}' % (self.offset+2, self.address+self.offset)
 
 ##################################################################
 ## argument conversion
@@ -1001,74 +1027,74 @@
     
     def execJNZ(self, bytemode, offset):
         if not self.SR.Z:
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
 
     def execJZ(self, bytemode, offset):
         if self.SR.Z:
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
 
     def execJC(self, bytemode, offset):
         if self.SR.C:
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
 
     def execJNC(self, bytemode, offset):
         if not self.SR.C:
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
 
     def execJN(self, bytemode, offset):
         if not self.SR.N:
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
     
     def execJGE(self, bytemode, offset):
         if not (self.SR.N ^ self.SR.V):
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
 
     def execJL(self, bytemode, offset):
         if self.SR.N ^ self.SR.V:
-            self.PC.set(self.PC.get() + int(offset))
+            self.PC += offset
 
     def execJMP(self, bytemode, offset):
-        self.PC.set(self.PC.get() + int(offset))
+        self.PC += offset
 
     #------------------------
     # instruction tables
     #------------------------
 
     singleOperandInstructions = {
-        0x00: ('rrc',  execRRC,  0),
-        0x01: ('swpb', execSWPB, 0),
-        0x02: ('rra',  execRRA,  0),
-        0x03: ('sxt',  execSXT,  0),
-        0x04: ('push', execPUSH, 2),    #write of stack -> 2
-        0x05: ('call', execCALL, 3),    #write of stack -> 2, modify PC -> 1
-        0x06: ('reti', execRETI, 4),    #pop SR -> 1, pop PC -> 1, modify PC -> 1,  +1??
+        0x00<<7: ('rrc',  execRRC,  0),
+        0x01<<7: ('swpb', execSWPB, 0),
+        0x02<<7: ('rra',  execRRA,  0),
+        0x03<<7: ('sxt',  execSXT,  0),
+        0x04<<7: ('push', execPUSH, 2),    #write of stack -> 2
+        0x05<<7: ('call', execCALL, 3),    #write of stack -> 2, modify PC -> 1
+        0x06<<7: ('reti', execRETI, 4),    #pop SR -> 1, pop PC -> 1, modify PC -> 1,  +1??
     }
 
     doubleOperandInstructions = {
-        0x4: ('mov',  execMOV,  0),
-        0x5: ('add',  execADD,  0),
-        0x6: ('addc', execADDC, 0),
-        0x7: ('subc', execSUBC, 0),
-        0x8: ('sub',  execSUB,  0),
-        0x9: ('cmp',  execCMP,  0),
-        0xa: ('dadd', execDADD, 0),
-        0xb: ('bit',  execBIT,  0),
-        0xc: ('bic',  execBIC,  0),
-        0xd: ('bis',  execBIS,  0),
-        0xe: ('xor',  execXOR,  0),
-        0xf: ('and',  execAND,  0),
+        0x4000: ('mov',  execMOV,  0),
+        0x5000: ('add',  execADD,  0),
+        0x6000: ('addc', execADDC, 0),
+        0x7000: ('subc', execSUBC, 0),
+        0x8000: ('sub',  execSUB,  0),
+        0x9000: ('cmp',  execCMP,  0),
+        0xa000: ('dadd', execDADD, 0),
+        0xb000: ('bit',  execBIT,  0),
+        0xc000: ('bic',  execBIC,  0),
+        0xd000: ('bis',  execBIS,  0),
+        0xe000: ('xor',  execXOR,  0),
+        0xf000: ('and',  execAND,  0),
     }
 
-    jumpInstructions = {
-        0x0: ('jnz',  execJNZ,  1), #jne
-        0x1: ('jz',   execJZ,   1), #jeq
-        0x2: ('jnc',  execJNC,  1),
-        0x3: ('jc',   execJC,   1),
-        0x4: ('jn',   execJN,   1),
-        0x5: ('jge',  execJGE,  1),
-        0x6: ('jl',   execJL,   1),
-        0x7: ('jmp',  execJMP,  1),
-    }
+    jumpInstructions = (
+        ('jnz',  execJNZ,  1), #jne        0x0: 
+        ('jz',   execJZ,   1), #jeq        0x1: 
+        ('jnc',  execJNC,  1), #           0x2: 
+        ('jc',   execJC,   1), #           0x3: 
+        ('jn',   execJN,   1), #           0x4: 
+        ('jge',  execJGE,  1), #           0x5: 
+        ('jl',   execJL,   1), #           0x6: 
+        ('jmp',  execJMP,  1), #           0x7: 
+    )
 
     #------------------------
     # methods
@@ -1110,8 +1136,8 @@
         self.memory.reset()
         self.notify()
 
-    def disassemble(self, pc):
-        """disasseble current PC location and advance PC to the next instruction.
+    def disassemble(self, pc, illegal_is_fatal=False):
+        """disassemble current PC location and advance PC to the next instruction.
         return a tuple with insn name, arguments (bytemode, arg1, arg2),
         core execution function for that insn and a cycle count.
         
@@ -1120,51 +1146,56 @@
         opcode = pc.next()
         cycles = 1              #count cycles, start with insn fetch
         x = y = None
+        #jump instructions
+        if (opcode & 0xe000) == 0x2000:
+            name, fu, addcyles = self.jumpInstructions[(opcode>>10) & 0x7]
+            offset = (opcode & 0x3ff) << 1
+            if offset & 0x400:  #negative?
+                offset = -((~offset + 1) & 0x7ff)
+            cycles += addcyles #jumps allways have 2 cycles
+            return name, [0, JumpTarget(self, int(pc), offset)], fu, cycles
+
         #single operand
-        if ((opcode & 0xf000) == 0x1000 and
-                ((opcode>>7)&0x1f in self.singleOperandInstructions.keys())
-        ):
-            bytemode = (opcode>>6) & 1
+        elif (opcode & 0xf000) == 0x1000:
+            bytemode = bool(opcode & 0x40) #(opcode>>6) & 1
             x,y,c = addressMode(self, pc, bytemode,
                 as=(opcode>>4) & 3,
                 src=opcode & 0xf
                 )
-            name, fu, addcyles = self.singleOperandInstructions[(opcode>>7) & 0x1f]
+            try:
+                name, fu, addcyles = self.singleOperandInstructions[opcode & 0x0f80]
+            except KeyError:
+                pass
+            else:
             cycles += c + addcyles #some functions have additional cycles (push etc)
             return name, [bytemode, x], fu, cycles
 
         #double operand
-        elif (opcode>>12)&0xf in self.doubleOperandInstructions.keys():
-            bytemode = (opcode>>6) & 1
+        else:
+            bytemode = bool(opcode & 0x40) #(opcode>>6) & 1
             x,y,c = addressMode(self, pc, bytemode,
                 src=(opcode>>8) & 0xf,
                 ad=(opcode>>7) & 1,
                 as=(opcode>>4) & 3,
                 dest=opcode & 0xf
                 )
-            name, fu, addcyles = self.doubleOperandInstructions[(opcode>>12) & 0xf]
+            try:
+                name, fu, addcyles = self.doubleOperandInstructions[opcode & 0xf000]
+            except KeyError:
+                pass
+            else:
             cycles += c + addcyles #some functions have additional cycles (push etc)
             return name, [bytemode, x, y], fu, cycles
 
-        #jump instructions
-        elif ((opcode & 0xe000) == 0x2000 and
-             ((opcode>>10)&0x7 in self.jumpInstructions.keys())
-        ):
-            name, fu, addcyles = self.jumpInstructions[(opcode>>10) & 0x7]
-            offset = ((opcode&0x3ff)<<1)
-            if offset & 0x400:  #negative?
-                offset = -((~offset + 1) & 0x7ff)
-            cycles += addcyles #jumps allways have 2 cycles
-            return name, [0, JumpTarget(self, int(pc), offset)], fu, cycles
-
         #unkown instruction
-        else:
+        if illegal_is_fatal:
+            raise MSP430CoreException('illegal instruction 0x%04x' % (opcode,))
             return 'illegal insn 0x%04x' % opcode, [0], None, cycles
 
-    def step(self):
+    def step(self, illegal_is_fatal=False):
         """perform one single step"""
         address = int(self.PC)
-        name, args, execfu, cycles = self.disassemble(self.PC)
+        name, args, execfu, cycles = self.disassemble(self.PC, illegal_is_fatal)
         self.cycles += cycles
         note = "%s%s %s (%d cycles)" % (
             name,
@@ -1172,16 +1203,16 @@
             ', '.join(map(str,args[1:])),
             cycles
         )
-        self.log.debug('step: %s' % (note,))
         if execfu:
+            self.log.info('step: %s' % (note,))
             apply(execfu, [self]+args)
         else:
-            self.log.warning("%s @0x%04x" % (name, address))
+            self.log.warning("step: %s @0x%04x" % (name, address))
         self.notify()
         return note
 
     def __repr__(self):
-        return ('%r\n'*16) % self.R
+        return ('%r\n'*15 + '%r') % self.R
 
 ##################################################################
 ## trace control object
@@ -1254,7 +1285,7 @@
     ))
     print core.memory.hexdump(0x0200, 0x02ff, log)
     tracer = Tracer(core)
-    tracer.start(0xf000, 43) #only N steps
+    tracer.start(0xf000, 50) #only N steps
     print "-"*40, "end"
     print core.memory.hexdump(0x0200, 0x02ff, log)
 

Index: gdbserver.py
===================================================================
RCS file: /cvsroot/mspgcc/msp430simu/gdbserver.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -d -r1.2 -r1.3
--- gdbserver.py	31 Dec 2005 00:25:06 -0000	1.2
+++ gdbserver.py	31 Dec 2005 04:27:36 -0000	1.3
@@ -21,6 +21,20 @@
         checksum = (checksum + ord(c)) & 0xff
     return checksum
 
+def unescape(data):
+    """decode binary packets with escapes"""
+    esc_found = False
+    out = []
+    for byte in data:
+        if esc_found:
+            out.append(byte ^ 0x20)
+            esc_found = False
+        elif byte == 0x7d:
+            esc_found = True
+        else:
+            out.append(byte)
+    return ''.join(out)
+
 
 class BreakpointRunner(threading.Thread):
     def __init__(self, core):
@@ -28,11 +42,19 @@
         self.core = core
         self.interrupted = False
         self.breakpoints = {}
+        #callback for signals
+        self.sig_trap = self._signal
+        self.sig_int = self._signal
+        self.sig_segv = self._signal
+        
         self.cmd_queue = Queue.Queue(1)
         threading.Thread.__init__(self)
-        self.setName('msp430 core')
+        self.setName('msp430 core runner')
         self.setDaemon(1)
         
+    def _signal(self):
+        self.log.error('signal called but no callback registered')
+        
     def set_breakpoint(self, address):
         self.breakpoints[address] = True
 
@@ -40,19 +62,24 @@
         if address in self.breakpoints:
             del self.breakpoints[address]
             
-    def command(self, cmd, action):
+    def command(self, cmd):
         self.log.info('queing remote command %r' % cmd)
-        self.cmd_queue.put((cmd, action))
+        self.cmd_queue.put(cmd)
     
     def interrupt(self):
+        self.log.info('interruption')
         self.interrupted = True
+        #empty command queue
+        while self.cmd_queue.qsize():
+            self.cmd_queue.get_nowait()
+            
 
     def run(self):
         """worker thread"""
         self.log.debug('worker thread started')
         while True:
             try:
-                command, action = self.cmd_queue.get()
+                command = self.cmd_queue.get()
                 self.log.info('executing remote command %r' % command)
                 if command == 'run':
                     self.interrupted = False
@@ -60,10 +87,16 @@
                     step_delta = 0
                     self.log.info('continuing from 0x%04x (cycle %d)' % (self.core.PC.get(), self.core.cycles))
                     while not self.interrupted:
-                        self.core.step()
+                        try:
+                            self.core.step(illegal_is_fatal=True)
+                        except core.MSP430CoreException, e:
+                            self.log.warning('could not execute instruction: %s' % e)
+                            self.sig_segv()
+                            break
+                        else:
                         if self.core.PC.get() in self.breakpoints:
                             self.log.info('breakpoint @0x%04x (cycle %d)' % (self.core.PC.get(), self.core.cycles))
-                            action()
+                                self.sig_trap()
                             break
                         step_delta += 1
                         if step_delta > 1000:          #after a few steps..
@@ -75,13 +108,13 @@
                                 self.log.info('still running @0x%04x (cycle %d)' % (self.core.PC.get(), self.core.cycles))
                     else:
                         self.log.info('interrupted @0x%04x (cycle %d)' % (self.core.PC.get(), self.core.cycles))
-                        action()
+                        self.sig_int()
                 elif command == 'step':
                     self.log.info('single step @0x%04x (cycle %d)' % (self.core.PC.get(), self.core.cycles))
                     self.core.step()
                     if self.core.PC.get() in self.breakpoints:
                         self.log.info('breakpoint @0x%04x (cycle %d)' % (self.core.PC.get(), self.core.cycles))
-                    action()
+                    self.sig_trap()
                 else:
                     self.log.error('unknown command %r' % (command, ))
             except:
@@ -116,6 +149,9 @@
         self.log = logging.getLogger("gdbclient")
         self.alive = True
         self.runner = BreakpointRunner(core)
+        self.runner.sig_trap = self._sigtrap
+        self.runner.sig_int = self._sigint
+        self.runner.sig_segv = self._sigsegv
         self.runner.start()
 
     def close(self):
@@ -126,10 +162,6 @@
         self.clientsocket.close()
         self.log.info("closed")
 
-    #~ def _answer_ok(self):
-    def _answer_sigtrap(self):
-        self.writePacket("S%02x" % (5,))    #SIGTRAP
-        
     def run(self):
         try:
             self.log.info("client loop ready...")
@@ -151,39 +183,73 @@
                         if len(pkt) > 1:
                             adr = int(pkt[1:],16)
                             self.core.PC.set(adr)
-                        self.runner.command('run', self._answer_sigtrap)
+                        self.runner.command('run')
                         #~ self.writePacket("S%02x" % (5,))    #SIGTRAP
+                    elif pkt[0] == "s":     #single step
+                        if len(pkt) > 1:
+                            adr = int(pkt[1:],16)
+                            self.core.PC.set(adr)
+                        self.runner.command('step')
                     elif pkt[0] == "D":     #detach
                         self.core.reset()
-                    elif pkt[0] == "g":     #Read general registers
-                        self.log.debug("Reading device registers")
+                        
+                    elif pkt[0] == "g":     #read registers
+                        self.log.info("Reading device registers")
                         self.writePacket(''.join(["%02x%02x" % (r.get()&0xff, (r.get()>>8)&0xff) for r in self.core.R]))
-                    elif pkt[0] == "G":     #write regs
-                        self.log.debug("Writing device registers")
+                    elif pkt[0] == "G":     #write registers
+                        self.log.info("Writing device registers")
                         for n, value in enumerate([int(pkt[i:i+2],16) + int(pkt[i+2:i+4],16)<<8 for i in range(1, 1+16*4, 4)]):
                             self.core.R[n].set(value)
-                        self.writePacket("OK")
+                        self.writeOK()
+                    elif pkt[0] == "p":     #read register
+                        reg = int(pkt[1:], 16)
+                        self.log.info("Reading device register R%d" % (reg))
+                        value = int(self.core.R[reg])
+                        self.writePacket("%02x%02x" % (value & 0xff, (value >> 8) & 0xff))
+                    elif pkt[0] == "P":     #write register
+                        reg, data = pkt[1:].split('=')
+                        reg = int(reg, 16)
+                        data = binascii.unhexlify(data)
+                        value = ord(data[0]) | (ord(data[1]) << 8)
+                        self.log.info("Writing device register R%d = 0x%04x" % (reg, value))
+                        self.core.R[reg].set(value)
+                        self.writeOK()
+                        
                     elif pkt[0] == "H":
-                        self.writePacket("OK")
+                        self.writeOK()
                     elif pkt[0] == "k":     #kill request
                         self.core.reset()
-                        self.writePacket("OK")
+                        self.writeOK()
                     elif pkt[0] == "m":     #read memory
-                        self.log.debug("Reading device memory")
                         fromadr, length = [int(x, 16) for x in pkt[1:].split(',')]
+                        self.log.info("Reading device memory @0x%04x %d bytes" % (fromadr, length))
                         mem = self.core.memory.read(fromadr, length)
-                        self.writePacket(''.join(["%02x" % ord(x) for x in mem]))
+                        self.writePacket(binascii.hexlify(mem))
                     elif pkt[0] == "M":     #write memory
-                        self.log.debug("Writing device memory")
                         meta, data = pkt.split(':')
                         fromadr, length = [int(x, 16) for x in meta[1:].split(',')]
-                        sdata = ''.join([chr(int(data[i:i+2],16)) for i in range(0,len(data),2)])
+                        self.log.info("Writing device memory @0x%04x %d bytes" % (fromadr, length))
+                        sdata = binascii.unhexlify(data)
                         try:
                             self.core.memory.write(fromadr, sdata)
                         except IOError:
-                            self.writePacket("E01") #write error
+                            self.writeError(1) #write error
                         else:
-                            self.writePacket("OK")
+                            self.writeOK()
+                    #~ elif pkt[0] == "X":     #write memory (binary)
+                        #~ meta, data = pkt.split(':')
+                        #~ fromadr, length = [int(x, 16) for x in meta[1:].split(',')]
+                        #~ if length:
+                            #~ self.log.info("Writing device memory @0x%04x %d bytes (X)" % (fromadr, length))
+                            #~ sdata = unescape(data)
+                            #~ try:
+                                #~ self.core.memory.write(fromadr, sdata)
+                            #~ except IOError:
+                                #~ self.writeError(1) #write error
+                            #~ else:
+                                #~ self.writeOK()
+                        #~ else:
+                            #~ self.writeOK()
                     elif pkt[0] == "q":     #remote commands
                         if pkt[1:5] == "Rcmd":
                             cmd = binascii.unhexlify(pkt.split(',')[1]).strip()
@@ -199,39 +265,36 @@
                                     getattr(self, method_name)(args)
                                 except:
                                     self.log.exception('error in monitor command')
-                                    self.writePacket("E03")
+                                    self.writeError(3)
                             else:
                                 self.log.warning('no such monitor command ("%s")' % command)
-                                self.writePacket("E02")
+                                self.writeError(2)
                         else:
-                            self.writePacket("E01") #commond not known
-                    elif pkt[0] == "s":     #single step
-                        if len(pkt) > 1:
-                            adr = int(pkt[1:],16)
-                            self.core.PC.set(adr)
-                        self.runner.command('step', self._answer_sigtrap)
+                            self.writeError(1) #commond not known
+                    
                     elif pkt[0] == "Z":     #set break or watchpoint
                         ty, adr, length = pkt[1:].split(',')
                         if ty == '0':
-                            self.log.debug("Setting breakpoint")
-                            self.runner.set_breakpoint(int(adr,16))
-                            self.writePacket("OK")
+                            address = int(adr,16)
+                            self.log.info("Setting breakpoint @0x%04x" % (address))
+                            self.runner.set_breakpoint(address)
+                            self.writeOK()
                         else:
-                            self.writePacket("E%02x" % (1,))
+                            self.writeError(1)
                     elif pkt[0] == "z":     #remove break or watchpoint
                         ty, adr, length = pkt[1:].split(',')
                         if ty == '0':
-                            self.log.debug("Clearing breakpoint")
-                            adr = int(adr,16)
-                            if adr in self.runner.breakpoints:
-                                self.runner.remove_breakpoint(adr)
-                                self.writePacket("OK")
+                            address = int(adr,16)
+                            self.log.info("Clearing breakpoint @0x%04x" % (address))
+                            if address in self.runner.breakpoints:
+                                self.runner.remove_breakpoint(address)
+                                self.writeOK()
                             else:
-                                self.writePacket("E%02x" % (2,))
+                                self.writeError(2)
                         else:
-                            self.writePacket("E%02x" % (1,))
+                            self.writeError(1)
                     else:   #command not supported
-                        self.log.debug("Unsupported comand %r" % pkt)
+                        self.log.warning("Unsupported comand %r" % pkt)
                         self.writePacket("")
         finally:
             self.close()
@@ -241,7 +304,7 @@
         gdbcommand = 0
         csum = 0
         packet = []
-        while 1:
+        while True:
             c = self.netin.read(1)
             if not c: self.close() #EOF
             if c == '\x03':     #ctrl+c
@@ -265,9 +328,22 @@
         self.netout.write("$%s#%02x" % (msg, checksum(msg)))
         self.netout.flush()
 
+    def writeOK(self):
+        self.writePacket("OK")
+        
+    def writeError(self, errorcode=0):
+        self.writePacket("E%02x" % (errorcode,))
+    
     def writeMessage(self, msg):
         self.writePacket("O%s" % binascii.hexlify(msg))
 
+    def writeSignal(self, signal):
+        self.writePacket("S%02x" % (signal,))
+
+    def _sigtrap(self): self.writeSignal(5)
+    def _sigint(self): self.writeSignal(2)
+    def _sigsegv(self): self.writeSignal(11)
+    
     # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     
     def monitor_help(self, args):
@@ -276,13 +352,13 @@
         for name in dir(self):
             if name.startswith('monitor_'):
                 self.writeMessage("%-10s: %s\n" % (name[8:], getattr(self, name).__doc__))
-        self.writePacket("OK")
+        self.writeOK()
         
     #~ def monitor_eval(self, args):
         #~ """evaluate python expression !Security risk!"""
         #~ ans = eval(args)
         #~ self.writeMessage("%r\n" % (ans,))
-        #~ self.writePacket("OK")
+        #~ self.writeOK()
     
     def monitor_erase(self, args):
         """erase flash"""
@@ -291,27 +367,29 @@
         #~ elif args == 'info':
         #~ elif args in ('', 'all'):
         #~ else: #accept "address size"
-        self.writePacket("OK")
+        self.writeOK()
 
     def monitor_puc(self, args):
         """reset target"""
         self.core.reset()
-        self.writePacket("OK")
+        self.writeOK()
         
     def monitor_reset(self, args):
         """reset target"""
         self.core.reset()
-        self.writePacket("OK")
+        self.writeOK()
 
     def monitor_vcc(self, args):
         """set adapter VCC, ignored. here to be compatible with the real gdbproxy"""
-        self.writePacket("OK")
+        self.writeOK()
 
 
 if __name__ == '__main__':
-    logging.basicConfig(level=logging.INFO)
+    logging.basicConfig(level=logging.WARN)
     #~ logging.basicConfig(level=logging.DEBUG)
-    log = logging.getLogger('trace')
+    log = logging.getLogger('gdbclient').setLevel(level=logging.INFO)
+    #~ log = logging.getLogger('gdbclient').setLevel(level=logging.DEBUG)
+    logging.getLogger("runner").setLevel(level=logging.INFO)
     
     msp430 = core.Core()
     msp430.memory.append(core.Multiplier())

Index: testing.py
===================================================================
RCS file: /cvsroot/mspgcc/msp430simu/testing.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -d -r1.5 -r1.6
--- testing.py	29 Dec 2005 21:17:23 -0000	1.5
+++ testing.py	31 Dec 2005 04:27:36 -0000	1.6
@@ -88,8 +88,8 @@
         return 0    #no functionality right now
 
 class TestCore(core.Core):
-    def __init__(self, log):
-        core.Core.__init__(self, log)
+    def __init__(self):
+        core.Core.__init__(self)
         self.testing = Testing(log)
         self.memory.append(self.testing)    #insert new peripherals in MSP's address pace
         self.memory.append(core.Multiplier())
@@ -124,7 +124,7 @@
     for f in sys.argv[1:]:
         print "Running Test: %s ...\n" % f
         log.info("Running Test: %s ..." % f)
-        msp = TestCore(log)
+        msp = TestCore()
         msp.memory.load(f)
         msp.start()
         failures += msp.testing.failures



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.