target.c 117 KB
Newer Older
2001

2002
2003
2004
2005
2006
2007
/* 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
 */
2008
int target_wait_state(target_t *target, enum target_state state, int ms)
2009
2010
{
	int retval;
zwelch's avatar
zwelch committed
2011
2012
	long long then = 0, cur;
	int once = 1;
oharboe's avatar
oharboe committed
2013

2014
2015
	for (;;)
	{
zwelch's avatar
zwelch committed
2016
		if ((retval = target_poll(target)) != ERROR_OK)
2017
2018
2019
2020
2021
			return retval;
		if (target->state == state)
		{
			break;
		}
2022
		cur = timeval_ms();
2023
2024
		if (once)
		{
zwelch's avatar
zwelch committed
2025
			once = 0;
2026
			then = timeval_ms();
2027
			LOG_DEBUG("waiting for target %s...",
2028
				Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
2029
		}
oharboe's avatar
oharboe committed
2030

zwelch's avatar
zwelch committed
2031
		if (cur-then > 500)
2032
2033
2034
2035
		{
			keep_alive();
		}

zwelch's avatar
zwelch committed
2036
		if ((cur-then) > ms)
2037
		{
2038
			LOG_ERROR("timed out while waiting for target %s",
2039
				Jim_Nvp_value2name_simple(nvp_target_state,state)->name);
oharboe's avatar
oharboe committed
2040
			return ERROR_FAIL;
2041
2042
		}
	}
oharboe's avatar
oharboe committed
2043

2044
2045
2046
	return ERROR_OK;
}

2047
static int handle_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2048
{
2049
	LOG_DEBUG("-");
2050

2051
2052
2053
	target_t *target = get_current_target(cmd_ctx);
	int retval = target_halt(target);
	if (ERROR_OK != retval)
2054
		return retval;
oharboe's avatar
oharboe committed
2055

2056
2057
	if (argc == 1)
	{
2058
2059
2060
2061
2062
		unsigned wait;
		retval = parse_uint(args[0], &wait);
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
		if (!wait)
2063
2064
2065
			return ERROR_OK;
	}

2066
2067
2068
	return handle_wait_halt_command(cmd_ctx, cmd, args, argc);
}

2069
static int handle_soft_reset_halt_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2070
2071
{
	target_t *target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
2072

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

oharboe's avatar
   
oharboe committed
2075
	target->type->soft_reset_halt(target);
oharboe's avatar
oharboe committed
2076

2077
2078
2079
	return ERROR_OK;
}

2080
static int handle_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2081
{
2082
2083
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2084

2085
2086
	enum target_reset_mode reset_mode = RESET_RUN;
	if (argc == 1)
2087
	{
2088
		const Jim_Nvp *n;
2089
		n = Jim_Nvp_name2value_simple(nvp_reset_modes, args[0]);
zwelch's avatar
zwelch committed
2090
		if ((n->name == NULL) || (n->value == RESET_UNKNOWN)) {
oharboe's avatar
oharboe committed
2091
			return ERROR_COMMAND_SYNTAX_ERROR;
2092
		}
2093
		reset_mode = n->value;
2094
	}
oharboe's avatar
oharboe committed
2095

2096
	/* reset *all* targets */
2097
	return target_process_reset(cmd_ctx, reset_mode);
2098
2099
}

2100

2101
static int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2102
{
2103
	int current = 1;
zwelch's avatar
zwelch committed
2104
2105
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2106

zwelch's avatar
zwelch committed
2107
2108
	target_t *target = get_current_target(cmd_ctx);
	target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
oharboe's avatar
oharboe committed
2109

zwelch's avatar
zwelch committed
2110
2111
2112
	/* with no args, resume from current pc, addr = 0,
	 * with one arguments, addr = args[0],
	 * handle breakpoints, not debugging */
2113
	uint32_t addr = 0;
zwelch's avatar
zwelch committed
2114
	if (argc == 1)
2115
2116
2117
2118
	{
		int retval = parse_u32(args[0], &addr);
		if (ERROR_OK != retval)
			return retval;
2119
		current = 0;
2120
	}
oharboe's avatar
oharboe committed
2121

2122
	return target_resume(target, current, addr, 1, 0);
2123
2124
}

2125
static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2126
{
zwelch's avatar
zwelch committed
2127
2128
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2129

2130
	LOG_DEBUG("-");
oharboe's avatar
oharboe committed
2131

zwelch's avatar
zwelch committed
2132
2133
2134
	/* with no args, step from current pc, addr = 0,
	 * with one argument addr = args[0],
	 * handle breakpoints, debugging */
2135
	uint32_t addr = 0;
2136
	int current_pc = 1;
2137
	if (argc == 1)
2138
2139
2140
2141
	{
		int retval = parse_u32(args[0], &addr);
		if (ERROR_OK != retval)
			return retval;
2142
		current_pc = 0;
2143
	}
oharboe's avatar
oharboe committed
2144

zwelch's avatar
zwelch committed
2145
	target_t *target = get_current_target(cmd_ctx);
2146
2147

	return target->type->step(target, current_pc, addr, 1);
2148
2149
}

2150
static void handle_md_output(struct command_context_s *cmd_ctx,
2151
		struct target_s *target, uint32_t address, unsigned size,
2152
		unsigned count, const uint8_t *buffer)
2153
2154
2155
2156
2157
2158
2159
2160
2161
{
	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) {
2162
2163
2164
	case 4: value_fmt = "%8.8x "; break;
	case 2: value_fmt = "%4.2x "; break;
	case 1: value_fmt = "%2.2x "; break;
2165
2166
2167
2168
	default:
		LOG_ERROR("invalid memory read size: %u", size);
		exit(-1);
	}
2169

2170
2171
2172
2173
2174
2175
	for (unsigned i = 0; i < count; i++)
	{
		if (i % line_modulo == 0)
		{
			output_len += snprintf(output + output_len,
					sizeof(output) - output_len,
2176
					"0x%8.8x: ",
duane's avatar
duane committed
2177
					(unsigned)(address + (i*size)));
2178
		}
2179

zwelch's avatar
zwelch committed
2180
		uint32_t value = 0;
2181
		const uint8_t *value_ptr = buffer + i * size;
2182
2183
2184
2185
2186
2187
2188
2189
		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);
2190

2191
2192
2193
2194
2195
2196
2197
		if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
		{
			command_print(cmd_ctx, "%s", output);
			output_len = 0;
		}
	}
}
2198

