target.c 118 KB
Newer Older
2001
2002
	if (argc == 0)
	{
2003
		command_print(cmd_ctx, "background polling: %s",
2004
				jtag_poll_get_enabled() ? "on" : "off");
zwelch's avatar
zwelch committed
2005
2006
2007
2008
2009
		command_print(cmd_ctx, "TAP: %s (%s)",
				target->tap->dotted_name,
				target->tap->enabled ? "enabled" : "disabled");
		if (!target->tap->enabled)
			return ERROR_OK;
2010
		if ((retval = target_poll(target)) != ERROR_OK)
2011
			return retval;
2012
		if ((retval = target_arch_state(target)) != ERROR_OK)
2013
2014
			return retval;

2015
	}
zwelch's avatar
zwelch committed
2016
	else if (argc == 1)
2017
2018
2019
	{
		if (strcmp(args[0], "on") == 0)
		{
2020
			jtag_poll_set_enabled(true);
2021
2022
2023
		}
		else if (strcmp(args[0], "off") == 0)
		{
2024
			jtag_poll_set_enabled(false);
2025
2026
2027
2028
2029
		}
		else
		{
			command_print(cmd_ctx, "arg is \"on\" or \"off\"");
		}
2030
2031
2032
	} else
	{
		return ERROR_COMMAND_SYNTAX_ERROR;
2033
	}
oharboe's avatar
oharboe committed
2034

2035
	return retval;
2036
2037
}

2038
COMMAND_HANDLER(handle_wait_halt_command)
2039
{
2040
2041
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2042

2043
2044
	unsigned ms = 5000;
	if (1 == argc)
2045
	{
2046
2047
		int retval = parse_uint(args[0], &ms);
		if (ERROR_OK != retval)
2048
		{
2049
			command_print(cmd_ctx, "usage: %s [seconds]", CMD_NAME);
2050
			return ERROR_COMMAND_SYNTAX_ERROR;
2051
		}
2052
2053
		// convert seconds (given) to milliseconds (needed)
		ms *= 1000;
2054
2055
	}

2056
	target_t *target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
2057
	return target_wait_state(target, TARGET_HALTED, ms);
2058
2059
}

2060
2061
2062
2063
2064
2065
/* wait for target state to change. The trick here is to have a low
 * latency for short waits and not to suck up all the CPU time
 * on longer waits.
 *
 * After 500ms, keep_alive() is invoked
 */
