Example #1
0
 def _run_exit_handler(self, opcode, pc):
   """regular end of a machine run"""
   sp = self.cpu.r_reg(REG_A7)
   callee_pc = self.mem.r32(sp)
   log_machine.debug("run exit: opcode=%04x, pc=%06x, sp=%06x, callee=%06x",
                     opcode, pc, sp, callee_pc)
   run_state = self.get_cur_run_state()
   run_state.done = True
   self.cpu.end()
Example #2
0
 def _trap_exc_handler(self, op, pc):
     """triggerd if Python code in a trap raised a Python exception"""
     log_machine.debug("trap exception handler: op=%04x pc=%06x", op, pc)
     # get pending exception
     exc_info = sys.exc_info()
     if exc_info:
         error = exc_info[1]
     else:
         error = RuntimeError("No exception?!")
     self._terminate_run(error)
Example #3
0
 def _trap_exc_handler(self, op, pc):
   """triggerd if Python code in a trap raised a Python exception"""
   log_machine.debug("trap exception handler: op=%04x pc=%06x", op, pc)
   # get pending exception
   exc_info = sys.exc_info()
   if exc_info:
     error = exc_info[1]
   else:
     error = RuntimeError("No exception?!")
   self._terminate_run(error)
Example #4
0
 def _trap_exc_handler(self, op, pc):
   log_machine.debug("trap exception handler: op=%04x pc=%06x", op, pc)
   run_state = self.get_cur_run_state()
   # get pending exception
   exc_info = sys.exc_info()
   if exc_info:
     run_state.error = exc_info[1]
   run_state.done = True
   # end time slice of cpu
   self.cpu.end()
   # report error
   self.error_reporter.report_error(run_state.error)
Example #5
0
 def _hw_exc_handler(self, opcode, pc):
     """an m68k Hardware Exception was triggered"""
     # get current pc
     sp = self.cpu.r_reg(REG_A7)
     callee_pc = self.mem.r32(sp)
     log_machine.debug("hw exception: pc=%06x sp=%06x callee=%06x", pc, sp,
                       callee_pc)
     # m68k Exception Triggered
     sr = self.mem.r16(sp)
     pc = self.mem.r32(sp + 2)
     txt = "m68k Exception: sr=%04x" % sr
     error = InvalidCPUStateError(pc, txt)
     self._terminate_run(error)
Example #6
0
 def _invalid_mem_access(self, mode, width, addr):
   log_machine.debug("invalid memory access: mode=%s width=%d addr=%06x",
                     mode, width, addr)
   run_state = self.get_cur_run_state()
   # already a pending error?
   if run_state.error:
     return
   run_state.error = InvalidMemoryAccessError(mode, width, addr)
   run_state.done = True
   # end time slice of cpu
   self.cpu.end()
   # report error
   self.error_reporter.report_error(run_state.error)
Example #7
0
 def _hw_exc_handler(self, opcode, pc):
   """an m68k Hardware Exception was triggered"""
   # get current pc
   sp = self.cpu.r_reg(REG_A7)
   callee_pc = self.mem.r32(sp)
   log_machine.debug("hw exception: pc=%06x sp=%06x callee=%06x",
                     pc, sp, callee_pc)
   # m68k Exception Triggered
   sr = self.mem.r16(sp)
   pc = self.mem.r32(sp + 2)
   txt = "m68k Exception: sr=%04x" % sr
   error = InvalidCPUStateError(pc, txt)
   self._terminate_run(error)
Example #8
0
 def _run_exit_handler(self, opcode, pc):
     """regular end of a machine run"""
     sp = self.cpu.r_reg(REG_A7)
     callee_pc = self.mem.r32(sp)
     log_machine.debug(
         "run exit: opcode=%04x, pc=%06x, sp=%06x, callee=%06x",
         opcode,
         pc,
         sp,
         callee_pc,
     )
     run_state = self.get_cur_run_state()
     run_state.done = True
     self.cpu.end()
