Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * several functions that help interpret ARC instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * used for unaligned accesses, kprobes and kgdb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/disasm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #if defined(CONFIG_KGDB) || defined(CONFIG_ARC_EMUL_UNALIGNED) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	defined(CONFIG_KPROBES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* disasm_instr: Analyses instruction at addr, stores
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * findings in *state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) void __kprobes disasm_instr(unsigned long addr, struct disasm_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	int userspace, struct pt_regs *regs, struct callee_regs *cregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	int fieldA = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	int fieldC = 0, fieldCisReg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	uint16_t word1 = 0, word0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	int subopcode, is_linked, op_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	uint16_t *ins_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	uint16_t ins_buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	int bytes_not_copied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	memset(state, 0, sizeof(struct disasm_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	/* This fetches the upper part of the 32 bit instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	 * in both the cases of Little Endian or Big Endian configurations. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (userspace) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		bytes_not_copied = copy_from_user(ins_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 						(const void __user *) addr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		if (bytes_not_copied > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		ins_ptr = ins_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		ins_ptr = (uint16_t *) addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	word1 = *((uint16_t *)addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	state->major_opcode = (word1 >> 11) & 0x1F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	/* Check if the instruction is 32 bit or 16 bit instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (state->major_opcode < 0x0B) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		if (bytes_not_copied > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			goto fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		state->instr_len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		word0 = *((uint16_t *)(addr+2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		state->words[0] = (word1 << 16) | word0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		state->instr_len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		state->words[0] = word1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	/* Read the second word in case of limm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	word1 = *((uint16_t *)(addr + state->instr_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	word0 = *((uint16_t *)(addr + state->instr_len + 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	state->words[1] = (word1 << 16) | word0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	switch (state->major_opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	case op_Bcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		/* unconditional branch s25, conditional branch s21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		fieldA = (IS_BIT(state->words[0], 16)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			FIELD_s25(state->words[0]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			FIELD_s21(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		state->delay_slot = IS_BIT(state->words[0], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		state->target = fieldA + (addr & ~0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		state->flow = direct_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	case op_BLcc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		if (IS_BIT(state->words[0], 16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			/* Branch and Link*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			/* unconditional branch s25, conditional branch s21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			fieldA = (IS_BIT(state->words[0], 17)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				(FIELD_s25(state->words[0]) & ~0x3) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				FIELD_s21(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			state->flow = direct_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			/*Branch On Compare */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			fieldA = FIELD_s9(state->words[0]) & ~0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			state->flow = direct_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		state->delay_slot = IS_BIT(state->words[0], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		state->target = fieldA + (addr & ~0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	case op_LD:  /* LD<zz> a,[b,s9] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		state->write = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		state->di = BITS(state->words[0], 11, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		if (state->di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		state->x = BITS(state->words[0], 6, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		state->zz = BITS(state->words[0], 7, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		state->aa = BITS(state->words[0], 9, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		state->wb_reg = FIELD_B(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (state->wb_reg == REG_LIMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			state->aa = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			state->src1 = state->words[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			state->src1 = get_reg(state->wb_reg, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		state->src2 = FIELD_s9(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		state->dest = FIELD_A(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		state->pref = (state->dest == REG_LIMM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	case op_ST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		state->write = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		state->di = BITS(state->words[0], 5, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		if (state->di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		state->aa = BITS(state->words[0], 3, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		state->zz = BITS(state->words[0], 1, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		state->src1 = FIELD_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		if (state->src1 == REG_LIMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			state->src1 = state->words[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			state->src1 = get_reg(state->src1, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		state->wb_reg = FIELD_B(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		if (state->wb_reg == REG_LIMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			state->aa = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			state->src2 = state->words[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			state->src2 = get_reg(state->wb_reg, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		state->src3 = FIELD_s9(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	case op_MAJOR_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		subopcode = MINOR_OPCODE(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		switch (subopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		case 32:	/* Jcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		case 33:	/* Jcc.D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		case 34:	/* JLcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		case 35:	/* JLcc.D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			is_linked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			if (subopcode == 33 || subopcode == 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				state->delay_slot = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			if (subopcode == 34 || subopcode == 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 				is_linked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			fieldCisReg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			op_format = BITS(state->words[0], 22, 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			if (op_format == 0 || ((op_format == 3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				(!IS_BIT(state->words[0], 5)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				fieldC = FIELD_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				if (fieldC == REG_LIMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 					fieldC = state->words[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 					state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 					fieldCisReg = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			} else if (op_format == 1 || ((op_format == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				&& (IS_BIT(state->words[0], 5)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				fieldC = FIELD_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			} else  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				/* op_format == 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				fieldC = FIELD_s12(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			if (!fieldCisReg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 				state->target = fieldC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				state->flow = is_linked ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 					direct_call : direct_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 				state->target = get_reg(fieldC, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 				state->flow = is_linked ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 					indirect_call : indirect_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		case 40:	/* LPcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			if (BITS(state->words[0], 22, 23) == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 				/* Conditional LPcc u7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				fieldC = FIELD_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				fieldC = fieldC << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 				fieldC += (addr & ~0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 				state->flow = direct_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 				state->target = fieldC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 			/* For Unconditional lp, next pc is the fall through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			 * which is updated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		case 48 ... 55:	/* LD a,[b,c] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			state->di = BITS(state->words[0], 15, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			if (state->di)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			state->x = BITS(state->words[0], 16, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			state->zz = BITS(state->words[0], 17, 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			state->aa = BITS(state->words[0], 22, 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			state->wb_reg = FIELD_B(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			if (state->wb_reg == REG_LIMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 				state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				state->src1 = state->words[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 				state->src1 = get_reg(state->wb_reg, regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 						cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			state->src2 = FIELD_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			if (state->src2 == REG_LIMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 				state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 				state->src2 = state->words[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 				state->src2 = get_reg(state->src2, regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 					cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			state->dest = FIELD_A(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			if (state->dest == REG_LIMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 				state->pref = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		case 10:	/* MOV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			/* still need to check for limm to extract instr len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			/* MOV is special case because it only takes 2 args */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			switch (BITS(state->words[0], 22, 23)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			case 0: /* OP a,b,c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				if (FIELD_C(state->words[0]) == REG_LIMM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 					state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			case 1: /* OP a,b,u6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			case 2: /* OP b,b,s12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			case 3: /* OP.cc b,b,c/u6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 				if ((!IS_BIT(state->words[0], 5)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 				    (FIELD_C(state->words[0]) == REG_LIMM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			/* Not a Load, Jump or Loop instruction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			/* still need to check for limm to extract instr len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			switch (BITS(state->words[0], 22, 23)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			case 0: /* OP a,b,c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 				if ((FIELD_B(state->words[0]) == REG_LIMM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				    (FIELD_C(state->words[0]) == REG_LIMM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 					state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			case 1: /* OP a,b,u6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			case 2: /* OP b,b,s12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			case 3: /* OP.cc b,b,c/u6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 				if ((!IS_BIT(state->words[0], 5)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				   ((FIELD_B(state->words[0]) == REG_LIMM) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				    (FIELD_C(state->words[0]) == REG_LIMM)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 					state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	/* 16 Bit Instructions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	case op_LD_ADD: /* LD_S|LDB_S|LDW_S a,[b,c] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		state->zz = BITS(state->words[0], 3, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		state->src1 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		state->src2 = get_reg(FIELD_S_C(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		state->dest = FIELD_S_A(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	case op_ADD_MOV_CMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		/* check for limm, ignore mov_s h,b (== mov_s 0,b) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		if ((BITS(state->words[0], 3, 4) < 3) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		    (FIELD_S_H(state->words[0]) == REG_LIMM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			state->instr_len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	case op_S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		subopcode = BITS(state->words[0], 5, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		switch (subopcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		case 0:	/* j_s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		case 1:	/* j_s.d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		case 2:	/* jl_s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		case 3:	/* jl_s.d */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			state->target = get_reg(FIELD_S_B(state->words[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 						regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			state->delay_slot = subopcode & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			state->flow = (subopcode >= 2) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				direct_call : indirect_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			switch (BITS(state->words[0], 8, 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			case 4:	/* jeq_s [blink] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 			case 5:	/* jne_s [blink] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			case 6:	/* j_s [blink] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			case 7:	/* j_s.d [blink] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 				state->delay_slot = (subopcode == 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 				state->flow = indirect_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				state->target = get_reg(31, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	case op_LD_S:	/* LD_S c, [b, u7] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		state->src1 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		state->src2 = FIELD_S_u7(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		state->dest = FIELD_S_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	case op_LDB_S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	case op_STB_S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		/* no further handling required as byte accesses should not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		 * cause an unaligned access exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		state->zz = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	case op_LDWX_S:	/* LDWX_S c, [b, u6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		state->x = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	case op_LDW_S:	/* LDW_S c, [b, u6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		state->zz = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		state->src1 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		state->src2 = FIELD_S_u6(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		state->dest = FIELD_S_C(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	case op_ST_S:	/* ST_S c, [b, u7] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		state->write = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		state->src1 = get_reg(FIELD_S_C(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		state->src2 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		state->src3 = FIELD_S_u7(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	case op_STW_S:	/* STW_S c,[b,u6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		state->write = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		state->zz = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		state->src1 = get_reg(FIELD_S_C(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		state->src2 = get_reg(FIELD_S_B(state->words[0]), regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		state->src3 = FIELD_S_u6(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	case op_SP:	/* LD_S|LDB_S b,[sp,u7], ST_S|STB_S b,[sp,u7] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		/* note: we are ignoring possibility of:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		 * ADD_S, SUB_S, PUSH_S, POP_S as these should not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		 * cause unaliged exception anyway */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		state->write = BITS(state->words[0], 6, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		state->zz = BITS(state->words[0], 5, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		if (state->zz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			break;	/* byte accesses should not come here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		if (!state->write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			state->src1 = get_reg(28, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			state->src2 = FIELD_S_u7(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			state->dest = FIELD_S_B(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			state->src1 = get_reg(FIELD_S_B(state->words[0]), regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 					cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			state->src2 = get_reg(28, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			state->src3 = FIELD_S_u7(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	case op_GP:	/* LD_S|LDB_S|LDW_S r0,[gp,s11/s9/s10] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		/* note: ADD_S r0, gp, s11 is ignored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		state->zz = BITS(state->words[0], 9, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		state->src1 = get_reg(26, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		state->src2 = state->zz ? FIELD_S_s10(state->words[0]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 			FIELD_S_s11(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		state->dest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	case op_Pcl:	/* LD_S b,[pcl,u10] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		state->src1 = regs->ret & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		state->src2 = FIELD_S_u10(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		state->dest = FIELD_S_B(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	case op_BR_S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		state->target = FIELD_S_s8(state->words[0]) + (addr & ~0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		state->flow = direct_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	case op_B_S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		fieldA = (BITS(state->words[0], 9, 10) == 3) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			FIELD_S_s7(state->words[0]) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			FIELD_S_s10(state->words[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		state->target = fieldA + (addr & ~0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		state->flow = direct_jump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	case op_BL_S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		state->target = FIELD_S_s13(state->words[0]) + (addr & ~0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		state->flow = direct_call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		state->is_branch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	if (bytes_not_copied <= (8 - state->instr_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) fault:	state->fault = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) long __kprobes get_reg(int reg, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		       struct callee_regs *cregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	long *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (reg <= 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		p = &regs->r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		return p[-reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (cregs && (reg <= 25)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		p = &cregs->r13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		return p[13-reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	if (reg == 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		return regs->r26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	if (reg == 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		return regs->fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	if (reg == 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		return regs->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	if (reg == 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		return regs->blink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) void __kprobes set_reg(int reg, long val, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		struct callee_regs *cregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	long *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	case 0 ... 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		p = &regs->r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		p[-reg] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	case 13 ... 25:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		if (cregs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			p = &cregs->r13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			p[13-reg] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	case 26:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		regs->r26 = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	case 27:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		regs->fp = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	case 28:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		regs->sp = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	case 31:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		regs->blink = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  * Disassembles the insn at @pc and sets @next_pc to next PC (which could be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  * @pc +2/4/6 (ARCompact ISA allows free intermixing of 16/32 bit insns).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)  * If @pc is a branch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)  *	-@tgt_if_br is set to branch target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)  *	-If branch has delay slot, @next_pc updated with actual next PC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int __kprobes disasm_next_pc(unsigned long pc, struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			     struct callee_regs *cregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 			     unsigned long *next_pc, unsigned long *tgt_if_br)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	struct disasm_state instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	memset(&instr, 0, sizeof(struct disasm_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	disasm_instr(pc, &instr, 0, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	*next_pc = pc + instr.instr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	/* Instruction with possible two targets branch, jump and loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	if (instr.is_branch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		*tgt_if_br = instr.target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	/* For the instructions with delay slots, the fall through is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	 * instruction following the instruction in delay slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	 if (instr.delay_slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		struct disasm_state instr_d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		disasm_instr(*next_pc, &instr_d, 0, regs, cregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		*next_pc += instr_d.instr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	 /* Zero Overhead Loop - end of the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	if (!(regs->status32 & STATUS32_L) && (*next_pc == regs->lp_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		&& (regs->lp_count > 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		*next_pc = regs->lp_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	return instr.is_branch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) #endif /* CONFIG_KGDB || CONFIG_ARC_EMUL_UNALIGNED || CONFIG_KPROBES */