arm920t.c 43.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/***************************************************************************
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
 *   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.             *
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "arm920t.h"
oharboe's avatar
oharboe committed
25
#include "time_support.h"
26
#include "target_type.h"
27
28


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
 * For information about the ARM920T, see ARM DDI 0151C especially
 * Chapter 9 about debug support, which shows how to manipulate each
 * of the different scan chains:
 *
 *   0 ... ARM920 signals, e.g. to rest of SOC (unused here)
 *   1 ... debugging; watchpoint and breakpoint status, etc; also
 *	MMU and cache access in conjunction with scan chain 15
 *   2 ... EmbeddedICE
 *   3 ... external boundary scan (SoC-specific, unused here)
 *   4 ... access to cache tag RAM
 *   6 ... ETM9
 *   15 ... access coprocessor 15, "physical" or "interpreted" modes
 *	"interpreted" works with a few actual MRC/MCR instructions
 *	"physical" provides register-like behaviors.
 *
 * The ARM922T is similar, but with smaller caches (8K each, vs 16K).
 */

48
49
50
51
52
53
#if 0
#define _DEBUG_INSTRUCTION_EXECUTION_
#endif

#define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))

54
55
static int arm920t_read_cp15_physical(target_t *target,
		int reg_addr, uint32_t *value)
56
{
57
	struct arm920t_common *arm920t = target_to_arm920(target);
58
	struct arm_jtag *jtag_info;
59
	struct scan_field fields[4];
60
61
62
	uint8_t access_type_buf = 1;
	uint8_t reg_addr_buf = reg_addr & 0x3f;
	uint8_t nr_w_buf = 0;
63

64
65
	jtag_info = &arm920t->arm9tdmi_common.arm7_9_common.jtag_info;

66
	jtag_set_end_state(TAP_IDLE);
67
68
69
	arm_jtag_scann(jtag_info, 0xf);
	arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);

70
	fields[0].tap = jtag_info->tap;
71
72
73
74
	fields[0].num_bits = 1;
	fields[0].out_value = &access_type_buf;
	fields[0].in_value = NULL;

75
	fields[1].tap = jtag_info->tap;
76
77
78
79
	fields[1].num_bits = 32;
	fields[1].out_value = NULL;
	fields[1].in_value = NULL;

80
	fields[2].tap = jtag_info->tap;
81
82
83
84
	fields[2].num_bits = 6;
	fields[2].out_value = &reg_addr_buf;
	fields[2].in_value = NULL;

85
	fields[3].tap = jtag_info->tap;
86
87
88
	fields[3].num_bits = 1;
	fields[3].out_value = &nr_w_buf;
	fields[3].in_value = NULL;
89

90
	jtag_add_dr_scan(4, fields, jtag_get_end_state());
91

92
	fields[1].in_value = (uint8_t *)value;
93

94
	jtag_add_dr_scan(4, fields, jtag_get_end_state());
95

96
	jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
oharboe's avatar
oharboe committed
97

98
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
99
	jtag_execute_queue();
100
	LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
101
102
103
104
105
#endif

	return ERROR_OK;
}

106
107
static int arm920t_write_cp15_physical(target_t *target,
		int reg_addr, uint32_t value)
108
{
109
	struct arm920t_common *arm920t = target_to_arm920(target);
110
	struct arm_jtag *jtag_info;
111
	struct scan_field fields[4];
112
113
114
115
	uint8_t access_type_buf = 1;
	uint8_t reg_addr_buf = reg_addr & 0x3f;
	uint8_t nr_w_buf = 1;
	uint8_t value_buf[4];
116

117
118
	jtag_info = &arm920t->arm9tdmi_common.arm7_9_common.jtag_info;

119
	buf_set_u32(value_buf, 0, 32, value);
120

121
	jtag_set_end_state(TAP_IDLE);
122
123
124
	arm_jtag_scann(jtag_info, 0xf);
	arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);

125
	fields[0].tap = jtag_info->tap;
126
127
128
	fields[0].num_bits = 1;
	fields[0].out_value = &access_type_buf;
	fields[0].in_value = NULL;
oharboe's avatar
oharboe committed
129

130
	fields[1].tap = jtag_info->tap;
131
132
133
	fields[1].num_bits = 32;
	fields[1].out_value = value_buf;
	fields[1].in_value = NULL;
