arm7_9_common.c 77.2 KB
Newer Older
2001
2002
2003
				u32 reg_list;
				thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
				reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2004

2005
2006
2007
2008
				for (i = 1; i <= thisrun_accesses; i++)
				{
					if (i > last_reg)
						last_reg = i;
2009
2010
					reg[i] = target_buffer_get_u32(target, buffer);
					buffer += 4;
2011
				}
2012

2013
				arm7_9->write_core_regs(target, reg_list, reg);
2014

2015
				arm7_9->store_word_regs(target, reg_list);
2016

2017
2018
2019
				/* fast memory writes are only safe when the target is running
				 * from a sufficiently high clock (32 kHz is usually too slow)
				 */
2020
				if (arm7_9->fast_memory_access)
2021
2022
2023
					arm7_9_execute_fast_sys_speed(target);
				else
					arm7_9_execute_sys_speed(target);
2024

2025
				num_accesses += thisrun_accesses;
2026
			}
2027
2028
2029
2030
2031
2032
2033
			break;
		case 2:
			while (num_accesses < count)
			{
				u32 reg_list;
				thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
				reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2034

2035
2036
2037
2038
				for (i = 1; i <= thisrun_accesses; i++)
				{
					if (i > last_reg)
						last_reg = i;
2039
2040
					reg[i] = target_buffer_get_u16(target, buffer) & 0xffff;
					buffer += 2;
2041
				}
2042

2043
				arm7_9->write_core_regs(target, reg_list, reg);
2044

2045
2046
2047
				for (i = 1; i <= thisrun_accesses; i++)
				{
					arm7_9->store_hword_reg(target, i);
2048

2049
2050
2051
					/* fast memory writes are only safe when the target is running
					 * from a sufficiently high clock (32 kHz is usually too slow)
					 */
2052
					if (arm7_9->fast_memory_access)
2053
2054
2055
2056
						arm7_9_execute_fast_sys_speed(target);
					else
						arm7_9_execute_sys_speed(target);
				}
2057

2058
				num_accesses += thisrun_accesses;
2059
			}
2060
2061
2062
2063
2064
2065
2066
			break;
		case 1:
			while (num_accesses < count)
			{
				u32 reg_list;
				thisrun_accesses = ((count - num_accesses) >= 14) ? 14 : (count - num_accesses);
				reg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;
2067

2068
2069
2070
2071
				for (i = 1; i <= thisrun_accesses; i++)
				{
					if (i > last_reg)
						last_reg = i;
2072
					reg[i] = *buffer++ & 0xff;
2073
				}
2074

2075
				arm7_9->write_core_regs(target, reg_list, reg);
2076

2077
2078
2079
2080
2081
2082
				for (i = 1; i <= thisrun_accesses; i++)
				{
					arm7_9->store_byte_reg(target, i);
					/* fast memory writes are only safe when the target is running
					 * from a sufficiently high clock (32 kHz is usually too slow)
					 */
2083
					if (arm7_9->fast_memory_access)
2084
2085
2086
2087
						arm7_9_execute_fast_sys_speed(target);
					else
						arm7_9_execute_sys_speed(target);
				}
2088

2089
				num_accesses += thisrun_accesses;
2090
			}
2091
2092
			break;
		default:
2093
			LOG_ERROR("BUG: we shouldn't get here");
2094
2095
2096
			exit(-1);
			break;
	}
2097

2098
2099
2100
	/* Re-Set DBGACK */
	buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);
	embeddedice_store_reg(dbg_ctrl);
2101

2102
2103
2104
	if (armv4_5_mode_to_number(armv4_5->core_mode)==-1)
		return ERROR_FAIL;

2105
	for (i=0; i<=last_reg; i++)
2106
		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
2107
2108
2109
2110

	arm7_9->read_xpsr(target, &cpsr, 0);
	if ((retval = jtag_execute_queue()) != ERROR_OK)
	{
2111
		LOG_ERROR("JTAG error while reading cpsr");
ntfreak's avatar
ntfreak committed
2112
		return ERROR_TARGET_DATA_ABORT;
2113
2114
2115
2116
	}

	if (((cpsr & 0x1f) == ARMV4_5_MODE_ABT) && (armv4_5->core_mode != ARMV4_5_MODE_ABT))
	{
2117
		LOG_WARNING("memory write caused data abort (address: 0x%8.8x, size: 0x%x, count: 0x%x)", address, size, count);
2118

2119
		arm7_9->write_xpsr_im8(target, buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8) & ~0x20, 0, 0);
