arm11.c 41 KB
Newer Older
1
2
/***************************************************************************
 *   Copyright (C) 2008 digenius technology GmbH.                          *
3
 *   Michael Bruck                                                         *
4
 *                                                                         *
oharboe's avatar
oharboe committed
5
 *   Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com         *
6
 *                                                                         *
7
8
 *   Copyright (C) 2008 Georg Acher <acher@in.tum.de>                      *
 *                                                                         *
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.             *
 ***************************************************************************/
oharboe's avatar
oharboe committed
24

25
26
27
28
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

29
#include "etm.h"
30
#include "breakpoints.h"
31
#include "arm11_dbgtap.h"
oharboe's avatar
oharboe committed
32
#include "arm_simulator.h"
dbrownell's avatar
dbrownell committed
33
#include "time_support.h"
34
#include "target_type.h"
35
#include "algorithm.h"
36
#include "register.h"
37
38
39
40
41
42


#if 0
#define _DEBUG_INSTRUCTION_EXECUTION_
#endif

43
44
45
46
47
static bool arm11_config_memwrite_burst = true;
static bool arm11_config_memwrite_error_fatal = true;
static uint32_t arm11_vcr = 0;
static bool arm11_config_step_irq_enable = false;
static bool arm11_config_hardware_step = false;
48
49
50

enum arm11_regtype
{
51
52
53
54
	/* debug regs */
	ARM11_REGISTER_DSCR,
	ARM11_REGISTER_WDTR,
	ARM11_REGISTER_RDTR,
55
56
57
};


58
struct arm11_reg_defs
59
{
60
	char *					name;
61
	uint32_t						num;
62
	int						gdb_num;
63
	enum arm11_regtype		type;
64
};
65
66

/* update arm11_regcache_ids when changing this */
67
static const struct arm11_reg_defs arm11_reg_defs[] =
68
{
69
70
71
72
	/* Debug Registers */
	{"dscr",	0,	-1,	ARM11_REGISTER_DSCR},
	{"wdtr",	0,	-1,	ARM11_REGISTER_WDTR},
	{"rdtr",	0,	-1,	ARM11_REGISTER_RDTR},
73
74
75
76
};

enum arm11_regcache_ids
{
77
78
79
	ARM11_RC_DSCR,
	ARM11_RC_WDTR,
	ARM11_RC_RDTR,
80

81
	ARM11_RC_MAX,
82
83
};

84
static int arm11_on_enter_debug_state(struct arm11_common *arm11);
Zachary T Welch's avatar
Zachary T Welch committed
85
static int arm11_step(struct target *target, int current,
86
87
		uint32_t address, int handle_breakpoints);
/* helpers */
Zachary T Welch's avatar
Zachary T Welch committed
88
static int arm11_build_reg_cache(struct target *target);
Zachary T Welch's avatar
Zachary T Welch committed
89
90
static int arm11_set_reg(struct reg *reg, uint8_t *buf);
static int arm11_get_reg(struct reg *reg);
91

92
93
94
95
96

/** Check and if necessary take control of the system
 *
 * \param arm11		Target state variable.
 * \param dscr		If the current DSCR content is
97
98
 *					available a pointer to a word holding the
 *					DSCR can be passed. Otherwise use NULL.
99
 */