2199
2200
static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
2201
	if (argc < 1)
2202
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2203

2204
2205
2206
2207
2208
2209
	unsigned size = 0;
	switch (cmd[2]) {
	case 'w': size = 4; break;
	case 'h': size = 2; break;
	case 'b': size = 1; break;
	default: return ERROR_COMMAND_SYNTAX_ERROR;
2210
2211
	}

2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
	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;
	}
2228
	uint32_t address;
2229
2230
2231
	int retval = parse_u32(args[0], &address);
	if (ERROR_OK != retval)
		return retval;
oharboe's avatar
oharboe committed
2232

2233
2234
	unsigned count = 1;
	if (argc == 2)
2235
2236
2237
2238
2239
	{
		retval = parse_uint(args[1], &count);
		if (ERROR_OK != retval)
			return retval;
	}
oharboe's avatar
oharboe committed
2240

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

2243
	target_t *target = get_current_target(cmd_ctx);
2244
	retval = fn(target, address, size, count, buffer);
2245
2246
	if (ERROR_OK == retval)
		handle_md_output(cmd_ctx, target, address, size, count, buffer);
2247
2248

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

oharboe's avatar
oharboe committed
2250
	return retval;
2251
2252
}

2253
static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2254
{
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
	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
2272
		return ERROR_COMMAND_SYNTAX_ERROR;
2273

2274
	uint32_t address;
2275
2276
2277
2278
	int retval = parse_u32(args[0], &address);
	if (ERROR_OK != retval)
		return retval;

2279
	uint32_t value;
2280
2281
2282
2283
2284
	retval = parse_u32(args[1], &value);
	if (ERROR_OK != retval)
		return retval;

	unsigned count = 1;
oharboe's avatar
oharboe committed
2285
	if (argc == 3)
2286
2287
2288
2289
2290
	{
		retval = parse_uint(args[2], &count);
		if (ERROR_OK != retval)
			return retval;
	}
oharboe's avatar
oharboe committed
2291

2292
2293
	target_t *target = get_current_target(cmd_ctx);
	unsigned wordsize;
2294
	uint8_t value_buf[4];
2295
2296
2297
	switch (cmd[2])
	{
		case 'w':
oharboe's avatar
oharboe committed
2298
			wordsize = 4;
2299
2300
2301
			target_buffer_set_u32(target, value_buf, value);
			break;
		case 'h':
oharboe's avatar
oharboe committed
2302
			wordsize = 2;
2303
2304
2305
			target_buffer_set_u16(target, value_buf, value);
			break;
		case 'b':
oharboe's avatar
oharboe committed
2306
			wordsize = 1;
2307
2308
2309
			value_buf[0] = value;
			break;
		default:
oharboe's avatar
oharboe committed
2310
			return ERROR_COMMAND_SYNTAX_ERROR;
2311
	}
2312
	for (unsigned i = 0; i < count; i++)
2313
	{
2314
		retval = fn(target,
2315
2316
				address + i * wordsize, wordsize, 1, value_buf);
		if (ERROR_OK != retval)
oharboe's avatar
oharboe committed
2317
			return retval;
2318
		keep_alive();
2319
2320
2321
2322
2323
2324
	}

	return ERROR_OK;

}

