mips32_pracc.c 33.8 KB
Newer Older
ntfreak's avatar
ntfreak committed
1
2
3
4
5
6
/***************************************************************************
 *   Copyright (C) 2008 by Spencer Oliver                                  *
 *   spen@spen-soft.co.uk                                                  *
 *                                                                         *
 *   Copyright (C) 2008 by David T.L. Wong                                 *
 *                                                                         *
7
8
 *   Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com>          *
 *                                                                         *
ntfreak's avatar
ntfreak committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
24
25
26
27
28
29
30

/*
This version has optimized assembly routines for 32 bit operations:
- read word
- write word
- write array of words

31
One thing to be aware of is that the MIPS32 cpu will execute the
32
33
34
35
36
37
38
39
instruction after a branch instruction (one delay slot).

For example:

    LW $2, ($5 +10)
    B foo
    LW $1, ($2 +100)

40
The LW $1, ($2 +100) instruction is also executed. If this is
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
not wanted a NOP can be inserted:

    LW $2, ($5 +10)
    B foo
    NOP
    LW $1, ($2 +100)

or the code can be changed to:

    B foo
    LW $2, ($5 +10)
    LW $1, ($2 +100)

The original code contained NOPs. I have removed these and moved
the branches.

I also moved the PRACC_STACK to 0xFF204000. This allows
the use of 16 bits offsets to get pointers to the input
and output area relative to the stack. Note that the stack
isn't really a stack (the stack pointer is not 'moving')
but a FIFO simulated in software.

These changes result in a 35% speed increase when programming an
external flash.

More improvement could be gained if the registers do no need
to be preserved but in that case the routines should be aware
OpenOCD is used as a flash programmer or as a debug tool.

Nico Coesel
*/

ntfreak's avatar
ntfreak committed
73
74
75
76
77
78
79
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "mips32.h"
#include "mips32_pracc.h"

Zachary T Welch's avatar
Zachary T Welch committed
80
81
struct mips32_pracc_context
{
82
	uint32_t *local_iparam;
ntfreak's avatar
ntfreak committed
83
	int num_iparam;
84
	uint32_t *local_oparam;
ntfreak's avatar
ntfreak committed
85
	int num_oparam;
86
	const uint32_t *code;
ntfreak's avatar
ntfreak committed
87
	int code_len;
88
	uint32_t stack[32];
ntfreak's avatar
ntfreak committed
89
	int stack_offset;
90
	struct mips_ejtag *ejtag_info;
Zachary T Welch's avatar
Zachary T Welch committed
91
};
ntfreak's avatar
ntfreak committed
92