100
static int arm11_check_init(struct arm11_common *arm11, uint32_t *dscr)
101
{
102
	uint32_t			dscr_local_tmp_copy;
103

104
105
	if (!dscr)
	{
106
		dscr = &dscr_local_tmp_copy;
107

108
		CHECK_RETVAL(arm11_read_DSCR(arm11, dscr));
109
	}
110

111
112
	if (!(*dscr & ARM11_DSCR_MODE_SELECT))
	{
113
		LOG_DEBUG("Bringing target into debug mode");
114

115
116
		*dscr |= ARM11_DSCR_MODE_SELECT;		/* Halt debug-mode */
		arm11_write_DSCR(arm11, *dscr);
117

118
		/* add further reset initialization here */
119

120
		arm11->simulate_reset_on_next_halt = true;
oharboe's avatar
oharboe committed
121

122
123
124
		if (*dscr & ARM11_DSCR_CORE_HALTED)
		{
			/** \todo TODO: this needs further scrutiny because
125
126
127
			  * arm11_on_enter_debug_state() never gets properly called.
			  * As a result we don't read the actual register states from
			  * the target.
128
			  */
oharboe's avatar
oharboe committed
129

130
131
132
133
134
135
136
137
			arm11->target->state	= TARGET_HALTED;
			arm11->target->debug_reason	= arm11_get_DSCR_debug_reason(*dscr);
		}
		else
		{
			arm11->target->state	= TARGET_RUNNING;
			arm11->target->debug_reason	= DBG_REASON_NOTHALTED;
		}
138

139
		arm11_sc7_clear_vbw(arm11);
140
	}
141
142

	return ERROR_OK;
143
144
145
146
147
}



#define R(x) \
148
	(arm11->reg_values[ARM11_RC_##x])
149
150
151
152
153
154
155

/** Save processor state.
  *
  * This is called when the HALT instruction has succeeded
  * or on other occasions that stop the processor.
  *
  */
156
static int arm11_on_enter_debug_state(struct arm11_common *arm11)
157
{
oharboe's avatar
oharboe committed
158
	int retval;
159

160
161
162
	/* REVISIT entire cache should already be invalid !!! */
	register_cache_invalidate(arm11->arm.core_cache);

163
	for (size_t i = 0; i < ARRAY_SIZE(arm11->reg_values); i++)
164
	{
165
166
		arm11->reg_list[i].valid	= 1;
		arm11->reg_list[i].dirty	= 0;
167
	}
168

169
170
	/* See e.g. ARM1136 TRM, "14.8.4 Entering Debug state" */

171
	/* Save DSCR */
172
	CHECK_RETVAL(arm11_read_DSCR(arm11, &R(DSCR)));
173

174
	/* Save wDTR */
175

176
177
	if (R(DSCR) & ARM11_DSCR_WDTR_FULL)
	{
178
		arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
179

180
		arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
181

182
		struct scan_field	chain5_fields[3];
183

184
		arm11_setup_field(arm11, 32, NULL, &R(WDTR),	chain5_fields + 0);
185
186
		arm11_setup_field(arm11,  1, NULL, NULL,		chain5_fields + 1);
		arm11_setup_field(arm11,  1, NULL, NULL,		chain5_fields + 2);
187

188
		arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);
189
190
191
	}
	else
	{
192
		arm11->reg_list[ARM11_RC_WDTR].valid	= 0;
193
	}
194
195


196
197
198
199
200
201
	/* DSCR: set ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE
	 *
	 * ARM1176 spec says this is needed only for wDTR/rDTR's "ITR mode",
	 * but not to issue ITRs. ARM1136 seems to require this to issue
	 * ITR's as well...
	 */
202
	uint32_t new_dscr = R(DSCR) | ARM11_DSCR_EXECUTE_ARM_INSTRUCTION_ENABLE;
203

204
	/* this executes JTAG queue: */
205

206
	arm11_write_DSCR(arm11, new_dscr);
207
208


209
	/* From the spec:
210
211
	   Before executing any instruction in debug state you have to drain the write buffer.
	   This ensures that no imprecise Data Aborts can return at a later point:*/
212

213
	/** \todo TODO: Test drain write buffer. */
214
215

#if 0
216
217
	while (1)
	{
218
219
		/* MRC p14,0,R0,c5,c10,0 */
		//	arm11_run_instr_no_data1(arm11, /*0xee150e1a*/0xe320f000);
220

221
222
		/* mcr	   15, 0, r0, cr7, cr10, {4} */
		arm11_run_instr_no_data1(arm11, 0xee070f9a);
223

224
		uint32_t dscr = arm11_read_DSCR(arm11);
225

226
		LOG_DEBUG("DRAIN, DSCR %08x", dscr);
227

228
229
230
		if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT)
		{
			arm11_run_instr_no_data1(arm11, 0xe320f000);
231

232
			dscr = arm11_read_DSCR(arm11);
233

234
			LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr);
235

236
237
			break;
		}
238
239
240
	}
