1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Support for processors implementing MIPS64 instruction set
4  *
5  * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
6  * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
7  * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
8  *
9  * Based on the work of:
10  *     Copyright (C) 2008 by Spencer Oliver
11  *     Copyright (C) 2008 by David T.L. Wong
12  *     Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
13  */
14 
15 #ifndef OPENOCD_TARGET_MIPS64_H
16 #define OPENOCD_TARGET_MIPS64_H
17 
18 #include "target.h"
19 #include "register.h"
20 #include "mips64_pracc.h"
21 
22 #define MIPS64_COMMON_MAGIC		0xB640B640
23 
24 /* MIPS64 CP0 registers */
25 #define MIPS64_C0_INDEX		0
26 #define MIPS64_C0_RANDOM	1
27 #define MIPS64_C0_ENTRYLO0	2
28 #define MIPS64_C0_ENTRYLO1	3
29 #define MIPS64_C0_CONTEXT	4
30 #define MIPS64_C0_PAGEMASK	5
31 #define MIPS64_C0_WIRED		6
32 #define MIPS64_C0_BADVADDR	8
33 #define MIPS64_C0_COUNT		9
34 #define MIPS64_C0_ENTRYHI	10
35 #define MIPS64_C0_COMPARE	11
36 #define MIPS64_C0_STATUS	12
37 #define MIPS64_C0_CAUSE		13
38 #define MIPS64_C0_EPC		14
39 #define MIPS64_C0_PRID		15
40 #define MIPS64_C0_CONFIG	16
41 #define MIPS64_C0_LLA		17
42 #define MIPS64_C0_WATCHLO	18
43 #define MIPS64_C0_WATCHHI	19
44 #define MIPS64_C0_XCONTEXT	20
45 #define MIPS64_C0_MEMCTRL	22
46 #define MIPS64_C0_DEBUG		23
47 #define MIPS64_C0_DEPC		24
48 #define MIPS64_C0_PERFCOUNT	25
49 #define MIPS64_C0_ECC		26
50 #define MIPS64_C0_CACHERR	27
51 #define MIPS64_C0_TAGLO		28
52 #define MIPS64_C0_TAGHI		29
53 #define MIPS64_C0_DATAHI	29
54 #define MIPS64_C0_EEPC		30
55 
56 /* MIPS64 CP1 registers */
57 #define MIPS64_C1_FIR		0
58 #define MIPS64_C1_FCONFIG	24
59 #define MIPS64_C1_FCSR		31
60 #define MIPS64_C1_FCCR		25
61 #define MIPS64_C1_FEXR		26
62 #define MIPS64_C1_FENR		28
63 
64 /* offsets into mips64 register cache */
65 #define MIPS64_NUM_CORE_REGS	34
66 #define MIPS64_NUM_C0_REGS	34
67 #define MIPS64_NUM_FP_REGS	38
68 
69 #define MIPS64_NUM_REGS		(MIPS64_NUM_CORE_REGS + \
70 				 MIPS64_NUM_C0_REGS + \
71 				 MIPS64_NUM_FP_REGS)
72 
73 #define MIPS64_NUM_CORE_C0_REGS	(MIPS64_NUM_CORE_REGS + MIPS64_NUM_C0_REGS)
74 
75 #define MIPS64_PC		MIPS64_NUM_CORE_REGS
76 
77 struct mips64_comparator {
78 	bool used;
79 	uint64_t bp_value;
80 	uint64_t reg_address;
81 };
82 
83 struct mips64_common {
84 	uint32_t common_magic;
85 	void *arch_info;
86 	struct reg_cache *core_cache;
87 	struct mips_ejtag ejtag_info;
88 	uint64_t core_regs[MIPS64_NUM_REGS];
89 
90 	struct working_area *fast_data_area;
91 
92 	bool bp_scanned;
93 	int num_inst_bpoints;
94 	int num_data_bpoints;
95 	int num_inst_bpoints_avail;
96 	int num_data_bpoints_avail;
97 	struct mips64_comparator *inst_break_list;
98 	struct mips64_comparator *data_break_list;
99 
100 	/* register cache to processor synchronization */
101 	int (*read_core_reg)(struct target *target, int num);
102 	int (*write_core_reg)(struct target *target, int num);
103 
104 	bool mips64mode32;
105 };
106 
107 struct mips64_core_reg {
108 	uint32_t num;
109 	struct target *target;
110 	struct mips64_common *mips64_common;
111 	uint8_t value[8];
112 	struct reg_feature feature;
113 	struct reg_data_type reg_data_type;
114 };
115 
116 #define MIPS64_OP_SRL	0x02
117 #define MIPS64_OP_BEQ	0x04
118 #define MIPS64_OP_BNE	0x05
119 #define MIPS64_OP_ADDI	0x08
120 #define MIPS64_OP_ANDI	0x0c
121 #define MIPS64_OP_DADDI	0x18
122 #define MIPS64_OP_DADDIU	0x19
123 #define MIPS64_OP_AND	0x24
124 #define MIPS64_OP_LUI	0x0F
125 #define MIPS64_OP_LW	0x23
126 #define MIPS64_OP_LD	0x37
127 #define MIPS64_OP_LBU	0x24
128 #define MIPS64_OP_LHU	0x25
129 #define MIPS64_OP_MFHI	0x10
130 #define MIPS64_OP_MTHI	0x11
131 #define MIPS64_OP_MFLO	0x12
132 #define MIPS64_OP_MTLO	0x13
133 #define MIPS64_OP_SB	0x28
134 #define MIPS64_OP_SH	0x29
135 #define MIPS64_OP_SW	0x2B
136 #define MIPS64_OP_SD	0x3F
137 #define MIPS64_OP_ORI	0x0D
138 #define MIPS64_OP_JR	0x08
139 
140 #define MIPS64_OP_COP0	0x10
141 #define MIPS64_OP_COP1	0x11
142 #define MIPS64_OP_COP2	0x12
143 
144 #define MIPS64_COP_MF	0x00
145 #define MIPS64_COP_DMF	0x01
146 #define MIPS64_COP_MT	0x04
147 #define MIPS64_COP_DMT	0x05
148 #define MIPS64_COP_CF	0x02
149 #define MIPS64_COP_CT	0x06
150 
151 #define MIPS64_R_INST(opcode, rs, rt, rd, shamt, funct) \
152 (((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct))
153 #define MIPS64_I_INST(opcode, rs, rt, immd)	(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))
154 #define MIPS64_J_INST(opcode, addr)	(((opcode) << 26) | (addr))
155 
156 #define MIPS64_NOP			0
157 #define MIPS64_ADDI(tar, src, val)	MIPS64_I_INST(MIPS64_OP_ADDI, src, tar, val)
158 #define MIPS64_DADDI(tar, src, val)	MIPS64_I_INST(MIPS64_OP_DADDI, src, tar, val)
159 #define MIPS64_DADDIU(tar, src, val)	MIPS64_I_INST(MIPS64_OP_DADDIU, src, tar, val)
160 #define MIPS64_AND(reg, off, val)	MIPS64_R_INST(0, off, val, reg, 0, MIPS64_OP_AND)
161 #define MIPS64_ANDI(d, s, im)		MIPS64_I_INST(MIPS64_OP_ANDI, s, d, im)
162 #define MIPS64_SRL(d, w, sh)		MIPS64_R_INST(0, 0, w, d, sh, MIPS64_OP_SRL)
163 #define MIPS64_B(off)			MIPS64_BEQ(0, 0, off)
164 #define MIPS64_BEQ(src, tar, off)	MIPS64_I_INST(MIPS64_OP_BEQ, src, tar, off)
165 #define MIPS64_BNE(src, tar, off)	MIPS64_I_INST(MIPS64_OP_BNE, src, tar, off)
166 #define MIPS64_MFC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MF, gpr, cpr, 0, sel)
167 #define MIPS64_DMFC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMF, gpr, cpr, 0, sel)
168 #define MIPS64_MTC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MT, gpr, cpr, 0, sel)
169 #define MIPS64_DMTC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMT, gpr, cpr, 0, sel)
170 #define MIPS64_MFC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MF, gpr, cpr, 0, 0)
171 #define MIPS64_DMFC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMF, gpr, cpr, 0, 0)
172 #define MIPS64_MTC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MT, gpr, cpr, 0, 0)
173 #define MIPS64_DMTC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMT, gpr, cpr, 0, 0)
174 #define MIPS64_MFC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MF, gpr, cpr, 0, sel)
175 #define MIPS64_MTC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MT, gpr, cpr, 0, sel)
176 #define MIPS64_CFC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CF, gpr, cpr, 0, 0)
177 #define MIPS64_CTC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CT, gpr, cpr, 0, 0)
178 #define MIPS64_CFC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CF, gpr, cpr, 0, sel)
179 #define MIPS64_CTC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CT, gpr, cpr, 0, sel)
180 #define MIPS64_LBU(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LBU, base, reg, off)
181 #define MIPS64_LHU(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LHU, base, reg, off)
182 #define MIPS64_LUI(reg, val)		MIPS64_I_INST(MIPS64_OP_LUI, 0, reg, val)
183 #define MIPS64_LW(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LW, base, reg, off)
184 #define MIPS64_LD(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LD, base, reg, off)
185 #define MIPS64_MFLO(reg)		MIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFLO)
186 #define MIPS64_MFHI(reg)		MIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFHI)
187 #define MIPS64_MTLO(reg)		MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTLO)
188 #define MIPS64_MTHI(reg)		MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTHI)
189 #define MIPS64_ORI(src, tar, val)	MIPS64_I_INST(MIPS64_OP_ORI, src, tar, val)
190 #define MIPS64_SB(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SB, base, reg, off)
191 #define MIPS64_SH(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SH, base, reg, off)
192 #define MIPS64_SW(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SW, base, reg, off)
193 #define MIPS64_SD(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SD, base, reg, off)
194 #define MIPS64_CACHE(op, reg, off)	(47 << 26 | (reg) << 21 | (op) << 16 | (off))
195 #define MIPS64_SYNCI(reg, off)		(1 << 26 | (reg) << 21 | 0x1f << 16 | (off))
196 #define MIPS64_JR(reg)			MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_JR)
197 
198 /* ejtag specific instructions */
199 #define MIPS64_DRET			0x4200001F
200 #define MIPS64_SDBBP			0x7000003F
201 #define MIPS64_SDBBP_LE			0x3f000007
202 #define MIPS64_SDBBP_SIZE		4
203 #define MIPS16_SDBBP_SIZE		2
204 
205 #define MIPS64_SYNC			0x0000000F
206 
207 int mips64_arch_state(struct target *target);
208 int mips64_init_arch_info(struct target *target, struct mips64_common *mips64, struct jtag_tap *tap);
209 int mips64_restore_context(struct target *target);
210 int mips64_save_context(struct target *target);
211 int mips64_build_reg_cache(struct target *target);
212 int mips64_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params,
213 	int num_reg_params, struct reg_param *reg_params,
214 	target_addr_t entry_point, target_addr_t exit_point,
215 	int timeout_ms, void *arch_info);
216 int mips64_configure_break_unit(struct target *target);
217 int mips64_enable_interrupts(struct target *target, bool enable);
218 int mips64_examine(struct target *target);
219 
220 int mips64_register_commands(struct command_context *cmd_ctx);
221 int mips64_invalidate_core_regs(struct target *target);
222 int mips64_get_gdb_reg_list(struct target *target,
223 	struct reg **reg_list[], int *reg_list_size,
224 	enum target_register_class reg_class);
225 
226 #endif	/* OPENOCD_TARGET_MIPS64_H */
227