target.c 113 KB
Newer Older
zwelch's avatar
zwelch committed
2001
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2002

zwelch's avatar
zwelch committed
2003
2004
	target_t *target = get_current_target(cmd_ctx);
	target_handle_event(target, TARGET_EVENT_OLD_pre_resume);
oharboe's avatar
oharboe committed
2005

zwelch's avatar
zwelch committed
2006
2007
2008
	/* with no args, resume from current pc, addr = 0,
	 * with one arguments, addr = args[0],
	 * handle breakpoints, not debugging */
2009
	uint32_t addr = 0;
zwelch's avatar
zwelch committed
2010
	if (argc == 1)
2011
2012
2013
2014
	{
		int retval = parse_u32(args[0], &addr);
		if (ERROR_OK != retval)
			return retval;
2015
		current = 0;
2016
	}
oharboe's avatar
oharboe committed
2017

2018
	return target_resume(target, current, addr, 1, 0);
2019
2020
}

2021
static int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2022
{
zwelch's avatar
zwelch committed
2023
2024
	if (argc > 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2025

2026
	LOG_DEBUG("-");
oharboe's avatar
oharboe committed
2027

zwelch's avatar
zwelch committed
2028
2029
2030
	/* with no args, step from current pc, addr = 0,
	 * with one argument addr = args[0],
	 * handle breakpoints, debugging */
2031
	uint32_t addr = 0;
2032
	if (argc == 1)
2033
2034
2035
2036
2037
	{
		int retval = parse_u32(args[0], &addr);
		if (ERROR_OK != retval)
			return retval;
	}
oharboe's avatar
oharboe committed
2038

zwelch's avatar
zwelch committed
2039
2040
	target_t *target = get_current_target(cmd_ctx);
	return target->type->step(target, 0, addr, 1);
2041
2042
}

2043
static void handle_md_output(struct command_context_s *cmd_ctx,
2044
		struct target_s *target, uint32_t address, unsigned size,
2045
		unsigned count, const uint8_t *buffer)
2046
2047
2048
2049
2050
2051
2052
2053
2054
{
	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) {
2055
2056
2057
	case 4: value_fmt = "%8.8x "; break;
	case 2: value_fmt = "%4.2x "; break;
	case 1: value_fmt = "%2.2x "; break;
2058
2059
2060
2061
	default:
		LOG_ERROR("invalid memory read size: %u", size);
		exit(-1);
	}
2062

2063
2064
2065
2066
2067
2068
	for (unsigned i = 0; i < count; i++)
	{
		if (i % line_modulo == 0)
		{
			output_len += snprintf(output + output_len,
					sizeof(output) - output_len,
duane's avatar
duane committed
2069
2070
					"0x%8.8x: ", 
					(unsigned)(address + (i*size)));
2071
		}
2072

2073
		uint32_t value=0;
2074
		const uint8_t *value_ptr = buffer + i * size;
2075
2076
2077
2078
2079
2080
2081
2082
		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);
2083

2084
2085
2086
2087
2088
2089
2090
		if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
		{
			command_print(cmd_ctx, "%s", output);
			output_len = 0;
		}
	}
}
2091

2092
2093
static int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
2094
	if (argc < 1)
2095
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2096

2097
2098
2099
2100
2101
2102
	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;
2103
2104
	}

2105
	uint32_t address;
2106
2107
2108
	int retval = parse_u32(args[0], &address);
	if (ERROR_OK != retval)
		return retval;
oharboe's avatar
oharboe committed
2109

2110
2111
	unsigned count = 1;
	if (argc == 2)
2112
2113
2114
2115
2116
	{
		retval = parse_uint(args[1], &count);
		if (ERROR_OK != retval)
			return retval;
	}
oharboe's avatar
oharboe committed
2117

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

2120
	target_t *target = get_current_target(cmd_ctx);
2121
	retval = target_read_memory(target,
2122
2123
2124
				address, size, count, buffer);
	if (ERROR_OK == retval)
		handle_md_output(cmd_ctx, target, address, size, count, buffer);
2125
2126

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

oharboe's avatar
oharboe committed
2128
	return retval;
2129
2130
}

