Beispiel #1
0
    def execute(self, code, mode='int', debug=False, params=None, n_spus=1):

        if type(code) is ParallelInstructionStream:
            raise Exception(
                'DebugProcessor does not support ParallelInstructionStream')

        self.code = code

        if len(code) == 0:
            return None

        # Add the debug instructions - two each for normal instructions and branch targets
        self.debug_idx = self.code.size()
        self.code.add(spu.stop(DEBUG_STOP))

        self.debug_branch = self.code.size()
        self.code.add(spu.stop(DEBUG_STOP))

        self.debug_target_idx = self.code.size()
        self.code.add(spu.stop(DEBUG_STOP_TARGET))

        self.debug_target_branch = self.code.size()
        self.code.add(spu.stop(DEBUG_STOP_TARGET))

        # Cache the code here
        if not code._cached:
            code.cache_code()

        # Setup the parameter structure
        if params is None:
            params = spu_exec.ExecParams()

        addr = code._prologue.inst_addr()
        params.addr = addr
        params.size = len(code.render_code) * 4  # size in bytes

        self.params = params
        self.ea = code._prologue.inst_addr()
        self.lsa = (0x3FFFF - params.size) & 0xFFF80
        self.size = params.size + (16 - params.size % 16)
        self.last_pc = self.lsa
        self.last_stop = (1, )

        self.debug_lsa = (self.lsa + self.code.code_offset * 4 +
                          self.debug_idx * 4) >> 2
        self.debug_target_lsa = (self.lsa + self.code.code_offset * 4 +
                                 self.debug_target_idx * 4) >> 2

        mode = 'async'

        # TODO: Factor replacing into one function in case the first one is a branch
        self.replace(self.last_stop[0],
                     spu.bra(self.debug_lsa, ignore_active=True))

        self.spe_id = spe.Processor.execute(self, code, mode, debug, params)
        code.print_code()

        retval = self.wait_debug()

        return retval
Beispiel #2
0
  def execute(self, code, mode = 'int', debug = False, params = None, n_spus = 1):

    if type(code) is ParallelInstructionStream:
      raise Exception('DebugProcessor does not support ParallelInstructionStream')

    self.code = code
    
    if len(code) == 0:
      return None

    # Add the debug instructions - two each for normal instructions and branch targets
    self.debug_idx = self.code.size()
    self.code.add(spu.stop(DEBUG_STOP))

    self.debug_branch = self.code.size()    
    self.code.add(spu.stop(DEBUG_STOP))    

    self.debug_target_idx = self.code.size()
    self.code.add(spu.stop(DEBUG_STOP_TARGET))

    self.debug_target_branch = self.code.size()    
    self.code.add(spu.stop(DEBUG_STOP_TARGET))    

    # Cache the code here
    if not code._cached:
      code.cache_code()

    # Setup the parameter structure
    if params is None:
      params = spu_exec.ExecParams()

    addr = code._prologue.inst_addr()
    params.addr = addr
    params.size = len(code.render_code) * 4 # size in bytes

    self.params = params
    self.ea   = code._prologue.inst_addr()
    self.lsa  = (0x3FFFF - params.size) & 0xFFF80;
    self.size = params.size + (16 - params.size % 16);
    self.last_pc   = self.lsa
    self.last_stop = (1,)

    self.debug_lsa = (self.lsa + self.code.code_offset * 4 + self.debug_idx * 4) >> 2
    self.debug_target_lsa = (self.lsa + self.code.code_offset * 4 + self.debug_target_idx * 4) >> 2    

    mode = 'async'

    # TODO: Factor replacing into one function in case the first one is a branch
    self.replace(self.last_stop[0], spu.bra(self.debug_lsa, ignore_active = True))

    self.spe_id = spe.Processor.execute(self, code, mode, debug, params)
    code.print_code()

    retval = self.wait_debug()
    
    return retval