oharboe's avatar
oharboe committed
134

135
	fields[2].tap = jtag_info->tap;
136
137
138
	fields[2].num_bits = 6;
	fields[2].out_value = &reg_addr_buf;
	fields[2].in_value = NULL;
oharboe's avatar
oharboe committed
139

140
	fields[3].tap = jtag_info->tap;
141
142
143
	fields[3].num_bits = 1;
	fields[3].out_value = &nr_w_buf;
	fields[3].in_value = NULL;
oharboe's avatar
oharboe committed
144

145
	jtag_add_dr_scan(4, fields, jtag_get_end_state());
146
147

#ifdef _DEBUG_INSTRUCTION_EXECUTION_
148
	LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
149
150
151
152
153
#endif

	return ERROR_OK;
}

154
155
static int arm920t_execute_cp15(target_t *target, uint32_t cp15_opcode,
		uint32_t arm_opcode)
156
{
157
	int retval;
158
	struct arm920t_common *arm920t = target_to_arm920(target);
159
	struct arm_jtag *jtag_info;
160
	struct scan_field fields[4];
161
162
163
164
	uint8_t access_type_buf = 0;		/* interpreted access */
	uint8_t reg_addr_buf = 0x0;
	uint8_t nr_w_buf = 0;
	uint8_t cp15_opcode_buf[4];
165

166
167
	jtag_info = &arm920t->arm9tdmi_common.arm7_9_common.jtag_info;

168
	jtag_set_end_state(TAP_IDLE);
169
170
	arm_jtag_scann(jtag_info, 0xf);
	arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
171

172
173
	buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);

174
	fields[0].tap = jtag_info->tap;
175
176
177
	fields[0].num_bits = 1;
	fields[0].out_value = &access_type_buf;
	fields[0].in_value = NULL;
oharboe's avatar
oharboe committed
178

179
	fields[1].tap = jtag_info->tap;
180
181
182
	fields[1].num_bits = 32;
	fields[1].out_value = cp15_opcode_buf;
	fields[1].in_value = NULL;
oharboe's avatar
oharboe committed
183

184
	fields[2].tap = jtag_info->tap;
185
186
187
	fields[2].num_bits = 6;
	fields[2].out_value = &reg_addr_buf;
	fields[2].in_value = NULL;
oharboe's avatar
oharboe committed
188

189
	fields[3].tap = jtag_info->tap;
190
191
192
	fields[3].num_bits = 1;
	fields[3].out_value = &nr_w_buf;
	fields[3].in_value = NULL;
oharboe's avatar
oharboe committed
193

194
	jtag_add_dr_scan(4, fields, jtag_get_end_state());
195
196
197

	arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
	arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
198
199
200
	retval = arm7_9_execute_sys_speed(target);
	if (retval != ERROR_OK)
		return retval;
201

202
	if ((retval = jtag_execute_queue()) != ERROR_OK)
203
	{
204
		LOG_ERROR("failed executing JTAG queue");
205
		return retval;
206
	}
207

208
209
210
	return ERROR_OK;
}

211
212
static int arm920t_read_cp15_interpreted(target_t *target,
		uint32_t cp15_opcode, uint32_t address, uint32_t *value)
213
{
214
	struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
215
216
217
	uint32_t* regs_p[1];
	uint32_t regs[2];
	uint32_t cp15c15 = 0x0;
218
219
220

	/* load address into R1 */
	regs[1] = address;
221
222
223
	arm9tdmi_write_core_regs(target, 0x2, regs);

	/* read-modify-write CP15 test state register
224
	* to enable interpreted access mode */
225
	arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
226
227
228
229
230
231
	jtag_execute_queue();
	cp15c15 |= 1;	/* set interpret mode */
	arm920t_write_cp15_physical(target, 0x1e, cp15c15);

	/* execute CP15 instruction and ARM load (reading from coprocessor) */
	arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
232

233
234
235
236
237
238
239
240
	/* disable interpreted access mode */
	cp15c15 &= ~1U;	/* clear interpret mode */
	arm920t_write_cp15_physical(target, 0x1e, cp15c15);

	/* retrieve value from R0 */
	regs_p[0] = value;
	arm9tdmi_read_core_regs(target, 0x1, regs_p);
	jtag_execute_queue();
241

242
#ifdef _DEBUG_INSTRUCTION_EXECUTION_
243
	LOG_DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", cp15_opcode, address, *value);
244
245
#endif

246
247
248
	if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
		return ERROR_FAIL;

249
250
251
252
253
254
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;

	return ERROR_OK;
}