2131
static int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2132
{
oharboe's avatar
oharboe committed
2133
2134
	 if ((argc < 2) || (argc > 3))
		return ERROR_COMMAND_SYNTAX_ERROR;
2135

2136
	uint32_t address;
2137
2138
2139
2140
	int retval = parse_u32(args[0], &address);
	if (ERROR_OK != retval)
		return retval;

2141
	uint32_t value;
2142
2143
2144
2145
2146
	retval = parse_u32(args[1], &value);
	if (ERROR_OK != retval)
		return retval;

	unsigned count = 1;
oharboe's avatar
oharboe committed
2147
	if (argc == 3)
2148
2149
2150
2151
2152
	{
		retval = parse_uint(args[2], &count);
		if (ERROR_OK != retval)
			return retval;
	}
oharboe's avatar
oharboe committed
2153

2154
2155
	target_t *target = get_current_target(cmd_ctx);
	unsigned wordsize;
2156
	uint8_t value_buf[4];
2157
2158
2159
	switch (cmd[2])
	{
		case 'w':
oharboe's avatar
oharboe committed
2160
			wordsize = 4;
2161
2162
2163
			target_buffer_set_u32(target, value_buf, value);
			break;
		case 'h':
oharboe's avatar
oharboe committed
2164
			wordsize = 2;
2165
2166
2167
			target_buffer_set_u16(target, value_buf, value);
			break;
		case 'b':
oharboe's avatar
oharboe committed
2168
			wordsize = 1;
2169
2170
2171
			value_buf[0] = value;
			break;
		default:
oharboe's avatar
oharboe committed
2172
			return ERROR_COMMAND_SYNTAX_ERROR;
2173
	}
2174
	for (unsigned i = 0; i < count; i++)
2175
	{
2176
		retval = target_write_memory(target,
2177
2178
				address + i * wordsize, wordsize, 1, value_buf);
		if (ERROR_OK != retval)
oharboe's avatar
oharboe committed
2179
			return retval;
2180
		keep_alive();
2181
2182
2183
2184
2185
2186
	}

	return ERROR_OK;

}

2187
static int parse_load_image_command_args(char **args, int argc,
2188
		image_t *image, uint32_t *min_address, uint32_t *max_address)
2189
{
2190
	if (argc < 1 || argc > 5)
2191
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2192

2193
2194
	/* a base address isn't always necessary,
	 * default to 0x0 (i.e. don't relocate) */
2195
2196
	if (argc >= 2)
	{
2197
		uint32_t addr;
2198
		int retval = parse_u32(args[1], &addr);
2199
2200
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
2201
2202
		image->base_address = addr;
		image->base_address_set = 1;
2203
2204
	}
	else
2205
		image->base_address_set = 0;
oharboe's avatar
oharboe committed
2206

2207
	image->start_address_set = 0;
oharboe's avatar
oharboe committed
2208

2209
	if (argc >= 4)
2210
	{
2211
		int retval = parse_u32(args[3], min_address);
2212
2213
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
2214
	}
2215
	if (argc == 5)
2216
	{
2217
		int retval = parse_u32(args[4], max_address);
2218
2219
2220
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
		// use size (given) to find max (required)
2221
		*max_address += *min_address;
2222
	}
oharboe's avatar
oharboe committed
2223

2224
	if (*min_address > *max_address)
2225
		return ERROR_COMMAND_SYNTAX_ERROR;
oharboe's avatar
oharboe committed
2226

2227
2228
2229
2230
2231
	return ERROR_OK;
}

static int handle_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
2232
	uint8_t *buffer;
2233
2234
2235
2236
	uint32_t buf_cnt;
	uint32_t image_size;
	uint32_t min_address = 0;
	uint32_t max_address = 0xffffffff;
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
	int i;
	int retvaltemp;

	image_t image;

	duration_t duration;
	char *duration_text;
	
	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);
2251
	duration_start_measure(&duration);
oharboe's avatar
oharboe committed
2252

2253
2254
2255
2256
	if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
	{
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
2257

2258
	image_size = 0x0;
2259
	retval = ERROR_OK;
2260
2261
2262
2263
2264
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
duane's avatar
duane committed
2265
2266
2267
			command_print(cmd_ctx, 
						  "error allocating buffer for section (%d bytes)", 
						  (int)(image.sections[i].size));
2268
2269
			break;
		}