2120
2121
2122

		return ERROR_TARGET_DATA_ABORT;
	}
2123

2124
2125
2126
	return ERROR_OK;
}

2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
static int dcc_count;
static u8 *dcc_buffer;


static int arm7_9_dcc_completion(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info)
{
	armv4_5_common_t *armv4_5 = target->arch_info;
	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
	int little=target->endianness==TARGET_LITTLE_ENDIAN;
	int count=dcc_count;
	u8 *buffer=dcc_buffer;
	if (count>2)
	{
		/* Handle first & last using standard embeddedice_write_reg and the middle ones w/the
		   core function repeated.
		 */
		embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
		buffer+=4;

		embeddedice_reg_t *ice_reg = arm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info;
		u8 reg_addr = ice_reg->addr & 0x1f;
		int chain_pos = ice_reg->jtag_info->chain_pos;

		embeddedice_write_dcc(chain_pos, reg_addr, buffer, little, count-2);
		buffer += (count-2)*4;

		embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
	} else
	{
		int i;
		for (i = 0; i < count; i++)
		{
			embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], fast_target_buffer_get_u32(buffer, little));
			buffer += 4;
		}
	}

	target_halt(target);
	return target_wait_state(target, TARGET_HALTED, 500);
}


2169
static const u32 dcc_code[] =
2170
2171
2172
2173
2174
{
	/* MRC      TST         BNE         MRC         STR         B */
	0xee101e10, 0xe3110001, 0x0afffffc, 0xee111e10, 0xe4801004, 0xeafffff9
};

2175
2176
2177
int armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem_param_t *mem_params, int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info));


2178
2179
2180
2181
2182
int arm7_9_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
{
	armv4_5_common_t *armv4_5 = target->arch_info;
	arm7_9_common_t *arm7_9 = armv4_5->arch_info;
	int i;
2183

2184
2185
2186
2187
2188
2189
	if (!arm7_9->dcc_downloads)
		return target->type->write_memory(target, address, 4, count, buffer);

	/* regrab previously allocated working_area, or allocate a new one */
	if (!arm7_9->dcc_working_area)
	{
2190
		u8 dcc_code_buf[6 * 4];
2191

2192
2193
2194
		/* make sure we have a working area */
		if (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK)
		{
2195
			LOG_INFO("no working area available, falling back to memory writes");
2196
2197
			return target->type->write_memory(target, address, 4, count, buffer);
		}
2198

2199
2200
2201
2202
2203
		/* copy target instructions to target endianness */
		for (i = 0; i < 6; i++)
		{
			target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]);
		}
2204

2205
		/* write DCC code to working area */
2206
		target->type->write_memory(target, arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf);
2207
	}
2208

2209
2210
	armv4_5_algorithm_t armv4_5_info;
	reg_param_t reg_params[1];
2211

2212
2213
2214
	armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
	armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
	armv4_5_info.core_state = ARMV4_5_STATE_ARM;
2215

2216
	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
2217

2218
	buf_set_u32(reg_params[0].value, 0, 32, address);
2219

2220
2221
2222
2223
2224
2225
2226
	//armv4_5_run_algorithm_inner(struct target_s *target, int num_mem_params, mem_param_t *mem_params,
	// int num_reg_params, reg_param_t *reg_params, u32 entry_point, u32 exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target_s *target, u32 exit_point, int timeout_ms, void *arch_info))
	int retval;
	dcc_count=count;
	dcc_buffer=buffer;
	retval = armv4_5_run_algorithm_inner(target, 0, NULL, 1, reg_params,
			arm7_9->dcc_working_area->address, arm7_9->dcc_working_area->address+6*4, 20*1000, &armv4_5_info, arm7_9_dcc_completion);