255
256
257
static
int arm920t_write_cp15_interpreted(target_t *target,
		uint32_t cp15_opcode, uint32_t value, uint32_t address)
258
{
259
	uint32_t cp15c15 = 0x0;
260
	struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
261
	uint32_t regs[2];
262
263
264
265
266
267

	/* load value, address into R0, R1 */
	regs[0] = value;
	regs[1] = address;
	arm9tdmi_write_core_regs(target, 0x3, regs);

268
	/* read-modify-write CP15 test state register
269
270
271
272
273
274
275
276
277
278
279
280
281
282
	* to enable interpreted access mode */
	arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
	jtag_execute_queue();
	cp15c15 |= 1;	/* set interpret mode */
	arm920t_write_cp15_physical(target, 0x1e, cp15c15);

	/* execute CP15 instruction and ARM store (writing to coprocessor) */
	arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));

	/* disable interpreted access mode */
	cp15c15 &= ~1U;	/* set interpret mode */
	arm920t_write_cp15_physical(target, 0x1e, cp15c15);

#ifdef _DEBUG_INSTRUCTION_EXECUTION_
283
	LOG_DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x", cp15_opcode, value, address);
284
285
#endif

286
287
	if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
		return ERROR_FAIL;
288

289
290
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
291

292
293
294
	return ERROR_OK;
}

295
// EXPORTED to FA256
296
uint32_t arm920t_get_ttb(target_t *target)
297
298
{
	int retval;
299
	uint32_t ttb = 0x0;
300
301
302
303
304
305
306

	if ((retval = arm920t_read_cp15_interpreted(target, 0xeebf0f51, 0x0, &ttb)) != ERROR_OK)
		return retval;

	return ttb;
}

307
// EXPORTED to FA256
308
309
void arm920t_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
{
310
	uint32_t cp15_control;
311
312
313
314

	/* read cp15 control register */
	arm920t_read_cp15_physical(target, 0x2, &cp15_control);
	jtag_execute_queue();
315

316
317
	if (mmu)
		cp15_control &= ~0x1U;
318

319
320
	if (d_u_cache)
		cp15_control &= ~0x4U;
321

322
323
324
325
326
327
	if (i_cache)
		cp15_control &= ~0x1000U;

	arm920t_write_cp15_physical(target, 0x2, cp15_control);
}

328
// EXPORTED to FA256
329
330
void arm920t_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
{
331
	uint32_t cp15_control;
332
333
334
335

	/* read cp15 control register */
	arm920t_read_cp15_physical(target, 0x2, &cp15_control);
	jtag_execute_queue();
336

337
338
	if (mmu)
		cp15_control |= 0x1U;
339

340
341
	if (d_u_cache)
		cp15_control |= 0x4U;
342

343
344
	if (i_cache)
		cp15_control |= 0x1000U;
345

346
347
348
	arm920t_write_cp15_physical(target, 0x2, cp15_control);
}

349
// EXPORTED to FA256
350
351
void arm920t_post_debug_entry(target_t *target)
{
352
	uint32_t cp15c15;
353
	struct arm920t_common *arm920t = target_to_arm920(target);
354

355
356
357
	/* examine cp15 control reg */
	arm920t_read_cp15_physical(target, 0x2, &arm920t->cp15_control_reg);
	jtag_execute_queue();
duane's avatar
duane committed
358
	LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm920t->cp15_control_reg);
359
360
361

	if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
	{
362
		uint32_t cache_type_reg;
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
		/* identify caches */
		arm920t_read_cp15_physical(target, 0x1, &cache_type_reg);
		jtag_execute_queue();
		armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache);
	}

	arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
	arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
	arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;

	/* save i/d fault status and address register */
	arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
	arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
	arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
	arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
378