oharboe's avatar
oharboe committed
2270

2271
2272
2273
		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
2274
2275
			break;
		}
oharboe's avatar
oharboe committed
2276

2277
2278
		uint32_t offset=0;
		uint32_t length=buf_cnt;
oharboe's avatar
oharboe committed
2279

2280
		/* DANGER!!! beware of unsigned comparision here!!! */
oharboe's avatar
oharboe committed
2281

2282
2283
		if ((image.sections[i].base_address+buf_cnt>=min_address)&&
				(image.sections[i].base_address<max_address))
2284
		{
2285
2286
2287
2288
			if (image.sections[i].base_address<min_address)
			{
				/* clip addresses below */
				offset+=min_address-image.sections[i].base_address;
zwelch's avatar
zwelch committed
2289
				length -= offset;
2290
			}
oharboe's avatar
oharboe committed
2291

2292
2293
			if (image.sections[i].base_address+buf_cnt>max_address)
			{
zwelch's avatar
zwelch committed
2294
				length -= (image.sections[i].base_address+buf_cnt)-max_address;
2295
			}
oharboe's avatar
oharboe committed
2296

2297
2298
2299
2300
2301
2302
			if ((retval = target_write_buffer(target, image.sections[i].base_address+offset, length, buffer+offset)) != ERROR_OK)
			{
				free(buffer);
				break;
			}
			image_size += length;
duane's avatar
duane committed
2303
2304
2305
			command_print(cmd_ctx, "%u byte written at address 0x%8.8" PRIx32 "", 
						  (unsigned int)length, 
						  image.sections[i].base_address+offset);
2306
		}
oharboe's avatar
oharboe committed
2307

2308
2309
2310
		free(buffer);
	}

zwelch's avatar
zwelch committed
2311
	if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2312
2313
2314
2315
2316
	{
		image_close(&image);
		return retvaltemp;
	}

2317
2318
	if (retval==ERROR_OK)
	{
duane's avatar
duane committed
2319
2320
2321
		command_print(cmd_ctx, "downloaded %u byte in %s", 
					  (unsigned int)image_size, 
					  duration_text);
2322
	}
2323
	free(duration_text);
oharboe's avatar
oharboe committed
2324

2325
2326
	image_close(&image);

2327
	return retval;
2328
2329
2330

}

2331
static int handle_dump_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2332
2333
{
	fileio_t fileio;
oharboe's avatar
oharboe committed
2334

2335
	uint8_t buffer[560];
2336
	int retvaltemp;
oharboe's avatar
oharboe committed
2337

2338
2339
	duration_t duration;
	char *duration_text;
oharboe's avatar
oharboe committed
2340

2341
2342
2343
2344
2345
2346
2347
2348
	target_t *target = get_current_target(cmd_ctx);

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

2349
	uint32_t address;
2350
2351
2352
2353
	int retval = parse_u32(args[1], &address);
	if (ERROR_OK != retval)
		return retval;

2354
	uint32_t size;
2355
2356
2357
	retval = parse_u32(args[2], &size);
	if (ERROR_OK != retval)
		return retval;
2358
2359
2360
2361
2362

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

2364
	duration_start_measure(&duration);
oharboe's avatar
oharboe committed
2365

2366
2367
	while (size > 0)
	{
2368
2369
		uint32_t size_written;
		uint32_t this_run_size = (size > 560) ? 560 : size;
oharboe's avatar
oharboe committed
2370

2371
		retval = target_read_buffer(target, address, this_run_size, buffer);
2372
2373
2374
2375
		if (retval != ERROR_OK)
		{
			break;
		}
oharboe's avatar
oharboe committed
2376

2377
2378
2379
2380
2381
		retval = fileio_write(&fileio, this_run_size, buffer, &size_written);
		if (retval != ERROR_OK)
		{
			break;
		}
oharboe's avatar
oharboe committed
2382

2383
2384
2385
2386
		size -= this_run_size;
		address += this_run_size;
	}

zwelch's avatar
zwelch committed
2387
	if ((retvaltemp = fileio_close(&fileio)) != ERROR_OK)
2388
2389
		return retvaltemp;

zwelch's avatar
zwelch committed
2390
	if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2391
		return retvaltemp;
2392

2393
2394
	if (retval==ERROR_OK)
	{
2395
2396
		command_print(cmd_ctx, "dumped %lld byte in %s",
				fileio.size, duration_text);
2397
		free(duration_text);
2398
	}
oharboe's avatar
oharboe committed
2399

2400
	return retval;
2401
2402
}