#endif

241
242
243
244
245
	/* Save registers.
	 *
	 * NOTE:  ARM1136 TRM suggests saving just R0 here now, then
	 * CPSR and PC after the rDTR stuff.  We do it all at once.
	 */
246
247
248
249
	retval = arm_dpm_read_current_registers(&arm11->dpm);
	if (retval != ERROR_OK)
		LOG_ERROR("DPM REG READ -- fail %d", retval);

Øyvind Harboe's avatar
Øyvind Harboe committed
250
251
252
	retval = arm11_run_instr_data_prepare(arm11);
	if (retval != ERROR_OK)
		return retval;
253

254
	/* maybe save rDTR */
255

256
	/* check rDTRfull in DSCR */
257

258
259
	if (R(DSCR) & ARM11_DSCR_RDTR_FULL)
	{
260
		/* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */
Øyvind Harboe's avatar
Øyvind Harboe committed
261
262
263
		retval = arm11_run_instr_data_from_core_via_r0(arm11, 0xEE100E15, &R(RDTR));
		if (retval != ERROR_OK)
			return retval;
264
265
266
	}
	else
	{
267
		arm11->reg_list[ARM11_RC_RDTR].valid	= 0;
268
	}
269

270
271
272
	/* REVISIT Now that we've saved core state, there's may also
	 * be MMU and cache state to care about ...
	 */
273

274
275
	if (arm11->simulate_reset_on_next_halt)
	{
276
		arm11->simulate_reset_on_next_halt = false;
oharboe's avatar
oharboe committed
277

278
		LOG_DEBUG("Reset c1 Control Register");
oharboe's avatar
oharboe committed
279

280
		/* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */
oharboe's avatar
oharboe committed
281

282
		/* MCR p15,0,R0,c1,c0,0 */
Øyvind Harboe's avatar
Øyvind Harboe committed
283
284
285
		retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);
		if (retval != ERROR_OK)
			return retval;
oharboe's avatar
oharboe committed
286

287
	}
oharboe's avatar
oharboe committed
288

Øyvind Harboe's avatar
Øyvind Harboe committed
289
290
291
	retval = arm11_run_instr_data_finish(arm11);
	if (retval != ERROR_OK)
		return retval;
292

293
	return ERROR_OK;
oharboe's avatar
oharboe committed
294
}
295
296
297
298
299
300

/** Restore processor state
  *
  * This is called in preparation for the RESTART function.
  *
  */
301
static int arm11_leave_debug_state(struct arm11_common *arm11)
302
{
Øyvind Harboe's avatar
Øyvind Harboe committed
303
	int retval;
304

305
	/* See e.g. ARM1136 TRM, "14.8.5 Leaving Debug state" */
306

307
308
309
310
	/* NOTE:  the ARM1136 TRM suggests restoring all registers
	 * except R0/PC/CPSR right now.  Instead, we do them all
	 * at once, just a bit later on.
	 */
311

312
313
314
	/* REVISIT once we start caring about MMU and cache state,
	 * address it here ...
	 */
315

316
317
318
	/* spec says clear wDTR and rDTR; we assume they are clear as
	   otherwise our programming would be sloppy */
	{
319
		uint32_t DSCR;
320
321

		CHECK_RETVAL(arm11_read_DSCR(arm11, &DSCR));
322

323
324
		if (DSCR & (ARM11_DSCR_RDTR_FULL | ARM11_DSCR_WDTR_FULL))
		{
325
326
327
328
329
330
331
			/*
			The wDTR/rDTR two registers that are used to send/receive data to/from
			the core in tandem with corresponding instruction codes that are
			written into the core. The RDTR FULL/WDTR FULL flag indicates that the
			registers hold data that was written by one side (CPU or JTAG) and not
			read out by the other side.
			*/
duane's avatar
duane committed
332
			LOG_ERROR("wDTR/rDTR inconsistent (DSCR %08" PRIx32 ")", DSCR);
333
			return ERROR_FAIL;
334
		}
335
336
	}

337
	/* maybe restore original wDTR */
338
339
	if ((R(DSCR) & ARM11_DSCR_WDTR_FULL) || arm11->reg_list[ARM11_RC_WDTR].dirty)
	{
340
341
342
343
		retval = arm11_run_instr_data_prepare(arm11);
		if (retval != ERROR_OK)
			return retval;

344
		/* MCR p14,0,R0,c0,c5,0 */
Øyvind Harboe's avatar
Øyvind Harboe committed
345
346
347
348
		retval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee000e15, R(WDTR));
		if (retval != ERROR_OK)
			return retval;

349
350
351
352
		retval = arm11_run_instr_data_finish(arm11);
		if (retval != ERROR_OK)
			return retval;
	}