93
static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
ntfreak's avatar
ntfreak committed
94
{
95
	uint32_t ejtag_ctrl;
96
97

	while (1)
ntfreak's avatar
ntfreak committed
98
99
	{
		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
100
		ejtag_ctrl = ejtag_info->ejtag_ctrl;
ntfreak's avatar
ntfreak committed
101
102
103
104
105
106
		mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
		if (ejtag_ctrl & EJTAG_CTRL_PRACC)
			break;
		LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
		return ERROR_JTAG_DEVICE_ERROR;
	}
107

ntfreak's avatar
ntfreak committed
108
109
110
111
	*ctrl = ejtag_ctrl;
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
112
static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t address)
ntfreak's avatar
ntfreak committed
113
{
114
	struct mips_ejtag *ejtag_info = ctx->ejtag_info;
ntfreak's avatar
ntfreak committed
115
	int offset;
116
	uint32_t ejtag_ctrl, data;
ntfreak's avatar
ntfreak committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130

	if ((address >= MIPS32_PRACC_PARAM_IN)
		&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
	{
		offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
		data = ctx->local_iparam[offset];
	}
	else if ((address >= MIPS32_PRACC_PARAM_OUT)
		&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
	{
		offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
		data = ctx->local_oparam[offset];
	}
	else if ((address >= MIPS32_PRACC_TEXT)
Spencer Oliver's avatar
Spencer Oliver committed
131
		&& (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4))
ntfreak's avatar
ntfreak committed
132
133
134
135
136
137
138
139
140
141
142
143
144
	{
		offset = (address - MIPS32_PRACC_TEXT) / 4;
		data = ctx->code[offset];
	}
	else if (address == MIPS32_PRACC_STACK)
	{
		/* save to our debug stack */
		data = ctx->stack[--ctx->stack_offset];
	}
	else
	{
		/* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back
		 * to start of debug vector */
145

ntfreak's avatar
ntfreak committed
146
		data = 0;
Spencer Oliver's avatar
Spencer Oliver committed
147
		LOG_ERROR("Error reading unexpected address 0x%8.8" PRIx32 "", address);
ntfreak's avatar
ntfreak committed
148
149
		return ERROR_JTAG_DEVICE_ERROR;
	}
150

ntfreak's avatar
ntfreak committed
151
152
153
154
155
	/* Send the data out */
	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
	mips_ejtag_drscan_32(ctx->ejtag_info, &data);

	/* Clear the access pending bit (let the processor eat!) */
156
	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
ntfreak's avatar
ntfreak committed
157
	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
158
	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
159
160
161

	jtag_add_clocks(5);
	jtag_execute_queue();
162

ntfreak's avatar
ntfreak committed
163
164
165
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
166
static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t address)
ntfreak's avatar
ntfreak committed
167
{
168
	uint32_t ejtag_ctrl,data;
ntfreak's avatar
ntfreak committed
169
	int offset;
170
	struct mips_ejtag *ejtag_info = ctx->ejtag_info;
171

ntfreak's avatar
ntfreak committed
172
173
	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
	mips_ejtag_drscan_32(ctx->ejtag_info, &data);
174

ntfreak's avatar
ntfreak committed
175
	/* Clear access pending bit */
176
	ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
ntfreak's avatar
ntfreak committed
177
	mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
178
	mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
179
180
181

	jtag_add_clocks(5);
	jtag_execute_queue();
182

ntfreak's avatar
ntfreak committed
183
184
185
186
187
188
	if ((address >= MIPS32_PRACC_PARAM_IN)
		&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
	{
		offset = (address - MIPS32_PRACC_PARAM_IN) / 4;
		ctx->local_iparam[offset] = data;
	}
189
	else if ((address >= MIPS32_PRACC_PARAM_OUT)
ntfreak's avatar
ntfreak committed
190
191
192
193
194
195
196
197
198
199
200
201
		&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))
	{
		offset = (address - MIPS32_PRACC_PARAM_OUT) / 4;
		ctx->local_oparam[offset] = data;
	}
	else if (address == MIPS32_PRACC_STACK)
	{
		/* save data onto our stack */
		ctx->stack[ctx->stack_offset++] = data;
	}
	else
	{
Spencer Oliver's avatar
Spencer Oliver committed
202
		LOG_ERROR("Error writing unexpected address 0x%8.8" PRIx32 "", address);
ntfreak's avatar
ntfreak committed
203
204
		return ERROR_JTAG_DEVICE_ERROR;
	}
205

ntfreak's avatar
ntfreak committed
206
207
208
	return ERROR_OK;
}

209
int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_t *code, int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle)
ntfreak's avatar
ntfreak committed
210
{
211
212
	uint32_t ejtag_ctrl;
	uint32_t address, data;
Zachary T Welch's avatar
Zachary T Welch committed
213
	struct mips32_pracc_context ctx;
ntfreak's avatar
ntfreak committed
214
215
	int retval;
	int pass = 0;
216

ntfreak's avatar
ntfreak committed
217
218
219
220
221
222
223
224
	ctx.local_iparam = param_in;
	ctx.local_oparam = param_out;
	ctx.num_iparam = num_param_in;
	ctx.num_oparam = num_param_out;
	ctx.code = code;
	ctx.code_len = code_len;
	ctx.ejtag_info = ejtag_info;
	ctx.stack_offset = 0;
225

ntfreak's avatar
ntfreak committed
226
227
	while (1)
	{
228
		if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
ntfreak's avatar
ntfreak committed
229
			return retval;
230

ntfreak's avatar
ntfreak committed
231
232
233
		address = data = 0;
		mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
		mips_ejtag_drscan_32(ejtag_info, &address);
234

ntfreak's avatar
ntfreak committed
235
		/* Check for read or write */
236
		if (ejtag_ctrl & EJTAG_CTRL_PRNW)
ntfreak's avatar
ntfreak committed
237
238
239
240
241
242
243
244
245
246
247
248
249
		{
			if ((retval = mips32_pracc_exec_write(&ctx, address)) != ERROR_OK)
				return retval;
		}
		else
		{
			/* Check to see if its reading at the debug vector. The first pass through
			 * the module is always read at the vector, so the first one we allow.  When
			 * the second read from the vector occurs we are done and just exit. */
			if ((address == MIPS32_PRACC_TEXT) && (pass++))
			{
				break;
			}
250

ntfreak's avatar
ntfreak committed
251
252
253
			if ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK)
				return retval;
		}
254

ntfreak's avatar
ntfreak committed
255
256
257
		if (cycle == 0)
			break;
	}
258

ntfreak's avatar
ntfreak committed
259
260
261
262
263
	/* stack sanity check */
	if (ctx.stack_offset != 0)
	{
		LOG_DEBUG("Pracc Stack not zero");
	}
264

ntfreak's avatar
ntfreak committed
265
266
267
	return ERROR_OK;
}

268
int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
ntfreak's avatar
ntfreak committed
269
270
271
272
{
	switch (size)
	{
		case 1:
273
			return mips32_pracc_read_mem8(ejtag_info, addr, count, (uint8_t*)buf);
ntfreak's avatar
ntfreak committed
274
		case 2:
zwelch's avatar
zwelch committed
275
			return mips32_pracc_read_mem16(ejtag_info, addr, count, (uint16_t*)buf);
ntfreak's avatar
ntfreak committed
276
		case 4:
zwelch's avatar
zwelch committed
277
			if (count == 1)
278
				return mips32_pracc_read_u32(ejtag_info, addr, (uint32_t*)buf);
279
			else
280
				return mips32_pracc_read_mem32(ejtag_info, addr, count, (uint32_t*)buf);
ntfreak's avatar
ntfreak committed
281
	}
282

ntfreak's avatar
ntfreak committed
283
284
285
	return ERROR_OK;
}

286
int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
287
{
288
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
289
290
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
291
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
292
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
293
294
295
296
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
		MIPS32_SW(10,0,15),									/* sw $10,($15) */
		MIPS32_SW(11,0,15),									/* sw $11,($15) */
297

ntfreak's avatar
ntfreak committed
298
299
		MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)),		/* $8 = MIPS32_PRACC_PARAM_IN */
		MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
zwelch's avatar
zwelch committed
300
		MIPS32_LW(9,0,8),									/* $9 = mem[$8]; read addr */
zwelch's avatar
zwelch committed
301
		MIPS32_LW(10,4,8),									/* $10 = mem[$8 + 4]; read count */