2403
static int handle_verify_image_command_internal(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, int verify)
2404
{
2405
	uint8_t *buffer;
2406
2407
	uint32_t buf_cnt;
	uint32_t image_size;
2408
	int i;
2409
	int retval, retvaltemp;
2410
2411
	uint32_t checksum = 0;
	uint32_t mem_checksum = 0;
2412

oharboe's avatar
oharboe committed
2413
2414
	image_t image;

2415
2416
	duration_t duration;
	char *duration_text;
oharboe's avatar
oharboe committed
2417

2418
	target_t *target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
2419

2420
2421
	if (argc < 1)
	{
2422
		return ERROR_COMMAND_SYNTAX_ERROR;
2423
	}
oharboe's avatar
oharboe committed
2424

2425
2426
	if (!target)
	{
2427
		LOG_ERROR("no target selected");
2428
		return ERROR_FAIL;
2429
	}
oharboe's avatar
oharboe committed
2430

2431
	duration_start_measure(&duration);
oharboe's avatar
oharboe committed
2432

2433
2434
	if (argc >= 2)
	{
2435
		uint32_t addr;
2436
2437
2438
2439
		retval = parse_u32(args[1], &addr);
		if (ERROR_OK != retval)
			return ERROR_COMMAND_SYNTAX_ERROR;
		image.base_address = addr;
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
		image.base_address_set = 1;
	}
	else
	{
		image.base_address_set = 0;
		image.base_address = 0x0;
	}

	image.start_address_set = 0;

2450
	if ((retval=image_open(&image, args[0], (argc == 3) ? args[2] : NULL)) != ERROR_OK)
2451
	{
2452
		return retval;
2453
	}
oharboe's avatar
oharboe committed
2454

2455
	image_size = 0x0;
2456
	retval=ERROR_OK;
2457
2458
2459
2460
2461
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
duane's avatar
duane committed
2462
2463
2464
			command_print(cmd_ctx, 
						  "error allocating buffer for section (%d bytes)", 
						  (int)(image.sections[i].size));
2465
2466
2467
2468
2469
			break;
		}
		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
2470
			break;
2471
		}
oharboe's avatar
oharboe committed
2472

oharboe's avatar
oharboe committed
2473
		if (verify)
2474
		{
oharboe's avatar
oharboe committed
2475
2476
			/* calculate checksum of image */
			image_calculate_checksum( buffer, buf_cnt, &checksum );
oharboe's avatar
oharboe committed
2477

oharboe's avatar
oharboe committed
2478
			retval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);
zwelch's avatar
zwelch committed
2479
			if ( retval != ERROR_OK )
2480
			{
oharboe's avatar
oharboe committed
2481
2482
				free(buffer);
				break;
2483
			}
oharboe's avatar
oharboe committed
2484

zwelch's avatar
zwelch committed
2485
			if ( checksum != mem_checksum )
2486
			{
oharboe's avatar
oharboe committed
2487
				/* failed crc checksum, fall back to a binary compare */
2488
				uint8_t *data;
oharboe's avatar
oharboe committed
2489
2490
2491

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

2492
				data = (uint8_t*)malloc(buf_cnt);
oharboe's avatar
oharboe committed
2493
2494
2495
2496
2497

				/* Can we use 32bit word accesses? */
				int size = 1;
				int count = buf_cnt;
				if ((count % 4) == 0)
2498
				{
oharboe's avatar
oharboe committed
2499
2500
2501
					size *= 4;
					count /= 4;
				}
zwelch's avatar
zwelch committed
2502
				retval = target_read_memory(target, image.sections[i].base_address, size, count, data);
oharboe's avatar
oharboe committed
2503
2504
				if (retval == ERROR_OK)
				{
2505
					uint32_t t;
oharboe's avatar
oharboe committed
2506
					for (t = 0; t < buf_cnt; t++)
oharboe's avatar
oharboe committed
2507
					{
oharboe's avatar
oharboe committed
2508
2509
						if (data[t] != buffer[t])
						{
duane's avatar
duane committed
2510
2511
2512
2513
2514
							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], 
										  buffer[t]);
oharboe's avatar
oharboe committed
2515
2516
2517
2518
2519
2520
2521
2522
2523
							free(data);
							free(buffer);
							retval=ERROR_FAIL;
							goto done;
						}
						if ((t%16384)==0)
						{
							keep_alive();
						}
oharboe's avatar
oharboe committed
2524
					}
