static void reset_registers(void) { uint32_t vectortable = read_word(VECTOR_TABLE_OFFSET); // R[0..12] = bits(32) UNKNOWN {nop} SW(&sp_main,read_word(vectortable) & 0xfffffffc); // sp_process = ((bits(30) UNKNOWN):'00') SW(&sp_process, SR(&sp_process) & ~0x3); CORE_reg_write(LR_REG, 0xFFFFFFFF); uint32_t tmp = read_word(vectortable+4); bool tbit = tmp & 0x1; CORE_reg_write(PC_REG, tmp & 0xfffffffe); if (! (tmp & 0x1) ) { WARN("Reset vector %08x at %08x invalid\n", tmp, vectortable+4); CORE_ERR_unpredictable("Thumb bit must be set for M-series\n"); } // ASPR = bits(32) UNKNOWN {nop} union ipsr_t ipsr = CORE_ipsr_read(); ipsr.bits.exception = 0; CORE_ipsr_write(ipsr); union epsr_t epsr = CORE_epsr_read(); epsr.bits.T = tbit; epsr.bits.ICI_IT_top = 0; epsr.bits.ICI_IT_bot = 0; CORE_epsr_write(epsr); }
// arm-thumb static void push_t1(uint16_t inst) { uint8_t register_list = inst & 0xff; bool M = (inst >> 8) & 0x1; uint16_t registers = register_list | (M << 14); if (hamming(registers) < 1) CORE_ERR_unpredictable("push_t1 case\n"); OP_DECOMPILE("PUSH<c> <registers>", registers); return push(registers); }
static void ldm_t2(uint32_t inst) { uint16_t reg_list = inst & 0x1fff; bool M = !!(inst & 0x4000); bool P = !!(inst & 0x8000); uint8_t rn = (inst & 0xf0000) >> 16; bool W = !!(inst & 0x200000); if ((W == 1) && (rn == 0xd)) CORE_ERR_unpredictable("ldm_t2 --> pop\n"); uint16_t registers = (P << 15) | (M << 14) | reg_list; bool wback = (W == 1); if ((rn == 15) || (hamming(registers) < 2) || ((P == 1) && (M == 1))) CORE_ERR_unpredictable("ldm_t2, long ||'s\n"); if ((registers & 0x8000) && in_ITblock() && !last_in_ITblock()) CORE_ERR_unpredictable("ldm_t2, itstate stuff\n"); if (wback && (registers & (1 << (rn)))) CORE_ERR_unpredictable("ldm_t2, writeback mismatch?\n"); return ldm(rn, registers, wback); }
static void pmu_reset_wr(uint32_t addr, uint32_t val, bool debugger __attribute__ ((unused)) ) { assert((addr & 0xfffffff0) & 0xA3000000); switch (val) { case 0x0: CORE_ERR_not_implemented("PMU DIV5 mode override"); case 0x1: CORE_ERR_not_implemented("PMU power-on-reset"); case 0x2: CORE_ERR_not_implemented("Ctrl CPU layer sleep"); default: WARN("Write %08x to %08x\n", val, addr); CORE_ERR_unpredictable("Bad CTRL PMU Special"); } }
static bool cpu_conf_regs_rd(uint32_t addr, uint32_t *val, bool debugger __attribute__ ((unused)) ) { assert((addr & 0xfffff000) == 0xA0001000); switch (addr) { case CHIP_ID_REG_RD: *val = SR(&m3_prc_reg_chip_id) & MASK(CHIP_ID_REG_NBITS); return true; case GOC_CTRL_REG_RD: *val = SR(&m3_prc_reg_goc_ctrl) & MASK(GOC_CTRL_REG_NBITS); return true; case PMU_CTRL_REG_RD: *val = SR(&m3_prc_reg_pmu_ctrl) & MASK(PMU_CTRL_REG_NBITS); return true; case WUP_CTRL_REG_RD: *val = SR(&m3_prc_reg_wup_ctrl) & MASK(WUP_CTRL_REG_NBITS); return true; case TSTAMP_REG_RD: *val = SR(&m3_prc_reg_tstamp) & MASK(TSTAMP_REG_NBITS); return true; case MSG_REG0_RD: *val = SR(&m3_prc_reg_msg0); return true; case MSG_REG1_RD: *val = SR(&m3_prc_reg_msg1); return true; case MSG_REG2_RD: *val = SR(&m3_prc_reg_msg2); return true; case MSG_REG3_RD: *val = SR(&m3_prc_reg_msg3); return true; case INT_MSG_REG0_RD: *val = SR(&m3_prc_reg_imsg0); return true; case INT_MSG_REG1_RD: *val = SR(&m3_prc_reg_imsg1); return true; case INT_MSG_REG2_RD: *val = SR(&m3_prc_reg_imsg2); return true; case INT_MSG_REG3_RD: *val = SR(&m3_prc_reg_imsg3); return true; default: CORE_ERR_unpredictable("Bad CPU Config Reg Read"); } }
static void reset_registers(void) { DBG2("begin\n"); uint32_t vectortable = read_word(VECTOR_TABLE_OFFSET); // R[0..12] = bits(32) UNKNOWN {nop} SW(&sp_main,read_word(vectortable) & 0xfffffffc); // sp_process = ((bits(30) UNKNOWN):'00') SW(&sp_process, SR(&sp_process) & ~0x3); CORE_reg_write(LR_REG, 0xFFFFFFFF); uint32_t tmp = read_word(vectortable+4); bool tbit = tmp & 0x1; CORE_reg_write(PC_REG, tmp & 0xfffffffe); if (!tbit) { WARN("Reset vector %08x at %08x invalid\n", tmp, vectortable+4); CORE_ERR_unpredictable("Thumb bit must be set for M-series\n"); } CORE_CurrentMode_write(Mode_Thread); // ASPR = bits(32) UNKNOWN {nop} union ipsr_t ipsr_temp = CORE_ipsr_read(); ipsr_temp.bits.exception = 0; CORE_ipsr_write(ipsr_temp); union epsr_t epsr_temp = CORE_epsr_read(); epsr_temp.bits.T = tbit; epsr_temp.bits.ICI_IT_top = 0; epsr_temp.bits.ICI_IT_bot = 0; CORE_epsr_write(epsr_temp); /// // B1.4.3: The special-purpose mask registers SW(&physical_primask, 0); SW(&physical_faultmask, 0); SW(&physical_basepri, 0); SW(&physical_control.storage, 0); DBG2("end\n"); }
static void mbus_mmio_wr(uint32_t addr, uint32_t val, bool debugger __attribute__ ((unused)) ) { switch (addr) { case MBUS_MMIO_ADDR: SW(&mbus_mmio_addr, val); break; case MBUS_MMIO_DATA: SW(&mbus_mmio_data, val); INFO("MBus message: addr %08x, data %08x\n", SR(&mbus_mmio_addr), SR(&mbus_mmio_data) ); break; default: WARN("Unknown address, %08x\n", addr); CORE_ERR_unpredictable("Bad MBus MMIO address"); } fflush(stdout); }
static void cpu_conf_regs_wr(uint32_t addr, uint32_t val, bool debugger __attribute__ ((unused)) ) { switch (addr) { case CHIP_ID_REG_WR: SW(&m3_prc_reg_chip_id, val & MASK(CHIP_ID_REG_NBITS)); break; case GOC_CTRL_REG_WR: SW(&m3_prc_reg_goc_ctrl, val & MASK(GOC_CTRL_REG_NBITS)); break; case PMU_CTRL_REG_WR: SW(&m3_prc_reg_pmu_ctrl, val & MASK(PMU_CTRL_REG_NBITS)); break; case WUP_CTRL_REG_WR: SW(&m3_prc_reg_wup_ctrl, val & MASK(WUP_CTRL_REG_NBITS)); break; case TSTAMP_REG_WR: SW(&m3_prc_reg_tstamp, val & MASK(TSTAMP_REG_NBITS)); break; default: CORE_ERR_unpredictable("Bad CPU Config Reg Write"); } }