Spencer Oliver's avatar
Spencer Oliver committed
302
		MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)),		/* $11 = MIPS32_PRACC_PARAM_OUT */
ntfreak's avatar
ntfreak committed
303
304
		MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
															/* loop: */
Spencer Oliver's avatar
Spencer Oliver committed
305
		MIPS32_BEQ(0,10,8),									/* beq 0, $10, end */
ntfreak's avatar
ntfreak committed
306
		MIPS32_NOP,
307

Spencer Oliver's avatar
Spencer Oliver committed
308
309
		MIPS32_LW(8,0,9),									/* lw $8,0($9), Load $8 with the word @mem[$9] */
		MIPS32_SW(8,0,11),									/* sw $8,0($11) */
310

Spencer Oliver's avatar
Spencer Oliver committed
311
312
313
		MIPS32_ADDI(10,10,NEG16(1)),						/* $10-- */
		MIPS32_ADDI(9,9,4),									/* $1 += 4 */
		MIPS32_ADDI(11,11,4),								/* $11 += 4 */
314

Spencer Oliver's avatar
Spencer Oliver committed
315
		MIPS32_B(NEG16(8)),									/* b loop */
ntfreak's avatar
ntfreak committed
316
317
		MIPS32_NOP,
															/* end: */
Spencer Oliver's avatar
Spencer Oliver committed
318
319
320
321
		MIPS32_LW(11,0,15),									/* lw $11,($15) */
		MIPS32_LW(10,0,15),									/* lw $10,($15) */
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
322
		MIPS32_B(NEG16(27)),								/* b start */
ntfreak's avatar
ntfreak committed
323
324
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
	};
325

326
	int retval = ERROR_OK;
ntfreak's avatar
ntfreak committed
327
328
	int blocksize;
	int bytesread;
329
	uint32_t param_in[2];
330

ntfreak's avatar
ntfreak committed
331
	bytesread = 0;
332

ntfreak's avatar
ntfreak committed
333
	while (count > 0)
334
	{
ntfreak's avatar
ntfreak committed
335
336
337
		blocksize = count;
		if (count > 0x400)
			blocksize = 0x400;
338

ntfreak's avatar
ntfreak committed
339
340
		param_in[0] = addr;
		param_in[1] = blocksize;
341

Zachary T Welch's avatar
Zachary T Welch committed
342
343
		if ((retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
			ARRAY_SIZE(param_in), param_in, blocksize, &buf[bytesread], 1)) != ERROR_OK)
oharboe's avatar
oharboe committed
344
		{
ntfreak's avatar
ntfreak committed
345
			return retval;
oharboe's avatar
oharboe committed
346
		}
347

ntfreak's avatar
ntfreak committed
348
349
350
351
352
353
354
355
		count -= blocksize;
		addr += blocksize;
		bytesread += blocksize;
	}

	return retval;
}

356
int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
357
{
358
	static const uint32_t code[] = {
359
360
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
361
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
362
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
363
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
364

Spencer Oliver's avatar
Spencer Oliver committed
365
		MIPS32_LW(8,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN),15), /* load R8 @ param_in[0] = address */
366

Spencer Oliver's avatar
Spencer Oliver committed
367
		MIPS32_LW(8,0,8),									/* lw $8,0($8), Load $8 with the word @mem[$8] */
Spencer Oliver's avatar
Spencer Oliver committed
368
		MIPS32_SW(8,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_OUT),15), /* store R8 @ param_out[0] */
369

Spencer Oliver's avatar
Spencer Oliver committed
370
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
371
372
		MIPS32_B(NEG16(9)),									/* b start */
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
373
374
375
	};

	int retval = ERROR_OK;
376
	uint32_t param_in[1];
377
378
379

	param_in[0] = addr;

Zachary T Welch's avatar
Zachary T Welch committed
380
	if ((retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
Spencer Oliver's avatar
Spencer Oliver committed
381
		ARRAY_SIZE(param_in), param_in, 1, buf, 1)) != ERROR_OK)
382
383
384
385
386
387
388
	{
		return retval;
	}

	return retval;
}

389
int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
ntfreak's avatar
ntfreak committed
390
{
391
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
392
393
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
394
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
395
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
396
397
398
399
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
		MIPS32_SW(10,0,15),									/* sw $10,($15) */
		MIPS32_SW(11,0,15),									/* sw $11,($15) */
400

ntfreak's avatar
ntfreak committed
401
402
		MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)),		/* $8 = MIPS32_PRACC_PARAM_IN */
		MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
zwelch's avatar
zwelch committed
403
		MIPS32_LW(9,0,8),									/* $9 = mem[$8]; read addr */
zwelch's avatar
zwelch committed
404
		MIPS32_LW(10,4,8),									/* $10 = mem[$8 + 4]; read count */
zwelch's avatar
zwelch committed
405
		MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)),		/* $11 = MIPS32_PRACC_PARAM_OUT */
ntfreak's avatar
ntfreak committed
406
407
		MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
															/* loop: */
Spencer Oliver's avatar
Spencer Oliver committed
408
		MIPS32_BEQ(0,10,8),									/* beq 0, $10, end */
ntfreak's avatar
ntfreak committed
409
		MIPS32_NOP,
410

Spencer Oliver's avatar
Spencer Oliver committed
411
412
		MIPS32_LHU(8,0,9),									/* lw $8,0($9), Load $8 with the halfword @mem[$9] */
		MIPS32_SW(8,0,11),									/* sw $8,0($11) */
413

