/* deliberately trigger an error in the sensor to trigger recovery */ void BMI160::test_error() { write_reg(BMIREG_CMD, BMI160_SOFT_RESET); ::printf("error triggered\n"); print_registers(); }
void cosim_check_scalar_store(struct core *core, uint32_t pc, uint32_t address, uint32_t size, uint32_t value) { uint32_t hardware_value; uint64_t reference_mask; hardware_value = expected_values[(address & CACHE_LINE_MASK) / 4]; if (size < 4) { uint32_t mask = (1 << (size * 8)) - 1; hardware_value &= mask; value &= mask; } reference_mask = ((1ull << size) - 1ull) << (CACHE_LINE_MASK - (address & CACHE_LINE_MASK) - (size - 1)); cosim_event_triggered = true; if (expected_event != EVENT_MEM_STORE || expected_pc != pc || expected_address != (address & ~CACHE_LINE_MASK) || expected_mask != reference_mask || hardware_value != value) { cosim_mismatch = true; print_registers(core, expected_thread); printf("COSIM MISMATCH, thread %d\n", expected_thread); printf("Reference: %08x memory[%x]{%016" PRIx64 "} <= %08x\n", pc, address & ~CACHE_LINE_MASK, reference_mask, value); printf("Hardware: "); print_cosim_expected(); return; } }
/* deliberately trigger an error in the sensor to trigger recovery */ void BMI055_gyro::test_error() { write_reg(BMI055_GYR_SOFTRESET, BMI055_SOFT_RESET); ::printf("error triggered\n"); print_registers(); }
/* deliberately trigger an error in the sensor to trigger recovery */ void BMI055_accel::test_error() { write_reg(BMI055_ACC_SOFTRESET, BMI055_SOFT_RESET); ::printf("error triggered\n"); print_registers(); }
void cosim_check_vector_store(struct core *core, uint32_t pc, uint32_t address, uint32_t mask, const uint32_t *values) { uint64_t byte_mask; int lane; byte_mask = 0; for (lane = 0; lane < NUM_VECTOR_LANES; lane++) { if (mask & (1 << lane)) byte_mask |= 0xfull << (lane * 4); } cosim_event_triggered = true; if (expected_event != EVENT_MEM_STORE || expected_pc != pc || expected_address != (address & ~(NUM_VECTOR_LANES * 4u - 1)) || expected_mask != byte_mask || !compare_masked(mask, expected_values, values)) { cosim_mismatch = true; print_registers(core, expected_thread); printf("COSIM MISMATCH, thread %d\n", expected_thread); printf("Reference: %08x memory[%x]{%016" PRIx64 "} <= ", pc, address, byte_mask); for (lane = NUM_VECTOR_LANES - 1; lane >= 0; lane--) printf("%08x ", values[lane]); printf("\n_hardware: "); print_cosim_expected(); return; } }
void cosim_check_set_vector_reg(struct core *core, uint32_t pc, uint32_t reg, uint32_t mask, const uint32_t *values) { int lane; cosim_event_triggered = true; if (expected_event != EVENT_VECTOR_WRITEBACK || expected_pc != pc || expected_register != reg || !compare_masked(mask, expected_values, values) || expected_mask != (mask & 0xffff)) { cosim_mismatch = true; print_registers(core, expected_thread); printf("COSIM MISMATCH, thread %d\n", expected_thread); printf("Reference: %08x v%d{%04x} <= ", pc, reg, mask & 0xffff); for (lane = NUM_VECTOR_LANES - 1; lane >= 0; lane--) printf("%08x ", values[lane]); printf("\n"); printf("Hardware: "); print_cosim_expected(); return; } }
/* deliberately trigger an error in the sensor to trigger recovery */ void MPU9250::test_error() { // deliberately trigger an error. This was noticed during // development as a handy way to test the reset logic uint8_t data[16]; memset(data, 0, sizeof(data)); transfer(data, data, sizeof(data)); ::printf("error triggered\n"); print_registers(); }
/* deliberately trigger an error in the sensor to trigger recovery */ void MPU9250::test_error() { // deliberately trigger an error. This was noticed during // development as a handy way to test the reset logic uint8_t data[16]; memset(data, 0, sizeof(data)); _interface->read(MPU9250_SET_SPEED(MPUREG_INT_STATUS, MPU9250_LOW_BUS_SPEED), data, sizeof(data)); ::printf("error triggered\n"); print_registers(); }
static int cmd_write(int argc, char **argv) { int id = -1; int reg8 = -1; int reg16 = -1; if (argc != 4) { printf("usage; %s <dev_id> <reg> <value>\n", argv[0]); print_registers(); return 1; } /* parse parameters */ id = parse_dev(argv[1]); if (id < 0) { return -1; } parse_reg(argv[2], ®8, ®16); if (reg8 < 0 && reg16 < 0) { return -1; } int val = atoi(argv[3]); if (val < 0) { return -1; } /* read */ feetech_t dev; feetech_init(&dev, &stream, id); if (reg8 >= 0) { int ret = feetech_write8(&dev, reg8, val); if (ret != FEETECH_OK) { printf("Error[%i] : No response from %i\n", ret, id); return -1; } printf("Written %i at address %i\n", (int)val, reg8); } else { int ret = feetech_write16(&dev, reg16, val); if (ret != FEETECH_OK) { printf("Error[%i] : No response from %i\n", ret, id); return -1; } printf("Written %i at address %i\n", (int)val, reg16); } return 0; }
void cosim_check_set_scalar_reg(struct core *core, uint32_t pc, uint32_t reg, uint32_t value) { cosim_event_triggered = true; if (expected_event != EVENT_SCALAR_WRITEBACK || expected_pc != pc || expected_register != reg || expected_values[0] != value) { cosim_mismatch = true; print_registers(core, expected_thread); printf("COSIM MISMATCH, thread %d\n", expected_thread); printf("Reference: %08x s%d <= %08x\n", pc, reg, value); printf("Hardware: "); print_cosim_expected(); return; } }
static int cmd_read(int argc, char **argv) { int id = -1; int reg8 = -1; int reg16 = -1; if (argc != 3) { printf("usage; %s <dev_id> <reg>\n", argv[0]); print_registers(); return 1; } /* parse parameters */ id = parse_dev(argv[1]); if (id < 0) { return -1; } parse_reg(argv[2], ®8, ®16); if (reg8 < 0 && reg16 < 0) { return -1; } /* read */ feetech_t dev; feetech_init(&dev, &stream, id); if (reg8 >= 0) { uint8_t val = 0; int ret = feetech_read8(&dev, reg8, &val); if (ret != FEETECH_OK) { printf("Error[%i] : No response from %i\n", ret, id); return -1; } printf("%i\n", (int)val); } else { uint16_t val = 0; int ret = feetech_read16(&dev, reg16, &val); if (ret != FEETECH_OK) { printf("Error[%i] : No response from %i\n", ret, id); return -1; } printf("%i\n", (int)val); } return 0; }
int exec(Memory entry_p) { Instruction insn; unsigned long clk = 0; uint32_t cmod; if(signal(SIGINT, signal_on_sigint) == SIG_ERR) { err(EXIT_FAILURE, "signal SIGINT"); } step_by_step = false; exec_finish = false; /* initialize internal variable */ memory_is_fault = 0; memory_io_writeback = 0; instruction_prefetch_flush(); /* setup system registers */ PSR = 0; cmod = (PSR & PSR_CMOD_MASK); PCR = entry_p; next_PCR = 0xffffffff; KSPR = (Memory)STACK_DEFAULT; #if !NO_DEBUG /* internal debug variable */ traceback_next = 0; FLAGR.flags = 0x80000000; prev_FLAGR.flags = 0x80000000; for(unsigned int i = 0; i < breakp_next; i++) { NOTICE("Break point[%d]: 0x%08x\n", i, breakp[i]); } #endif NOTICE("Execution Start: entry = 0x%08x\n", PCR); do { /* choose stack */ if(cmod != (PSR & PSR_CMOD_MASK)) { SPR = !cmod ? USPR : KSPR; } cmod = (PSR & PSR_CMOD_MASK); #if !NO_DEBUG /* break point check */ for(unsigned int i = 0; i < breakp_next; i++) { if(PCR == breakp[i]) { step_by_step = true; break; } } #endif /* instruction fetch */ insn.value = instruction_fetch(PCR); if(memory_is_fault) { /* fault fetch */ DEBUGINT("[FAULT] Instruction fetch: %08x\n", PCR); goto fault; } #if !NO_DEBUG if(DEBUG || step_by_step) { puts("---"); print_instruction(insn); } #endif /* execution */ insn_dispatch(insn); fault: if(memory_is_fault) { /* faulting memory access */ interrupt_dispatch_nonmask(memory_is_fault); next_PCR = PCR; memory_io_writeback = 0; memory_is_fault = 0; } else if(memory_io_writeback) { /* sync io */ io_store(memory_io_writeback); memory_io_writeback = 0; } /* writeback SP */ if(cmod) { USPR = SPR; } else { KSPR = SPR; } #if !NO_DEBUG if(step_by_step) { step_by_step_pause(); } else { if(DEBUG && DEBUG_REG) { print_registers(); } if(DEBUG_TRACE) { print_traceback(); } if(DEBUG_STACK) { print_stack(SPR); } if(DEBUG_DPS) { dps_info(); } } #endif if(!(clk & MONITOR_RECV_INTERVAL_MASK)) { if((PSR & PSR_IM_ENABLE) && IDT_ISENABLE(IDT_DPS_LS_NUM)) { dps_sci_recv(); } if(MONITOR) { monitor_method_recv(); monitor_send_queue(); } } /* next */ if(next_PCR != 0xffffffff) { #if !NO_DEBUG /* alignment check */ if(next_PCR & 0x3) { abort_sim(); errx(EXIT_FAILURE, "invalid branch addres. %08x", next_PCR); } #endif PCR = next_PCR; next_PCR = 0xffffffff; } else { PCR += 4; } /* interrupt check */ interrupt_dispatcher(); #if !NO_DEBUG /* for invalid flags checking */ prev_FLAGR.flags = FLAGR.flags; FLAGR._invalid |= 1; #endif /* next cycle */ clk++; } while(!(PCR == 0 && GR[31] == 0 && DEBUG_EXIT_B0) && !exec_finish); /* DEBUG_EXIT_B0: exit if b rret && rret == 0 */ NOTICE("---- Program Terminated ----\n"); print_instruction(insn); print_registers(); return 0; }
int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb) { int nleft; int nbytes; int nparts; int status; uint32_t chip; char lbuff[64]; uint32_t cval; if ((status = iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK) return(status); if ((msg->i.xtype & _IO_XTYPE_NONE) != _IO_XTYPE_NONE) return (ENOSYS); /* * On all reads, calculate how many * bytes we can return to the client * based upon the number of bytes available (nleft) * and the client's buffer size */ nleft = ocb->attr->nbytes - ocb->offset; nbytes = min(msg->i.nbytes, nleft); cval = *(uint32_t *)ics660->regs.control; fprintf(stderr,"io_read - cval %d\n",cval); sprintf(lbuff,"%x",cval); for( chip=1; chip<=4; chip++){ select_chip(ics660->mod_control_reg,chip); printf("MAIN PRINT_REGISTER\n"); print_registers(ics660->dc60m_regs); } select_chip(ics660->mod_control_reg,(uint32_t)0x0); if (nbytes > 0){ /* set up the return data IOV */ //SETIOV( ctp->iov, buffer + ocb->offset, nbytes ); SETIOV( ctp->iov, lbuff + ocb->offset, nbytes ); /* set up the number of bytes (returned by client's read()) */ _IO_SET_READ_NBYTES(ctp, nbytes); /* * advance the offset by the number of bytes * returned to the client. */ ocb->offset += nbytes; nparts = 1; } else { /* * they've asked for zero bytres or they've already * read everything */ _IO_SET_READ_NBYTES(ctp,0); nparts = 0; } /* mark the access time as invalid (we just accessed it) */ if (msg->i.nbytes > 0) ocb->attr->flags |= IOFUNC_ATTR_ATIME; return (_RESMGR_NPARTS(nparts)); }
void execute_one_inst(processor_t* p, int prompt, int print_regs) { inst_t inst; /* fetch an instruction */ inst.bits = load_mem(p->pc, SIZE_WORD); /* interactive-mode prompt */ if(prompt) { if (prompt == 1) { printf("simulator paused, enter to continue..."); while(getchar() != '\n') ; } printf("%08x: ",p->pc); disassemble(inst); } switch (inst.rtype.opcode) /* could also use e.g. inst.itype.opcode */ { case 0x0: // opcode == 0x0 (SPECIAL) switch (inst.rtype.funct) { case 0x0: //opcode = 0x0 (SLL) p->R[inst.rtype.rd] = p->R[inst.rtype.rt] << inst.rtype.shamt; p->pc += 4; break; case 0x2: //opcode = 0x2 (SRL) p->R[inst.rtype.rd] = p->R[inst.rtype.rt] >> inst.rtype.shamt; p->pc += 4; break; case 0x3: //opcode = 0x3 (SRA) p->R[inst.rtype.rd] = (signed int)(p->R[inst.rtype.rt]) >> inst.rtype.shamt; p->pc += 4; break; case 0x8: //opcode = 0x8 (JR) p->pc = p->R[inst.rtype.rs]; break; case 0x9: //opcode = 0x9 (JALR) { int tmp = p->pc + 4; p->pc = p->R[inst.rtype.rs]; p->R[inst.rtype.rd] = tmp; } break; case 0xc: // funct == 0xc (SYSCALL) handle_syscall(p); p->pc += 4; break; case 0x21: //opcode = 0x21 (ADDU) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] + p->R[inst.rtype.rt]; p->pc += 4; break; case 0x23: //opcode = 0x23 (SUBU) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] - p->R[inst.rtype.rt]; p->pc += 4; break; case 0x24: //opcode = 0x24 (AND) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] & p->R[inst.rtype.rt]; p->pc += 4; break; case 0x25: // funct == 0x25 (OR) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] | p->R[inst.rtype.rt]; p->pc += 4; break; case 0x26: // funct == 0x26 (XOR) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] ^ p->R[inst.rtype.rt]; p->pc += 4; break; case 0x27: // funct == 0x27 (NOR) p->R[inst.rtype.rd] = ~(p->R[inst.rtype.rs] ^ p->R[inst.rtype.rt]); p->pc += 4; break; case 0x2a: // funct == 0x2a (SLT) p->R[inst.rtype.rd] = (signed int)(p->R[inst.rtype.rs]) < (signed int)(p->R[inst.rtype.rt]); p->pc += 4; break; case 0x2b: // funct == 0x2b (SLTU) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] < p->R[inst.rtype.rt]; p->pc += 4; break; default: // undefined funct fprintf(stderr, "%s: pc=%08x, illegal instruction=%08x\n", __FUNCTION__, p->pc, inst.bits); exit(-1); break; } break; case 0x2: // opcode == 0x2 (J) p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2); break; case 0x3: // opcode == 0x3 (JAL) p->R[31] = p->pc + 4; p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2); break; case 0x4: // opcode == 0x4 (BEQ) if (p->R[inst.itype.rs] == p->R[inst.itype.rt]) { p->pc += (4 + (((int16_t)inst.itype.imm) << 2)); } else { p->pc += 4; } break; case 0x5: // opcode == 0x5 (BNE) if (p->R[inst.itype.rs] != p->R[inst.itype.rt]) { p->pc += (4 + (((int16_t)inst.itype.imm) << 2)); } else { p->pc += 4; } break; case 0x9: // opcode == 0x9 (ADDIU) p->R[inst.itype.rt] = p->R[inst.itype.rs] + (int16_t)(inst.itype.imm); p->pc += 4; break; case 0xa: // opcode == 0xa (SLTI) p->R[inst.itype.rt] = (signed int)p->R[inst.itype.rs] < (int16_t)(inst.itype.imm); p->pc += 4; break; case 0xb: // opcode == 0xb (SLTIU) p->R[inst.itype.rt] = p->R[inst.itype.rs] < (int16_t)(inst.itype.imm); p->pc += 4; break; case 0xc: // opcode == 0xc (ANDI) p->R[inst.itype.rt] = p->R[inst.itype.rs] & inst.itype.imm; p->pc += 4; break; case 0xd: // opcode == 0xd (ORI) p->R[inst.itype.rt] = p->R[inst.itype.rs] | inst.itype.imm; p->pc += 4; break; case 0xe: // opcode == 0xe (XORI) p->R[inst.itype.rt] = p->R[inst.itype.rs] ^ inst.itype.imm; p->pc += 4; break; case 0xf: // opcode == 0xf (LUI) p->R[inst.itype.rt] = inst.itype.imm << 16; p->pc += 4; break; case 0x20: // opcode == 0x20 (LB) p->R[inst.itype.rt] = (int8_t)(load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_BYTE)); p->pc += 4; break; case 0x21: // opcode == 0x21 (LH) p->R[inst.itype.rt] = (int16_t)(load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_HALF_WORD)); p->pc += 4; break; case 0x23: // opcode == 0x23 (LW) p->R[inst.itype.rt] = (int32_t)load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_WORD); p->pc += 4; break; case 0x24: // opcode == 0x24 (LBU) p->R[inst.itype.rt] = load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_BYTE); p->pc += 4; break; case 0x25: // opcode == 0x25 (LHU) p->R[inst.itype.rt] = load_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_HALF_WORD); p->pc += 4; break; case 0x28: // opcode == 0x28 (SB) store_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_BYTE, p->R[inst.itype.rt]); p->pc += 4; break; case 0x29: // opcode == 0x29 (SH) store_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_HALF_WORD, p->R[inst.itype.rt]); p->pc += 4; break; case 0x2b: // opcode == 0x2b (SW) store_mem(p->R[inst.itype.rs] + (int16_t)(inst.itype.imm), SIZE_WORD, p->R[inst.itype.rt]); p->pc += 4; break; default: // undefined opcode fprintf(stderr, "%s: pc=%08x, illegal instruction: %08x\n", __FUNCTION__, p->pc, inst.bits); exit(-1); break; } // enforce $0 being hard-wired to 0 p->R[0] = 0; if(print_regs) print_registers(p); }
static void hook_code32(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { //uint8_t opcode[256]; uint8_t tmp[16]; uint32_t tmp4[1]; uint32_t ecx; printf("\nhook_code32: Address: %"PRIx64", Opcode Size: %d\n", address, size); print_registers(uc); size = MIN(sizeof(tmp), size); if (!uc_mem_read(uc, address, tmp, size)) { uint32_t i; printf("Opcode: "); for (i=0; i<size; i++) { printf("%x ", tmp[i]); } printf("\n"); } dump_stack_mem(uc); if (address == 0x60000025) { // double-check that opcode is // IMUL aex,[eax+0x41],0x10 if ((tmp[0] != 0x6b) || (tmp[1] != 0x41) || (tmp[2] != 0x41) || (tmp[3] != 0x10)) { printf("FAILED set-up of opcode\n"); exit(-1); } printf("IMUL eax,[ecx+0x41],0x10\n"); // double-check that memory operand points to 0x6000003a uc_reg_read(uc, UC_X86_REG_ECX, &ecx); if (ecx != 0x5ffffff9) { printf("FAILED EAX register not having 0x5ffffff9\n"); exit(-1); } printf("ECX = %8.8x\n", ecx); printf("%8.8x + 0x41 = %8.8x\n", 0x5ffffff9, 0x5ffffff9 + 0x41); // double-check that memory location 0x60000039 // contains 0x5151494a if (!uc_mem_read(uc, 0x6000003a, tmp4, 4)) { if (tmp4[0] != 0x5151494a) { printf("FAILED set-up\n"); exit(-1); } printf("Proved that 0x6000003a contains the proper 0x5151494a\n"); } // dump_stack_mem(uc); } // Stop after 'imul eax,[ecx+0x41],0x10 if (address == 0x60000029) { uint32_t eax; // IMUL eax,mem,Ib // mem = [ecx+0x41] // ecx = 0x5ffffff9 // [6000003A] = 0x5151494a // Stop after 'imul eax,[ecx+0x41],0x10 // This step basically shifts left 8-bit...elaborately. // multiplying 0x5151494a x 0x10 = 0x151494a0 uc_reg_read(uc, UC_X86_REG_EAX, &eax); if (eax != 0x151494a0) { fail_msg("FAIL: TB did not flush; eax is not the expected 0x151494a0\n"); print_registers(uc); //dump_stack_mem(uc); exit(-1); } printf("PASS\n"); } print_registers(uc); // dump_stack_mem(uc); return; }
void execute_one_inst(processor_t* p, int prompt, int print_regs) { inst_t inst; /* fetch an instruction */ inst.bits = load_mem(p->pc, SIZE_WORD); /* interactive-mode prompt */ if(prompt) { if (prompt == 1) { printf("simulator paused, enter to continue..."); while(getchar() != '\n') ; } printf("%08x: ",p->pc); disassemble(inst); } uint32_t temp; switch (inst.rtype.opcode) /* could also use e.g. inst.itype.opcode */ { case 0x0: // opcode == 0x0 (SPECIAL) switch (inst.rtype.funct) { case 0x0: // funct == 0x0 (sll) p->R[inst.rtype.rd] = p->R[inst.rtype.rt] << inst.rtype.shamt; p->pc += 4; break; case 0x2: // funct == 0x0 (srl) p->R[inst.rtype.rd] = p->R[inst.rtype.rt] >> inst.rtype.shamt; p->pc += 4; break; case 0x3: // funct == 0x0 (sra) p->R[inst.rtype.rd] = (signed)p->R[inst.rtype.rt] >> inst.rtype.shamt; p->pc += 4; break; case 0x8: // funct == 0x8 (jr) p->pc = p->R[inst.rtype.rs]; break; case 0x9: // funct == 0x9 (jalr) temp = p->pc + 4; p->pc = p->R[inst.rtype.rs]; p->R[inst.rtype.rd] = temp; break; case 0x10: // funct == 0x10 (mfhi) p->R[inst.rtype.rd] = p->RHI; p->pc += 4; break; case 0x12: // funct == 0x12 (mflo) p->R[inst.rtype.rd] = p->RLO; p->pc += 4; break; case 0x18: // funct == 0x18 (mult) perform_mult(p->R[inst.rtype.rs], p->R[inst.rtype.rt], &(p->RHI), &(p->RLO)); p->pc += 4; break; case 0x21: // funct == 0x21 (addu) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] + p->R[inst.rtype.rt]; p->pc += 4; break; case 0x23: // funct == 0x23 (subu) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] - p->R[inst.rtype.rd]; p->pc += 4; break; case 0x24: // funct == 0x24 (and) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] & p->R[inst.rtype.rt]; p->pc += 4; break; case 0x26: // funct == 0x26 (xor) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] ^ p->R[inst.rtype.rt]; p->pc += 4; break; case 0x27: // funct == 0x27 (nor) p->R[inst.rtype.rd] = ~(p->R[inst.rtype.rs] | p->R[inst.rtype.rt]); p->pc += 4; break; case 0x2a: // funct == 0x2a (slt) p->R[inst.rtype.rd] = (signed)p->R[inst.rtype.rs] < (signed)p->R[inst.rtype.rt]; p->pc += 4; break; case 0x2b: // funct == 0x2a (sltu) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] < p->R[inst.rtype.rt]; p->pc += 4; break; case 0xc: // funct == 0xc (SYSCALL) handle_syscall(p); p->pc += 4; break; case 0x25: // funct == 0x25 (OR) p->R[inst.rtype.rd] = p->R[inst.rtype.rs] | p->R[inst.rtype.rt]; p->pc += 4; break; default: // undefined funct fprintf(stderr, "%s: pc=%08x, illegal instruction=%08x\n", __FUNCTION__, p->pc, inst.bits); exit(-1); break; } break; case 0x3: // opcode == 0x3 (jal) p->R[31] = p->pc += 4; p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2); break; case 0x4: // opcode == 0x4 (beq) if (p->R[inst.itype.rs] == p->R[inst.itype.rt]) { p->pc += 4 + signext(inst.itype.imm)*4; } else { p->pc += 4; } break; case 0x5: // opcode == 0x4 (bne) if (p->R[inst.itype.rs] != p->R[inst.itype.rt]) { p->pc += 4 + signext(inst.itype.imm)*4; } else { p->pc += 4; } break; case 0x9: // opcode == 0x9 (addiu) p->R[inst.rtype.rt] = p->R[inst.itype.rs] + signext(inst.itype.imm); p->pc += 4; break; case 0xa: // opcode == 0xa (slti) p->R[inst.itype.rt] = (signed)p->R[inst.itype.rs] < signext(inst.itype.imm); p->pc += 4; break; case 0xb: // opcode == 0xb (sltiu) p->R[inst.rtype.rt] = (signed)p->R[inst.itype.rs] < signext(inst.itype.imm); p->pc += 4; break; case 0xc: // opcode == 0xc (andi) p->R[inst.rtype.rt] = p->R[inst.itype.rs] & zeroext(inst.itype.imm); p->pc += 4; break; case 0xe: // opcode == 0xe (xori) p->R[inst.rtype.rt] = p->R[inst.itype.rs] ^ zeroext(inst.itype.imm); p->pc += 4; break; case 0xf: // opcode == 0xf (lui) p->R[inst.rtype.rt] = inst.itype.imm << 16; p->pc += 4; break; case 0x20: // opcode == 0x20 (lb) p->R[inst.rtype.rt] = signext(load_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_BYTE)); p->pc += 4; break; case 0x23: // opcode == 0x23 (lw) p->R[inst.rtype.rt] = load_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_WORD); p->pc += 4; break; case 0x24: // opcode == 0x24 (lbu) p->R[inst.itype.rt] = zeroext(load_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_WORD)); p->pc += 4; break; case 0x28: // opcode == 0x28 (sb) store_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_BYTE, p->R[inst.itype.rt]); p->pc += 4; break; case 0x2b: // opcode == 0x20 (sw) store_mem(p->R[inst.itype.rs] + signext(inst.itype.imm), SIZE_WORD, p->R[inst.itype.rt]); p->pc += 4; break; case 0xd: // opcode == 0xd (ORI) p->R[inst.itype.rt] = (p->R[inst.itype.rs] | inst.itype.imm); p->pc += 4; break; case 0x2: // opcode == 0x2 (J) p->pc = ((p->pc+4) & 0xf0000000) | (inst.jtype.addr << 2); break; default: // undefined opcode fprintf(stderr, "%s: pc=%08x, illegal instruction: %08x\n", __FUNCTION__, p->pc, inst.bits); exit(-1); break; } // enforce $0 being hard-wired to 0 p->R[0] = 0; if(print_regs) { print_registers(p); } }
asmlinkage void do_unknown(struct pt_regs *regs) { print_registers(regs); hal_panic("TODO"); }