2325
static int parse_load_image_command_args(char **args, int argc,
2326
		image_t *image, uint32_t *min_address, uint32_t *max_address)
2327
{
2328
	if (argc < 1 || argc > 5)
2329
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2330

2331
2332
	/* a base address isn't always necessary,
	 * default to 0x0 (i.e. don't relocate) */
2333
2334
	if (argc >= 2)
	{
2335
		uint32_t addr;
2336
		int retval = parse_u32(args[1], &addr);
2337
2338
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
2339
2340
		image->base_address = addr;
		image->base_address_set = 1;
2341
2342
	}
	else
2343
		image->base_address_set = 0;
oharboe's avatar
oharboe committed
2344

2345
	image->start_address_set = 0;
oharboe's avatar
oharboe committed
2346

2347
	if (argc >= 4)
2348
	{
2349
		int retval = parse_u32(args[3], min_address);
2350
2351
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
2352
	}
2353
	if (argc == 5)
2354
	{
2355
		int retval = parse_u32(args[4], max_address);
2356
2357
2358
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
		// use size (given) to find max (required)
2359
		*max_address += *min_address;
2360
	}
oharboe's avatar
oharboe committed
2361

2362
	if (*min_address > *max_address)
2363
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2364

2365
2366
2367
2368
2369
	return ERROR_OK;
}

static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
2370
	uint8_t *buffer;
2371
2372
2373
2374
	uint32_t buf_cnt;
	uint32_t image_size;
	uint32_t min_address = 0;
	uint32_t max_address = 0xffffffff;
2375
2376
2377
2378
2379
2380
2381
	int i;
	int retvaltemp;

	image_t image;

	duration_t duration;
	char *duration_text;
2382

2383
2384
2385
2386
2387
2388
	int retval = parse_load_image_command_args(args, argc,
			&image, &min_address, &max_address);
	if (ERROR_OK != retval)
		return retval;

	target_t *target = get_current_target(cmd_ctx);
2389
	duration_start_measure(&duration);
oharboe's avatar
oharboe committed
2390

2391
2392
2393
2394
	if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
	{
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
2395

2396
	image_size = 0x0;
2397
	retval = ERROR_OK;
2398
2399
2400
2401
2402
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
2403
2404
			command_print(cmd_ctx,
						  "error allocating buffer for section (%d bytes)",
duane's avatar
duane committed
2405
						  (int)(image.sections[i].size));
2406
2407
			break;
		}
oharboe's avatar
oharboe committed
2408

2409
2410
2411
		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
2412
2413
			break;
		}
oharboe's avatar
oharboe committed
2414

zwelch's avatar
zwelch committed
2415
2416
		uint32_t offset = 0;
		uint32_t length = buf_cnt;
oharboe's avatar
oharboe committed
2417

2418
		/* DANGER!!! beware of unsigned comparision here!!! */
oharboe's avatar
oharboe committed
2419

zwelch's avatar
zwelch committed
2420
		if ((image.sections[i].base_address + buf_cnt >= min_address)&&
zwelch's avatar
zwelch committed
2421
				(image.sections[i].base_address < max_address))