duane's avatar
duane committed
379
	LOG_DEBUG("D FSR: 0x%8.8" PRIx32 ", D FAR: 0x%8.8" PRIx32 ", I FSR: 0x%8.8" PRIx32 ", I FAR: 0x%8.8" PRIx32 "",
380
		arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
381
382
383

	if (arm920t->preserve_cache)
	{
384
		/* read-modify-write CP15 test state register
385
386
387
388
389
390
391
392
		 * to disable I/D-cache linefills */
		arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
		jtag_execute_queue();
		cp15c15 |= 0x600;
		arm920t_write_cp15_physical(target, 0x1e, cp15c15);
	}
}

393
// EXPORTED to FA256
394
395
void arm920t_pre_restore_context(target_t *target)
{
396
	uint32_t cp15c15;
397
	struct arm920t_common *arm920t = target_to_arm920(target);
398

399
400
401
402
403
	/* restore i/d fault status and address register */
	arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
	arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
	arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
	arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
404
405

	/* read-modify-write CP15 test state register
406
407
408
409
410
411
412
413
414
415
	* to reenable I/D-cache linefills */
	if (arm920t->preserve_cache)
	{
		arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
		jtag_execute_queue();
		cp15c15 &= ~0x600U;
		arm920t_write_cp15_physical(target, 0x1e, cp15c15);
	}
}

416
static const char arm920_not[] = "target is not an ARM920";
417

418
static int arm920t_verify_pointer(struct command_context_s *cmd_ctx,
419
		struct arm920t_common *arm920t)
420
421
422
423
{
	if (arm920t->common_magic != ARM920T_COMMON_MAGIC) {
		command_print(cmd_ctx, arm920_not);
		return ERROR_TARGET_INVALID;
424
	}
425

426
427
428
	return ERROR_OK;
}

429
/** Logs summary of ARM920 state for a halted target. */
430
431
int arm920t_arch_state(struct target_s *target)
{
432
	static const char *state[] =
433
434
435
	{
		"disabled", "enabled"
	};
436

437
	struct arm920t_common *arm920t = target_to_arm920(target);
438
439
440
	struct armv4_5_common_s *armv4_5;

	if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
441
	{
442
443
		LOG_ERROR("BUG: %s", arm920_not);
		return ERROR_TARGET_INVALID;
444
	}
445

446
447
	armv4_5 = &arm920t->arm9tdmi_common.arm7_9_common.armv4_5_common;

448
	LOG_USER("target halted in %s state due to %s, current mode: %s\n"
duane's avatar
duane committed
449
			"cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
450
451
			"MMU: %s, D-Cache: %s, I-Cache: %s",
			 armv4_5_state_strings[armv4_5->core_state],
452
			 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
453
454
455
456
			 armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
			 buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
			 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
			 state[arm920t->armv4_5_mmu.mmu_enabled],
457
			 state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
458
			 state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
459

460
461
462
	return ERROR_OK;
}

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
static int arm920_mmu(struct target_s *target, int *enabled)
{
	if (target->state != TARGET_HALTED) {
		LOG_ERROR("%s: target not halted", __func__);
		return ERROR_TARGET_INVALID;
	}

	*enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled;
	return ERROR_OK;
}

static int arm920_virt2phys(struct target_s *target,
		uint32_t virt, uint32_t *phys)
{
	/** @todo Implement this!  */
	LOG_ERROR("%s: not implemented", __func__);
	return ERROR_FAIL;
}

482
/** Reads a buffer, in the specified word size, with current MMU settings. */
483
int arm920t_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
484
485
{
	int retval;
486

487
	retval = arm7_9_read_memory(target, address, size, count, buffer);
488

489
490
491
	return retval;
}

492

493
494
495
static int arm920t_read_phys_memory(struct target_s *target,
		uint32_t address, uint32_t size,
		uint32_t count, uint8_t *buffer)
496
{
497
	struct arm920t_common *arm920t = target_to_arm920(target);
498

499
500
	return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,
			address, size, count, buffer);
501
502
}

503
504
505
static int arm920t_write_phys_memory(struct target_s *target,
		uint32_t address, uint32_t size,
		uint32_t count, uint8_t *buffer)
506
{
507
	struct arm920t_common *arm920t = target_to_arm920(target);
508

509
510
	return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,
			address, size, count, buffer);
511
512
513
}