Example #9
0
    def run(self,
            pc,
            sp=None,
            set_regs=None,
            get_regs=None,
            max_cycles=0,
            cycles_per_run=0,
            name=None):
        mem = self.mem
        cpu = self.cpu

        if name is None:
            name = "default"

        # current run nesting level
        nesting = len(self.run_states)

        # return address of a run is always run_end_addr
        ret_addr = self.run_exit_addr

        # get cpu context
        if nesting > 0:
            cpu_ctx = cpu.get_cpu_context()
        else:
            cpu_ctx = None

        # share stack with last run if not specified
        if sp is None:
            if nesting == 0:
                raise ValueError("stack must be specified!")
            else:
                sp = cpu.r_reg(REG_A7)
                sp -= 4

        log_machine.info("run#%d(%s): begin pc=%06x, sp=%06x, ret_addr=%06x",
                         nesting, name, pc, sp, ret_addr)

        # store return address on stack
        mem.w32(sp, ret_addr)

        # setup pc, sp
        cpu.w_pc(pc)
        cpu.w_reg(REG_A7, sp)

        # create run state for this run and push it
        run_state = RunState(name, pc, sp, ret_addr)
        self.run_states.append(run_state)

        # setup regs
        if set_regs:
            set_regs_txt = self._print_regs(set_regs)
            log_machine.info("run#%d: set_regs=%s", nesting, set_regs_txt)
            for reg in set_regs:
                val = set_regs[reg]
                cpu.w_reg(reg, val)

        # get cycle params either from this call or from default
        if not cycles_per_run:
            cycles_per_run = self.cycles_per_run
        if not max_cycles:
            max_cycles = self.max_cycles

        # main execution loop of run
        total_cycles = 0
        start_time = time.clock()
        try:
            while not run_state.done:
                log_machine.debug("+ cpu.execute")
                total_cycles += cpu.execute(cycles_per_run)
                log_machine.debug("- cpu.execute")
                # end after enough cycles
                if max_cycles > 0 and total_cycles >= max_cycles:
                    break
        except Exception as e:
            self.error_reporter.report_error(e)
        end_time = time.clock()

        # retrieve regs
        if get_regs:
            regs = {}
            for reg in get_regs:
                val = cpu.r_reg(reg)
                regs[reg] = val
            regs_text = self._print_regs(regs)
            log_machine.info("run #%d: get_regs=%s", nesting, regs_text)
            run_state.regs = regs

        # restore cpu context
        if cpu_ctx:
            cpu.set_cpu_context(cpu_ctx)

        # update run state
        run_state.time_delta = end_time - start_time
        run_state.cycles = total_cycles
        # pop
        self.run_states.pop()

        log_machine.info("run #%d(%s): end. state=%s", nesting, name,
                         run_state)

        # if run_state has error and we are not a top-level raise an error
        # so the running trap code gets aborted and propagates the abort
        if run_state.error:
            if nesting > 0 or self.raise_on_main_run:
                pc = cpu.r_pc()
                raise NestedCPURunError(pc, run_state.error)

        return run_state
Example #10
0
 def _invalid_mem_access(self, mode, width, addr):
     """triggered by invalid memory access"""
     log_machine.debug("invalid memory access: mode=%s width=%d addr=%06x",
                       mode, width, addr)
     error = InvalidMemoryAccessError(mode, width, addr)
     self._terminate_run(error)
Example #11
0
 def _shutdown_trap(self, op, pc):
   log_machine.debug("trigger shutdown func")
   self.shutdown_func()
Example #12
0
  def run(self, pc, sp=None, set_regs=None, get_regs=None,
          max_cycles=0, cycles_per_run=0, name=None):
    mem = self.mem
    cpu = self.cpu

    if name is None:
      name = "default"

    # current run nesting level
    nesting = len(self.run_states)

    # return address of a run is always run_end_addr
    ret_addr = self.run_exit_addr

    # get cpu context
    if nesting > 0:
      cpu_ctx = cpu.get_cpu_context()
    else:
      cpu_ctx = None

    # share stack with last run if not specified
    if sp is None:
      if nesting == 0:
        raise ValueError("stack must be specified!")
      else:
        sp = cpu.r_reg(REG_A7)
        sp -= 4

    log_machine.info("run#%d(%s): begin pc=%06x, sp=%06x, ret_addr=%06x",
                     nesting, name, pc, sp, ret_addr)

    # store return address on stack
    mem.w32(sp, ret_addr)

    # setup pc, sp
    cpu.w_pc(pc)
    cpu.w_reg(REG_A7, sp)

    # create run state for this run and push it
    run_state = RunState(name, pc, sp, ret_addr)
    self.run_states.append(run_state)

    # setup regs
    if set_regs:
      set_regs_txt = self._print_regs(set_regs)
      log_machine.info("run#%d: set_regs=%s", nesting, set_regs_txt)
      for reg in set_regs:
        val = set_regs[reg]
        cpu.w_reg(reg, val)

    # get cycle params either from this call or from default
    if not cycles_per_run:
      cycles_per_run = self.cycles_per_run
    if not max_cycles:
      max_cycles = self.max_cycles

    # main execution loop of run
    total_cycles = 0
    start_time = time.clock()
    try:
      while not run_state.done:
        log_machine.debug("+ cpu.execute")
        total_cycles += cpu.execute(cycles_per_run)
        log_machine.debug("- cpu.execute")
        # end after enough cycles
        if max_cycles > 0 and total_cycles >= max_cycles:
          break
    except Exception as e:
      self.error_reporter.report_error(e)
    end_time = time.clock()

    # retrieve regs
    if get_regs:
      regs = {}
      for reg in get_regs:
        val = cpu.r_reg(reg)
        regs[reg] = val
      regs_text = self._print_regs(regs)
      log_machine.info("run #%d: get_regs=%s", nesting, regs_text)
      run_state.regs = regs

    # restore cpu context
    if cpu_ctx:
      cpu.set_cpu_context(cpu_ctx)

    # update run state
    run_state.time_delta = end_time - start_time
    run_state.cycles = total_cycles
    # pop
    self.run_states.pop()

    log_machine.info("run #%d(%s): end. state=%s", nesting, name, run_state)

    # if run_state has error and we are not a top-level raise an error
    # so the running trap code gets aborted and propagates the abort
    if run_state.error:
      if nesting > 0 or self.raise_on_main_run:
        pc = cpu.r_pc()
        raise NestedCPURunError(pc, run_state.error)

    return run_state
Example #13
0
 def _invalid_mem_access(self, mode, width, addr):
   """triggered by invalid memory access"""
   log_machine.debug("invalid memory access: mode=%s width=%d addr=%06x",
                     mode, width, addr)
   error = InvalidMemoryAccessError(mode, width, addr)
   self._terminate_run(error)