353

354
355
356
357
	/* restore CPSR, PC, and R0 ... after flushing any modified
	 * registers.
	 */
	retval = arm_dpm_write_dirty_registers(&arm11->dpm);
358
359
360

	register_cache_invalidate(arm11->arm.core_cache);

361
	/* restore DSCR */
362

363
	arm11_write_DSCR(arm11, R(DSCR));
364

365
	/* maybe restore rDTR */
366

367
368
	if (R(DSCR) & ARM11_DSCR_RDTR_FULL || arm11->reg_list[ARM11_RC_RDTR].dirty)
	{
369
		arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
370

371
		arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
372

373
		struct scan_field	chain5_fields[3];
374

375
376
		uint8_t			Ready		= 0;	/* ignored */
		uint8_t			Valid		= 0;	/* ignored */
377

378
379
380
		arm11_setup_field(arm11, 32, &R(RDTR),	NULL, chain5_fields + 0);
		arm11_setup_field(arm11,  1, &Ready,	NULL, chain5_fields + 1);
		arm11_setup_field(arm11,  1, &Valid,	NULL, chain5_fields + 2);
381

382
		arm11_add_dr_scan_vc(ARRAY_SIZE(chain5_fields), chain5_fields, TAP_DRPAUSE);
383
	}
384

385
386
	/* now processor is ready to RESTART */

387
	return ERROR_OK;
oharboe's avatar
oharboe committed
388
}
389
390

/* poll current target status */
Zachary T Welch's avatar
Zachary T Welch committed
391
static int arm11_poll(struct target *target)
392
{
oharboe's avatar
oharboe committed
393
	int retval;
394
	struct arm11_common *arm11 = target_to_arm11(target);
395
	uint32_t	dscr;
396

397
	CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
398

duane's avatar
duane committed
399
	LOG_DEBUG("DSCR %08" PRIx32 "", dscr);
400

401
	CHECK_RETVAL(arm11_check_init(arm11, &dscr));
402

403
404
	if (dscr & ARM11_DSCR_CORE_HALTED)
	{
405
406
407
		if (target->state != TARGET_HALTED)
		{
			enum target_state old_state = target->state;
oharboe's avatar
oharboe committed
408

409
			LOG_DEBUG("enter TARGET_HALTED");
410
			target->state			= TARGET_HALTED;
411
			target->debug_reason	= arm11_get_DSCR_debug_reason(dscr);
oharboe's avatar
oharboe committed
412
413
414
			retval = arm11_on_enter_debug_state(arm11);
			if (retval != ERROR_OK)
				return retval;
oharboe's avatar
oharboe committed
415

416
417
418
			target_call_event_callbacks(target,
				old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED);
		}
419
420
421
	}
	else
	{
422
423
424
		if (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING)
		{
			LOG_DEBUG("enter TARGET_RUNNING");
425
			target->state			= TARGET_RUNNING;
426
427
			target->debug_reason	= DBG_REASON_NOTHALTED;
		}
428
429
	}

430
	return ERROR_OK;
431
432
}
/* architecture specific status reply */
Zachary T Welch's avatar
Zachary T Welch committed
433
static int arm11_arch_state(struct target *target)
434
{
435
	int retval;
436

437
	retval = armv4_5_arch_state(target);
438

439
440
441
	/* REVISIT also display ARM11-specific MMU and cache status ... */

	return retval;
442
443
444
}