Beispiel #3
0
  def dump_regs(self):
    mbox   = 28 # write out mbox channel

    # Pseudo-code:
    #  1) Save code is: (do this as an array, not an instruction stream)
    save_size = 128 * 2 + 4
    save_code = extarray.extarray('I', range(save_size))
    
    for i in range(0, 128 * 2, 2):
      save_code[i] = spu.wrch(i / 2, mbox, ignore_active = True).render()
      save_code[i + 1] = spu.stop(0x6, ignore_active = True).render()

    # branch back to the debug stop
    save_code[128 * 2] = spu.stop(0x7, ignore_active = True).render()
    ret = spu.bra(self.debug_lsa, ignore_active = True)
    save_code[128 * 2 + 1] = ret.render()

    #aligned_save_code = aligned_memory(save_size, typecode = 'I')
    #aligned_save_code.copy_to(save_code.buffer_info()[0], len(save_code))

    #  2) Save lsa[0:len(save_code)]
    # TODO: do this with putb

    #  3) Push save code to lsa[0:]
    tag = 2
    spu_exec.spu_getb(self.spe_id, 0, save_code.buffer_info()[0], save_size * 4, tag, 0, 0)
    spu_exec.read_tag_status_all(self.spe_id, 1 << tag);
    
    #  3) Replace the debug branch with a branch to 0
    self.replace(self.debug_branch, spu.bra(0, ignore_active = True))
    self.get_instructions()

    #  4) Resume
    self.resume(self.spe_id)    

    #  5) Read the register values and send the ok signal
    regs = []
    for i in range(128):
      while spu_exec.stat_out_mbox(self.spe_id) == 0: pass
      value = spu_exec.read_out_mbox(self.spe_id)
      regs.append(value)

      r = spu_exec.wait_stop_event(self.spe_id)
      self.resume(self.spe_id)

    r = spu_exec.wait_stop_event(self.spe_id)
    print 'next stop', r
    #  6) Restore code at original pc
    self.restore(self.debug_branch)
    self.get_instructions()

    #  7) Restore lsa[0:len(save_code)]
    # TODO: do this with putb

    #  8) Resume
    # self.resume(self.spe_id)    
    # r = spu_exec.wait_stop_event(self.spe_id)
    self.resume(self.spe_id)
    r = self.wait_debug()

    return regs
Beispiel #4
0
  def nexti(self):
    
    if len(self.last_stop) == 1:
      # Restore a single instruction
      current_inst = self.restore(self.last_stop[0])
      last_idx = self.last_stop[0]
    else:
      # Restore two branch targets and determine which branch was taken
      # based on the stop code 
      i1 = self.restore(self.last_stop[0])
      i2 = self.restore(self.last_stop[1])
      if self.stop_code == DEBUG_STOP:
        current_inst = i1
        last_idx = self.last_stop[0]
      else:
        current_inst = i2
        last_idx = self.last_stop[1]
        
    # If the current instruction is a branch, get the location
    # of all possible next instructions
    if isinstance(current_inst, (spu.br, spu.brsl)):
      next_stop = (self.last_stop[0] + current_inst.I16,)
      print 'next br:', next_stop
    elif isinstance(current_inst, (spu.bra, spu.brasl)):
      next_stop = (current_inst.I16 - (self.lsa >> 2),)
    elif isinstance(current_inst, (spu.brnz, spu.brz, spu.brhnz, spu.brhz)):
      next_stop = (self.last_stop[0] + 1,
                   self.last_stop[0] + current_inst.I16)
      
    elif isinstance(current_inst, (spu.bi, spu.bisled, spu.bisl)):
      raise Exception("DebugProcessor does not support branch indirect (bi) instructions")
    else:
      next_stop = (self.last_stop[0] + 1,)
          

    # TODO: Get rid of last instruction.  Do something smarter.
    last_instruction = (next_stop[0] == (self.debug_idx - 1))


    # !!! STOPPED HERE !!!
    # !!! STILL WRONG !!!
    if not last_instruction:
      # Normal instructions and single target branches
      self.replace(next_stop[0],    spu.bra(self.debug_lsa, ignore_active = True))
      print 'target (1):', -(self.debug_lsa - ((self.lsa >> 2) + next_stop[0])), self.debug_lsa, last_idx, self.lsa
      self.replace(self.debug_branch, spu.br(-(self.debug_lsa - ((self.lsa >> 2) + next_stop[0])),
                                             ignore_active = True))
      # Branch target for test-based branch instructions
      if len(next_stop) == 2:
        self.replace(next_stop[1],    spu.bra(self.debug_target_lsa, ignore_active = True))
        print 'target (2):', -(self.debug_target_lsa - ((self.lsa >> 2) + next_stop[1])), self.debug_target_lsa
        self.replace(self.debug_target_branch,
                     spu.br(-(self.debug_target_lsa - ((self.lsa >> 2) + next_stop[1])), ignore_active = True))
        
      # self.replace(next_stop, self.debug_stop)
      
    self.get_instructions()
    self.code.print_code()
    self.resume(self.spe_id)

    if last_instruction:
      r = self.join(self.spe_id)
      r = None
    else:
      r = self.wait_debug()
      self.last_stop = next_stop
      self.stop_code = r
      
    return r
