aboutsummaryrefslogtreecommitdiff
path: root/src/target/mips64.h
blob: 3453e4ed1ab6f62e20fbc0a145680103a4f3383b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Support for processors implementing MIPS64 instruction set
 *
 * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>
 * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>
 * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>
 *
 * Based on the work of:
 *     Copyright (C) 2008 by Spencer Oliver
 *     Copyright (C) 2008 by David T.L. Wong
 *     Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev
 */

#ifndef OPENOCD_TARGET_MIPS64_H
#define OPENOCD_TARGET_MIPS64_H

#include "target.h"
#include "register.h"
#include "mips64_pracc.h"

#define MIPS64_COMMON_MAGIC		0xB640B640

/* MIPS64 CP0 registers */
#define MIPS64_C0_INDEX		0
#define MIPS64_C0_RANDOM	1
#define MIPS64_C0_ENTRYLO0	2
#define MIPS64_C0_ENTRYLO1	3
#define MIPS64_C0_CONTEXT	4
#define MIPS64_C0_PAGEMASK	5
#define MIPS64_C0_WIRED		6
#define MIPS64_C0_BADVADDR	8
#define MIPS64_C0_COUNT		9
#define MIPS64_C0_ENTRYHI	10
#define MIPS64_C0_COMPARE	11
#define MIPS64_C0_STATUS	12
#define MIPS64_C0_CAUSE		13
#define MIPS64_C0_EPC		14
#define MIPS64_C0_PRID		15
#define MIPS64_C0_CONFIG	16
#define MIPS64_C0_LLA		17
#define MIPS64_C0_WATCHLO	18
#define MIPS64_C0_WATCHHI	19
#define MIPS64_C0_XCONTEXT	20
#define MIPS64_C0_MEMCTRL	22
#define MIPS64_C0_DEBUG		23
#define MIPS64_C0_DEPC		24
#define MIPS64_C0_PERFCOUNT	25
#define MIPS64_C0_ECC		26
#define MIPS64_C0_CACHERR	27
#define MIPS64_C0_TAGLO		28
#define MIPS64_C0_TAGHI		29
#define MIPS64_C0_DATAHI	29
#define MIPS64_C0_EEPC		30

/* MIPS64 CP1 registers */
#define MIPS64_C1_FIR		0
#define MIPS64_C1_FCONFIG	24
#define MIPS64_C1_FCSR		31
#define MIPS64_C1_FCCR		25
#define MIPS64_C1_FEXR		26
#define MIPS64_C1_FENR		28

/* offsets into mips64 register cache */
#define MIPS64_NUM_CORE_REGS	34
#define MIPS64_NUM_C0_REGS	34
#define MIPS64_NUM_FP_REGS	38

#define MIPS64_NUM_REGS		(MIPS64_NUM_CORE_REGS + \
				 MIPS64_NUM_C0_REGS + \
				 MIPS64_NUM_FP_REGS)

#define MIPS64_NUM_CORE_C0_REGS	(MIPS64_NUM_CORE_REGS + MIPS64_NUM_C0_REGS)

#define MIPS64_PC		MIPS64_NUM_CORE_REGS

struct mips64_comparator {
	bool used;
	uint64_t bp_value;
	uint64_t reg_address;
};

struct mips64_common {
	uint32_t common_magic;
	void *arch_info;
	struct reg_cache *core_cache;
	struct mips_ejtag ejtag_info;
	uint64_t core_regs[MIPS64_NUM_REGS];

	struct working_area *fast_data_area;

	bool bp_scanned;
	int num_inst_bpoints;
	int num_data_bpoints;
	int num_inst_bpoints_avail;
	int num_data_bpoints_avail;
	struct mips64_comparator *inst_break_list;
	struct mips64_comparator *data_break_list;

	/* register cache to processor synchronization */
	int (*read_core_reg)(struct target *target, int num);
	int (*write_core_reg)(struct target *target, int num);

	bool mips64mode32;
};

struct mips64_core_reg {
	uint32_t num;
	struct target *target;
	struct mips64_common *mips64_common;
	uint8_t value[8];
	struct reg_feature feature;
	struct reg_data_type reg_data_type;
};

#define MIPS64_OP_SRL	0x02
#define MIPS64_OP_BEQ	0x04
#define MIPS64_OP_BNE	0x05
#define MIPS64_OP_ADDI	0x08
#define MIPS64_OP_ANDI	0x0c
#define MIPS64_OP_DADDI	0x18
#define MIPS64_OP_DADDIU	0x19
#define MIPS64_OP_AND	0x24
#define MIPS64_OP_LUI	0x0F
#define MIPS64_OP_LW	0x23
#define MIPS64_OP_LD	0x37
#define MIPS64_OP_LBU	0x24
#define MIPS64_OP_LHU	0x25
#define MIPS64_OP_MFHI	0x10
#define MIPS64_OP_MTHI	0x11
#define MIPS64_OP_MFLO	0x12
#define MIPS64_OP_MTLO	0x13
#define MIPS64_OP_SB	0x28
#define MIPS64_OP_SH	0x29
#define MIPS64_OP_SW	0x2B
#define MIPS64_OP_SD	0x3F
#define MIPS64_OP_ORI	0x0D
#define MIPS64_OP_JR	0x08

#define MIPS64_OP_COP0	0x10
#define MIPS64_OP_COP1	0x11
#define MIPS64_OP_COP2	0x12