2525
				}
oharboe's avatar
oharboe committed
2526

oharboe's avatar
oharboe committed
2527
2528
2529
2530
				free(data);
			}
		} else
		{
duane's avatar
duane committed
2531
2532
2533
			command_print(cmd_ctx, "address 0x%08" PRIx32 " length 0x%08" PRIx32 "", 
						  image.sections[i].base_address, 
						  buf_cnt);
2534
		}
oharboe's avatar
oharboe committed
2535

2536
2537
2538
		free(buffer);
		image_size += buf_cnt;
	}
oharboe's avatar
oharboe committed
2539
done:
2540

zwelch's avatar
zwelch committed
2541
	if ((retvaltemp = duration_stop_measure(&duration, &duration_text)) != ERROR_OK)
2542
2543
2544
2545
2546
	{
		image_close(&image);
		return retvaltemp;
	}

2547
2548
	if (retval==ERROR_OK)
	{
duane's avatar
duane committed
2549
2550
2551
		command_print(cmd_ctx, "verified %u bytes in %s", 
					  (unsigned int)image_size, 
					  duration_text);
2552
	}
2553
	free(duration_text);
oharboe's avatar
oharboe committed
2554

2555
	image_close(&image);
oharboe's avatar
oharboe committed
2556

2557
	return retval;
2558
2559
}

2560
static int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
oharboe's avatar
oharboe committed
2561
2562
2563
2564
{
	return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 1);
}

2565
static int handle_test_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
oharboe's avatar
oharboe committed
2566
2567
2568
2569
{
	return handle_verify_image_command_internal(cmd_ctx, cmd, args, argc, 0);
}

zwelch's avatar
zwelch committed
2570
static int handle_bp_command_list(struct command_context_s *cmd_ctx)
2571
2572
{
	target_t *target = get_current_target(cmd_ctx);
zwelch's avatar
zwelch committed
2573
2574
	breakpoint_t *breakpoint = target->breakpoints;
	while (breakpoint)
2575
	{
zwelch's avatar
zwelch committed
2576
		if (breakpoint->type == BKPT_SOFT)
2577
		{
zwelch's avatar
zwelch committed
2578
2579
			char* buf = buf_to_str(breakpoint->orig_instr,
					breakpoint->length, 16);
duane's avatar
duane committed
2580
2581
2582
			command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i, 0x%s",
					breakpoint->address, 
					breakpoint->length,
zwelch's avatar
zwelch committed
2583
2584
					breakpoint->set, buf);
			free(buf);
2585
2586
2587
		}
		else
		{
duane's avatar
duane committed
2588
2589
2590
			command_print(cmd_ctx, "0x%8.8" PRIx32 ", 0x%x, %i",
						  breakpoint->address, 
						  breakpoint->length, breakpoint->set);
2591
		}
zwelch's avatar
zwelch committed
2592
2593

		breakpoint = breakpoint->next;
2594
	}
zwelch's avatar
zwelch committed
2595
2596
2597
2598
	return ERROR_OK;
}

static int handle_bp_command_set(struct command_context_s *cmd_ctx,
2599
		uint32_t addr, uint32_t length, int hw)
zwelch's avatar
zwelch committed
2600
2601
2602
2603
{
	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
2604
		command_print(cmd_ctx, "breakpoint set at 0x%8.8" PRIx32 "", addr);
2605
	else
zwelch's avatar
zwelch committed
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
		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)
