Пример #1
0
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);
}
Пример #2
0
void strb_imm(uint8_t rt, uint8_t rn, uint32_t imm32,
		bool index, bool add, bool wback) {
	DBG2("strb r%02d, [r%02d, #%08x]\n", rt, rn, imm32);

	uint32_t rn_val = CORE_reg_read(rn);
	uint32_t rt_val = CORE_reg_read(rt);

	uint32_t offset_addr;
	if (add) {
		offset_addr = rn_val + imm32;
	} else {
		offset_addr = rn_val - imm32;
	}

	uint32_t address;
	if (index) {
		address = offset_addr;
	} else {
		address = rn_val;
	}

	DBG2("address: %08x\n", address);

	write_byte(address, rt_val & 0xff);

	if (wback) {
		CORE_reg_write(rn, offset_addr);
	}

	DBG2("strb_imm ran\n");
}
Пример #3
0
void pop(uint16_t registers) {
	uint32_t address = CORE_reg_read(SP_REG);

	int i;
	for (i = 0; i <= 14; i++) {
		if (registers & (1 << i)) {
			CORE_reg_write(i, read_word(address));
			address += 4;
		}
	}

	if (registers & (1 << 15)) {
		LoadWritePC(read_word(address));
	}

	CORE_reg_write(SP_REG, CORE_reg_read(SP_REG) + 4 * hamming(registers));
}
Пример #4
0
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");
}
Пример #5
0
void orr_imm(uint8_t rd, uint8_t rn, bool setflags,
		union apsr_t apsr, uint32_t imm32, bool carry) {
	uint32_t result = CORE_reg_read(rn) | imm32;
	CORE_reg_write(rd, result);
	if (setflags) {
		apsr.bits.N = HIGH_BIT(result);
		apsr.bits.Z = result == 0;
		apsr.bits.C = carry;
		CORE_apsr_write(apsr);
	}
}
Пример #6
0
void bic_imm(union apsr_t apsr, uint8_t setflags,
		uint8_t rd, uint8_t rn, uint32_t imm32, uint8_t carry) {
	uint32_t result = CORE_reg_read(rn) & (~imm32);
	CORE_reg_write(rd, result);

	if (setflags) {
		apsr.bits.N = HIGH_BIT(result);
		apsr.bits.Z = result == 0;
		apsr.bits.C = carry;
		CORE_apsr_write(apsr);
	}
}
Пример #7
0
static void ldm(uint8_t rn, uint16_t registers, uint8_t wback) {
	uint32_t address = CORE_reg_read(rn);

	int i;
	for (i = 0; i <= 14; i++) {	// stupid arm inclusive for
		if (registers & (1 << i)) {
			CORE_reg_write(i, read_word(address));
			address += 4;
		}
	}
	if (registers & 0x8000) {
		//LoadWritePC(MemA[address, 4]);
		CORE_ERR_not_implemented("ldm PC");
	}

	if (wback && ((registers & (1 << rn)) == 0)) {
		CORE_reg_write(rn, CORE_reg_read(rn) + 4U*hamming(registers));
	}

	DBG2("ldm had loads of fun\n");
}
Пример #8
0
void bic_reg(uint8_t rd, uint8_t rn, uint8_t rm,
		bool setflags, enum SRType shift_t, uint8_t shift_n) {
	union apsr_t apsr = CORE_apsr_read();

	uint32_t shifted;
	bool carry_out;
	Shift_C(CORE_reg_read(rm), 32, shift_t, shift_n, apsr.bits.C,
			&shifted, &carry_out);

	uint32_t result = CORE_reg_read(rn) & ~shifted;
	CORE_reg_write(rd, result);

	if (setflags) {
		apsr.bits.N = HIGH_BIT(result);
		apsr.bits.Z = result == 0;
		apsr.bits.C = carry_out;
		CORE_apsr_write(apsr);
	}
}
Пример #9
0
void orr_reg(uint8_t setflags, uint8_t rd, uint8_t rn, uint8_t rm,
		enum SRType shift_t, uint8_t shift_n) {
	uint32_t result;
	bool carry_out;

	union apsr_t apsr = CORE_apsr_read();

	Shift_C(CORE_reg_read(rm), 32, shift_t, shift_n, apsr.bits.C, &result, &carry_out);

	result = CORE_reg_read(rn) | result;
	CORE_reg_write(rd, result);

	if (setflags) {
		apsr.bits.N = HIGH_BIT(result);
		apsr.bits.Z = result == 0;
		apsr.bits.C = carry_out;
		CORE_apsr_write(apsr);
	}
}
Пример #10
0
void and_imm(union apsr_t apsr, uint8_t setflags, uint8_t rd, uint8_t rn,
		uint32_t imm32, uint8_t carry) {
	uint32_t rn_val = CORE_reg_read(rn);

	uint32_t result = rn_val & imm32;
	if (rd == 15) {
		// ALUWritePC(result);
		CORE_ERR_not_implemented("ALUWritePC and_imm\n");
	} else {
		CORE_reg_write(rd, result);
		if (setflags) {
			apsr.bits.N = HIGH_BIT(result);
			apsr.bits.Z = result == 0;
			apsr.bits.C = carry;
			CORE_apsr_write(apsr);
		}
	}

	DBG2("and_imm done\n");
}
Пример #11
0
void str_imm(uint8_t rt, uint8_t rn, uint32_t imm32,
		bool index, bool add, bool wback) {
	uint32_t rn_val = CORE_reg_read(rn);

	uint32_t offset_addr;
	if (add)
		offset_addr = rn_val + imm32;
	else
		offset_addr = rn_val - imm32;

	uint32_t address;
	if (index)
		address = offset_addr;
	else
		address = rn_val;

	uint32_t rt_val = CORE_reg_read(rt);
	write_word_unaligned(address, rt_val);

	if (wback)
		CORE_reg_write(rn, offset_addr);
}
Пример #12
0
void strd_imm(uint8_t rt, uint8_t rt2, uint8_t rn, uint32_t imm32,
		bool index, bool add, bool wback) {
	uint32_t offset_addr;
	if (add) {
		offset_addr = CORE_reg_read(rn) + imm32;
	} else {
		offset_addr = CORE_reg_read(rn) - imm32;
	}

	uint32_t address;
	if (index) {
		address = offset_addr;
	} else {
		address = CORE_reg_read(rn);
	}

	write_word_aligned(address, CORE_reg_read(rt));
	write_word_aligned(address + 4, CORE_reg_read(rt2));

	if (wback) {
		CORE_reg_write(rn, offset_addr);
	}
}