Spencer Oliver's avatar
Spencer Oliver committed
414
415
416
		MIPS32_ADDI(10,10,NEG16(1)),						/* $10-- */
		MIPS32_ADDI(9,9,2),									/* $9 += 2 */
		MIPS32_ADDI(11,11,4),								/* $11 += 4 */
Spencer Oliver's avatar
Spencer Oliver committed
417
		MIPS32_B(NEG16(8)),									/* b loop */
ntfreak's avatar
ntfreak committed
418
		MIPS32_NOP,
Spencer Oliver's avatar
Spencer Oliver committed
419
															/* end: */
Spencer Oliver's avatar
Spencer Oliver committed
420
421
422
423
		MIPS32_LW(11,0,15),									/* lw $11,($15) */
		MIPS32_LW(10,0,15),									/* lw $10,($15) */
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
424
425
		MIPS32_B(NEG16(27)),								/* b start */
		MIPS32_MFC0(15,30,0),								/* move COP0 DeSave to $15 */
ntfreak's avatar
ntfreak committed
426
427
	};

Spencer Oliver's avatar
Spencer Oliver committed
428
	/* TODO remove array */
429
	uint32_t *param_out = malloc(count * sizeof(uint32_t));
ntfreak's avatar
ntfreak committed
430
	int i;
431

ntfreak's avatar
ntfreak committed
432
433
434
//	int retval;
	int blocksize;
	int bytesread;
435
	uint32_t param_in[2];
436

ntfreak's avatar
ntfreak committed
437
	bytesread = 0;
438

ntfreak's avatar
ntfreak committed
439
	//while (count > 0)
440
	{
ntfreak's avatar
ntfreak committed
441
442
443
		blocksize = count;
		if (count > 0x400)
			blocksize = 0x400;
444

ntfreak's avatar
ntfreak committed
445
446
		param_in[0] = addr;
		param_in[1] = blocksize;
447

Zachary T Welch's avatar
Zachary T Welch committed
448
449
		mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
			ARRAY_SIZE(param_in), param_in, count, param_out, 1);
450

ntfreak's avatar
ntfreak committed
451
452
453
454
//		count -= blocksize;
//		addr += blocksize;
//		bytesread += blocksize;
	}
455

ntfreak's avatar
ntfreak committed
456
457
458
459
	for (i = 0; i < count; i++)
	{
		buf[i] = param_out[i];
	}
460

461
462
	free(param_out);

ntfreak's avatar
ntfreak committed
463
464
465
	return ERROR_OK;
}

466
int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
ntfreak's avatar
ntfreak committed
467
{
468
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
469
470
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
471
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
472
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
473
474
475
476
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
		MIPS32_SW(10,0,15),									/* sw $10,($15) */
		MIPS32_SW(11,0,15),									/* sw $11,($15) */
477

Spencer Oliver's avatar
Spencer Oliver committed
478
		MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)),		/* $8 = MIPS32_PRACC_PARAM_IN */
ntfreak's avatar
ntfreak committed
479
		MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
Spencer Oliver's avatar
Spencer Oliver committed
480
481
482
		MIPS32_LW(9,0,8),									/* $9 = mem[$8]; read addr */
		MIPS32_LW(10,4,8),									/* $10 = mem[$8 + 4]; read count */
		MIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)),		/* $11 = MIPS32_PRACC_PARAM_OUT */
ntfreak's avatar
ntfreak committed
483
484
		MIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),
															/* loop: */
Spencer Oliver's avatar
Spencer Oliver committed
485
		MIPS32_BEQ(0,10,8),									/* beq 0, $10, end */
ntfreak's avatar
ntfreak committed
486
		MIPS32_NOP,
487

Spencer Oliver's avatar
Spencer Oliver committed
488
489
		MIPS32_LBU(8,0,9),									/* lw $8,0($9), Load t4 with the byte @mem[t1] */
		MIPS32_SW(8,0,11),									/* sw $8,0($11) */
490

Spencer Oliver's avatar
Spencer Oliver committed
491
492
493
		MIPS32_ADDI(10,10,NEG16(1)),						/* $10-- */
		MIPS32_ADDI(9,9,1),									/* $9 += 1 */
		MIPS32_ADDI(11,11,4),								/* $11 += 4 */
Spencer Oliver's avatar
Spencer Oliver committed
494
		MIPS32_B(NEG16(8)),									/* b loop */
ntfreak's avatar
ntfreak committed
495
496
		MIPS32_NOP,
															/* end: */
Spencer Oliver's avatar
Spencer Oliver committed
497
498
499
500
		MIPS32_LW(11,0,15),									/* lw $11,($15) */
		MIPS32_LW(10,0,15),									/* lw $10,($15) */
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
501
		MIPS32_B(NEG16(27)),								/* b start */
ntfreak's avatar
ntfreak committed
502
503
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
	};
504

Spencer Oliver's avatar
Spencer Oliver committed
505
	/* TODO remove array */
506
	uint32_t *param_out = malloc(count * sizeof(uint32_t));
ntfreak's avatar
ntfreak committed
507
	int i;
508

ntfreak's avatar
ntfreak committed
509
510
511
//	int retval;
	int blocksize;
	int bytesread;
512
	uint32_t param_in[2];
513

ntfreak's avatar
ntfreak committed
514
	bytesread = 0;
515

ntfreak's avatar
ntfreak committed
516
//	while (count > 0)
517
	{
ntfreak's avatar
ntfreak committed
518
519
520
		blocksize = count;
		if (count > 0x400)
			blocksize = 0x400;
521

ntfreak's avatar
ntfreak committed
522
523
		param_in[0] = addr;
		param_in[1] = blocksize;
524

Zachary T Welch's avatar
Zachary T Welch committed
525
526
		mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
			ARRAY_SIZE(param_in), param_in, count, param_out, 1);
