void opc_cmp_handler(char *opd1,char *opd2,char *offset,char *immi){ int ans; int dec_opd2=bintodec(opd2); if(immi[1]=='0'){ if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); int val_opd2=get_reg_val(dec_opd2); ans=val_opd2-get_reg_val(dec_opd1); } else{ int dec_im_opd1=bintodec(opd1); ans=get_reg_val(dec_opd2)-dec_im_opd1; } } else{ int dec_off=bintodec(offset); if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); ans=get_mem_val(dec_opd2+dec_off)-get_reg_val(dec_opd1); } else{ int dec_im_opd1=bintodec(opd1); ans=get_mem_val(dec_opd2+dec_off)-dec_im_opd1; } } if(ans==0){ set_reg_val(regfile+R_FLAGS,0); } else if(ans>0){ set_reg_val(regfile+R_FLAGS,1); } else{ set_reg_val(regfile+R_FLAGS,2); } }
/* Implements both ID and WB */ void do_id_wb_stages() { /* Set up write backs. Don't occur until end of cycle */ wb_destE = gen_w_dstE(); wb_valE = gen_w_valE(); wb_destM = gen_w_dstM(); wb_valM = gen_w_valM(); id_ex_next->srca = gen_new_E_srcA(); id_ex_next->srcb = gen_new_E_srcB(); id_ex_next->deste = gen_new_E_dstE(); id_ex_next->destm = gen_new_E_dstM(); /* Read the registers */ d_regvala = get_reg_val(reg, id_ex_next->srca); d_regvalb = get_reg_val(reg, id_ex_next->srcb); /* Do forwarding and valA selection */ id_ex_next->vala = gen_new_E_valA(); id_ex_next->valb = gen_new_E_valB(); id_ex_next->icode = if_id_curr->icode; id_ex_next->ifun = if_id_curr->ifun; id_ex_next->valc = if_id_curr->valc; id_ex_next->stage_pc = if_id_curr->stage_pc; id_ex_next->exception = (if_id_curr->icode == I_HALT) ? EXC_HALT : if_id_curr->exception; sim_log("Decode: instr = %s, exc=%s\n", iname(HPACK(if_id_curr->icode, if_id_curr->ifun)), exc_name(if_id_curr->exception)); }
/* Implements both ID and WB */ void do_id_wb_stages() { /* Set up write backs. Don't occur until end of cycle */ wb_destE = gen_w_dstE(); wb_valE = gen_w_valE(); wb_destM = gen_w_dstM(); wb_valM = gen_w_valM(); /* Update processor status */ status = gen_Stat(); id_ex_next->srca = gen_d_srcA(); id_ex_next->srcb = gen_d_srcB(); id_ex_next->deste = gen_d_dstE(); id_ex_next->destm = gen_d_dstM(); /* Read the registers */ d_regvala = get_reg_val(reg, id_ex_next->srca); d_regvalb = get_reg_val(reg, id_ex_next->srcb); /* Do forwarding and valA selection */ id_ex_next->vala = gen_d_valA(); id_ex_next->valb = gen_d_valB(); id_ex_next->icode = if_id_curr->icode; id_ex_next->ifun = if_id_curr->ifun; id_ex_next->valc = if_id_curr->valc; id_ex_next->stage_pc = if_id_curr->stage_pc; id_ex_next->status = if_id_curr->status; }
void execute(_decoder_output *decoded_instr){ instr_handlers[0]=opc_add_handler; instr_handlers[1]=opc_sub_handler; instr_handlers[2]=opc_mov_handler; instr_handlers[3]=opc_and_handler; instr_handlers[4]=opc_xor_handler; instr_handlers[5]=opc_or_handler; instr_handlers[6]=opc_cmp_handler; instr_handlers[8]=opc_xchange_handler; instr_handlers[9]=opc_push_handler; instr_handlers[10]=opc_pop_handler; instr_handlers[11]=opc_mul_handler; instr_handlers[12]=opc_mul_handler; instr_handlers[13]=opc_div_handler; instr_handlers[14]=opc_div_handler; instr_handlers[15]=opc_jmp_handler; instr_handlers[16]=opc_je_handler; instr_handlers[17]=opc_jne_handler; instr_handlers[18]=opc_jg_handler; instr_handlers[19]=opc_jge_handler; instr_handlers[20]=opc_jl_handler; instr_handlers[21]=opc_jle_handler; instr_handlers[22]=opc_jmp_handler; if(clock>2){ int dec_opc=bintodec(decoded_instr->opc); if(dec_opc==63){ printf("\n\npc is %d\n",get_reg_val(15)); printf("\n\nregister file is\n"); print(regfile); printf("\n\nmemory is\n"); print(mem); printf("exiting"); exit(0); } instr_handlers[dec_opc](decoded_instr->opd1,decoded_instr->opd2,decoded_instr->offset,decoded_instr->immi); } switch(pending_bds){ case 2: set_reg_val(regfile+REG_PC,get_reg_val(REG_PC)+1); pending_bds--; break; case 1: set_reg_val(regfile+REG_PC,get_reg_val(REG_NEXTPC)-2); pending_bds--; break; case 0: set_reg_val(regfile+REG_PC,get_reg_val(REG_PC)+1); break; } }
void opc_pop_handler(char *opd1,char *opd2,char *offset,char *immi){ int ans; int dec_opd2=bintodec(opd2); int val_esp=get_reg_val(8); if(immi[1]=='0'){ if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); int val_mem=get_mem_val(mem+val_esp); ans=val_mem; set_reg_val(regfile+dec_opd1,ans); } } int new_esp=get_reg_val(8)+1; set_reg_val(regfile+8,new_esp); }
inline bool get_reg_val(const char *regname, ulonglong *ival) { regval_t regval; if (!get_reg_val(regname, ®val)) return false; if (ival != NULL) *ival = regval.ival; return true; }
void exec_pipeline_stages(void){ _decoder_output cur_decoder_output; static _decoder_output prev_decoded_instr; fetch(get_reg_val(REG_NEXTPC)); decode(peek_pipeline(1),&cur_decoder_output); execute(&prev_decoded_instr); prev_decoded_instr = cur_decoder_output; }
void opc_div_handler(char *opd1,char *opd2,char *offset,char *immi){ int ans; int dec_opd2=bintodec(opd2); if(immi[1]=='0'){ if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); int val_eax=get_reg_val(0); ans=val_eax/get_reg_val(dec_opd1); set_reg_val(regfile+0,ans); } else{ int dec_im_opd1=bintodec(opd1); ans=get_reg_val(0)/dec_im_opd1; set_reg_val(regfile+0,ans); } } }
void start_cpu(void){ int RESET_VEC_ADDR=0; set_reg_val(regfile+16,RESET_VEC_ADDR); //NEXT_PC set_reg_val(regfile+15,get_reg_val(REG_NEXTPC)-2); //PC pending_bds =0 ; while(1){ if(no_of_ins-1>stop_ins){ printf("\n\npc is %d\n",get_reg_val(15)); printf("\n\nregister file is\n"); print(regfile); printf("\n\nmemory is\n"); print(mem); exit(0); } start_new_cycle(); exec_pipeline_stages(); } }
void opc_push_handler(char *opd1,char *opd2,char *offset,char *immi){ int ans; int dec_opd2=bintodec(opd2); int val_esp=get_reg_val(8); if(immi[1]=='0'){ if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); ans=get_reg_val(dec_opd1); set_reg_val(mem+val_esp,ans); } else{ int dec_im_opd1=bintodec(opd1); ans=dec_im_opd1; set_reg_val(mem+val_esp,ans); } } int new_esp=get_reg_val(8)-1; set_reg_val(regfile+8,new_esp); }
void decode( char *instr, _decoder_output *out){ if(instr){ get_opcode(instr,out); get_operands(instr,out); } else{ out->opc[0] = '\0'; } set_reg_val(regfile+REG_NEXTPC,get_reg_val(REG_NEXTPC)+1); }
void opc_jne_handler(char *opd1,char *opd2,char *offset,char *immi){ int ans; int dec_opd2=bintodec(opd2); int flag=get_reg_val(17); if(flag!=0){ if(immi[1]=='0'){ if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); ans=get_reg_val(dec_opd1)-1; set_reg_val(regfile+15,ans); } else{ int dec_im_opd1=bintodec(opd1); ans=dec_im_opd1-1; set_reg_val(regfile+15,ans); } } pending_bds=2; } }
static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd) { int ret, val, odr_tbl_size; uint8_t ctrl_reg, reg_val; const struct accel_param_pair *data_rates; struct lsm6ds0_data *data = s->drv_data; ctrl_reg = get_ctrl_reg(s->type); data_rates = get_odr_table(s->type, &odr_tbl_size); reg_val = get_reg_val(rate, rnd, data_rates, odr_tbl_size); /* * Lock accel resource to prevent another task from attempting * to write accel parameters until we are done. */ mutex_lock(s->mutex); ret = raw_read8(s->addr, ctrl_reg, &val); if (ret != EC_SUCCESS) goto accel_cleanup; val = (val & ~LSM6DS0_ODR_MASK) | reg_val; ret = raw_write8(s->addr, ctrl_reg, val); /* Now that we have set the odr, update the driver's value. */ if (ret == EC_SUCCESS) data->base.odr = get_engineering_val(reg_val, data_rates, odr_tbl_size); /* CTRL_REG3_G 12h * [7] low-power mode = 0; * [6] high pass filter disabled; * [5:4] 0 keep const 0 * [3:0] HPCF_G * Table 48 Gyroscope high-pass filter cutoff frequency */ if (MOTIONSENSE_TYPE_GYRO == s->type) { ret = raw_read8(s->addr, LSM6DS0_CTRL_REG3_G, &val); if (ret != EC_SUCCESS) goto accel_cleanup; val &= ~(0x3 << 4); /* clear bit [5:4] */ val = (rate > 119000) ? (val | (1<<7)) /* set high-power mode */ : (val & ~(1<<7)); /* set low-power mode */ ret = raw_write8(s->addr, LSM6DS0_CTRL_REG3_G, val); } accel_cleanup: mutex_unlock(s->mutex); return ret; }
int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) { int r = 0; union kvmppc_one_reg val; int size; size = one_reg_size(reg->id); if (size > sizeof(val)) return -EINVAL; r = kvmppc_get_one_reg(vcpu, reg->id, &val); if (r == -EINVAL) { r = 0; switch (reg->id) { #ifdef CONFIG_ALTIVEC case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } val.vval = vcpu->arch.vr.vr[reg->id - KVM_REG_PPC_VR0]; break; case KVM_REG_PPC_VSCR: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } val = get_reg_val(reg->id, vcpu->arch.vr.vscr.u[3]); break; case KVM_REG_PPC_VRSAVE: val = get_reg_val(reg->id, vcpu->arch.vrsave); break; #endif /* CONFIG_ALTIVEC */ default: r = -EINVAL; break; } }
void opc_xchange_handler(char *opd1,char *opd2,char *offset,char *immi){ int ans1,ans2; int dec_opd2=bintodec(opd2); if(immi[1]=='0'){ if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); int val_opd2=get_reg_val(dec_opd2); ans1=get_reg_val(dec_opd1); set_reg_val(regfile+dec_opd2,ans1); ans2=get_reg_val(dec_opd2); set_reg_val(regfile+dec_opd1,ans2); } } else{ int dec_off=bintodec(offset); if(immi[0]=='0'){ int dec_opd1=bintodec(opd1); ans1=get_mem_val(dec_opd2+dec_off)+get_reg_val(dec_opd1); set_reg_val(mem+dec_opd2+dec_off,ans1); ans2=get_mem_val(dec_opd2+dec_off); set_reg_val(regfile+dec_opd1,ans2); } } }
void main(void) { unsigned hder = 0, new_hder = 0; unsigned crt_address; BIOS_VAR _far *bios_var_ptr; unsigned i = 0; // Получаем указатель на область переменных видеофункций BIOS bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410); // Определяем адрес порта индексного регистра контроллера ЭЛТ crt_address = bios_var_ptr->crt_address; disable_protection_mode(crt_address); // Читаем значение HDER hder = get_reg_val(crt_address, HDER); // Очищаем экран clrscr(); printf("\nТекущее значение HDER регистра %d\n", hder); for (i = 0; i < hder; i++) { printf("*"); } printf("\nВведите длину отображаемой части горизонтальной развертки:"); scanf("%d", &new_hder); // Устанавливаем новое значение set_reg_val(crt_address, HDER, new_hder); printf("\nДля завершения программы нажмите любую клавишу"); getch(); // Восстанавливаем значение по умолчанию set_reg_val(crt_address, HDER, hder); }
//--------------------------------------------------------------------------- bool x86seh_ctx_t::get_sehlist() { uint64 fs_sel; ea_t fs_base; uint32 excr_ea; handlers.clear(); if ( !get_reg_val("fs", &fs_sel) || internal_get_sreg_base(tid, int(fs_sel), &fs_base) <= 0 || read_dbg_memory(fs_base, &excr_ea, sizeof(excr_ea)) != sizeof(excr_ea) ) { warning("Failed to build the SEH list for thread %08X", tid); return false; } struct EXC_REG_RECORD { uint32 p_prev; uint32 p_handler; }; EXC_REG_RECORD rec; std::set<uint32> seen; while ( excr_ea != 0xffffffff ) { if ( read_dbg_memory(excr_ea, &rec, sizeof(rec)) != sizeof(rec) ) break; if ( !seen.insert(excr_ea).second ) { msg("Circular SEH record has been detected\n"); break; } handlers.push_back(rec.p_handler); excr_ea = rec.p_prev; } return true; }
static int set_range(const struct motion_sensor_t *s, int range, int rnd) { int ret, ctrl_val, range_tbl_size; uint8_t ctrl_reg, reg_val; const struct gyro_param_pair *ranges; struct l3gd20_data *data = (struct l3gd20_data *)s->drv_data; ctrl_reg = L3GD20_CTRL_REG4; ranges = get_range_table(s->type, &range_tbl_size); reg_val = get_reg_val(range, rnd, ranges, range_tbl_size); /* * Lock Gyro resource to prevent another task from attempting * to write Gyro parameters until we are done. */ mutex_lock(s->mutex); ret = raw_read8(s->port, s->addr, ctrl_reg, &ctrl_val); if (ret != EC_SUCCESS) goto gyro_cleanup; ctrl_val = (ctrl_val & ~L3GD20_RANGE_MASK) | reg_val; ret = raw_write8(s->port, s->addr, ctrl_reg, ctrl_val); /* Now that we have set the range, update the driver's value. */ if (ret == EC_SUCCESS) data->base.range = get_engineering_val(reg_val, ranges, range_tbl_size); gyro_cleanup: mutex_unlock(s->mutex); return EC_SUCCESS; }
static int set_range(const struct motion_sensor_t *s, int range, int rnd) { int ret, ctrl_val, range_tbl_size; uint8_t ctrl_reg, reg_val; const struct accel_param_pair *ranges; struct lsm6ds0_data *data = s->drv_data; ctrl_reg = get_ctrl_reg(s->type); ranges = get_range_table(s->type, &range_tbl_size); reg_val = get_reg_val(range, rnd, ranges, range_tbl_size); /* * Lock accel resource to prevent another task from attempting * to write accel parameters until we are done. */ mutex_lock(s->mutex); ret = raw_read8(s->addr, ctrl_reg, &ctrl_val); if (ret != EC_SUCCESS) goto accel_cleanup; ctrl_val = (ctrl_val & ~LSM6DS0_RANGE_MASK) | reg_val; ret = raw_write8(s->addr, ctrl_reg, ctrl_val); /* Now that we have set the range, update the driver's value. */ if (ret == EC_SUCCESS) data->base.range = get_engineering_val(reg_val, ranges, range_tbl_size); accel_cleanup: mutex_unlock(s->mutex); return ret; }
//-------------------------------------------------------------------------- static int idaapi callback( void * /*user_data*/, int notification_code, va_list va) { static int stage = 0; static bool is_dll; static char needed_file[QMAXPATH]; switch ( notification_code ) { case dbg_process_start: case dbg_process_attach: get_input_file_path(needed_file, sizeof(needed_file)); // no break case dbg_library_load: if ( stage == 0 ) { const debug_event_t *pev = va_arg(va, const debug_event_t *); if ( !strieq(pev->modinfo.name, needed_file) ) break; if ( notification_code == dbg_library_load ) is_dll = true; // remember the current module bounds if ( pev->modinfo.rebase_to != BADADDR ) curmod.startEA = pev->modinfo.rebase_to; else curmod.startEA = pev->modinfo.base; curmod.endEA = curmod.startEA + pev->modinfo.size; deb(IDA_DEBUG_PLUGIN, "UUNP: module space %a-%a\n", curmod.startEA, curmod.endEA); ++stage; } break; case dbg_library_unload: if ( stage != 0 && is_dll ) { const debug_event_t *pev = va_arg(va, const debug_event_t *); if ( curmod.startEA == pev->modinfo.base || curmod.startEA == pev->modinfo.rebase_to ) { deb(IDA_DEBUG_PLUGIN, "UUNP: unload unpacked module\n"); if ( stage > 2 ) enable_step_trace(false); stage = 0; curmod.startEA = 0; curmod.endEA = 0; _hide_wait_box(); } } break; case dbg_run_to: // Parameters: const debug_event_t *event dbg->stopped_at_debug_event(true); bp_gpa = get_name_ea(BADADDR, "kernel32_GetProcAddress"); #ifndef __X64__ if( (LONG)GetVersion() < 0 ) // win9x mode -- use thunk's { is_9x = true; win9x_resolve_gpa_thunk(); } #endif if ( bp_gpa == BADADDR ) { bring_debugger_to_front(); warning("Sorry, could not find kernel32.GetProcAddress"); FORCE_STOP: stage = 4; // last stage clear_requests_queue(); request_exit_process(); run_requests(); break; } else if( !my_add_bpt(bp_gpa) ) { bring_debugger_to_front(); warning("Sorry, can not set bpt to kernel32.GetProcAddress"); goto FORCE_STOP; } else { ++stage; set_wait_box("Waiting for a call to GetProcAddress()"); } continue_process(); break; case dbg_bpt: // A user defined breakpoint was reached. // Parameters: thid_t tid // ea_t breakpoint_ea // int *warn = -1 // Return (in *warn): // -1 - to display a breakpoint warning dialog // if the process is suspended. // 0 - to never display a breakpoint warning dialog. // 1 - to always display a breakpoint warning dialog. { thid_t tid = va_arg(va, thid_t); qnotused(tid); ea_t ea = va_arg(va, ea_t); //int *warn = va_arg(va, int*); if ( stage == 2 ) { if ( ea == bp_gpa ) { regval_t rv; if ( get_reg_val(REGNAME_ESP, &rv) ) { ea_t esp = ea_t(rv.ival); invalidate_dbgmem_contents(esp, 1024); ea_t gpa_caller = getPtr(esp); if ( !is_library_entry(gpa_caller) ) { ea_t nameaddr; if ( ptrSz == 4 ) { nameaddr = get_long(esp+8); } else { get_reg_val(REGNAME_ECX, &rv); nameaddr = ea_t(rv.ival); } invalidate_dbgmem_contents(nameaddr, 1024); char name[MAXSTR]; size_t len = get_max_ascii_length(nameaddr, ASCSTR_C, ALOPT_IGNHEADS); name[0] = '\0'; get_ascii_contents2(nameaddr, len, ASCSTR_C, name, sizeof(name)); if ( !ignore_win32_api(name) ) { deb(IDA_DEBUG_PLUGIN, "%a: found a call to GetProcAddress(%s)\n", gpa_caller, name); if ( !my_del_bpt(bp_gpa) || !my_add_bpt(gpa_caller) ) error("Can not modify breakpoint"); } } } } else if ( ea == bpt_ea ) { my_del_bpt(ea); if ( !is_library_entry(ea) ) { msg("Uunp: reached unpacker code at %a, switching to trace mode\n", ea); enable_step_trace(true); ++stage; uint64 eax; if ( get_reg_val(REGNAME_EAX, &eax) ) an_imported_func = ea_t(eax); set_wait_box("Waiting for the unpacker to finish"); } else { warning("%a: bpt in library code", ea); // how can it be? my_add_bpt(bp_gpa); } } // not our bpt? skip it else { // hide the wait box to allow others plugins to properly stop _hide_wait_box(); break; } } } // while continue_process() would work here too, request+run is more universal // because they do not ignore the request queue request_continue_process(); run_requests(); break; case dbg_trace: // A step occured (one instruction was executed). This event // notification is only generated if step tracing is enabled. // Parameter: none if ( stage == 3 ) { thid_t tid = va_arg(va, thid_t); qnotused(tid); ea_t ip = va_arg(va, ea_t); // ip reached the OEP range? if ( oep_area.contains(ip) ) { // stop the trace mode enable_step_trace(false); msg("Uunp: reached OEP %a\n", ip); set_wait_box("Reanalyzing the unpacked code"); // reanalyze the unpacked code do_unknown_range(oep_area.startEA, oep_area.size(), DOUNK_EXPAND); auto_make_code(ip); // plan to make code noUsed(oep_area.startEA, oep_area.endEA); // plan to reanalyze auto_mark_range(oep_area.startEA, oep_area.endEA, AU_FINAL); // plan to analyze move_entry(ip); // mark the program's entry point _hide_wait_box(); // inform the user bring_debugger_to_front(); if ( askyn_c(1, "HIDECANCEL\n" "The universal unpacker has finished its work.\n" "Do you want to take a memory snapshot and stop now?\n" "(you can do it yourself if you want)\n") > 0 ) { set_wait_box("Recreating the import table"); invalidate_dbgmem_config(); if ( is_9x ) find_thunked_imports(); create_impdir(); set_wait_box("Storing resources to 'resource.res'"); if ( resfile[0] != '\0' ) extract_resource(resfile); _hide_wait_box(); if ( take_memory_snapshot(true) ) goto FORCE_STOP; } suspend_process(); unhook_from_notification_point(HT_DBG, callback, NULL); } } break; case dbg_process_exit: { stage = 0; // stop the tracing _hide_wait_box(); unhook_from_notification_point(HT_DBG, callback, NULL); if ( success ) jumpto(inf.beginEA, -1); else tell_about_failure(); } break; case dbg_exception:// Parameters: const debug_event_t *event // int *warn = -1 // Return (in *warn): // -1 - to display an exception warning dialog // if the process is suspended. // 0 - to never display an exception warning dialog. // 1 - to always display an exception warning dialog. { // const debug_event_t *event = va_arg(va, const debug_event_t *); // int *warn = va_arg(va, int *); // FIXME: handle code which uses SEH to unpack itself if ( askyn_c(1, "AUTOHIDE DATABASE\n" "HIDECANCEL\n" "An exception occurred in the program.\n" "UUNP does not support exceptions yet.\n" "The execution has been suspended.\n" "Do you want to continue the unpacking?") <= 0 ) { _hide_wait_box(); stage = 0; enable_step_trace(false); // stop the trace mode suspend_process(); } else { continue_process(); } } break; case dbg_request_error: // An error occured during the processing of a request. // Parameters: ui_notification_t failed_command // dbg_notification_t failed_dbg_notification { ui_notification_t failed_cmd = va_arg(va, ui_notification_t); dbg_notification_t failed_dbg_notification = va_arg(va, dbg_notification_t); _hide_wait_box(); stage = 0; warning("dbg request error: command: %d notification: %d", failed_cmd, failed_dbg_notification); } break; } return 0; }
/* Execute single instruction. Return exception condition. */ exc_t step_state(state_ptr s, FILE *error_file) { word_t argA, argB; byte_t byte0 = 0; byte_t byte1 = 0; itype_t hi0; alu_t lo0; reg_id_t hi1 = REG_NONE; reg_id_t lo1 = REG_NONE; bool_t ok1 = TRUE; word_t cval; word_t okc = TRUE; word_t val, dval; bool_t need_regids; bool_t need_imm; word_t ftpc = s->pc; if (!get_byte_val(s->m, ftpc, &byte0)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } ftpc++; hi0 = HI4(byte0); lo0 = LO4(byte0); need_regids = (hi0 == I_RRMOVL || hi0 == I_ALU || hi0 == I_PUSHL || hi0 == I_POPL || hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL || hi0 == I_ALUI); if (need_regids) { ok1 = get_byte_val(s->m, ftpc, &byte1); ftpc++; hi1 = HI4(byte1); lo1 = LO4(byte1); } need_imm = (hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL || hi0 == I_JXX || hi0 == I_CALL || hi0 == I_ALUI); if (need_imm) { okc = get_word_val(s->m, ftpc, &cval); ftpc += 4; } switch (hi0) { case I_NOP: s->pc = ftpc; break; case I_HALT: s->pc = ftpc; return EXC_HALT; break; case I_RRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } if (lo1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return EXC_INSTR; } val = get_reg_val(s->r, hi1); set_reg_val(s->r, lo1, val); s->pc = ftpc; break; #if 0 case I_IRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return EXC_INSTR; } if (lo1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return EXC_INSTR; } set_reg_val(s->r, lo1, cval); s->pc = ftpc; break; #endif case I_RMMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_INSTR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } if (lo1 < 8) cval += get_reg_val(s->r, lo1); val = get_reg_val(s->r, hi1); if (!set_word_val(s->m, cval, val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid data address 0x%x\n", s->pc, cval); return EXC_ADDR; } s->pc = ftpc; break; case I_MRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction addres\n", s->pc); return EXC_INSTR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } if (lo1 < 8) cval += get_reg_val(s->r, lo1); if (!get_word_val(s->m, cval, &val)) return EXC_ADDR; set_reg_val(s->r, hi1, val); s->pc = ftpc; break; case I_ALU: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } argA = get_reg_val(s->r, hi1); argB = get_reg_val(s->r, lo1); val = compute_alu(lo0, argA, argB); set_reg_val(s->r, lo1, val); s->cc = compute_cc(lo0, argA, argB); s->pc = ftpc; break; case I_JXX: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (take_branch(s->cc, lo0)) s->pc = cval; else s->pc = ftpc; break; #if 0 case I_CALL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } val = get_reg_val(s->r, REG_ESP) - 4; set_reg_val(s->r, REG_ESP, val); if (!set_word_val(s->m, val, ftpc)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, val); return EXC_ADDR; } s->pc = cval; break; case I_RET: /* Return Instruction. Pop address from stack */ dval = get_reg_val(s->r, REG_ESP); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } set_reg_val(s->r, REG_ESP, dval + 4); s->pc = val; break; #endif case I_PUSHL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } val = get_reg_val(s->r, hi1); dval = get_reg_val(s->r, REG_ESP) - 4; set_reg_val(s->r, REG_ESP, dval); if (!set_word_val(s->m, dval, val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } s->pc = ftpc; break; case I_POPL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (hi1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return EXC_INSTR; } dval = get_reg_val(s->r, REG_ESP); set_reg_val(s->r, REG_ESP, dval+4); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } set_reg_val(s->r, hi1, val); s->pc = ftpc; break; case I_LEAVE: dval = get_reg_val(s->r, REG_EBP); set_reg_val(s->r, REG_ESP, dval+4); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return EXC_ADDR; } set_reg_val(s->r, REG_EBP, val); s->pc = ftpc; break; #if 0 case I_ALUI: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return EXC_ADDR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return EXC_INSTR; } if (lo1 >= 8) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return EXC_INSTR; } argB = get_reg_val(s->r, lo1); val = argB + cval; set_reg_val(s->r, lo1, val); s->cc = compute_cc(A_ADD, cval, argB); s->pc = ftpc; break; #endif default: if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0); return EXC_INSTR; } return EXC_NONE; }
/* Return resulting exception status */ static exc_t sim_step() { word_t aluA; word_t aluB; word_t alufun; exc_t status = update_state(); /* Update state from last cycle */ if (plusmode) { pc = gen_pc(); } valp = pc; if (get_byte_val(mem, valp, &instr)) { icode = HI4(instr); ifun = LO4(instr); } else { instr = HPACK(I_NOP,0); icode = I_NOP; ifun = 0; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; if (gen_need_regids()) { byte_t regids; if (get_byte_val(mem, valp, ®ids)) { ra = GET_RA(regids); rb = GET_RB(regids); } else { ra = REG_NONE; rb = REG_NONE; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; } else { ra = REG_NONE; rb = REG_NONE; } if (gen_need_valC()) { if (get_word_val(mem, valp, &valc)) { } else { valc = 0; status = EXC_ADDR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp+=4; } else { valc = 0; } if (status == EXC_NONE && !gen_instr_valid()) { status = EXC_INSTR; } sim_log("IF: Fetched %s at 0x%x. ra=%s, rb=%s, valC = 0x%x\n", iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc); if (status == EXC_NONE && icode == I_HALT) { status = EXC_HALT; } srcA = gen_srcA(); if (srcA != REG_NONE) { vala = get_reg_val(reg, srcA); } else { vala = 0; } srcB = gen_srcB(); if (srcB != REG_NONE) { valb = get_reg_val(reg, srcB); } else { valb = 0; } destE = gen_dstE(); destM = gen_dstM(); aluA = gen_aluA(); aluB = gen_aluB(); alufun = gen_alufun(); vale = compute_alu(alufun, aluA, aluB); cc_in = cc; if (gen_set_cc()) cc_in = compute_cc(alufun, aluA, aluB); bcond = (icode == I_JMP) && take_branch(cc, ifun); mem_addr = gen_mem_addr(); mem_data = gen_mem_data(); if (status == EXC_NONE && gen_mem_read()) { if (!get_word_val(mem, mem_addr, &valm)) { sim_log("Couldn't read at address 0x%x\n", mem_addr); return EXC_ADDR; } } else valm = 0; mem_write = status == EXC_NONE && gen_mem_write(); if (plusmode) { prev_icode_in = icode; prev_ifun_in = ifun; prev_valc_in = valc; prev_valm_in = valm; prev_valp_in = valp; prev_bcond_in = bcond; } else { /* Update PC */ pc_in = gen_new_pc(); } sim_report(); return status; }
static int idaapi hook_ui(void *user_data, int notification_code, va_list va) { switch (notification_code) { case ui_notification_t::ui_get_custom_viewer_hint: { TCustomControl *viewer = va_arg(va, TCustomControl *); place_t *place = va_arg(va, place_t *); int *important_lines = va_arg(va, int *); qstring &hint = *va_arg(va, qstring *); if (place == NULL) return 0; int x, y; if (get_custom_viewer_place(viewer, true, &x, &y) == NULL) return 0; char buf[MAXSTR]; const char *line = get_custom_viewer_curline(viewer, true); tag_remove(line, buf, sizeof(buf)); if (x >= (int)strlen(buf)) return 0; idaplace_t &pl = *(idaplace_t *)place; if (decode_insn(pl.ea) && dbg_started) { insn_t _cmd = cmd; int flags = calc_default_idaplace_flags(); linearray_t ln(&flags); for (int i = 0; i < qnumber(_cmd.Operands); i++) { op_t op = _cmd.Operands[i]; if (op.type != o_void) { switch (op.type) { case o_mem: case o_near: { idaplace_t here; here.ea = op.addr; here.lnnum = 0; ln.set_place(&here); hint.cat_sprnt((COLSTR(SCOLOR_INV"OPERAND#%d (ADDRESS: $%a)\n", SCOLOR_DREF)), op.n, op.addr); (*important_lines)++; int n = qmin(ln.get_linecnt(), 10); // how many lines for this address? (*important_lines) += n; for (int j = 0; j < n; ++j) { hint.cat_sprnt("%s\n", ln.down()); } } break; case o_phrase: case o_reg: { regval_t reg; int reg_idx = idp_to_dbg_reg(op.reg); const char *reg_name = dbg->registers(reg_idx).name; if (get_reg_val(reg_name, ®)) { idaplace_t here; here.ea = (uint32)reg.ival; here.lnnum = 0; ln.set_place(&here); hint.cat_sprnt((COLSTR(SCOLOR_INV"OPERAND#%d (REGISTER: %s)\n", SCOLOR_DREF)), op.n, reg_name); (*important_lines)++; int n = qmin(ln.get_linecnt(), 10); // how many lines for this address? (*important_lines) += n; for (int j = 0; j < n; ++j) { hint.cat_sprnt("%s\n", ln.down()); } } } break; case o_displ: { regval_t main_reg, add_reg; int main_reg_idx = idp_to_dbg_reg(op.reg); int add_reg_idx = idp_to_dbg_reg(op.specflag1 & 0xF); main_reg.ival = 0; add_reg.ival = 0; if (op.specflag2 & 0x10) { get_reg_val(dbg->registers(add_reg_idx).name, &add_reg); if (op.specflag1 & 0x10) add_reg.ival &= 0xFFFF; } if (main_reg_idx != R_PC) get_reg_val(dbg->registers(main_reg_idx).name, &main_reg); idaplace_t here; ea_t addr = (uint32)main_reg.ival + op.addr + (uint32)add_reg.ival; // TODO: displacements with PC and other regs unk_123(pc, d0.l); unk_111(d0, d2.w) here.ea = addr; here.lnnum = 0; ln.set_place(&here); hint.cat_sprnt((COLSTR(SCOLOR_INV"OPERAND#%d (DISPLACEMENT: [$%s%X($%X", SCOLOR_DREF)), op.n, ((int)op.addr < 0) ? "-" : "", ((int)op.addr < 0) ? -(int)op.addr : op.addr, (uint32)main_reg.ival ); if (op.specflag2 & 0x10) hint.cat_sprnt((COLSTR(",$%X", SCOLOR_DREF)), (uint32)add_reg.ival); hint.cat_sprnt((COLSTR(")])\n", SCOLOR_DREF))); (*important_lines)++; int n = qmin(ln.get_linecnt(), 10); // how many lines for this address? (*important_lines) += n; for (int j = 0; j < n; ++j) { hint.cat_sprnt("%s\n", ln.down()); } } break; } } } return 1; } } default: return 0; } }
/* Return resulting status */ static byte_t sim_step() { word_t aluA; word_t aluB; word_t alufun; status = STAT_AOK; imem_error = dmem_error = FALSE; update_state(); /* Update state from last cycle */ if (plusmode) { pc = gen_pc(); } valp = pc; instr = HPACK(I_NOP, F_NONE); imem_error = !get_byte_val(mem, valp, &instr); if (imem_error) { sim_log("Couldn't fetch at address 0x%x\n", valp); } imem_icode = HI4(instr); imem_ifun = LO4(instr); icode = gen_icode(); ifun = gen_ifun(); instr_valid = gen_instr_valid(); valp++; if (gen_need_regids()) { byte_t regids; if (get_byte_val(mem, valp, ®ids)) { ra = GET_RA(regids); rb = GET_RB(regids); } else { ra = REG_NONE; rb = REG_NONE; status = STAT_ADR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp++; } else { ra = REG_NONE; rb = REG_NONE; } if (gen_need_valC()) { if (get_word_val(mem, valp, &valc)) { } else { valc = 0; status = STAT_ADR; sim_log("Couldn't fetch at address 0x%x\n", valp); } valp+=4; } else { valc = 0; } sim_log("IF: Fetched %s at 0x%x. ra=%s, rb=%s, valC = 0x%x\n", iname(HPACK(icode,ifun)), pc, reg_name(ra), reg_name(rb), valc); if (status == STAT_AOK && icode == I_HALT) { status = STAT_HLT; } srcA = gen_srcA(); if (srcA != REG_NONE) { vala = get_reg_val(reg, srcA); } else { vala = 0; } srcB = gen_srcB(); if (srcB != REG_NONE) { valb = get_reg_val(reg, srcB); } else { valb = 0; } cond = cond_holds(cc, ifun); destE = gen_dstE(); destM = gen_dstM(); aluA = gen_aluA(); aluB = gen_aluB(); alufun = gen_alufun(); vale = compute_alu(alufun, aluA, aluB); cc_in = cc; if (gen_set_cc()) cc_in = compute_cc(alufun, aluA, aluB); bcond = cond && (icode == I_JMP); mem_addr = gen_mem_addr(); mem_data = gen_mem_data(); if (gen_mem_read()) { dmem_error = dmem_error || !get_word_val(mem, mem_addr, &valm); if (dmem_error) { sim_log("Couldn't read at address 0x%x\n", mem_addr); } } else valm = 0; mem_write = gen_mem_write(); if (mem_write) { /* Do a test read of the data memory to make sure address is OK */ word_t junk; dmem_error = dmem_error || !get_word_val(mem, mem_addr, &junk); } status = gen_Stat(); if (plusmode) { prev_icode_in = icode; prev_ifun_in = ifun; prev_valc_in = valc; prev_valm_in = valm; prev_valp_in = valp; prev_bcond_in = bcond; } else { /* Update PC */ pc_in = gen_new_pc(); } sim_report(); return status; }
/* Execute single instruction. Return status. */ stat_t step_state(state_ptr s, FILE *error_file) { word_t argA, argB; byte_t byte0 = 0; byte_t byte1 = 0; itype_t hi0; alu_t lo0; reg_id_t hi1 = REG_NONE; reg_id_t lo1 = REG_NONE; bool_t ok1 = TRUE; word_t cval = 0; word_t okc = TRUE; word_t val, dval; bool_t need_regids; bool_t need_imm; word_t ftpc = s->pc; /* Fall-through PC */ if (!get_byte_val(s->m, ftpc, &byte0)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } ftpc++; hi0 = HI4(byte0); lo0 = LO4(byte0); need_regids = (hi0 == I_RRMOVL || hi0 == I_ALU || hi0 == I_PUSHL || hi0 == I_POPL || hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL || hi0 == I_IADDL || hi0 == I_ISUBL); if (need_regids) { ok1 = get_byte_val(s->m, ftpc, &byte1); ftpc++; hi1 = HI4(byte1); lo1 = LO4(byte1); } need_imm = (hi0 == I_IRMOVL || hi0 == I_RMMOVL || hi0 == I_MRMOVL || hi0 == I_JMP || hi0 == I_CALL || hi0 == I_IADDL || hi0 == I_ISUBL); if (need_imm) { okc = get_word_val(s->m, ftpc, &cval); ftpc += 4; } switch (hi0) { case I_NOP: s->pc = ftpc; break; case I_HALT: return STAT_HLT; break; case I_RRMOVL: /* Both unconditional and conditional moves */ if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!reg_valid(hi1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return STAT_INS; } if (!reg_valid(lo1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return STAT_INS; } val = get_reg_val(s->r, hi1); if (cond_holds(s->cc, lo0)) set_reg_val(s->r, lo1, val); s->pc = ftpc; break; case I_IRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return STAT_INS; } if (!reg_valid(lo1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return STAT_INS; } set_reg_val(s->r, lo1, cval); s->pc = ftpc; break; case I_RMMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_INS; } if (!reg_valid(hi1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return STAT_INS; } if (reg_valid(lo1)) cval += get_reg_val(s->r, lo1); val = get_reg_val(s->r, hi1); if (!set_word_val(s->m, cval, val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid data address 0x%x\n", s->pc, cval); return STAT_ADR; } s->pc = ftpc; break; case I_MRMOVL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction addres\n", s->pc); return STAT_INS; } if (!reg_valid(hi1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return STAT_INS; } if (reg_valid(lo1)) cval += get_reg_val(s->r, lo1); if (!get_word_val(s->m, cval, &val)) return STAT_ADR; set_reg_val(s->r, hi1, val); s->pc = ftpc; break; case I_ALU: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } argA = get_reg_val(s->r, hi1); argB = get_reg_val(s->r, lo1); val = compute_alu(lo0, argA, argB); set_reg_val(s->r, lo1, val); s->cc = compute_cc(lo0, argA, argB); s->pc = ftpc; break; case I_JMP: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (cond_holds(s->cc, lo0)) s->pc = cval; else s->pc = ftpc; break; case I_CALL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } val = get_reg_val(s->r, REG_ESP) - 4; set_reg_val(s->r, REG_ESP, val); if (!set_word_val(s->m, val, ftpc)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, val); return STAT_ADR; } s->pc = cval; break; case I_RET: /* Return Instruction. Pop address from stack */ dval = get_reg_val(s->r, REG_ESP); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return STAT_ADR; } set_reg_val(s->r, REG_ESP, dval + 4); s->pc = val; break; case I_PUSHL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!reg_valid(hi1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return STAT_INS; } val = get_reg_val(s->r, hi1); dval = get_reg_val(s->r, REG_ESP) - 4; set_reg_val(s->r, REG_ESP, dval); if (!set_word_val(s->m, dval, val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return STAT_ADR; } s->pc = ftpc; break; case I_POPL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!reg_valid(hi1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, hi1); return STAT_INS; } dval = get_reg_val(s->r, REG_ESP); set_reg_val(s->r, REG_ESP, dval+4); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return STAT_ADR; } set_reg_val(s->r, hi1, val); s->pc = ftpc; break; case I_LEAVE: dval = get_reg_val(s->r, REG_EBP); set_reg_val(s->r, REG_ESP, dval+4); if (!get_word_val(s->m, dval, &val)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid stack address 0x%x\n", s->pc, dval); return STAT_ADR; } set_reg_val(s->r, REG_EBP, val); s->pc = ftpc; break; case I_IADDL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return STAT_INS; } if (!reg_valid(lo1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return STAT_INS; } argB = get_reg_val(s->r, lo1); val = argB + cval; set_reg_val(s->r, lo1, val); s->cc = compute_cc(A_ADD, cval, argB); s->pc = ftpc; break; case I_ISUBL: if (!ok1) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address\n", s->pc); return STAT_ADR; } if (!okc) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction address", s->pc); return STAT_INS; } if (!reg_valid(lo1)) { if (error_file) fprintf(error_file, "PC = 0x%x, Invalid register ID 0x%.1x\n", s->pc, lo1); return STAT_INS; } argB = get_reg_val(s->r, lo1); val = argB - cval; set_reg_val(s->r, lo1, val); s->cc = compute_cc(A_SUB, cval, argB); s->pc = ftpc; break; default: if (error_file) fprintf(error_file, "PC = 0x%x, Invalid instruction %.2x\n", s->pc, byte0); return STAT_INS; } return STAT_AOK; }
/* * nexti: execute single instruction and return status. * args * sim: the y86 image with PC, register and memory * * return * STAT_AOK: continue * STAT_HLT: halt * STAT_ADR: invalid instruction address, data address, stack address, ... * STAT_INS: invalid instruction, register id, ... */ stat_t nexti(y86sim_t *sim) { byte_t codefun = 0; itype_t icode; alu_t ifun; long_t valP = sim->pc; /* get code and function (1 byte) */ if (!get_byte_val(sim->m, valP, &codefun)) { err_print("PC = 0x%x, Invalid instruction address", sim->pc); return STAT_ADR; } icode = GET_ICODE(codefun); ifun = GET_FUN(codefun); valP++; /* get registers if needed (1 byte) */ byte_t byte; long_t valA, valB, valC, val; regid_t regA, regB; if ((icode>1 && icode<7) || icode==I_PUSHL || icode==I_POPL) { if (!get_byte_val(sim->m, valP, &byte)) { err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC); return STAT_ADR; } valP++; regA = HIGH(byte); regB = LOW(byte); } /* get immediate if needed (4 bytes) */ if (icode>=3 && icode<=8 && icode!=I_ALU) { if (!get_long_val(sim->m, valP, &valC)) { err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC); return STAT_ADR; } valP+=4; } /* execute the instruction */ switch (icode) { case I_HALT: /* 0:0 */ return STAT_HLT; break; case I_NOP: /* 1:0 */ sim->pc = valP; break; case I_RRMOVL: sim->pc = valP; if (!cond_doit(sim->cc,ifun)) break; val = get_reg_val(sim->r, regA); set_reg_val(sim->r, regB, val); break; /* 2:x regA:regB */ case I_IRMOVL: set_reg_val(sim->r, regB, valC); sim->pc = valP; break; /* 3:0 F:regB imm */ case I_RMMOVL: valC += get_reg_val(sim->r, regB); val = get_reg_val(sim->r, regA); set_long_val(sim->m, valC, val); sim->pc = valP; break; /* 4:0 regA:regB imm */ case I_MRMOVL: valC += get_reg_val(sim->r, regB); if (!get_long_val(sim->m, valC, &val)) { err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, valC); return STAT_ADR; } set_reg_val(sim->r, regA, val); sim->pc = valP; break; /* 5:0 regB:regA imm */ case I_ALU: valA = get_reg_val(sim->r,regA); valB = get_reg_val(sim->r,regB); val = compute_alu(ifun, valA, valB); set_reg_val(sim->r, regB, val); sim->cc = compute_cc(ifun, valA, valB, val); sim->pc = valP; break; /* 6:x regA:regB */ case I_JMP: sim->pc = (cond_doit(sim->cc,ifun))?valC:valP; break; /* 7:x imm */ case I_CALL: val = get_reg_val(sim->r, REG_ESP) - 4; set_reg_val(sim->r, REG_ESP, val); if (!set_long_val(sim->m, val, valP)) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, val); return STAT_ADR; } sim->pc = valC; break; /* 8:x imm */ case I_RET: valA = get_reg_val(sim->r, REG_ESP); if (!get_long_val(sim->m, valA, &valB)) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, valA); return STAT_ADR; } set_reg_val(sim->r, REG_ESP, valA+4); sim->pc = valB; break; /* 9:0 */ case I_PUSHL: valA = get_reg_val(sim->r, regA); val = get_reg_val(sim->r, REG_ESP) - 4; set_reg_val(sim->r, REG_ESP, val); if (!set_long_val(sim->m, val, valA)) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, val); return STAT_ADR; } sim->pc = valP; break; /* A:0 regA:F */ case I_POPL: valA = get_reg_val(sim->r, REG_ESP); set_reg_val(sim->r, REG_ESP, valA+4); if (!get_long_val(sim->m, valA, &valB)) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, valA); return STAT_ADR; } set_reg_val(sim->r, regA, valB); sim->pc = valP; break; /* B:0 regA:F */ default: err_print("PC = 0x%x, Invalid instruction %.2x", sim->pc, codefun); return STAT_INS; } return STAT_AOK; }
/* * nexti: execute single instruction and return status. * args * sim: the y86 image with PC, register and memory * * return * STAT_AOK: continue * STAT_HLT: halt * STAT_ADR: invalid instruction address * STAT_INS: invalid instruction, register id, data address, stack address, ... */ stat_t nexti(y86sim_t *sim) { byte_t codefun = 0; itype_t icode; alu_t ifun; long_t next_pc = sim->pc; regid_t rA = REG_NONE; regid_t rB = REG_NONE; long_t im_value = 0; /* get code and function (1 byte) */ if (!get_byte_val(sim->m, next_pc, &codefun)) { err_print("PC = 0x%x, Invalid instruction address", sim->pc); return STAT_ADR; } icode = GET_ICODE(codefun); ifun = GET_FUN(codefun); next_pc++; /* get registers if needed (1 byte) */ byte_t reg = 0; switch (icode) { case I_RRMOVL: case I_IRMOVL: case I_RMMOVL: case I_MRMOVL: case I_ALU: case I_PUSHL: case I_POPL: if(!get_byte_val(sim->m, next_pc, ®)) { err_print("PC = 0x%x, Invalid instruction address", sim->pc); return STAT_ADR; } rA = GET_REGA(reg); rB = GET_REGB(reg); next_pc++; case I_HALT:case I_NOP:case I_JMP:case I_CALL:case I_RET:default: break; } /* get immediate if needed (4 bytes) */ switch(icode) { case I_IRMOVL: case I_RMMOVL: case I_MRMOVL: case I_JMP: case I_CALL: if(!get_long_val(sim->m, next_pc, &im_value)) { err_print("PC = 0x%x, Invalid instruction address", sim->pc); return STAT_ADR; } next_pc += 4; case I_HALT:case I_NOP:case I_RRMOVL:case I_ALU: case I_RET:case I_PUSHL:case I_POPL:default: break; } /* execute the instruction */ switch (icode) { case I_HALT: /* 0:0 */ return STAT_HLT; break; case I_NOP: /* 1:0 */ sim->pc = next_pc; break; case I_RRMOVL:/* 2:x regA:regB */ { long_t rr_temp = get_reg_val(sim->r, rA); if (cond_doit(sim->cc, ifun)) set_reg_val(sim->r, rB, rr_temp); sim->pc = next_pc; break; } case I_IRMOVL: /* 3:0 F:regB imm */ { set_reg_val(sim->r, rB, im_value); sim->pc = next_pc; break; } case I_RMMOVL: /* 4:0 regA:regB imm */ { long_t rm_temp_rA = get_reg_val(sim->r, rA); long_t rm_temp_rB = get_reg_val(sim->r, rB); set_long_val(sim->m, im_value+rm_temp_rB, rm_temp_rA); sim->pc = next_pc; break; } case I_MRMOVL: /* 5:0 regB:regA imm */ { long_t mr_temp_rB = get_reg_val(sim->r, rB); long_t temp_val = 0; if(!get_long_val(sim->m, im_value+mr_temp_rB, &temp_val)) { err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, im_value+mr_temp_rB); return STAT_ADR; } set_reg_val(sim->r, rA, temp_val); sim->pc = next_pc; break; } case I_ALU: /* 6:x regA:regB */ { long_t rA_val = get_reg_val(sim->r, rA); long_t rB_val = get_reg_val(sim->r, rB); long_t alu_result = 0; switch (ifun) { case A_ADD:case A_SUB:case A_AND:case A_XOR: alu_result = compute_alu(ifun, rA_val, rB_val); set_reg_val(sim->r, rB, alu_result); break; case A_NONE:default: return STAT_INS; } sim->cc = compute_cc(ifun, rA_val, rB_val, alu_result); sim->pc = next_pc; break; } case I_JMP: /* 7:x imm */ { if (cond_doit(sim->cc, ifun)) sim->pc = im_value; else sim->pc=next_pc; break; } case I_CALL: /* 8:x imm */ { long_t esp = get_reg_val(sim->r, REG_ESP); esp -= 4; set_reg_val(sim->r, REG_ESP, esp); if (esp < 0) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp); return STAT_ADR; } set_long_val(sim->m, esp, next_pc); sim->pc = im_value; break; } case I_RET: /* 9:0 */ { long_t esp = get_reg_val(sim->r, REG_ESP); long_t return_value = 0; if(!get_long_val(sim->m, esp, &return_value)) { err_print("PC = 0x%x, Invalid data address 0x%x", sim->pc, esp); return STAT_ADR; } esp += 4; set_reg_val(sim->r, REG_ESP, esp); if (esp < 0) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp); return STAT_ADR; } sim->pc = return_value; break; } case I_PUSHL: /* A:0 regA:F */ { long_t esp = get_reg_val(sim->r, REG_ESP); long_t rA_value = get_reg_val(sim->r, rA); esp -= 4; set_reg_val(sim->r, REG_ESP, esp); if (esp < 0) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp); return STAT_ADR; } set_long_val(sim->m, esp, rA_value); sim->pc = next_pc; break; } case I_POPL: /* B:0 regA:F */ { long_t esp = get_reg_val(sim->r, REG_ESP); long_t temp_value = 0; if(!get_long_val(sim->m, esp, &temp_value)) { err_print("PC = 0x%x, Invalid instruction address", esp); return STAT_ADR; } esp += 4; set_reg_val(sim->r, REG_ESP, esp); if (esp < 0) { err_print("PC = 0x%x, Invalid stack address 0x%x", sim->pc, esp); return STAT_ADR; } set_reg_val(sim->r, rA, temp_value); sim->pc = next_pc; break; } return STAT_INS; /* unsupported now, replace it with your implementation */ break; default: err_print("PC = 0x%x, Invalid instruction %.2x", sim->pc, codefun); return STAT_INS; } return STAT_AOK; }
static int set_data_rate(const struct motion_sensor_t *s, int rate, int rnd) { int ret, val, odr_tbl_size; uint8_t ctrl_reg, reg_val; const struct gyro_param_pair *data_rates; struct l3gd20_data *data = s->drv_data; ctrl_reg = get_ctrl_reg(s->type); data_rates = get_odr_table(s->type, &odr_tbl_size); reg_val = get_reg_val(rate, rnd, data_rates, odr_tbl_size); /* * Lock gyro resource to prevent another task from attempting * to write gyro parameters until we are done. */ mutex_lock(s->mutex); ret = raw_read8(s->port, s->addr, ctrl_reg, &val); if (ret != EC_SUCCESS) goto gyro_cleanup; val = (val & ~(L3GD20_ODR_MASK | L3GD20_ODR_PD_MASK)) | (reg_val & ~L3GD20_LOW_ODR_MASK); ret = raw_write8(s->port, s->addr, ctrl_reg, val); /* Now that we have set the odr, update the driver's value. */ if (ret == EC_SUCCESS) data->base.odr = get_engineering_val(reg_val, data_rates, odr_tbl_size); ret = raw_read8(s->port, s->addr, L3GD20_LOW_ODR, &val); if (ret != EC_SUCCESS) goto gyro_cleanup; /* We need to clear low_ODR bit for higher data rates */ if (reg_val & L3GD20_LOW_ODR_MASK) val |= 1; else val &= ~1; ret = raw_write8(s->port, s->addr, L3GD20_LOW_ODR, val); if (ret != EC_SUCCESS) goto gyro_cleanup; /* CTRL_REG5 24h * [7] low-power mode = 0; * [6] fifo disabled = 0; * [5] Stop on fth = 0; * [4] High pass filter enable = 1; * [3:2] int1_sel = 0; * [1:0] out_sel = 1; */ ret = raw_read8(s->port, s->addr, L3GD20_CTRL_REG5, &val); if (ret != EC_SUCCESS) goto gyro_cleanup; val |= (1 << 4); /* high-pass filter enabled */ val |= (1 << 0); /* data in data reg are high-pass filtered */ ret = raw_write8(s->port, s->addr, L3GD20_CTRL_REG5, val); if (ret != EC_SUCCESS) goto gyro_cleanup; ret = raw_read8(s->port, s->addr, L3GD20_CTRL_REG2, &val); if (ret != EC_SUCCESS) goto gyro_cleanup; /* * Table 25. High pass filter mode configuration * Table 26. High pass filter cut off frequency configuration */ val &= 0xf0; val |= 0x04; ret = raw_write8(s->port, s->addr, L3GD20_CTRL_REG2, val); gyro_cleanup: mutex_unlock(s->mutex); return ret; }
/* * nexti: execute single instruction and return status. * args * sim: the y64 image with PC, register and memory * * return * STAT_AOK: continue * STAT_HLT: halt * STAT_ADR: invalid instruction address * STAT_INS: invalid instruction, register id, data address, stack address, ... */ stat_t nexti(y64sim_t *sim) { byte_t codefun = 0; /* 1 byte */ itype_t icode; alu_t ifun; long_t next_pc = sim->pc; /* get code and function (1 byte) */ if (!get_byte_val(sim->m, next_pc, &codefun)) { err_print("PC = 0x%lx, Invalid instruction address", sim->pc); return STAT_ADR; } icode = GET_ICODE(codefun); ifun = GET_FUN(codefun); next_pc++; /* get registers if needed (1 byte) */ byte_t rArB = 0; regid_t rA = REG_ERR, rB = REG_ERR; if((icode == I_RRMOVQ) || (icode == I_ALU) || (icode == I_RMMOVQ) || (icode == I_PUSHQ) || (icode == I_POPQ) || (icode == I_IRMOVQ) || (icode == I_MRMOVQ) ){ get_byte_val(sim->m, next_pc, &rArB); rA = GET_REGA(rArB); rB = GET_REGB(rArB); next_pc++; } /* get immediate if needed (8 bytes) */ long_t valC; if(icode == I_IRMOVQ || icode == I_RMMOVQ ||icode == I_MRMOVQ || icode == I_JMP || icode == I_CALL){ get_long_val(sim->m,next_pc,&valC); next_pc += 8; } /* execute the instruction*/ long_t valA,valB,valE,valM; switch (icode) { case I_HALT: /* 0:0 */ return STAT_HLT; break; case I_NOP: /* 1:0 */ sim->pc = next_pc; break; case I_RRMOVQ: /* 2:x regA:regB */ if(!NORM_REG(rA) || !NORM_REG(rB)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r,rA); valE = valA + 0; if(cond_doit(sim->cc, ifun)) set_reg_val(sim->r, rB, valE); sim->pc = next_pc; break; case I_IRMOVQ: /* 3:0 F:regB imm */ if(!NORM_REG(rB) || !NONE_REG(rA)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r, rA); valB = get_reg_val(sim->r, rB); valE = 0 + valC; set_reg_val(sim->r, rB, valE); sim->pc = next_pc; break; case I_RMMOVQ: /* 4:0 regA:regB imm */ if(!NORM_REG(rA) || !NORM_REG(rB)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r, rA); valB = get_reg_val(sim->r, rB); valE = valB + valC; if(!set_long_val(sim->m, valE, valA)){ err_print("PC = 0x%lx, Invalid data address 0x%.8lx", sim->pc, valE); return STAT_ADR; } sim->pc = next_pc; break; case I_MRMOVQ: /* 5:0 regB:regA imm */ if(!NORM_REG(rA) || !NORM_REG(rB)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r, rA); valB = get_reg_val(sim->r, rB); valE = valB + valC; if(!get_long_val(sim->m, valE, &valM)){ err_print("PC = 0x%lx, Invalid data address 0x%.8lx", sim->pc, valE); return STAT_ADR; } set_reg_val(sim->r, rA, valM); sim->pc = next_pc; break; case I_ALU: /* 6:x regA:regB */ if(!NORM_REG(rA) || !NORM_REG(rB)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r, rA); valB = get_reg_val(sim->r, rB); valE = compute_alu(ifun, valA, valB); sim->cc = compute_cc(ifun, valA, valB, valE); set_reg_val(sim->r, rB, valE); sim->pc = next_pc; break; case I_JMP: /* 7:x imm */ if(ifun > 6){ err_print("PC = 0x%lx, Invalid instruction %.2x", sim->pc, codefun); return STAT_INS; } sim->pc = cond_doit(sim->cc,ifun)? valC : next_pc; break; case I_CALL: /* 8:x imm */ valB = get_reg_val(sim->r, REG_RSP); valE = valB + (-8); set_reg_val(sim->r, REG_RSP, valE); if(!set_long_val(sim->m, valE, next_pc)){ err_print("PC = 0x%lx, Invalid stack address 0x%.8lx", sim->pc, valE); return STAT_ADR; } sim->pc = valC; break; case I_RET: /* 9:0 */ valA = get_reg_val(sim->r, REG_RSP); valB = valA; valE = valB + 8; get_long_val(sim->m, valA, &valM); set_reg_val(sim->r, REG_RSP, valE); sim->pc = valM; break; case I_PUSHQ: /* A:0 regA:F */ if(!NORM_REG(rA)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r, rA); valB = get_reg_val(sim->r, REG_RSP); valE = valB + (-8); set_reg_val(sim->r, REG_RSP, valE); if(!set_long_val(sim->m, valE, valA)){ err_print("PC = 0x%lx, Invalid stack address 0x%.8lx", sim->pc, valE); return STAT_ADR; } sim->pc = next_pc; break; case I_POPQ: /* B:0 regA:F */ if(!NORM_REG(rA)){ err_print("PC = 0x%lx, Invalid register id %.2x", sim->pc, rArB); return STAT_INS; } valA = get_reg_val(sim->r, REG_RSP); valB = valA; valE = valB + 8; get_long_val(sim->m, valA, &valM); set_reg_val(sim->r, REG_RSP, valE); set_reg_val(sim->r, rA, valM); sim->pc = next_pc; break; // return STAT_INS; /* unsupported now, replace it with your implementation */ default: err_print("PC = 0x%lx, Invalid instruction %.2x", sim->pc, codefun); return STAT_INS; } return STAT_AOK; }