Beispiel #5
0
    def dump_regs(self):
        mbox = 28  # write out mbox channel

        # Pseudo-code:
        #  1) Save code is: (do this as an array, not an instruction stream)
        save_size = 128 * 2 + 4
        save_code = extarray.extarray('I', range(save_size))

        for i in range(0, 128 * 2, 2):
            save_code[i] = spu.wrch(i / 2, mbox, ignore_active=True).render()
            save_code[i + 1] = spu.stop(0x6, ignore_active=True).render()

        # branch back to the debug stop
        save_code[128 * 2] = spu.stop(0x7, ignore_active=True).render()
        ret = spu.bra(self.debug_lsa, ignore_active=True)
        save_code[128 * 2 + 1] = ret.render()

        #aligned_save_code = aligned_memory(save_size, typecode = 'I')
        #aligned_save_code.copy_to(save_code.buffer_info()[0], len(save_code))

        #  2) Save lsa[0:len(save_code)]
        # TODO: do this with putb

        #  3) Push save code to lsa[0:]
        tag = 2
        spu_exec.spu_getb(self.spe_id, 0,
                          save_code.buffer_info()[0], save_size * 4, tag, 0, 0)
        spu_exec.read_tag_status_all(self.spe_id, 1 << tag)

        #  3) Replace the debug branch with a branch to 0
        self.replace(self.debug_branch, spu.bra(0, ignore_active=True))
        self.get_instructions()

        #  4) Resume
        self.resume(self.spe_id)

        #  5) Read the register values and send the ok signal
        regs = []
        for i in range(128):
            while spu_exec.stat_out_mbox(self.spe_id) == 0:
                pass
            value = spu_exec.read_out_mbox(self.spe_id)
            regs.append(value)

            r = spu_exec.wait_stop_event(self.spe_id)
            self.resume(self.spe_id)

        r = spu_exec.wait_stop_event(self.spe_id)
        print 'next stop', r
        #  6) Restore code at original pc
        self.restore(self.debug_branch)
        self.get_instructions()

        #  7) Restore lsa[0:len(save_code)]
        # TODO: do this with putb

        #  8) Resume
        # self.resume(self.spe_id)
        # r = spu_exec.wait_stop_event(self.spe_id)
        self.resume(self.spe_id)
        r = self.wait_debug()

        return regs
Beispiel #6
0
    def nexti(self):

        if len(self.last_stop) == 1:
            # Restore a single instruction
            current_inst = self.restore(self.last_stop[0])
            last_idx = self.last_stop[0]
        else:
            # Restore two branch targets and determine which branch was taken
            # based on the stop code
            i1 = self.restore(self.last_stop[0])
            i2 = self.restore(self.last_stop[1])
            if self.stop_code == DEBUG_STOP:
                current_inst = i1
                last_idx = self.last_stop[0]
            else:
                current_inst = i2
                last_idx = self.last_stop[1]

        # If the current instruction is a branch, get the location
        # of all possible next instructions
        if isinstance(current_inst, (spu.br, spu.brsl)):
            next_stop = (self.last_stop[0] + current_inst.I16, )
            print 'next br:', next_stop
        elif isinstance(current_inst, (spu.bra, spu.brasl)):
            next_stop = (current_inst.I16 - (self.lsa >> 2), )
        elif isinstance(current_inst,
                        (spu.brnz, spu.brz, spu.brhnz, spu.brhz)):
            next_stop = (self.last_stop[0] + 1,
                         self.last_stop[0] + current_inst.I16)

        elif isinstance(current_inst, (spu.bi, spu.bisled, spu.bisl)):
            raise Exception(
                "DebugProcessor does not support branch indirect (bi) instructions"
            )
        else:
            next_stop = (self.last_stop[0] + 1, )

        # TODO: Get rid of last instruction.  Do something smarter.
        last_instruction = (next_stop[0] == (self.debug_idx - 1))

        # !!! STOPPED HERE !!!
        # !!! STILL WRONG !!!
        if not last_instruction:
            # Normal instructions and single target branches
            self.replace(next_stop[0],
                         spu.bra(self.debug_lsa, ignore_active=True))
            print 'target (1):', -(self.debug_lsa -
                                   ((self.lsa >> 2) + next_stop[0])
                                   ), self.debug_lsa, last_idx, self.lsa
            self.replace(
                self.debug_branch,
                spu.br(-(self.debug_lsa - ((self.lsa >> 2) + next_stop[0])),
                       ignore_active=True))
            # Branch target for test-based branch instructions
            if len(next_stop) == 2:
                self.replace(
                    next_stop[1],
                    spu.bra(self.debug_target_lsa, ignore_active=True))
                print 'target (2):', -(self.debug_target_lsa - (
                    (self.lsa >> 2) + next_stop[1])), self.debug_target_lsa
                self.replace(
                    self.debug_target_branch,
                    spu.br(-(self.debug_target_lsa -
                             ((self.lsa >> 2) + next_stop[1])),
                           ignore_active=True))

            # self.replace(next_stop, self.debug_stop)

        self.get_instructions()
        self.code.print_code()
        self.resume(self.spe_id)

        if last_instruction:
            r = self.join(self.spe_id)
            r = None
        else:
            r = self.wait_debug()
            self.last_stop = next_stop
            self.stop_code = r

        return r