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
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
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
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
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
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