/* target request support */
Zachary T Welch's avatar
Zachary T Welch committed
445
static int arm11_target_request_data(struct target *target,
446
		uint32_t size, uint8_t *buffer)
447
{
David Brownell's avatar
David Brownell committed
448
	LOG_WARNING("Not implemented: %s", __func__);
449

David Brownell's avatar
David Brownell committed
450
	return ERROR_FAIL;
451
452
453
}

/* target execution control */
Zachary T Welch's avatar
Zachary T Welch committed
454
static int arm11_halt(struct target *target)
455
{
456
	struct arm11_common *arm11 = target_to_arm11(target);
457

458
	LOG_DEBUG("target->state: %s",
459
		target_state_name(target));
460

461
462
	if (target->state == TARGET_UNKNOWN)
	{
463
		arm11->simulate_reset_on_next_halt = true;
464
	}
oharboe's avatar
oharboe committed
465

466
467
	if (target->state == TARGET_HALTED)
	{
468
469
		LOG_DEBUG("target was already halted");
		return ERROR_OK;
470
	}
471

472
	arm11_add_IR(arm11, ARM11_HALT, TAP_IDLE);
473

474
	CHECK_RETVAL(jtag_execute_queue());
475

476
	uint32_t dscr;
477

478
	int i = 0;
479
480
	while (1)
	{
481
		CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
482

483
484
		if (dscr & ARM11_DSCR_CORE_HALTED)
			break;
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500


		long long then = 0;
		if (i == 1000)
		{
			then = timeval_ms();
		}
		if (i >= 1000)
		{
			if ((timeval_ms()-then) > 1000)
			{
				LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
				return ERROR_FAIL;
			}
		}
		i++;
501
	}
502

503
	arm11_on_enter_debug_state(arm11);
504

505
	enum target_state old_state	= target->state;
oharboe's avatar
oharboe committed
506

507
508
	target->state		= TARGET_HALTED;
	target->debug_reason	= arm11_get_DSCR_debug_reason(dscr);
oharboe's avatar
oharboe committed
509

510
511
512
	CHECK_RETVAL(
		target_call_event_callbacks(target,
			old_state == TARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED));
oharboe's avatar
oharboe committed
513

514
	return ERROR_OK;
515
516
}

517
518
519
520
521
522
523
524
525
526
527
528
529
static uint32_t
arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address)
{
	void *value = arm11->arm.core_cache->reg_list[15].value;

	if (!current)
		buf_set_u32(value, 0, 32, address);
	else
		address = buf_get_u32(value, 0, 32);

	return address;
}

Zachary T Welch's avatar
Zachary T Welch committed
530
static int arm11_resume(struct target *target, int current,
531
		uint32_t address, int handle_breakpoints, int debug_execution)
532
{
533
534
	//	  LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d",
	//	current, address, handle_breakpoints, debug_execution);
oharboe's avatar
oharboe committed
535

536
	struct arm11_common *arm11 = target_to_arm11(target);
537

538
	LOG_DEBUG("target->state: %s",
539
		target_state_name(target));
540

541

542
	if (target->state != TARGET_HALTED)
oharboe's avatar
oharboe committed
543
544
545
546
	{
		LOG_ERROR("Target not halted");
		return ERROR_TARGET_NOT_HALTED;
	}
547

548
	address = arm11_nextpc(arm11, current, address);
549

550
	LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");
oharboe's avatar
oharboe committed
551

552
553
	/* clear breakpoints/watchpoints and VCR*/
	arm11_sc7_clear_vbw(arm11);
oharboe's avatar
oharboe committed
554

555
	if (!debug_execution)
556
557
558
559
		target_free_all_working_areas(target);

	/* Set up breakpoints */
	if (handle_breakpoints)
560
	{
561
		/* check if one matches PC and step over it if necessary */
oharboe's avatar
oharboe committed
562

563
		struct breakpoint *	bp;
oharboe's avatar
oharboe committed
564

565
		for (bp = target->breakpoints; bp; bp = bp->next)
566
		{
567
			if (bp->address == address)
568
			{
duane's avatar
duane committed
569
				LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
570
571
572
				arm11_step(target, 1, 0, 0);
				break;
			}
573
		}
oharboe's avatar
oharboe committed
574

575
		/* set all breakpoints */
oharboe's avatar
oharboe committed
576

577
		unsigned brp_num = 0;
578

579
580
		for (bp = target->breakpoints; bp; bp = bp->next)
		{
581
			struct arm11_sc7_action	brp[2];
oharboe's avatar
oharboe committed
582

583
584
585
586
587
588
			brp[0].write	= 1;
			brp[0].address	= ARM11_SC7_BVR0 + brp_num;
			brp[0].value	= bp->address;
			brp[1].write	= 1;
			brp[1].address	= ARM11_SC7_BCR0 + brp_num;
			brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);
589

590
			arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp));