527

ntfreak's avatar
ntfreak committed
528
529
530
531
//		count -= blocksize;
//		addr += blocksize;
//		bytesread += blocksize;
	}
532

ntfreak's avatar
ntfreak committed
533
534
535
536
537
	for (i = 0; i < count; i++)
	{
		buf[i] = param_out[i];
	}

538
539
	free(param_out);

ntfreak's avatar
ntfreak committed
540
541
542
	return ERROR_OK;
}

543
int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
ntfreak's avatar
ntfreak committed
544
545
546
547
{
	switch (size)
	{
		case 1:
548
			return mips32_pracc_write_mem8(ejtag_info, addr, count, (uint8_t*)buf);
ntfreak's avatar
ntfreak committed
549
		case 2:
zwelch's avatar
zwelch committed
550
			return mips32_pracc_write_mem16(ejtag_info, addr, count,(uint16_t*)buf);
ntfreak's avatar
ntfreak committed
551
		case 4:
zwelch's avatar
zwelch committed
552
			if (count == 1)
553
				return mips32_pracc_write_u32(ejtag_info, addr, (uint32_t*)buf);
554
			else
555
				return mips32_pracc_write_mem32(ejtag_info, addr, count, (uint32_t*)buf);
ntfreak's avatar
ntfreak committed
556
	}
557

ntfreak's avatar
ntfreak committed
558
559
560
	return ERROR_OK;
}

561
int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
ntfreak's avatar
ntfreak committed
562
{
563
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
564
565
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
566
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
567
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
568
569
570
571
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
		MIPS32_SW(10,0,15),									/* sw $10,($15) */
		MIPS32_SW(11,0,15),									/* sw $11,($15) */
572

Spencer Oliver's avatar
Spencer Oliver committed
573
		MIPS32_ADDI(8,15,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)),  /* $8= MIPS32_PRACC_PARAM_IN */
Spencer Oliver's avatar
Spencer Oliver committed
574
		MIPS32_LW(9,0,8),									/* Load write addr to $9 */
Spencer Oliver's avatar
Spencer Oliver committed
575
576
		MIPS32_LW(10,4,8),									/* Load write count to $10 */
		MIPS32_ADDI(8,8,8),									/* $8 += 8 beginning of data */
577

Spencer Oliver's avatar
Spencer Oliver committed
578
															/* loop: */
Spencer Oliver's avatar
Spencer Oliver committed
579
580
		MIPS32_LW(11,0,8),									/* lw $11,0($8), Load $11 with the word @mem[$8] */
		MIPS32_SW(11,0,9),									/* sw $11,0($9) */
581

Spencer Oliver's avatar
Spencer Oliver committed
582
		MIPS32_ADDI(9,9,4),									/* $9 += 4 */
Spencer Oliver's avatar
Spencer Oliver committed
583
584
585
		MIPS32_BNE(10,9,NEG16(4)),							/* bne $10, $9, loop */
		MIPS32_ADDI(8,8,4),									/* $8 += 4 */

ntfreak's avatar
ntfreak committed
586
															/* end: */
Spencer Oliver's avatar
Spencer Oliver committed
587
588
589
590
		MIPS32_LW(11,0,15),									/* lw $11,($15) */
		MIPS32_LW(10,0,15),									/* lw $10,($15) */
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
591
		MIPS32_B(NEG16(21)),								/* b start */
ntfreak's avatar
ntfreak committed
592
593
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
	};
594

ntfreak's avatar
ntfreak committed
595
	/* TODO remove array */
596
	uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t));
ntfreak's avatar
ntfreak committed
597
	param_in[0] = addr;
Spencer Oliver's avatar
Spencer Oliver committed
598
	param_in[1] = addr + (count * sizeof(uint32_t));	/* last address */
599

600
	memcpy(&param_in[2], buf, count * sizeof(uint32_t));
601

Zachary T Welch's avatar
Zachary T Welch committed
602
	mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
603
		count + 2, param_in, 0, NULL, 1);
ntfreak's avatar
ntfreak committed
604

605
606
	free(param_in);

ntfreak's avatar
ntfreak committed
607
608
609
	return ERROR_OK;
}

610
int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
611
{
612
	static const uint32_t code[] = {
613
614
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
615
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
616
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
617
618
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
619

Spencer Oliver's avatar
Spencer Oliver committed
620
621
		MIPS32_LW(8,NEG16((MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN)-4), 15),	/* load R8 @ param_in[1] = data */
		MIPS32_LW(9,NEG16(MIPS32_PRACC_STACK-MIPS32_PRACC_PARAM_IN), 15),		/* load R9 @ param_in[0] = address */
622

Spencer Oliver's avatar
Spencer Oliver committed
623
		MIPS32_SW(8,0,9),									/* sw $8,0($9) */
624

Spencer Oliver's avatar
Spencer Oliver committed
625
626
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
627
		MIPS32_B(NEG16(11)),								/* b start */
Spencer Oliver's avatar
Spencer Oliver committed
628
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
629
630
631
	};

	/* TODO remove array */
zwelch's avatar
zwelch committed
632
	uint32_t param_in[1 + 1];
633
634
635
	param_in[0] = addr;
	param_in[1] = *buf;

Zachary T Welch's avatar
Zachary T Welch committed
636
	mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
Spencer Oliver's avatar
Spencer Oliver committed
637
		ARRAY_SIZE(param_in), param_in, 0, NULL, 1);
638
639
640
641

	return ERROR_OK;
}