514
/** Writes a buffer, in the specified word size, with current MMU settings. */
515
int arm920t_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
516
517
{
	int retval;
518

519
520
521
	if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
		return retval;

522
523
524
525
	/* This fn is used to write breakpoints, so we need to make sure
	 * that the data cache is flushed and the instruction cache is
	 * invalidated
	 */
526
527
	if (((size == 4) || (size == 2)) && (count == 1))
	{
528
		struct arm920t_common *arm920t = target_to_arm920(target);
529

530
531
		if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
		{
532
533
534
535
536
			LOG_DEBUG("D-Cache enabled, flush and invalidate cache line");
			/* MCR p15,0,Rd,c7,c10,2 */
			retval = arm920t_write_cp15_interpreted(target, 0xee070f5e, 0x0, address);
			if (retval != ERROR_OK)
				return retval;
537
		}
538

539
540
		if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
		{
541
			LOG_DEBUG("I-Cache enabled, invalidating affected I-Cache line");
542
543
544
			retval = arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
			if (retval != ERROR_OK)
				return retval;
545
546
547
548
549
550
		}
	}

	return retval;
}

551
// EXPORTED to FA256
552
553
int arm920t_soft_reset_halt(struct target_s *target)
{
554
	int retval = ERROR_OK;
555
	struct arm920t_common *arm920t = target_to_arm920(target);
556
	struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
557
	struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
Zachary T Welch's avatar
Zachary T Welch committed
558
	struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
559

560
	if ((retval = target_halt(target)) != ERROR_OK)
561
562
563
	{
		return retval;
	}
564

zwelch's avatar
zwelch committed
565
	long long then = timeval_ms();
oharboe's avatar
oharboe committed
566
	int timeout;
zwelch's avatar
zwelch committed
567
	while (!(timeout = ((timeval_ms()-then) > 1000)))
568
	{
569
570
571
		if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
		{
			embeddedice_read_reg(dbg_stat);
572
			if ((retval = jtag_execute_queue()) != ERROR_OK)
573
574
575
			{
				return retval;
			}
576
577
578
579
		} else
		{
			break;
		}
zwelch's avatar
zwelch committed
580
		if (debug_level >= 3)
oharboe's avatar
oharboe committed
581
582
583
584
585
586
587
		{
			/* do not eat all CPU, time out after 1 se*/
			alive_sleep(100);
		} else
		{
			keep_alive();
		}
588
	}
oharboe's avatar
oharboe committed
589
	if (timeout)
590
591
592
	{
		LOG_ERROR("Failed to halt CPU after 1 sec");
		return ERROR_TARGET_TIMEOUT;
593
	}
594

595
	target->state = TARGET_HALTED;
596

597
598
599
600
	/* SVC, ARM state, IRQ and FIQ disabled */
	buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
	armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
	armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
601

602
603
604
605
	/* start fetching from 0x0 */
	buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
	armv4_5->core_cache->reg_list[15].dirty = 1;
	armv4_5->core_cache->reg_list[15].valid = 1;
606

607
608
	armv4_5->core_mode = ARMV4_5_MODE_SVC;
	armv4_5->core_state = ARMV4_5_STATE_ARM;
609

610
611
612
613
614
	arm920t_disable_mmu_caches(target, 1, 1, 1);
	arm920t->armv4_5_mmu.mmu_enabled = 0;
	arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
	arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;

615
	if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
616
617
618
	{
		return retval;
	}
619

620
621
622
	return ERROR_OK;
}

623
int arm920t_init_arch_info(target_t *target, struct arm920t_common *arm920t, struct jtag_tap *tap)
624
{
625
	struct arm9tdmi_common *arm9tdmi = &arm920t->arm9tdmi_common;
626
	struct arm7_9_common *arm7_9 = &arm9tdmi->arm7_9_common;
627

628
629
	/* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
	 */
630
	arm9tdmi_init_arch_info(target, arm9tdmi, tap);
631
632

	arm920t->common_magic = ARM920T_COMMON_MAGIC;
633

634
635
	arm7_9->post_debug_entry = arm920t_post_debug_entry;
	arm7_9->pre_restore_context = arm920t_pre_restore_context;
636

637
638
639
640
641
642
643
644
	arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
	arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
	arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
	arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
	arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
	arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
	arm920t->armv4_5_mmu.has_tiny_pages = 1;
	arm920t->armv4_5_mmu.mmu_enabled = 0;
645

646
647
648
649
650
	/* disabling linefills leads to lockups, so keep them enabled for now
	 * this doesn't affect correctness, but might affect timing issues, if
	 * important data is evicted from the cache during the debug session
	 * */
	arm920t->preserve_cache = 0;
651

652
653
	/* override hw single-step capability from ARM9TDMI */
	arm7_9->has_single_step = 1;
654

655
656
657
	return ERROR_OK;
}

