Example #1
0
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);
}
}
Example #2
0
/* 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));
}
Example #3
0
File: psim.c Project: PiffNP/CSAPP
/* 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;
}
Example #4
0
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;
}
}
Example #5
0
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);
}
Example #6
0
inline bool get_reg_val(const char *regname, ulonglong *ival)
{
  regval_t regval;
  if (!get_reg_val(regname, &regval)) return false;
  if (ival != NULL) *ival = regval.ival;
  return true;
}
Example #7
0
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;
}
Example #8
0
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);
}
}
}
Example #9
0
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();
}
}
Example #10
0
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);
}
Example #11
0
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);
}
Example #12
0
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;
		}
	}
Example #15
0
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);
}
}
}
Example #16
0
File: HDER.C Project: venzhega/aokt
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;
}
Example #18
0
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;
}
Example #20
0
//--------------------------------------------------------------------------
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;
}
Example #21
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;
}
Example #22
0
/* 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, &regids)) {
	    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;
}
Example #23
0
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, &reg))
						{
							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;
	}
}
Example #24
0
File: ssim.c Project: Azard/icslabs
/* 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, &regids)) {
	    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;
}
Example #25
0
/* 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;
}
Example #26
0
/* 
 * 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;
}
Example #27
0
/* 
 * 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, &reg)) {
				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;
}
Example #28
0
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;
}