2422
		{
zwelch's avatar
zwelch committed
2423
			if (image.sections[i].base_address < min_address)
2424
2425
			{
				/* clip addresses below */
zwelch's avatar
zwelch committed
2426
				offset += min_address-image.sections[i].base_address;
zwelch's avatar
zwelch committed
2427
				length -= offset;
2428
			}
oharboe's avatar
oharboe committed
2429

zwelch's avatar
zwelch committed
2430
			if (image.sections[i].base_address + buf_cnt > max_address)
2431
			{
zwelch's avatar
zwelch committed
2432
				length -= (image.sections[i].base_address + buf_cnt)-max_address;
2433
			}
oharboe's avatar
oharboe committed
2434

zwelch's avatar
zwelch committed
2435
			if ((retval = target_write_buffer(target, image.sections[i].base_address + offset, length, buffer + offset)) != ERROR_OK)
2436
2437
2438
2439
2440
			{
				free(buffer);
				break;
			}
			image_size += length;
oharboe's avatar
oharboe committed
2441
			command_print(cmd_ctx, "%u bytes written at address 0x%8.8" PRIx32 "",
2442
						  (unsigned int)length,
zwelch's avatar
zwelch committed
2443
						  image.sections[i].base_address + offset);
2444
		}
oharboe's avatar
oharboe committed
2445

2446
2447
2448
		free(buffer);
	}

zwelch's avatar
zwelch committed
2449
	if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2450
2451
2452
2453
2454
	{
		image_close(&image);
		return retvaltemp;
	}

zwelch's avatar
zwelch committed
2455
	if (retval == ERROR_OK)
2456
	{
2457
2458
		command_print(cmd_ctx, "downloaded %u byte in %s",
					  (unsigned int)image_size,
duane's avatar
duane committed
2459
					  duration_text);
2460
	}
2461
	free(duration_text);
oharboe's avatar
oharboe committed
2462

2463
2464
	image_close(&image);

2465
	return retval;
2466
2467
2468

}

2469
static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2470
2471
{
	fileio_t fileio;
oharboe's avatar
oharboe committed
2472

2473
	uint8_t buffer[560];
2474
	int retvaltemp;
oharboe's avatar
oharboe committed
2475

2476
2477
	duration_t duration;
	char *duration_text;
oharboe's avatar
oharboe committed
2478

2479
2480
2481
2482
2483
2484
2485
2486
	target_t *target = get_current_target(cmd_ctx);

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

2487
	uint32_t address;
2488
2489
2490
2491
	int retval = parse_u32(args[1], &address);
	if (ERROR_OK != retval)
		return retval;

2492
	uint32_t size;
2493
2494
2495
	retval = parse_u32(args[2], &size);
	if (ERROR_OK != retval)
		return retval;
2496
2497
2498
2499
2500

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

2502
	duration_start_measure(&duration);
oharboe's avatar
oharboe committed
2503

2504
2505
	while (size > 0)
	{
2506
2507
		uint32_t size_written;
		uint32_t this_run_size = (size > 560) ? 560 : size;
oharboe's avatar
oharboe committed
2508

2509
		retval = target_read_buffer(target, address, this_run_size, buffer);
2510
2511
2512
2513
		if (retval != ERROR_OK)
		{
			break;
		}
oharboe's avatar
oharboe committed
2514

2515
2516
2517
2518
2519
		retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
		if (retval != ERROR_OK)
		{
			break;
		}
oharboe's avatar
oharboe committed
2520

2521
2522
2523
2524
		size -= this_run_size;
		address += this_run_size;
	}

zwelch's avatar
zwelch committed
2525
	if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
2526
2527
		return retvaltemp;

zwelch's avatar
zwelch committed
2528
	if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2529
		return retvaltemp;
2530

zwelch's avatar
zwelch committed
2531
	if (retval == ERROR_OK)
2532
	{
2533
2534
		command_print(cmd_ctx, "dumped %lld byte in %s",
				fileio.size, duration_text);
2535
		free(duration_text);
2536
	}
oharboe's avatar
oharboe committed
2537

2538
	return retval;
2539
2540
}