642
int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
ntfreak's avatar
ntfreak committed
643
{
644
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
645
646
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
647
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
648
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
649
650
651
652
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
		MIPS32_SW(10,0,15),									/* sw $10,($15) */
		MIPS32_SW(11,0,15),									/* sw $11,($15) */
653

Spencer Oliver's avatar
Spencer Oliver committed
654
		MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)),		/* $8 = MIPS32_PRACC_PARAM_IN */
ntfreak's avatar
ntfreak committed
655
		MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
Spencer Oliver's avatar
Spencer Oliver committed
656
657
658
		MIPS32_LW(9,0,8),									/* Load write addr to $9 */
		MIPS32_LW(10,4,8),									/* Load write count to $10 */
		MIPS32_ADDI(8,8,8),									/* $8 += 8 */
ntfreak's avatar
ntfreak committed
659
															/* loop: */
Spencer Oliver's avatar
Spencer Oliver committed
660
		MIPS32_BEQ(0,10,8),									/* beq $0, $10, end */
ntfreak's avatar
ntfreak committed
661
		MIPS32_NOP,
662

Spencer Oliver's avatar
Spencer Oliver committed
663
664
		MIPS32_LW(11,0,8),									/* lw $11,0($8), Load $11 with the word @mem[$8] */
		MIPS32_SH(11,0,9),									/* sh $11,0($9) */
665

Spencer Oliver's avatar
Spencer Oliver committed
666
667
668
		MIPS32_ADDI(10,10,NEG16(1)),						/* $10-- */
		MIPS32_ADDI(9,9,2),									/* $9 += 2 */
		MIPS32_ADDI(8,8,4),									/* $8 += 4 */
669

Spencer Oliver's avatar
Spencer Oliver committed
670
		MIPS32_B(NEG16(8)),									/* b loop */
ntfreak's avatar
ntfreak committed
671
672
		MIPS32_NOP,
															/* end: */
Spencer Oliver's avatar
Spencer Oliver committed
673
674
675
676
		MIPS32_LW(11,0,15),									/* lw $11,($15) */
		MIPS32_LW(10,0,15),									/* lw $10,($15) */
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
677
		MIPS32_B(NEG16(26)),								/* b start */
ntfreak's avatar
ntfreak committed
678
679
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
	};
680

ntfreak's avatar
ntfreak committed
681
	/* TODO remove array */
682
	uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t));
ntfreak's avatar
ntfreak committed
683
684
685
	int i;
	param_in[0] = addr;
	param_in[1] = count;
686

ntfreak's avatar
ntfreak committed
687
688
	for (i = 0; i < count; i++)
	{
zwelch's avatar
zwelch committed
689
		param_in[i + 2] = buf[i];
ntfreak's avatar
ntfreak committed
690
	}
691

Zachary T Welch's avatar
Zachary T Welch committed
692
	mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
693
		count + 2, param_in, 0, NULL, 1);
ntfreak's avatar
ntfreak committed
694

695
696
	free(param_in);

ntfreak's avatar
ntfreak committed
697
698
699
	return ERROR_OK;
}

700
int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
ntfreak's avatar
ntfreak committed
701
{
702
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
703
704
															/* start: */
		MIPS32_MTC0(15,31,0),								/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
705
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),			/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
706
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
707
708
709
710
		MIPS32_SW(8,0,15),									/* sw $8,($15) */
		MIPS32_SW(9,0,15),									/* sw $9,($15) */
		MIPS32_SW(10,0,15),									/* sw $10,($15) */
		MIPS32_SW(11,0,15),									/* sw $11,($15) */
711

Spencer Oliver's avatar
Spencer Oliver committed
712
		MIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)),		/* $8 = MIPS32_PRACC_PARAM_IN */
ntfreak's avatar
ntfreak committed
713
		MIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),
Spencer Oliver's avatar
Spencer Oliver committed
714
715
716
		MIPS32_LW(9,0,8),									/* Load write addr to $9 */
		MIPS32_LW(10,4,8),									/* Load write count to $10 */
		MIPS32_ADDI(8,8,8),									/* $8 += 8 */
ntfreak's avatar
ntfreak committed
717
															/* loop: */
Spencer Oliver's avatar
Spencer Oliver committed
718
		MIPS32_BEQ(0,10,8),									/* beq $0, $10, end */
ntfreak's avatar
ntfreak committed
719
		MIPS32_NOP,
720

Spencer Oliver's avatar
Spencer Oliver committed
721
722
		MIPS32_LW(11,0,8),									/* lw $11,0($8), Load $11 with the word @mem[$8] */
		MIPS32_SB(11,0,9),									/* sb $11,0($9) */
723

Spencer Oliver's avatar
Spencer Oliver committed
724
725
726
		MIPS32_ADDI(10,10,NEG16(1)),						/* $10-- */
		MIPS32_ADDI(9,9,1),									/* $9 += 1 */
		MIPS32_ADDI(8,8,4),									/* $8 += 4 */
727

Spencer Oliver's avatar
Spencer Oliver committed
728
		MIPS32_B(NEG16(8)),									/* b loop */
ntfreak's avatar
ntfreak committed
729
730
		MIPS32_NOP,
															/* end: */
Spencer Oliver's avatar
Spencer Oliver committed
731
732
733
734
		MIPS32_LW(11,0,15),									/* lw $11,($15) */
		MIPS32_LW(10,0,15),									/* lw $10,($15) */
		MIPS32_LW(9,0,15),									/* lw $9,($15) */
		MIPS32_LW(8,0,15),									/* lw $8,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
735
		MIPS32_B(NEG16(26)),								/* b start */