658
static int arm920t_target_create(struct target_s *target, Jim_Interp *interp)
659
{
660
	struct arm920t_common *arm920t = calloc(1,sizeof(struct arm920t_common));
661

662
	return arm920t_init_arch_info(target, arm920t, target->tap);
663
664
}

665
COMMAND_HANDLER(arm920t_handle_read_cache_command)
666
{
667
	int retval = ERROR_OK;
668
	target_t *target = get_current_target(cmd_ctx);
669
	struct arm920t_common *arm920t = target_to_arm920(target);
670
	struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
671
	struct armv4_5_common_s *armv4_5 = &arm7_9->armv4_5_common;
672
673
674
675
676
	uint32_t cp15c15;
	uint32_t cp15_ctrl, cp15_ctrl_saved;
	uint32_t regs[16];
	uint32_t *regs_p[16];
	uint32_t C15_C_D_Ind, C15_C_I_Ind;
677
678
	int i;
	FILE *output;
679
	struct arm920t_cache_line d_cache[8][64], i_cache[8][64];
680
	int segment, index;
681

682
683
684
685
	retval = arm920t_verify_pointer(cmd_ctx, arm920t);
	if (retval != ERROR_OK)
		return retval;

686
687
688
689
690
	if (argc != 1)
	{
		command_print(cmd_ctx, "usage: arm920t read_cache <filename>");
		return ERROR_OK;
	}
691

692
693
	if ((output = fopen(args[0], "w")) == NULL)
	{
694
		LOG_DEBUG("error opening cache content file");
695
696
		return ERROR_OK;
	}
697

698
699
	for (i = 0; i < 16; i++)
		regs_p[i] = &regs[i];
700

701
702
	/* disable MMU and Caches */
	arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
703
	if ((retval = jtag_execute_queue()) != ERROR_OK)
704
705
706
	{
		return retval;
	}
707
708
709
710
	cp15_ctrl_saved = cp15_ctrl;
	cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
	arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);

711
	/* read CP15 test state register */
712
713
	arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
	jtag_execute_queue();
714

715
716
	/* read DCache content */
	fprintf(output, "DCache:\n");
717
718

	/* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
719
720
721
	for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
	{
		fprintf(output, "\nsegment: %i\n----------", segment);
722

723
724
725
		/* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
		regs[0] = 0x0 | (segment << 5);
		arm9tdmi_write_core_regs(target, 0x1, regs);
726

727
728
729
		/* set interpret mode */
		cp15c15 |= 0x1;
		arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
730

731
732
		/* D CAM Read, loads current victim into C15.C.D.Ind */
		arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(1, 0));
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
		/* read current victim */
		arm920t_read_cp15_physical(target, 0x3d, &C15_C_D_Ind);

		/* clear interpret mode */
		cp15c15 &= ~0x1;
		arm920t_write_cp15_physical(target, 0x1e, cp15c15);

		for (index = 0; index < 64; index++)
		{
			/* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
			regs[0] = 0x0 | (segment << 5) | (index << 26);
			arm9tdmi_write_core_regs(target, 0x1, regs);

			/* set interpret mode */
			cp15c15 |= 0x1;
			arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
750

751
752
			/* Write DCache victim */
			arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
753

754
755
			/* Read D RAM */
			arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,10,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
756

757
758
			/* Read D CAM */
			arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(9, 0));
759

760
761
762
763
764
765
			/* clear interpret mode */
			cp15c15 &= ~0x1;
			arm920t_write_cp15_physical(target, 0x1e, cp15c15);

			/* read D RAM and CAM content */
			arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
766
			if ((retval = jtag_execute_queue()) != ERROR_OK)
767
768
769
			{
				return retval;
			}
770
771

			d_cache[segment][index].cam = regs[9];