2227

2228
	if (retval==ERROR_OK)
2229
	{
2230
2231
		u32 endaddress=buf_get_u32(reg_params[0].value, 0, 32);
		if (endaddress!=(address+count*4))
oharboe's avatar
oharboe committed
2232
		{
2233
2234
			LOG_ERROR("DCC write failed, expected end address 0x%08x got 0x%0x", (address+count*4), endaddress);
			retval=ERROR_FAIL;
oharboe's avatar
oharboe committed
2235
		}
2236
	}
2237

2238
	destroy_reg_param(&reg_params[0]);
2239

2240
	return retval;
2241
2242
}

ntfreak's avatar
ntfreak committed
2243
2244
2245
2246
2247
2248
int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
{
	working_area_t *crc_algorithm;
	armv4_5_algorithm_t armv4_5_info;
	reg_param_t reg_params[2];
	int retval;
2249

ntfreak's avatar
ntfreak committed
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
	u32 arm7_9_crc_code[] = {
		0xE1A02000,				/* mov		r2, r0 */
		0xE3E00000,				/* mov		r0, #0xffffffff */
		0xE1A03001,				/* mov		r3, r1 */
		0xE3A04000,				/* mov		r4, #0 */
		0xEA00000B,				/* b		ncomp */
								/* nbyte: */
		0xE7D21004,				/* ldrb	r1, [r2, r4] */
		0xE59F7030,				/* ldr		r7, CRC32XOR */
		0xE0200C01,				/* eor		r0, r0, r1, asl 24 */
		0xE3A05000,				/* mov		r5, #0 */
								/* loop: */
		0xE3500000,				/* cmp		r0, #0 */
		0xE1A06080,				/* mov		r6, r0, asl #1 */
		0xE2855001,				/* add		r5, r5, #1 */
		0xE1A00006,				/* mov		r0, r6 */
		0xB0260007,				/* eorlt	r0, r6, r7 */
		0xE3550008,				/* cmp		r5, #8 */
		0x1AFFFFF8,				/* bne		loop */
		0xE2844001,				/* add		r4, r4, #1 */
								/* ncomp: */
		0xE1540003,				/* cmp		r4, r3 */
		0x1AFFFFF1,				/* bne		nbyte */
								/* end: */
		0xEAFFFFFE,				/* b		end */
		0x04C11DB7				/* CRC32XOR:	.word 0x04C11DB7 */
	};
2277

ntfreak's avatar
ntfreak committed
2278
	int i;
2279

ntfreak's avatar
ntfreak committed
2280
2281
2282
2283
	if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
	{
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
	}
2284

ntfreak's avatar
ntfreak committed
2285
2286
	/* convert flash writing code into a buffer in target endianness */
	for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
2287
2288
2289
2290
2291
2292
	{
		if ((retval=target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]))!=ERROR_OK)
		{
			return retval;
		}
	}
2293

ntfreak's avatar
ntfreak committed
2294
2295
2296
	armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
	armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
	armv4_5_info.core_state = ARMV4_5_STATE_ARM;
2297

ntfreak's avatar
ntfreak committed
2298
2299
	init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
2300

ntfreak's avatar
ntfreak committed
2301
2302
	buf_set_u32(reg_params[0].value, 0, 32, address);
	buf_set_u32(reg_params[1].value, 0, 32, count);
2303

ntfreak's avatar
ntfreak committed
2304
2305
2306
	if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
		crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
	{
2307
		LOG_ERROR("error executing arm7_9 crc algorithm");
ntfreak's avatar
ntfreak committed
2308
2309
2310
2311
2312
		destroy_reg_param(&reg_params[0]);
		destroy_reg_param(&reg_params[1]);
		target_free_working_area(target, crc_algorithm);
		return retval;
	}
2313

ntfreak's avatar
ntfreak committed
2314
	*checksum = buf_get_u32(reg_params[0].value, 0, 32);
2315

ntfreak's avatar
ntfreak committed
2316
2317
	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);
2318

ntfreak's avatar
ntfreak committed
2319
	target_free_working_area(target, crc_algorithm);
2320