ntfreak's avatar
ntfreak committed
736
737
		MIPS32_MFC0(15,31,0),								/* move COP0 DeSave to $15 */
	};
738

ntfreak's avatar
ntfreak committed
739
	/* TODO remove array */
740
	uint32_t *param_in = malloc((count + 2) * sizeof(uint32_t));
ntfreak's avatar
ntfreak committed
741
742
743
744
	int retval;
	int i;
	param_in[0] = addr;
	param_in[1] = count;
745

ntfreak's avatar
ntfreak committed
746
747
	for (i = 0; i < count; i++)
	{
zwelch's avatar
zwelch committed
748
		param_in[i + 2] = buf[i];
ntfreak's avatar
ntfreak committed
749
	}
750

Zachary T Welch's avatar
Zachary T Welch committed
751
	retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
Spencer Oliver's avatar
Spencer Oliver committed
752
		count + 2, param_in, 0, NULL, 1);
ntfreak's avatar
ntfreak committed
753

754
755
	free(param_in);

ntfreak's avatar
ntfreak committed
756
757
758
	return retval;
}

759
int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
ntfreak's avatar
ntfreak committed
760
{
761
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
762
														/* start: */
Spencer Oliver's avatar
Spencer Oliver committed
763
		MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_IN)),	/* $2 = MIPS32_PRACC_PARAM_IN */
ntfreak's avatar
ntfreak committed
764
		MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_IN)),
Spencer Oliver's avatar
Spencer Oliver committed
765
766
		MIPS32_LW(1,1*4,2),								/* lw $1,1*4($2) */
		MIPS32_LW(15,15*4,2),							/* lw $15,15*4($2) */
767
		MIPS32_MTC0(15,31,0),							/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
768
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),		/* $15 = MIPS32_PRACC_STACK */
769
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
770
771
		MIPS32_SW(1,0,15),								/* sw $1,($15) */
		MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_IN)),	/* $1 = MIPS32_PRACC_PARAM_IN */
ntfreak's avatar
ntfreak committed
772
		MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_IN)),
Spencer Oliver's avatar
Spencer Oliver committed
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
		MIPS32_LW(3,3*4,1),								/* lw $3,3*4($1) */
		MIPS32_LW(4,4*4,1),								/* lw $4,4*4($1) */
		MIPS32_LW(5,5*4,1),								/* lw $5,5*4($1) */
		MIPS32_LW(6,6*4,1),								/* lw $6,6*4($1) */
		MIPS32_LW(7,7*4,1),								/* lw $7,7*4($1) */
		MIPS32_LW(8,8*4,1),								/* lw $8,8*4($1) */
		MIPS32_LW(9,9*4,1),								/* lw $9,9*4($1) */
		MIPS32_LW(10,10*4,1),							/* lw $10,10*4($1) */
		MIPS32_LW(11,11*4,1),							/* lw $11,11*4($1) */
		MIPS32_LW(12,12*4,1),							/* lw $12,12*4($1) */
		MIPS32_LW(13,13*4,1),							/* lw $13,13*4($1) */
		MIPS32_LW(14,14*4,1),							/* lw $14,14*4($1) */
		MIPS32_LW(16,16*4,1),							/* lw $16,16*4($1) */
		MIPS32_LW(17,17*4,1),							/* lw $17,17*4($1) */
		MIPS32_LW(18,18*4,1),							/* lw $18,18*4($1) */
		MIPS32_LW(19,19*4,1),							/* lw $19,19*4($1) */
		MIPS32_LW(20,20*4,1),							/* lw $20,20*4($1) */
		MIPS32_LW(21,21*4,1),							/* lw $21,21*4($1) */
		MIPS32_LW(22,22*4,1),							/* lw $22,22*4($1) */
		MIPS32_LW(23,23*4,1),							/* lw $23,23*4($1) */
		MIPS32_LW(24,24*4,1),							/* lw $24,24*4($1) */
		MIPS32_LW(25,25*4,1),							/* lw $25,25*4($1) */
		MIPS32_LW(26,26*4,1),							/* lw $26,26*4($1) */
		MIPS32_LW(27,27*4,1),							/* lw $27,27*4($1) */
		MIPS32_LW(28,28*4,1),							/* lw $28,28*4($1) */
		MIPS32_LW(29,29*4,1),							/* lw $29,29*4($1) */
		MIPS32_LW(30,30*4,1),							/* lw $30,30*4($1) */
		MIPS32_LW(31,31*4,1),							/* lw $31,31*4($1) */

		MIPS32_LW(2,32*4,1),							/* lw $2,32*4($1) */
803
		MIPS32_MTC0(2,12,0),							/* move $2 to status */
Spencer Oliver's avatar
Spencer Oliver committed
804
		MIPS32_LW(2,33*4,1),							/* lw $2,33*4($1) */
805
		MIPS32_MTLO(2),									/* move $2 to lo */
Spencer Oliver's avatar
Spencer Oliver committed
806
		MIPS32_LW(2,34*4,1),							/* lw $2,34*4($1) */
807
		MIPS32_MTHI(2),									/* move $2 to hi */
Spencer Oliver's avatar
Spencer Oliver committed
808
		MIPS32_LW(2,35*4,1),							/* lw $2,35*4($1) */
809
		MIPS32_MTC0(2,8,0),								/* move $2 to badvaddr */
Spencer Oliver's avatar
Spencer Oliver committed
810
		MIPS32_LW(2,36*4,1),							/* lw $2,36*4($1) */