2617
2618
	{
		command_print(cmd_ctx, "usage: bp <address> <length> ['hw']");
zwelch's avatar
zwelch committed
2619
		return ERROR_COMMAND_SYNTAX_ERROR;
2620
2621
	}

2622
	uint32_t addr;
2623
2624
2625
2626
	int retval = parse_u32(args[0], &addr);
	if (ERROR_OK != retval)
		return retval;

2627
	uint32_t length;
2628
2629
2630
	retval = parse_u32(args[1], &length);
	if (ERROR_OK != retval)
		return retval;
zwelch's avatar
zwelch committed
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641

	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);
2642
2643
}

2644
static int handle_rbp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2645
{
2646
2647
	if (argc != 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
2648

2649
	uint32_t addr;
2650
2651
2652
2653
2654
2655
	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);
2656
2657
2658
2659

	return ERROR_OK;
}

2660
static int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2661
2662
2663
2664
2665
2666
2667
2668
2669
{
	target_t *target = get_current_target(cmd_ctx);

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

		while (watchpoint)
		{
duane's avatar
duane committed
2670
2671
2672
2673
2674
2675
2676
			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, 
						  watchpoint->length,
						  (int)(watchpoint->rw),
						  watchpoint->value,
						  watchpoint->mask);
2677
2678
			watchpoint = watchpoint->next;
		}
2679
		return ERROR_OK;
oharboe's avatar
oharboe committed
2680
2681
	}

2682
	enum watchpoint_rw type = WPT_ACCESS;
2683
2684
2685
2686
	uint32_t addr = 0;
	uint32_t length = 0;
	uint32_t data_value = 0x0;
	uint32_t data_mask = 0xffffffff;
2687
	int retval;
oharboe's avatar
oharboe committed
2688

2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
	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
2702
		switch (args[2][0])
2703
		{
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
		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;
2716
		}
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
		// fall through
	case 2:
		retval = parse_u32(args[1], &length);
		if (ERROR_OK != retval)
			return retval;
		retval = parse_u32(args[0], &addr);
		if (ERROR_OK != retval)
			return retval;
		break;

	default:
2728
		command_print(cmd_ctx, "usage: wp <address> <length> [r/w/a] [value] [mask]");
2729
		return ERROR_COMMAND_SYNTAX_ERROR;
2730
	}
oharboe's avatar
oharboe committed
2731

2732
2733
2734
2735
2736
2737
	retval = watchpoint_add(target, addr, length, type,
			data_value, data_mask);
	if (ERROR_OK != retval)
		LOG_ERROR("Failure setting watchpoints");

	return retval;
2738
2739
}

2740
static int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2741
{
2742
2743
	if (argc != 1)
		return ERROR_COMMAND_SYNTAX_ERROR;
2744

2745
	uint32_t addr;
2746
2747
2748
2749
	int retval = parse_u32(args[0], &addr);
	if (ERROR_OK != retval)
		return retval;

2750
	target_t *target = get_current_target(cmd_ctx);
2751
	watchpoint_remove(target, addr);
oharboe's avatar
oharboe committed
2752

2753
2754
2755
2756
	return ERROR_OK;
}


2757
2758
2759
2760
2761
2762
2763
2764
2765
/**
 * Translate a virtual address to a physical address.
 *
 * The low-level target implementation must have logged a detailed error
 * which is forwarded to telnet/GDB session.
 */
static int handle_virt2phys_command(command_context_t *cmd_ctx,
		char *cmd, char **args, int argc)
{
2766
2767
2768
	if (argc != 1)
		return ERROR_COMMAND_SYNTAX_ERROR;

2769
	uint32_t va;
2770
2771
2772
	int retval = parse_u32(args[0], &va);
	if (ERROR_OK != retval)
		return retval;
2773
	uint32_t pa;
2774

2775
2776
	target_t *target = get_current_target(cmd_ctx);
	retval = target->type->virt2phys(target, va, &pa);
2777
	if (retval == ERROR_OK)
duane's avatar
duane committed
2778
		command_print(cmd_ctx, "Physical address 0x%08" PRIx32 "", pa);
2779

2780
2781
	return retval;
}
2782

2783
2784
static void writeData(FILE *f, const void *data, size_t len)
{
2785
	size_t written = fwrite(data, 1, len, f);
2786
	if (written != len)
2787
		LOG_ERROR("failed to write %zu bytes: %s", len, strerror(errno));
2788
2789
}