ntfreak's avatar
ntfreak committed
2321
2322
2323
	return ERROR_OK;
}

2324
2325
2326
2327
2328
2329
2330
int arm7_9_blank_check_memory(struct target_s *target, u32 address, u32 count, u32* blank)
{
	working_area_t *erase_check_algorithm;
	reg_param_t reg_params[3];
	armv4_5_algorithm_t armv4_5_info;
	int retval;
	int i;
2331

2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
	u32 erase_check_code[] =
	{
						/* loop: */
		0xe4d03001,		/* ldrb r3, [r0], #1	*/
		0xe0022003,		/* and r2, r2, r3 		*/
		0xe2511001, 	/* subs r1, r1, #1		*/
		0x1afffffb,		/* bne loop				*/
						/* end: */
		0xeafffffe		/* b end				*/
	};

	/* make sure we have a working area */
	if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
	{
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
	}
2348

2349
2350
2351
	/* convert flash writing code into a buffer in target endianness */
	for (i = 0; i < (sizeof(erase_check_code)/sizeof(u32)); i++)
		target_write_u32(target, erase_check_algorithm->address + i*sizeof(u32), erase_check_code[i]);
2352

2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
	armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
	armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
	armv4_5_info.core_state = ARMV4_5_STATE_ARM;

	init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
	buf_set_u32(reg_params[0].value, 0, 32, address);

	init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
	buf_set_u32(reg_params[1].value, 0, 32, count);

	init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
	buf_set_u32(reg_params[2].value, 0, 32, 0xff);
2365
2366

	if ((retval = target->type->run_algorithm(target, 0, NULL, 3, reg_params,
2367
2368
2369
2370
2371
2372
2373
2374
			erase_check_algorithm->address, erase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &armv4_5_info)) != ERROR_OK)
	{
		destroy_reg_param(&reg_params[0]);
		destroy_reg_param(&reg_params[1]);
		destroy_reg_param(&reg_params[2]);
		target_free_working_area(target, erase_check_algorithm);
		return 0;
	}
2375

2376
	*blank = buf_get_u32(reg_params[2].value, 0, 32);
2377

2378
2379
2380
	destroy_reg_param(&reg_params[0]);
	destroy_reg_param(&reg_params[1]);
	destroy_reg_param(&reg_params[2]);
2381

2382
	target_free_working_area(target, erase_check_algorithm);
2383

2384
2385
2386
	return ERROR_OK;
}