2066
int target_wait_state(target_t *target, enum target_state state, int ms)
2067
2068
{
	int retval;
zwelch's avatar
zwelch committed
2069
2070
	long long then = 0, cur;
	int once = 1;
oharboe's avatar
oharboe committed
2071

2072
2073
	for (;;)
	{
zwelch's avatar
zwelch committed
2074
		if ((retval = target_poll(target)) != ERROR_OK)
2075
2076
2077
2078
2079
			return retval;
		if (target->state == state)
		{
			break;
		}
2080
		cur = timeval_ms();
2081
2082
		if (once)
		{
zwelch's avatar
zwelch committed
2083
			once = 0;
2084
			then = timeval_ms();
2085
			LOG_DEBUG("waiting for target %s...",
2086
				Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
2087
		}
oharboe's avatar
oharboe committed
2088

zwelch's avatar
zwelch committed
2089
		if (cur-then > 500)
2090
2091
2092
2093
		{
			keep_alive();
		}

zwelch's avatar
zwelch committed
2094
		if ((cur-then) > ms)
2095
		{
2096
			LOG_ERROR("timed out while waiting for target %s",
2097
				Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
oharboe's avatar
oharboe committed
2098
			return ERROR_FAIL;
2099
2100
		}
	}
oharboe's avatar
oharboe committed
2101

2102
2103
2104
	return ERROR_OK;
}

2105
COMMAND_HANDLER(handle_halt_command)
2106
{
2107
	LOG_DEBUG("-");
2108

2109
2110
2111
	target_t *target = get_current_target(cmd_ctx);
	int retval = target_halt(target);
	if (ERROR_OK != retval)
2112
		return retval;
oharboe's avatar
oharboe committed
2113

2114
2115
	if (argc == 1)
	{
2116
2117
2118
2119
2120
		unsigned wait;
		retval = parse_uint(args[0], &wait);
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
		if (!wait)
2121
2122
2123
			return ERROR_OK;
	}

2124
	return CALL_COMMAND_HANDLER(handle_wait_halt_command);
2125
2126
}

2127
COMMAND_HANDLER(handle_soft_reset_halt_command)
2128
2129
{
	target_t *target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
2130

2131
	LOG_USER("requesting target halt and executing a soft reset");
oharboe's avatar
oharboe committed
2132

oharboe's avatar
   
oharboe committed
2133
	target->type->soft_reset_halt(target);
oharboe's avatar
oharboe committed
2134

2135
2136
2137
	return ERROR_OK;
}

2138
COMMAND_HANDLER(handle_reset_command)
2139
{
2140
2141
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2142

2143
2144
	enum target_reset_mode reset_mode = RESET_RUN;
	if (argc == 1)
2145
	{
2146
		const Jim_Nvp *n;
2147
		n = Jim_Nvp_name2value_simple(nvp_reset_modes, args[0]);
zwelch's avatar
zwelch committed
2148
		if ((n->name == NULL) || (n->value == RESET_UNKNOWN)) {
oharboe's avatar
oharboe committed
2149
			return ERROR_COMMAND_SYNTAX_ERROR;
2150
		}
2151
		reset_mode = n->value;
2152
	}
oharboe's avatar
oharboe committed
2153

2154
	/* reset *all* targets */
2155
	return target_process_reset(cmd_ctx, reset_mode);
2156
2157
}

2158

2159
COMMAND_HANDLER(handle_resume_command)
2160
{
2161
	int current = 1;
zwelch's avatar
zwelch committed
2162
2163
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2164

zwelch's avatar
zwelch committed
2165
2166
	target_t *target = get_current_target(cmd_ctx);
	target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
oharboe's avatar
oharboe committed
2167

zwelch's avatar
zwelch committed
2168
2169
2170
	/* with no args, resume from current pc, addr = 0,
	 * with one arguments, addr = args[0],
	 * handle breakpoints, not debugging */
2171
	uint32_t addr = 0;
zwelch's avatar
zwelch committed
2172
	if (argc == 1)
2173
	{
2174
		COMMAND_PARSE_NUMBER(u32, args[0], addr);
2175
		current = 0;
2176
	}
oharboe's avatar
oharboe committed
2177

2178
	return target_resume(target, current, addr, 1, 0);
2179
2180
}

2181
COMMAND_HANDLER(handle_step_command)
2182
{
zwelch's avatar
zwelch committed
2183
2184
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2185

2186
	LOG_DEBUG("-");
oharboe's avatar
oharboe committed
2187

zwelch's avatar
zwelch committed
2188
2189
2190
	/* with no args, step from current pc, addr = 0,
	 * with one argument addr = args[0],
	 * handle breakpoints, debugging */
2191
	uint32_t addr = 0;
2192
	int current_pc = 1;
2193
	if (argc == 1)
2194
	{
2195
		COMMAND_PARSE_NUMBER(u32, args[0], addr);
2196
		current_pc = 0;
2197
	}
oharboe's avatar
oharboe committed
2198

zwelch's avatar
zwelch committed
2199
	target_t *target = get_current_target(cmd_ctx);
2200
2201

	return target->type->step(target, current_pc, addr, 1);
2202
2203
}

2204
static void handle_md_output(struct command_context_s *cmd_ctx,
2205
		struct target_s *target, uint32_t address, unsigned size,
2206
		unsigned count, const uint8_t *buffer)
2207
2208
2209
2210
2211
2212
2213
2214
2215
{
	const unsigned line_bytecnt = 32;
	unsigned line_modulo = line_bytecnt / size;

	char output[line_bytecnt * 4 + 1];
	unsigned output_len = 0;

	const char *value_fmt;
	switch (size) {
2216
2217
2218
	case 4: value_fmt = "%8.8x "; break;
	case 2: value_fmt = "%4.2x "; break;
	case 1: value_fmt = "%2.2x "; break;
2219
2220
2221
2222
	default:
		LOG_ERROR("invalid memory read size: %u", size);
		exit(-1);
	}
2223

2224
2225
2226
2227
2228
2229
	for (unsigned i = 0; i < count; i++)
	{
		if (i % line_modulo == 0)
		{
			output_len += snprintf(output + output_len,
					sizeof(output) - output_len,
2230
					"0x%8.8x: ",
duane's avatar
duane committed
2231
					(unsigned)(address + (i*size)));
2232
		}
2233

zwelch's avatar
zwelch committed
2234
		uint32_t value = 0;
2235
		const uint8_t *value_ptr = buffer + i * size;
2236
2237
2238
2239
2240
2241
2242
2243
		switch (size) {
		case 4: value = target_buffer_get_u32(target, value_ptr); break;
		case 2: value = target_buffer_get_u16(target, value_ptr); break;
		case 1: value = *value_ptr;
		}
		output_len += snprintf(output + output_len,
				sizeof(output) - output_len,
				value_fmt, value);
2244

2245
2246
2247
2248
2249
2250
2251
		if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
		{
			command_print(cmd_ctx, "%s", output);
			output_len = 0;
		}
	}
}
2252

2253
COMMAND_HANDLER(handle_md_command)
2254
{
2255
	if (argc < 1)
2256
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2257

2258
	unsigned size = 0;
2259
	switch (CMD_NAME[2]) {
2260
2261
2262
2263
	case 'w': size = 4; break;
	case 'h': size = 2; break;
	case 'b': size = 1; break;
	default: return ERROR_COMMAND_SYNTAX_ERROR;
2264
2265
	}

2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
	bool physical=strcmp(args[0], "phys")==0;
	int (*fn)(struct target_s *target,
			uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
	if (physical)
	{
		argc--;
		args++;
		fn=target_read_phys_memory;
	} else
	{
		fn=target_read_memory;
	}
	if ((argc < 1) || (argc > 2))
	{
		return ERROR_COMMAND_SYNTAX_ERROR;
	}
2282

2283
	uint32_t address;
2284
	COMMAND_PARSE_NUMBER(u32, args[0], address);
oharboe's avatar
oharboe committed
2285

2286
2287
	unsigned count = 1;
	if (argc == 2)
2288
		COMMAND_PARSE_NUMBER(uint, args[1], count);
oharboe's avatar
oharboe committed
2289

2290
	uint8_t *buffer = calloc(count, size);
oharboe's avatar
oharboe committed
2291

2292
	target_t *target = get_current_target(cmd_ctx);
2293
	int retval = fn(target, address, size, count, buffer);
2294
2295
	if (ERROR_OK == retval)
		handle_md_output(cmd_ctx, target, address, size, count, buffer);
2296
2297

	free(buffer);
oharboe's avatar
oharboe committed
2298

oharboe's avatar
oharboe committed
2299
	return retval;
2300
2301
}

2302
COMMAND_HANDLER(handle_mw_command)
2303
{
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
	if (argc < 2)
	{
		return ERROR_COMMAND_SYNTAX_ERROR;
	}
	bool physical=strcmp(args[0], "phys")==0;
	int (*fn)(struct target_s *target,
			uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
	if (physical)
	{
		argc--;
		args++;
		fn=target_write_phys_memory;
	} else
	{
		fn=target_write_memory;
	}
	if ((argc < 2) || (argc > 3))
oharboe's avatar
oharboe committed
2321
		return ERROR_COMMAND_SYNTAX_ERROR;
2322

2323
	uint32_t address;
2324
	COMMAND_PARSE_NUMBER(u32, args[0], address);
2325

2326
	uint32_t value;
2327
	COMMAND_PARSE_NUMBER(u32, args[1], value);
2328
2329

	unsigned count = 1;
oharboe's avatar
oharboe committed
2330
	if (argc == 3)
2331
		COMMAND_PARSE_NUMBER(uint, args[2], count);
oharboe's avatar
oharboe committed
2332

2333
2334
	target_t *target = get_current_target(cmd_ctx);
	unsigned wordsize;
2335
	uint8_t value_buf[4];
2336
	switch (CMD_NAME[2])
2337
2338
	{
		case 'w':
oharboe's avatar
oharboe committed
2339
			wordsize = 4;
2340
2341
2342
			target_buffer_set_u32(target, value_buf, value);
			break;
		case 'h':
oharboe's avatar
oharboe committed
2343
			wordsize = 2;
2344
2345
2346
			target_buffer_set_u16(target, value_buf, value);
			break;
		case 'b':
oharboe's avatar
oharboe committed
2347
			wordsize = 1;
2348
2349
2350
			value_buf[0] = value;
			break;
		default:
oharboe's avatar
oharboe committed
2351
			return ERROR_COMMAND_SYNTAX_ERROR;
2352
	}
2353
	for (unsigned i = 0; i < count; i++)
2354
	{
2355
		int retval = fn(target,
2356
2357
				address + i * wordsize, wordsize, 1, value_buf);
		if (ERROR_OK != retval)
oharboe's avatar
oharboe committed
2358
			return retval;
2359
		keep_alive();
2360
2361
2362
2363
2364
2365
	}

	return ERROR_OK;

}

Zachary T Welch's avatar
Zachary T Welch committed
2366
static COMMAND_HELPER(parse_load_image_command_args, struct image *image,
2367
		uint32_t *min_address, uint32_t *max_address)
2368
{
2369
	if (argc < 1 || argc > 5)
2370
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2371

2372
2373
	/* a base address isn't always necessary,
	 * default to 0x0 (i.e. don't relocate) */
2374
2375
	if (argc >= 2)
	{
2376
		uint32_t addr;
2377
		COMMAND_PARSE_NUMBER(u32, args[1], addr);
2378
2379
		image->base_address = addr;
		image->base_address_set = 1;
2380
2381
	}
	else
2382
		image->base_address_set = 0;
oharboe's avatar
oharboe committed
2383

2384
	image->start_address_set = 0;
oharboe's avatar
oharboe committed
2385

2386
	if (argc >= 4)
2387
	{
2388
		COMMAND_PARSE_NUMBER(u32, args[3], *min_address);
2389
	}
2390
	if (argc == 5)
2391
	{
2392
		COMMAND_PARSE_NUMBER(u32, args[4], *max_address);
2393
		// use size (given) to find max (required)
2394
		*max_address += *min_address;
2395
	}
oharboe's avatar
oharboe committed
2396

2397
	if (*min_address > *max_address)
2398
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2399

2400
2401
2402
	return ERROR_OK;
}

2403
COMMAND_HANDLER(handle_load_image_command)
2404
{
2405
	uint8_t *buffer;
2406
2407
2408
2409
	uint32_t buf_cnt;
	uint32_t image_size;
	uint32_t min_address = 0;
	uint32_t max_address = 0xffffffff;
2410
	int i;
Zachary T Welch's avatar
Zachary T Welch committed
2411
	struct image image;
2412

2413
	int retval = CALL_COMMAND_HANDLER(parse_load_image_command_args,
2414
2415
2416
2417
2418
			&image, &min_address, &max_address);
	if (ERROR_OK != retval)
		return retval;

	target_t *target = get_current_target(cmd_ctx);
Zachary T Welch's avatar
Zachary T Welch committed
2419
2420
2421

	struct duration bench;
	duration_start(&bench);
oharboe's avatar
oharboe committed
2422

2423
2424
2425
2426
	if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
	{
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
2427

2428
	image_size = 0x0;
2429
	retval = ERROR_OK;
2430
2431
2432
2433
2434
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
2435
2436
			command_print(cmd_ctx,
						  "error allocating buffer for section (%d bytes)",
duane's avatar
duane committed
2437
						  (int)(image.sections[i].size));
2438
2439
			break;
		}
oharboe's avatar
oharboe committed
2440

2441
2442
2443
		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
2444
2445
			break;
		}
oharboe's avatar
oharboe committed
2446

zwelch's avatar
zwelch committed
2447
2448
		uint32_t offset = 0;
		uint32_t length = buf_cnt;
oharboe's avatar
oharboe committed
2449

2450
		/* DANGER!!! beware of unsigned comparision here!!! */
oharboe's avatar
oharboe committed
2451

zwelch's avatar
zwelch committed
2452
		if ((image.sections[i].base_address + buf_cnt >= min_address)&&
zwelch's avatar
zwelch committed
2453
				(image.sections[i].base_address < max_address))
2454
		{
zwelch's avatar
zwelch committed
2455
			if (image.sections[i].base_address < min_address)
2456
2457
			{
				/* clip addresses below */
zwelch's avatar
zwelch committed
2458
				offset += min_address-image.sections[i].base_address;
zwelch's avatar
zwelch committed
2459
				length -= offset;
2460
			}
oharboe's avatar
oharboe committed
2461

zwelch's avatar
zwelch committed
2462
			if (image.sections[i].base_address + buf_cnt > max_address)
2463
			{
zwelch's avatar
zwelch committed
2464
				length -= (image.sections[i].base_address + buf_cnt)-max_address;
2465
			}
oharboe's avatar
oharboe committed
2466

zwelch's avatar
zwelch committed
2467
			if ((retval = target_write_buffer(target, image.sections[i].base_address + offset, length, buffer + offset)) != ERROR_OK)
2468
2469
2470
2471
2472
			{
				free(buffer);
				break;
			}
			image_size += length;
oharboe's avatar
oharboe committed
2473
			command_print(cmd_ctx, "%u bytes written at address 0x%8.8" PRIx32 "",
2474
						  (unsigned int)length,
zwelch's avatar
zwelch committed
2475
						  image.sections[i].base_address + offset);
2476
		}
oharboe's avatar
oharboe committed
2477

2478
2479
2480
		free(buffer);
	}

Zachary T Welch's avatar
Zachary T Welch committed
2481
	if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
2482
	{
Zachary T Welch's avatar
Zachary T Welch committed
2483
2484
2485
		command_print(cmd_ctx, "downloaded %" PRIu32 " bytes "
				"in %fs (%0.3f kb/s)", image_size,
				duration_elapsed(&bench), duration_kbps(&bench, image_size));
2486
2487
	}

2488
2489
	image_close(&image);

2490
	return retval;
2491
2492
2493

}

2494
COMMAND_HANDLER(handle_dump_image_command)
2495
{
Zachary T Welch's avatar
Zachary T Welch committed
2496
	struct fileio fileio;
oharboe's avatar
oharboe committed
2497

2498
	uint8_t buffer[560];
2499
	int retvaltemp;
oharboe's avatar
oharboe committed
2500
2501


2502
2503
2504
2505
2506
2507
2508
2509
	target_t *target = get_current_target(cmd_ctx);

	if (argc != 3)
	{
		command_print(cmd_ctx, "usage: dump_image <filename> <address> <size>");
		return ERROR_OK;
	}

2510
	uint32_t address;
2511
	COMMAND_PARSE_NUMBER(u32, args[1], address);
2512
	uint32_t size;
2513
	COMMAND_PARSE_NUMBER(u32, args[2], size);
2514
2515
2516
2517
2518

	if (fileio_open(&fileio, args[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)
	{
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
2519

Zachary T Welch's avatar
Zachary T Welch committed
2520
2521
	struct duration bench;
	duration_start(&bench);
oharboe's avatar
oharboe committed
2522

2523
	int retval = ERROR_OK;
2524
2525
	while (size > 0)
	{
2526
2527
		uint32_t size_written;
		uint32_t this_run_size = (size > 560) ? 560 : size;
2528
		retval = target_read_buffer(target, address, this_run_size, buffer);
2529
2530
2531
2532
		if (retval != ERROR_OK)
		{
			break;
		}
oharboe's avatar
oharboe committed
2533

2534
2535
2536
2537
2538
		retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
		if (retval != ERROR_OK)
		{
			break;
		}
oharboe's avatar
oharboe committed
2539

2540
2541
2542
2543
		size -= this_run_size;
		address += this_run_size;
	}

zwelch's avatar
zwelch committed
2544
	if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
2545
2546
		return retvaltemp;

Zachary T Welch's avatar
Zachary T Welch committed
2547
	if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
2548
	{
Zachary T Welch's avatar
Zachary T Welch committed
2549
2550
2551
		command_print(cmd_ctx,
				"dumped %lld bytes in %fs (%0.3f kb/s)", fileio.size,
				duration_elapsed(&bench), duration_kbps(&bench, fileio.size));
2552
	}
oharboe's avatar
oharboe committed
2553

2554
	return retval;
2555
2556
}

2557
static COMMAND_HELPER(handle_verify_image_command_internal, int verify)
2558
{
2559
	uint8_t *buffer;
2560
2561
	uint32_t buf_cnt;
	uint32_t image_size;
2562
	int i;
Zachary T Welch's avatar
Zachary T Welch committed
2563
	int retval;
2564
2565
	uint32_t checksum = 0;
	uint32_t mem_checksum = 0;
2566

Zachary T Welch's avatar
Zachary T Welch committed
2567
	struct image image;
oharboe's avatar
oharboe committed
2568

2569
	target_t *target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
2570

2571
2572
	if (argc < 1)
	{
2573
		return ERROR_COMMAND_SYNTAX_ERROR;
2574
	}
oharboe's avatar
oharboe committed
2575

2576
2577
	if (!target)
	{
2578
		LOG_ERROR("no target selected");
2579
		return ERROR_FAIL;
2580
	}
oharboe's avatar
oharboe committed
2581

Zachary T Welch's avatar
Zachary T Welch committed
2582
2583
	struct duration bench;
	duration_start(&bench);
oharboe's avatar
oharboe committed
2584

2585
2586
	if (argc >= 2)
	{
2587
		uint32_t addr;
2588
		COMMAND_PARSE_NUMBER(u32, args[1], addr);
2589
		image.base_address = addr;
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
		image.base_address_set = 1;
	}
	else
	{
		image.base_address_set = 0;
		image.base_address = 0x0;
	}

	image.start_address_set = 0;

zwelch's avatar
zwelch committed
2600
	if ((retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL)) != ERROR_OK)
2601
	{
2602
		return retval;
2603
	}
oharboe's avatar
oharboe committed
2604

2605
	image_size = 0x0;
zwelch's avatar
zwelch committed
2606
	retval = ERROR_OK;
2607
2608
2609
2610
2611
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
2612
2613
			command_print(cmd_ctx,
						  "error allocating buffer for section (%d bytes)",
duane's avatar
duane committed
2614
						  (int)(image.sections[i].size));
2615
2616
2617
2618
2619
			break;
		}
		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
2620
			break;
2621
		}
oharboe's avatar
oharboe committed
2622

oharboe's avatar
oharboe committed
2623
		if (verify)
2624
		{
oharboe's avatar
oharboe committed
2625
			/* calculate checksum of image */
2626
			image_calculate_checksum(buffer, buf_cnt, &checksum);
oharboe's avatar
oharboe committed
2627

oharboe's avatar
oharboe committed
2628
			retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
2629
			if (retval != ERROR_OK)
2630
			{
oharboe's avatar
oharboe committed
2631
2632
				free(buffer);
				break;
2633
			}
oharboe's avatar
oharboe committed
2634

2635
			if (checksum != mem_checksum)
2636
			{
oharboe's avatar
oharboe committed
2637
				/* failed crc checksum, fall back to a binary compare */
2638
				uint8_t *data;
oharboe's avatar
oharboe committed
2639
2640
2641

				command_print(cmd_ctx, "checksum mismatch - attempting binary compare");

2642
				data = (uint8_t*)malloc(buf_cnt);
oharboe's avatar
oharboe committed
2643
2644
2645
2646
2647

				/* Can we use 32bit word accesses? */
				int size = 1;
				int count = buf_cnt;
				if ((count % 4) == 0)
2648
				{
oharboe's avatar
oharboe committed
2649
2650
2651
					size *= 4;
					count /= 4;
				}
zwelch's avatar
zwelch committed
2652
				retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
oharboe's avatar
oharboe committed
2653
2654
				if (retval == ERROR_OK)
				{
2655
					uint32_t t;
oharboe's avatar
oharboe committed
2656
					for (t = 0; t < buf_cnt; t++)
oharboe's avatar
oharboe committed
2657
					{
oharboe's avatar
oharboe committed
2658
2659
						if (data[t] != buffer[t])
						{
2660
2661
2662
2663
							command_print(cmd_ctx,
										  "Verify operation failed address 0x%08x. Was 0x%02x instead of 0x%02x\n",
										  (unsigned)(t + image.sections[i].base_address),
										  data[t],
duane's avatar
duane committed
2664
										  buffer[t]);
oharboe's avatar
oharboe committed
2665
2666
							free(data);
							free(buffer);
zwelch's avatar
zwelch committed
2667
							retval = ERROR_FAIL;
oharboe's avatar
oharboe committed
2668
2669
							goto done;
						}
zwelch's avatar
zwelch committed
2670
						if ((t%16384) == 0)
oharboe's avatar
oharboe committed
2671
2672
2673
						{
							keep_alive();
						}
oharboe's avatar
oharboe committed
2674
					}
2675
				}
oharboe's avatar
oharboe committed
2676

oharboe's avatar
oharboe committed
2677
2678
2679
2680
				free(data);
			}
		} else
		{
2681
2682
			command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "",
						  image.sections[i].base_address,
duane's avatar
duane committed
2683
						  buf_cnt);
2684
		}
oharboe's avatar
oharboe committed
2685

2686
2687
2688
		free(buffer);
		image_size += buf_cnt;
	}
oharboe's avatar
oharboe committed
2689
done:
Zachary T Welch's avatar
Zachary T Welch committed
2690
	if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
2691
	{
Zachary T Welch's avatar
Zachary T Welch committed
2692
2693
2694
		command_print(cmd_ctx, "verified %" PRIu32 " bytes "
				"in %fs (%0.3f kb/s)", image_size,
				duration_elapsed(&bench), duration_kbps(&bench, image_size));
2695
	}
oharboe's avatar
oharboe committed
2696

2697
	image_close(&image);
oharboe's avatar
oharboe committed
2698

2699
	return retval;
2700
2701
}