2541
static int handle_verify_image_command_internal(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, int verify)
2542
{
2543
	uint8_t *buffer;
2544
2545
	uint32_t buf_cnt;
	uint32_t image_size;
2546
	int i;
2547
	int retval, retvaltemp;
2548
2549
	uint32_t checksum = 0;
	uint32_t mem_checksum = 0;
2550

oharboe's avatar
oharboe committed
2551
2552
	image_t image;

2553
2554
	duration_t duration;
	char *duration_text;
oharboe's avatar
oharboe committed
2555

2556
	target_t *target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
2557

2558
2559
	if (argc < 1)
	{
2560
		return ERROR_COMMAND_SYNTAX_ERROR;
2561
	}
oharboe's avatar
oharboe committed
2562

2563
2564
	if (!target)
	{
2565
		LOG_ERROR("no target selected");
2566
		return ERROR_FAIL;
2567
	}
oharboe's avatar
oharboe committed
2568

2569
	duration_start_measure(&duration);
oharboe's avatar
oharboe committed
2570

2571
2572
	if (argc >= 2)
	{
2573
		uint32_t addr;
2574
2575
2576
2577
		retval = parse_u32(args[1], &addr);
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
		image.base_address = addr;
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
		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
2588
	if ((retval = image_open(&image, args[0], (argc == 3) ? args[2] : NULL)) != ERROR_OK)
2589
	{
2590
		return retval;
2591
	}
oharboe's avatar
oharboe committed
2592

2593
	image_size = 0x0;
zwelch's avatar
zwelch committed
2594
	retval = ERROR_OK;
2595
2596
2597
2598
2599
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
2600
2601
			command_print(cmd_ctx,
						  "error allocating buffer for section (%d bytes)",
duane's avatar
duane committed
2602
						  (int)(image.sections[i].size));
2603
2604
2605
2606
2607
			break;
		}
		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
2608
			break;
2609
		}
oharboe's avatar
oharboe committed
2610

oharboe's avatar
oharboe committed
2611
		if (verify)
2612
		{
oharboe's avatar
oharboe committed
2613
			/* calculate checksum of image */
2614
			image_calculate_checksum(buffer, buf_cnt, &checksum);
oharboe's avatar
oharboe committed
2615

oharboe's avatar
oharboe committed
2616
			retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
2617
			if (retval != ERROR_OK)
2618
			{
oharboe's avatar
oharboe committed
2619
2620
				free(buffer);
				break;
2621
			}
oharboe's avatar
oharboe committed
2622

2623
			if (checksum != mem_checksum)
2624
			{
oharboe's avatar
oharboe committed
2625
				/* failed crc checksum, fall back to a binary compare */
2626
				uint8_t *data;
oharboe's avatar
oharboe committed
2627
2628
2629

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

2630
				data = (uint8_t*)malloc(buf_cnt);
oharboe's avatar
oharboe committed
2631
2632
2633
2634
2635

				/* Can we use 32bit word accesses? */
				int size = 1;
				int count = buf_cnt;
				if ((count % 4) == 0)
2636
				{
oharboe's avatar
oharboe committed
2637
2638
2639
					size *= 4;
					count /= 4;
				}
zwelch's avatar
zwelch committed
2640
				retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
oharboe's avatar
oharboe committed
2641
2642
				if (retval == ERROR_OK)
				{
2643
					uint32_t t;
oharboe's avatar
oharboe committed
2644
					for (t = 0; t < buf_cnt; t++)
oharboe's avatar
oharboe committed
2645
					{
oharboe's avatar
oharboe committed
2646
2647
						if (data[t] != buffer[t])
						{
2648
2649
2650
2651
							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
2652
										  buffer[t]);
oharboe's avatar
oharboe committed
2653
2654
							free(data);
							free(buffer);
zwelch's avatar
zwelch committed
2655
							retval = ERROR_FAIL;
oharboe's avatar
oharboe committed
2656
2657
							goto done;
						}
zwelch's avatar
zwelch committed
2658
						if ((t%16384) == 0)
oharboe's avatar
oharboe committed
2659
2660
2661
						{
							keep_alive();
						}
oharboe's avatar
oharboe committed
2662
					}
2663
				}
oharboe's avatar
oharboe committed
2664

oharboe's avatar
oharboe committed
2665
2666
2667
2668
				free(data);
			}
		} else
		{
2669
2670
			command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "",
						  image.sections[i].base_address,
duane's avatar
duane committed
2671
						  buf_cnt);
2672
		}
oharboe's avatar
oharboe committed
2673

2674
2675
2676
		free(buffer);
		image_size += buf_cnt;
	}
oharboe's avatar
oharboe committed
2677
done:
2678

zwelch's avatar
zwelch committed
2679
	if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2680
2681
2682
2683
2684
	{
		image_close(&image);
		return retvaltemp;
	}