2387
2388
2389
int arm7_9_register_commands(struct command_context_s *cmd_ctx)
{
	command_t *arm7_9_cmd;
2390

2391
	arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
2392

2393
2394
	register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
	register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
2395
2396
2397

	register_command(cmd_ctx, arm7_9_cmd, "write_core_reg", handle_arm7_9_write_core_reg_command, COMMAND_EXEC, "write core register <num> <mode> <value>");

2398
2399
	register_command(cmd_ctx, arm7_9_cmd, "dbgrq", handle_arm7_9_dbgrq_command,
		COMMAND_ANY, "use EmbeddedICE dbgrq instead of breakpoint for target halt requests <enable|disable>");
2400
2401
2402
2403
	register_command(cmd_ctx, arm7_9_cmd, "fast_writes", handle_arm7_9_fast_memory_access_command,
		 COMMAND_ANY, "(deprecated, see: arm7_9 fast_memory_access)");
	register_command(cmd_ctx, arm7_9_cmd, "fast_memory_access", handle_arm7_9_fast_memory_access_command,
		 COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
2404
2405
2406
2407
	register_command(cmd_ctx, arm7_9_cmd, "dcc_downloads", handle_arm7_9_dcc_downloads_command,
		COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");

	armv4_5_register_commands(cmd_ctx);
2408

2409
	etm_register_commands(cmd_ctx);
2410

2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
	return ERROR_OK;
}

int handle_arm7_9_write_xpsr_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	u32 value;
	int spsr;
	int retval;
	target_t *target = get_current_target(cmd_ctx);
	armv4_5_common_t *armv4_5;
	arm7_9_common_t *arm7_9;

	if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
	{
		command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
		return ERROR_OK;
	}
2428

2429
2430
2431
2432
2433
	if (target->state != TARGET_HALTED)
	{
		command_print(cmd_ctx, "can't write registers while running");
		return ERROR_OK;
	}
2434

2435
2436
2437
2438
2439
	if (argc < 2)
	{
		command_print(cmd_ctx, "usage: write_xpsr <value> <not cpsr|spsr>");
		return ERROR_OK;
	}
2440

2441
2442
	value = strtoul(args[0], NULL, 0);
	spsr = strtol(args[1], NULL, 0);
2443

2444
2445
2446
	/* if we're writing the CPSR, mask the T bit */
	if (!spsr)
		value &= ~0x20;
2447

2448
2449
2450
	arm7_9->write_xpsr(target, value, spsr);
	if ((retval = jtag_execute_queue()) != ERROR_OK)
	{
2451
		LOG_ERROR("JTAG error while writing to xpsr");
2452
		return retval;
2453
	}
2454

2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
	return ERROR_OK;
}

int handle_arm7_9_write_xpsr_im8_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	u32 value;
	int rotate;
	int spsr;
	int retval;
	target_t *target = get_current_target(cmd_ctx);
	armv4_5_common_t *armv4_5;
	arm7_9_common_t *arm7_9;

	if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
	{
		command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
		return ERROR_OK;
	}
2473

2474
2475
2476
2477
2478
	if (target->state != TARGET_HALTED)
	{
		command_print(cmd_ctx, "can't write registers while running");
		return ERROR_OK;
	}
2479

2480
2481
2482
2483
2484
	if (argc < 3)
	{
		command_print(cmd_ctx, "usage: write_xpsr_im8 <im8> <rotate> <not cpsr|spsr>");
		return ERROR_OK;
	}
2485

2486
2487
2488
	value = strtoul(args[0], NULL, 0);
	rotate = strtol(args[1], NULL, 0);
	spsr = strtol(args[2], NULL, 0);
2489

2490
2491
2492
	arm7_9->write_xpsr_im8(target, value, rotate, spsr);
	if ((retval = jtag_execute_queue()) != ERROR_OK)
	{
2493
		LOG_ERROR("JTAG error while writing 8-bit immediate to xpsr");
2494
		return retval;
2495
	}
2496

2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
	return ERROR_OK;
}

int handle_arm7_9_write_core_reg_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	u32 value;
	u32 mode;
	int num;
	target_t *target = get_current_target(cmd_ctx);
	armv4_5_common_t *armv4_5;
	arm7_9_common_t *arm7_9;
2508

2509
2510
2511
2512
2513
	if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
	{
		command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
		return ERROR_OK;
	}
2514

2515
2516
2517
2518
2519
	if (target->state != TARGET_HALTED)
	{
		command_print(cmd_ctx, "can't write registers while running");
		return ERROR_OK;
	}
2520

2521
2522
2523
2524
2525
	if (argc < 3)
	{
		command_print(cmd_ctx, "usage: write_core_reg <num> <mode> <value>");
		return ERROR_OK;
	}
2526

2527
2528
2529
	num = strtol(args[0], NULL, 0);
	mode = strtoul(args[1], NULL, 0);
	value = strtoul(args[2], NULL, 0);
2530

2531
	arm7_9_write_core_reg(target, num, mode, value);
2532

2533
2534
2535
2536
2537
2538
2539
2540
2541
	return ERROR_OK;
}


int handle_arm7_9_dbgrq_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	target_t *target = get_current_target(cmd_ctx);
	armv4_5_common_t *armv4_5;
	arm7_9_common_t *arm7_9;
2542

2543
2544
2545
2546
2547
	if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
	{
		command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
		return ERROR_OK;
	}
2548

2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
	if (argc > 0)
	{
		if (strcmp("enable", args[0]) == 0)
		{
			arm7_9->use_dbgrq = 1;
		}
		else if (strcmp("disable", args[0]) == 0)
		{
			arm7_9->use_dbgrq = 0;
		}
		else
		{
			command_print(cmd_ctx, "usage: arm7_9 dbgrq <enable|disable>");
		}
	}
2564