oharboe's avatar
oharboe committed
591

592
593
			LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num,
					bp->address);
oharboe's avatar
oharboe committed
594

595
596
			brp_num++;
		}
oharboe's avatar
oharboe committed
597

598
		arm11_sc7_set_vcr(arm11, arm11_vcr);
599
	}
600

601
	arm11_leave_debug_state(arm11);
602

603
	arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
604

605
	CHECK_RETVAL(jtag_execute_queue());
606

607
	int i = 0;
608
609
	while (1)
	{
610
		uint32_t dscr;
611

612
		CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
613

duane's avatar
duane committed
614
		LOG_DEBUG("DSCR %08" PRIx32 "", dscr);
615

616
617
		if (dscr & ARM11_DSCR_CORE_RESTARTED)
			break;
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633


		long long then = 0;
		if (i == 1000)
		{
			then = timeval_ms();
		}
		if (i >= 1000)
		{
			if ((timeval_ms()-then) > 1000)
			{
				LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
				return ERROR_FAIL;
			}
		}
		i++;
634
	}
635

636
637
	if (!debug_execution)
	{
638
		target->state			= TARGET_RUNNING;
639
		target->debug_reason	= DBG_REASON_NOTHALTED;
640

641
		CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
642
643
644
	}
	else
	{
645
		target->state			= TARGET_DEBUG_RUNNING;
646
		target->debug_reason	= DBG_REASON_NOTHALTED;
647
648

		CHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));
649
	}
650

651
	return ERROR_OK;
652
653
}

Zachary T Welch's avatar
Zachary T Welch committed
654
static int arm11_step(struct target *target, int current,
655
		uint32_t address, int handle_breakpoints)