2790
2791
2792
2793
2794
2795
static void writeLong(FILE *f, int l)
{
	int i;
	for (i=0; i<4; i++)
	{
		char c=(l>>(i*8))&0xff;
2796
		writeData(f, &c, 1);
2797
	}
oharboe's avatar
oharboe committed
2798

2799
}
2800

2801
2802
static void writeString(FILE *f, char *s)
{
2803
	writeData(f, s, strlen(s));
2804
2805
}

2806
/* Dump a gmon.out histogram file. */
2807
static void writeGmon(uint32_t *samples, uint32_t sampleNum, char *filename)
2808
{
2809
	uint32_t i;
2810
2811
2812
	FILE *f=fopen(filename, "w");
	if (f==NULL)
		return;
2813
	writeString(f, "gmon");
2814
2815
2816
2817
	writeLong(f, 0x00000001); /* Version */
	writeLong(f, 0); /* padding */
	writeLong(f, 0); /* padding */
	writeLong(f, 0); /* padding */
oharboe's avatar
oharboe committed
2818

2819
	uint8_t zero = 0;  /* GMON_TAG_TIME_HIST */
2820
	writeData(f, &zero, 1);
2821

2822
	/* figure out bucket size */
2823
2824
	uint32_t min=samples[0];
	uint32_t max=samples[0];
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
	for (i=0; i<sampleNum; i++)
	{
		if (min>samples[i])
		{
			min=samples[i];
		}
		if (max<samples[i])
		{
			max=samples[i];
		}
	}

	int addressSpace=(max-min+1);
oharboe's avatar
oharboe committed
2838

2839
2840
	static const uint32_t maxBuckets = 256 * 1024; /* maximum buckets. */
	uint32_t length = addressSpace;
2841
2842
	if (length > maxBuckets)
	{
oharboe's avatar
oharboe committed
2843
		length=maxBuckets;
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
	}
	int *buckets=malloc(sizeof(int)*length);
	if (buckets==NULL)
	{
		fclose(f);
		return;
	}
	memset(buckets, 0, sizeof(int)*length);
	for (i=0; i<sampleNum;i++)
	{
2854
		uint32_t address=samples[i];
2855
2856
2857
		long long a=address-min;
		long long b=length-1;
		long long c=addressSpace-1;
2858
		int index=(a*b)/c; /* danger!!!! int32 overflows */
2859
2860
		buckets[index]++;
	}
oharboe's avatar
oharboe committed
2861

2862
2863
2864
2865
2866
	/* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
	writeLong(f, min); 			/* low_pc */
	writeLong(f, max);			/* high_pc */
	writeLong(f, length);		/* # of samples */
	writeLong(f, 64000000); 	/* 64MHz */
2867
2868
	writeString(f, "seconds");
	for (i=0; i<(15-strlen("seconds")); i++)
2869
		writeData(f, &zero, 1);
2870
	writeString(f, "s");
oharboe's avatar
oharboe committed
2871

2872
	/*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */
oharboe's avatar
oharboe committed
2873

2874
	char *data=malloc(2*length);
zwelch's avatar
zwelch committed
2875
	if (data != NULL)
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
	{
		for (i=0; i<length;i++)
		{
			int val;
			val=buckets[i];
			if (val>65535)
			{
				val=65535;
			}
			data[i*2]=val&0xff;
			data[i*2+1]=(val>>8)&0xff;
		}
		free(buckets);
2889
		writeData(f, data, length * 2);
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
		free(data);
	} else
	{
		free(buckets);
	}

	fclose(f);
}

/* profiling samples the CPU PC as quickly as OpenOCD is able, which will be used as a random sampling of PC */
2900
static int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2901
2902
2903
{
	target_t *target = get_current_target(cmd_ctx);
	struct timeval timeout, now;
oharboe's avatar
oharboe committed
2904

2905
	gettimeofday(&timeout, NULL);
zwelch's avatar
zwelch committed
2906
	if (argc != 2)
2907
2908
2909
	{
		return ERROR_COMMAND_SYNTAX_ERROR;
	}
2910
2911
2912