2565
2566
2567
2568
2569
	command_print(cmd_ctx, "use of EmbeddedICE dbgrq instead of breakpoint for target halt %s", (arm7_9->use_dbgrq) ? "enabled" : "disabled");

	return ERROR_OK;
}

2570
int handle_arm7_9_fast_memory_access_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
2571
2572
2573
2574
{
	target_t *target = get_current_target(cmd_ctx);
	armv4_5_common_t *armv4_5;
	arm7_9_common_t *arm7_9;
2575

2576
2577
2578
2579
2580
	if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
	{
		command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
		return ERROR_OK;
	}
2581

2582
2583
2584
2585
	if (argc > 0)
	{
		if (strcmp("enable", args[0]) == 0)
		{
2586
			arm7_9->fast_memory_access = 1;
2587
2588
2589
		}
		else if (strcmp("disable", args[0]) == 0)
		{
2590
			arm7_9->fast_memory_access = 0;
2591
2592
2593
		}
		else
		{
2594
			command_print(cmd_ctx, "usage: arm7_9 fast_memory_access <enable|disable>");
2595
2596
		}
	}
2597

2598
	command_print(cmd_ctx, "fast memory access is %s", (arm7_9->fast_memory_access) ? "enabled" : "disabled");
2599
2600
2601
2602
2603
2604
2605
2606
2607

	return ERROR_OK;
}

int handle_arm7_9_dcc_downloads_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	target_t *target = get_current_target(cmd_ctx);
	armv4_5_common_t *armv4_5;
	arm7_9_common_t *arm7_9;
2608

2609
2610
2611
2612
2613
	if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
	{
		command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
		return ERROR_OK;
	}
2614

2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
	if (argc > 0)
	{
		if (strcmp("enable", args[0]) == 0)
		{
			arm7_9->dcc_downloads = 1;
		}
		else if (strcmp("disable", args[0]) == 0)
		{
			arm7_9->dcc_downloads = 0;
		}
		else
		{
			command_print(cmd_ctx, "usage: arm7_9 dcc_downloads <enable|disable>");
		}
	}
2630

2631
2632
2633
2634
2635
2636
2637
2638
	command_print(cmd_ctx, "dcc downloads are %s", (arm7_9->dcc_downloads) ? "enabled" : "disabled");

	return ERROR_OK;
}

int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
{
	armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
2639

2640
	arm7_9->common_magic = ARM7_9_COMMON_MAGIC;
2641

2642
	arm_jtag_setup_connection(&arm7_9->jtag_info);
2643
2644
	arm7_9->wp_available = 0; /* this is set up in arm7_9_clear_watchpoints() */
	arm7_9->wp_available_max = 2;
2645
2646
	arm7_9->sw_breakpoints_added = 0;
	arm7_9->breakpoint_count = 0;
2647
2648
	arm7_9->wp0_used = 0;
	arm7_9->wp1_used = 0;
2649
	arm7_9->wp1_used_default = 0;
2650
	arm7_9->use_dbgrq = 0;
2651

2652
	arm7_9->etm_ctx = NULL;
2653
2654
2655
	arm7_9->has_single_step = 0;
	arm7_9->has_monitor_mode = 0;
	arm7_9->has_vector_catch = 0;
2656

2657
	arm7_9->debug_entry_from_reset = 0;
2658

2659
	arm7_9->dcc_working_area = NULL;
2660

oharboe's avatar
oharboe committed
2661
2662
	arm7_9->fast_memory_access = fast_and_dangerous;
	arm7_9->dcc_downloads = fast_and_dangerous;
2663

oharboe's avatar
oharboe committed
2664
	arm7_9->need_bypass_before_restart = 0;
2665

2666
2667
2668
2669
	armv4_5->arch_info = arm7_9;
	armv4_5->read_core_reg = arm7_9_read_core_reg;
	armv4_5->write_core_reg = arm7_9_write_core_reg;
	armv4_5->full_context = arm7_9_full_context;
2670

2671
	armv4_5_init_arch_info(target, armv4_5);
2672

2673
	target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target);
2674

2675
2676
	return ERROR_OK;
}
For faster browsing, not all history is shown. View entire blame