2702
COMMAND_HANDLER(handle_verify_image_command)
oharboe's avatar
oharboe committed
2703
{
2704
	return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, 1);
oharboe's avatar
oharboe committed
2705
2706
}

2707
COMMAND_HANDLER(handle_test_image_command)
oharboe's avatar
oharboe committed
2708
{
2709
	return CALL_COMMAND_HANDLER(handle_verify_image_command_internal, 0);
oharboe's avatar
oharboe committed
2710
2711
}

zwelch's avatar
zwelch committed
2712
static int handle_bp_command_list(struct command_context_s *cmd_ctx)
2713
2714
{
	target_t *target = get_current_target(cmd_ctx);
2715
	struct breakpoint *breakpoint = target->breakpoints;
zwelch's avatar
zwelch committed
2716
	while (breakpoint)
2717
	{
zwelch's avatar
zwelch committed
2718
		if (breakpoint->type == BKPT_SOFT)
2719
		{
zwelch's avatar
zwelch committed
2720
2721
			char* buf = buf_to_str(breakpoint->orig_instr,
					breakpoint->length, 16);
duane's avatar
duane committed
2722
			command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i, 0x%s",
2723
					breakpoint->address,
duane's avatar
duane committed
2724
					breakpoint->length,
zwelch's avatar
zwelch committed
2725
2726
					breakpoint->set, buf);
			free(buf);
2727
2728
2729
		}
		else
		{
duane's avatar
duane committed
2730
			command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i",
2731
						  breakpoint->address,
duane's avatar
duane committed
2732
						  breakpoint->length, breakpoint->set);
2733
		}