656
{
657
	LOG_DEBUG("target->state: %s",
658
		target_state_name(target));
659

660
661
	if (target->state != TARGET_HALTED)
	{
662
663
		LOG_WARNING("target was not halted");
		return ERROR_TARGET_NOT_HALTED;
664
	}
665

666
	struct arm11_common *arm11 = target_to_arm11(target);
667

668
	address = arm11_nextpc(arm11, current, address);
oharboe's avatar
oharboe committed
669

670
	LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");
671

672

673
	/** \todo TODO: Thumb not supported here */
674

675
	uint32_t	next_instruction;
676

677
	CHECK_RETVAL(arm11_read_memory_word(arm11, address, &next_instruction));
678

679
680
681
	/* skip over BKPT */
	if ((next_instruction & 0xFFF00070) == 0xe1200070)
	{
682
		address = arm11_nextpc(arm11, 0, address + 4);
683
		LOG_DEBUG("Skipping BKPT");
684
685
686
687
688
	}
	/* skip over Wait for interrupt / Standby */
	/* mcr	15, 0, r?, cr7, cr0, {4} */
	else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90)
	{
689
		address = arm11_nextpc(arm11, 0, address + 4);
690
		LOG_DEBUG("Skipping WFI");
691
692
693
694
	}
	/* ignore B to self */
	else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
	{
695
		LOG_DEBUG("Not stepping jump to self");
696
697
698
	}
	else
	{
699
700
		/** \todo TODO: check if break-/watchpoints make any sense at all in combination
		* with this. */
701

702
703
		/** \todo TODO: check if disabling IRQs might be a good idea here. Alternatively
		* the VCR might be something worth looking into. */
704
705


706
		/* Set up breakpoint for stepping */
707

708
		struct arm11_sc7_action	brp[2];
709

710
711
712
713
		brp[0].write	= 1;
		brp[0].address	= ARM11_SC7_BVR0;
		brp[1].write	= 1;
		brp[1].address	= ARM11_SC7_BCR0;
714
715
716

		if (arm11_config_hardware_step)
		{
717
718
719
720
721
722
723
724
725
726
727
			/* Hardware single stepping ("instruction address
			 * mismatch") is used if enabled.  It's not quite
			 * exactly "run one instruction"; "branch to here"
			 * loops won't break, neither will some other cases,
			 * but it's probably the best default.
			 *
			 * Hardware single stepping isn't supported on v6
			 * debug modules.  ARM1176 and v7 can support it...
			 *
			 * FIXME Thumb stepping likely needs to use 0x03
			 * or 0xc0 byte masks, not 0x0f.
728
			 */
729
			 brp[0].value	= address;
730
731
732
			 brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5)
					| (0 << 14) | (0 << 16) | (0 << 20)
					| (2 << 21);
733
734
		} else
		{
735
736
737
738
739
			/* Sets a breakpoint on the next PC, as calculated
			 * by instruction set simulation.
			 *
			 * REVISIT stepping Thumb on ARM1156 requires Thumb2
			 * support from the simulator.
740
741
742
			 */
			uint32_t next_pc;
			int retval;
743
744

			retval = arm_simulate_step(target, &next_pc);
745
746
			if (retval != ERROR_OK)
				return retval;
747

748
			brp[0].value	= next_pc;
749
750
751
			brp[1].value	= 0x1 | (3 << 1) | (0x0F << 5)
					| (0 << 14) | (0 << 16) | (0 << 20)
					| (0 << 21);
752
		}
753

754
		CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));
755

756
		/* resume */
757
758


759
760
761
762
		if (arm11_config_step_irq_enable)
			R(DSCR) &= ~ARM11_DSCR_INTERRUPTS_DISABLE;		/* should be redundant */
		else
			R(DSCR) |= ARM11_DSCR_INTERRUPTS_DISABLE;
763

764

765
		CHECK_RETVAL(arm11_leave_debug_state(arm11));
766

767
		arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
768

769
		CHECK_RETVAL(jtag_execute_queue());
770

771
		/* wait for halt */
772
		int i = 0;
773
774
		while (1)
		{
775
			uint32_t dscr;
776
777

			CHECK_RETVAL(arm11_read_DSCR(arm11, &dscr));
778

duane's avatar
duane committed
779
			LOG_DEBUG("DSCR %08" PRIx32 "e", dscr);
780
781
782
783

			if ((dscr & (ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED)) ==
				(ARM11_DSCR_CORE_RESTARTED | ARM11_DSCR_CORE_HALTED))
				break;
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798

			long long then = 0;
			if (i == 1000)
			{
				then = timeval_ms();
			}
			if (i >= 1000)
			{
				if ((timeval_ms()-then) > 1000)
				{
					LOG_WARNING("Timeout (1000ms) waiting for instructions to complete");
					return ERROR_FAIL;
				}
			}
			i++;
799
800
801
802
803
804
		}

		/* clear breakpoint */
		arm11_sc7_clear_vbw(arm11);

		/* save state */
805
		CHECK_RETVAL(arm11_on_enter_debug_state(arm11));
806
807
808

	    /* restore default state */
		R(DSCR) &= ~ARM11_DSCR_INTERRUPTS_DISABLE;
oharboe's avatar
oharboe committed
809

810
	}
811

812
	//	  target->state		= TARGET_HALTED;
813
	target->debug_reason	= DBG_REASON_SINGLESTEP;
drath's avatar