772

773
774
			/* mask LFSR[6] */
			regs[9] &= 0xfffffffe;
duane's avatar
duane committed
775
			fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" PRIx32 ", content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
776

777
778
779
			for (i = 1; i < 9; i++)
			{
				 d_cache[segment][index].data[i] = regs[i];
duane's avatar
duane committed
780
				 fprintf(output, "%i: 0x%8.8" PRIx32 "\n", i-1, regs[i]);
781
			}
782

783
		}
784

785
786
787
788
789
790
791
		/* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
		regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
		arm9tdmi_write_core_regs(target, 0x1, regs);

		/* set interpret mode */
		cp15c15 |= 0x1;
		arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
792

793
794
		/* Write DCache victim */
		arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
795

796
797
798
799
800
801
802
		/* clear interpret mode */
		cp15c15 &= ~0x1;
		arm920t_write_cp15_physical(target, 0x1e, cp15c15);
	}

	/* read ICache content */
	fprintf(output, "ICache:\n");
803
804

	/* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
805
806
807
	for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
	{
		fprintf(output, "segment: %i\n----------", segment);
808

809
810
811
		/* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
		regs[0] = 0x0 | (segment << 5);
		arm9tdmi_write_core_regs(target, 0x1, regs);
812

813
814
815
		/* set interpret mode */
		cp15c15 |= 0x1;
		arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
816

817
818
		/* I CAM Read, loads current victim into C15.C.I.Ind */
		arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(1, 0));
819

820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
		/* read current victim */
		arm920t_read_cp15_physical(target, 0x3b, &C15_C_I_Ind);

		/* clear interpret mode */
		cp15c15 &= ~0x1;
		arm920t_write_cp15_physical(target, 0x1e, cp15c15);

		for (index = 0; index < 64; index++)
		{
			/* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
			regs[0] = 0x0 | (segment << 5) | (index << 26);
			arm9tdmi_write_core_regs(target, 0x1, regs);

			/* set interpret mode */
			cp15c15 |= 0x1;
			arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
836

837
838
			/* Write ICache victim */
			arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
839

840
841
			/* Read I RAM */
			arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,9,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
842

843
844
			/* Read I CAM */
			arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(9, 0));
845

846
847
848
849
850
851
			/* clear interpret mode */
			cp15c15 &= ~0x1;
			arm920t_write_cp15_physical(target, 0x1e, cp15c15);

			/* read I RAM and CAM content */
			arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
852
			if ((retval = jtag_execute_queue()) != ERROR_OK)
853
854
855
			{
				return retval;
			}
856
857

			i_cache[segment][index].cam = regs[9];
858

859
860
			/* mask LFSR[6] */
			regs[9] &= 0xfffffffe;
duane's avatar
duane committed
861
			fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8" PRIx32 ", content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
862

863
864
865
			for (i = 1; i < 9; i++)
			{
				 i_cache[segment][index].data[i] = regs[i];
duane's avatar
duane committed
866
				 fprintf(output, "%i: 0x%8.8" PRIx32 "\n", i-1, regs[i]);
867
868
			}
		}
869

870
871
872
873
874
875
876
		/* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
		regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
		arm9tdmi_write_core_regs(target, 0x1, regs);

		/* set interpret mode */
		cp15c15 |= 0x1;
		arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
877

878
879
		/* Write ICache victim */
		arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
880

881
882
883
884
		/* clear interpret mode */
		cp15c15 &= ~0x1;
		arm920t_write_cp15_physical(target, 0x1e, cp15c15);
	}
885

886
887
	/* restore CP15 MMU and Cache settings */
	arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
888

889
	command_print(cmd_ctx, "cache content successfully output to %s", args[0]);
890

891
	fclose(output);
892

893
894
895
	if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
		return ERROR_FAIL;

896
897
898
899
900
901
902
903
904
905
906
	/* mark registers dirty. */
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
907

908
909
910
	return ERROR_OK;
}

911
COMMAND_HANDLER(arm920t_handle_read_mmu_command)
912
{
913
	int retval = ERROR_OK;
914
	target_t *target = get_current_target(cmd_ctx);
915
	struct arm920t_common *arm920t = target_to_arm920(target);
916
	struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
917
	struct armv4_5_common_s *