#define MIPS64_COP_MF	0x00
#define MIPS64_COP_DMF	0x01
#define MIPS64_COP_MT	0x04
#define MIPS64_COP_DMT	0x05
#define MIPS64_COP_CF	0x02
#define MIPS64_COP_CT	0x06

#define MIPS64_R_INST(opcode, rs, rt, rd, shamt, funct) \
(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct))
#define MIPS64_I_INST(opcode, rs, rt, immd)	(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))
#define MIPS64_J_INST(opcode, addr)	(((opcode) << 26) | (addr))

#define MIPS64_NOP			0
#define MIPS64_ADDI(tar, src, val)	MIPS64_I_INST(MIPS64_OP_ADDI, src, tar, val)
#define MIPS64_DADDI(tar, src, val)	MIPS64_I_INST(MIPS64_OP_DADDI, src, tar, val)
#define MIPS64_DADDIU(tar, src, val)	MIPS64_I_INST(MIPS64_OP_DADDIU, src, tar, val)
#define MIPS64_AND(reg, off, val)	MIPS64_R_INST(0, off, val, reg, 0, MIPS64_OP_AND)
#define MIPS64_ANDI(d, s, im)		MIPS64_I_INST(MIPS64_OP_ANDI, s, d, im)
#define MIPS64_SRL(d, w, sh)		MIPS64_R_INST(0, 0, w, d, sh, MIPS64_OP_SRL)
#define MIPS64_B(off)			MIPS64_BEQ(0, 0, off)
#define MIPS64_BEQ(src, tar, off)	MIPS64_I_INST(MIPS64_OP_BEQ, src, tar, off)
#define MIPS64_BNE(src, tar, off)	MIPS64_I_INST(MIPS64_OP_BNE, src, tar, off)
#define MIPS64_MFC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MF, gpr, cpr, 0, sel)
#define MIPS64_DMFC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMF, gpr, cpr, 0, sel)
#define MIPS64_MTC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MT, gpr, cpr, 0, sel)
#define MIPS64_DMTC0(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMT, gpr, cpr, 0, sel)
#define MIPS64_MFC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MF, gpr, cpr, 0, 0)
#define MIPS64_DMFC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMF, gpr, cpr, 0, 0)
#define MIPS64_MTC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MT, gpr, cpr, 0, 0)
#define MIPS64_DMTC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMT, gpr, cpr, 0, 0)
#define MIPS64_MFC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MF, gpr, cpr, 0, sel)
#define MIPS64_MTC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MT, gpr, cpr, 0, sel)
#define MIPS64_CFC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CF, gpr, cpr, 0, 0)
#define MIPS64_CTC1(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CT, gpr, cpr, 0, 0)
#define MIPS64_CFC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CF, gpr, cpr, 0, sel)
#define MIPS64_CTC2(gpr, cpr, sel)	MIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CT, gpr, cpr, 0, sel)
#define MIPS64_LBU(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LBU, base, reg, off)
#define MIPS64_LHU(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LHU, base, reg, off)
#define MIPS64_LUI(reg, val)		MIPS64_I_INST(MIPS64_OP_LUI, 0, reg, val)
#define MIPS64_LW(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LW, base, reg, off)
#define MIPS64_LD(reg, off, base)	MIPS64_I_INST(MIPS64_OP_LD, base, reg, off)
#define MIPS64_MFLO(reg)		MIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFLO)
#define MIPS64_MFHI(reg)		MIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFHI)
#define MIPS64_MTLO(reg)		MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTLO)
#define MIPS64_MTHI(reg)		MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTHI)
#define MIPS64_ORI(src, tar, val)	MIPS64_I_INST(MIPS64_OP_ORI, src, tar, val)
#define MIPS64_SB(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SB, base, reg, off)
#define MIPS64_SH(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SH, base, reg, off)
#define MIPS64_SW(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SW, base, reg, off)
#define MIPS64_SD(reg, off, base)	MIPS64_I_INST(MIPS64_OP_SD, base, reg, off)
#define MIPS64_CACHE(op, reg, off)	(47 << 26 | (reg) << 21 | (op) << 16 | (off))
#define MIPS64_SYNCI(reg, off)		(1 << 26 | (reg) << 21 | 0x1f << 16 | (off))
#define MIPS64_JR(reg)			MIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_JR)

/* ejtag specific instructions */
#define MIPS64_DRET			0x4200001F
#define MIPS64_SDBBP			0x7000003F
#define MIPS64_SDBBP_LE			0x3f000007
#define MIPS64_SDBBP_SIZE		4
#define MIPS16_SDBBP_SIZE		2

#define MIPS64_SYNC			0x0000000F

int mips64_arch_state(struct target *target);
int mips64_init_arch_info(struct target *target, struct mips64_common *mips64, struct jtag_tap *tap);
int mips64_restore_context(struct target *target);
int mips64_save_context(struct target *target);
int mips64_build_reg_cache(struct target *target);
int mips64_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params,
	int num_reg_params, struct reg_param *reg_params,
	target_addr_t entry_point, target_addr_t exit_point,
	int timeout_ms, void *arch_info);
int mips64_configure_break_unit(struct target *target);
int mips64_enable_interrupts(struct target *target, bool enable);
int mips64_examine(struct target *target);

int mips64_register_commands(struct command_context *cmd_ctx);
int mips64_invalidate_core_regs(struct target *target);
int mips64_get_gdb_reg_list(struct target *target,
	struct reg **reg_list[], int *reg_list_size,
	enum target_register_class reg_class);

#endif	/* OPENOCD_TARGET_MIPS64_H */