zwelch's avatar
zwelch committed
2734
2735

		breakpoint = breakpoint->next;
2736
	}
zwelch's avatar
zwelch committed
2737
2738
2739
2740
	return ERROR_OK;
}

static int handle_bp_command_set(struct command_context_s *cmd_ctx,
2741
		uint32_t addr, uint32_t length, int hw)
zwelch's avatar
zwelch committed
2742
2743
2744
2745
{
	target_t *target = get_current_target(cmd_ctx);
	int retval = breakpoint_add(target, addr, length, hw);
	if (ERROR_OK == retval)
duane's avatar
duane committed
2746
		command_print(cmd_ctx, "breakpoint set at 0x%8.8" PRIx32 "", addr);
2747
	else
zwelch's avatar
zwelch committed
2748
2749
2750
2751
		LOG_ERROR("Failure setting breakpoint");
	return retval;
}

2752
COMMAND_HANDLER(handle_bp_command)
zwelch's avatar
zwelch committed
2753
2754
2755
2756
2757
{
	if (argc == 0)
		return handle_bp_command_list(cmd_ctx);

	if (argc < 2 || argc > 3)
2758
2759
	{
		command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
zwelch's avatar
zwelch committed
2760
		return ERROR_COMMAND_SYNTAX_ERROR;
2761
2762
	}

2763
	uint32_t addr;
2764
	COMMAND_PARSE_NUMBER(u32, args[0], addr);
2765
	uint32_t length;
2766
	COMMAND_PARSE_NUMBER(u32, args[1], length);
zwelch's avatar
zwelch committed
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777

	int hw = BKPT_SOFT;
	if (argc == 3)
	{
		if (strcmp(args[2], "hw") == 0)
			hw = BKPT_HARD;
		else
			return ERROR_COMMAND_SYNTAX_ERROR;
	}

	return handle_bp_command_set(cmd_ctx, addr, length, hw);
2778
2779
}

2780
COMMAND_HANDLER(handle_rbp_command)
2781
{
2782
2783
	if (argc != 1)
		return ERROR_COMMAND_SYNTAX_ERROR;