811
		MIPS32_MTC0(2,13,0),							/* move $2 to cause*/
Spencer Oliver's avatar
Spencer Oliver committed
812
		MIPS32_LW(2,37*4,1),							/* lw $2,37*4($1) */
813
		MIPS32_MTC0(2,24,0),							/* move $2 to depc (pc) */
814

Spencer Oliver's avatar
Spencer Oliver committed
815
816
		MIPS32_LW(2,2*4,1),								/* lw $2,2*4($1) */
		MIPS32_LW(1,0,15),								/* lw $1,($15) */
Spencer Oliver's avatar
Spencer Oliver committed
817
		MIPS32_B(NEG16(53)),							/* b start */
818
		MIPS32_MFC0(15,31,0),							/* move COP0 DeSave to $15 */
ntfreak's avatar
ntfreak committed
819
	};
820

ntfreak's avatar
ntfreak committed
821
	int retval;
822

Zachary T Welch's avatar
Zachary T Welch committed
823
	retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
Spencer Oliver's avatar
Spencer Oliver committed
824
			MIPS32NUMCOREREGS, regs, 0, NULL, 1);
825

ntfreak's avatar
ntfreak committed
826
827
828
	return retval;
}

829
int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
ntfreak's avatar
ntfreak committed
830
{
831
	static const uint32_t code[] = {
ntfreak's avatar
ntfreak committed
832
833
														/* start: */
		MIPS32_MTC0(2,31,0),							/* move $2 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
834
		MIPS32_LUI(2,UPPER16(MIPS32_PRACC_PARAM_OUT)),	/* $2 = MIPS32_PRACC_PARAM_OUT */
ntfreak's avatar
ntfreak committed
835
836
		MIPS32_ORI(2,2,LOWER16(MIPS32_PRACC_PARAM_OUT)),
		MIPS32_SW(0,0*4,2),								/* sw $0,0*4($2) */
Spencer Oliver's avatar
Spencer Oliver committed
837
838
		MIPS32_SW(1,1*4,2),								/* sw $1,1*4($2) */
		MIPS32_SW(15,15*4,2),							/* sw $15,15*4($2) */
ntfreak's avatar
ntfreak committed
839
840
		MIPS32_MFC0(2,31,0),							/* move COP0 DeSave to $2 */
		MIPS32_MTC0(15,31,0),							/* move $15 to COP0 DeSave */
Spencer Oliver's avatar
Spencer Oliver committed
841
		MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),		/* $15 = MIPS32_PRACC_STACK */
ntfreak's avatar
ntfreak committed
842
		MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),
Spencer Oliver's avatar
Spencer Oliver committed
843
844
845
		MIPS32_SW(1,0,15),								/* sw $1,($15) */
		MIPS32_SW(2,0,15),								/* sw $2,($15) */
		MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)),	/* $1 = MIPS32_PRACC_PARAM_OUT */
ntfreak's avatar
ntfreak committed
846
		MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)),
Spencer Oliver's avatar
Spencer Oliver committed
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
		MIPS32_SW(2,2*4,1),								/* sw $2,2*4($1) */
		MIPS32_SW(3,3*4,1),								/* sw $3,3*4($1) */
		MIPS32_SW(4,4*4,1),								/* sw $4,4*4($1) */
		MIPS32_SW(5,5*4,1),								/* sw $5,5*4($1) */
		MIPS32_SW(6,6*4,1),								/* sw $6,6*4($1) */
		MIPS32_SW(7,7*4,1),								/* sw $7,7*4($1) */
		MIPS32_SW(8,8*4,1),								/* sw $8,8*4($1) */
		MIPS32_SW(9,9*4,1),								/* sw $9,9*4($1) */
		MIPS32_SW(10,10*4,1),							/* sw $10,10*4($1) */
		MIPS32_SW(11,11*4,1),							/* sw $11,11*4($1) */
		MIPS32_SW(12,12*4,1),							/* sw $12,12*4($1) */
		MIPS32_SW(13,13*4,1),							/* sw $13,13*4($1) */
		MIPS32_SW(14,14*4,1),							/* sw $14,14*4($1) */
		MIPS32_SW(16,16*4,1),							/* sw $16,16*4($1) */
		MIPS32_SW(17,17*4,1),							/* sw $17,17*4($1) */
		MIPS32_SW(18,18*4,1),							/* sw $18,18*4($1) */
		MIPS32_SW(19,19*4,1),							/* sw $19,19*4($1) */
		MIPS32_SW(20,20*4,1),							/* sw $20,20*4($1) */
		MIPS32_SW(21,21*4,1),							/* sw $21,21*4($1) */
		MIPS32_SW(22,22*4,1),							/* sw $22,22*4($1) */
		MIPS32_SW(23,23*4,1),							/* sw $23,23*4($1) */
		MIPS32_SW(24,24*4,1),							/* sw $24,24*4($1) */
		MIPS32_SW(25,25*4,1),							/* sw $25,25*4($1) */
		MIPS32_SW(26,26*4,1),							/* sw $26,26*4($1) */
		MIPS32_SW(27,27*4,1),							/* sw $27,27*4($1) */
		MIPS32_SW(28,28*4,1),							/* sw $28,28*4($1) */
		MIPS32_SW(29,29*4,1),							/* sw $29,29*4($1) */
		MIPS32_SW(30,30*4,1),							/* sw $30,30*4($1) */
		MIPS32_SW(31,31*4,1),							/* sw $31,31*4($1) */
876

ntfreak's avatar
ntfreak committed
877
		MIPS32_MFC0(2,12,0),							/* move status to $2 */