zwelch's avatar
zwelch committed
2685
	if (retval == ERROR_OK)
2686
	{
2687
2688
		command_print(cmd_ctx, "verified %u bytes in %s",
					  (unsigned int)image_size,
duane's avatar
duane committed
2689
					  duration_text);
2690
	}
2691
	free(duration_text);
oharboe's avatar
oharboe committed
2692

2693
	image_close(&image);
oharboe's avatar
oharboe committed
2694

2695
	return retval;
2696
2697
}

2698
static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
oharboe's avatar
oharboe committed
2699
2700
2701
2702
{
	return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 1);
}

2703
static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
oharboe's avatar
oharboe committed
2704
2705
2706
2707
{
	return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 0);
}

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

		breakpoint = breakpoint->next;
2732
	}
zwelch's avatar
zwelch committed
2733
2734
2735
2736
	return ERROR_OK;
}

static int handle_bp_command_set(struct command_context_s *cmd_ctx,
2737
		uint32_t addr, uint32_t length, int hw)
zwelch's avatar
zwelch committed
2738
2739
2740
2741
{
	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
2742
		command_print(cmd_ctx, "breakpoint set at 0x%8.8" PRIx32 "", addr);
2743
	else
zwelch's avatar
zwelch committed
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
		LOG_ERROR("Failure setting breakpoint");
	return retval;
}

static int handle_bp_command(struct command_context_s *cmd_ctx,
		char *cmd, char **args, int argc)
{
	if (argc == 0)
		return handle_bp_command_list(cmd_ctx);

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

2760
	uint32_t addr;
2761
2762
2763
2764
	int retval = parse_u32(args[0], &addr);
	if (ERROR_OK != retval)
		return retval;

2765
	uint32_t length;
2766
2767
2768
	retval = parse_u32(args[1], &length);
	if (ERROR_OK != retval)
		return retval;
zwelch's avatar
zwelch committed
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779

	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);
2780
2781
}

2782
static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2783
{
2784
2785
	if (argc != 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
2786

2787
	uint32_t addr;
2788
2789
2790
2791
2792
2793
	int retval = parse_u32(args[0], &addr);
	if (ERROR_OK != retval)
		return retval;

	target_t *target = get_current_target(cmd_ctx);
	breakpoint_remove(target, addr);
2794
2795
2796
2797

	return ERROR_OK;
}

2798
static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2799
2800
2801
2802
2803
2804
2805
2806
2807
{
	target_t *target = get_current_target(cmd_ctx);

	if (argc == 0)
	{
		watchpoint_t *watchpoint = target->watchpoints;

		while (watchpoint)
		{
2808
2809
2810
			command_print(cmd_ctx,
						  "address: 0x%8.8" PRIx32 ", len: 0x%8.8x, r/w/a: %i, value: 0x%8.8" PRIx32 ", mask: 0x%8.8" PRIx32 "",
						  watchpoint->address,
duane's avatar
duane committed
2811
2812
2813
2814
						  watchpoint->length,
						  (int)(watchpoint->rw),
						  watchpoint->value,
						  watchpoint->mask);
2815
2816
			watchpoint = watchpoint->next;
		}
2817
		return ERROR_OK;
oharboe's avatar
oharboe committed
2818
2819
	}

2820
	enum watchpoint_rw type = WPT_ACCESS;
2821
2822
2823
2824
	uint32_t addr = 0;
	uint32_t length = 0;
	uint32_t data_value = 0x0;
	uint32_t data_mask = 0xffffffff;
2825
	int retval;
oharboe's avatar
oharboe committed
2826

2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
	switch (argc)
	{
	case 5:
		retval = parse_u32(args[4], &data_mask);
		if (ERROR_OK != retval)
			return retval;
		// fall through
	case 4:
		retval = parse_u32(args[3], &data_value);
		if (ERROR_OK != retval)
			return retval;
		// fall through
	case 3:
zwelch's avatar
zwelch committed
2840
		switch (args[2][0])
2841
		{
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
		case 'r':
			type = WPT_READ;
			break;
		case 'w':
			type = WPT_WRITE;
			break;
		case 'a':
			type = WPT_ACCESS;
			break;
		default:
			LOG_ERROR("invalid watchpoint mode ('%c')", args[2][0]);
			return ERROR_COMMAND_SYNTAX_ERROR;