target.c 121 KB
Newer Older
1001
1002
1003
1004
1005
1006
1007
			free(c);
			return ERROR_OK;
		}
		else
			p = &(c->next);
		c = next;
	}
oharboe's avatar
oharboe committed
1008

1009
1010
1011
1012
1013
1014
1015
	return ERROR_OK;
}

int target_call_event_callbacks(target_t *target, enum target_event event)
{
	target_event_callback_t *callback = target_event_callbacks;
	target_event_callback_t *next_callback;
oharboe's avatar
oharboe committed
1016

1017
1018
1019
	if (event == TARGET_EVENT_HALTED)
	{
		/* execute early halted first */
1020
		target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
1021
1022
	}

1023
1024
	LOG_DEBUG("target event %i (%s)",
			  event,
1025
			  Jim_Nvp_value2name_simple(nvp_target_event, event)->name);
oharboe's avatar
oharboe committed
1026

1027
	target_handle_event(target, event);
1028

1029
1030
1031
1032
1033
1034
	while (callback)
	{
		next_callback = callback->next;
		callback->callback(target, event, callback->priv);
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1035

1036
1037
1038
	return ERROR_OK;
}

1039
1040
static int target_timer_callback_periodic_restart(
		target_timer_callback_t *cb, struct timeval *now)
1041
{
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
	int time_ms = cb->time_ms;
	cb->when.tv_usec = now->tv_usec + (time_ms % 1000) * 1000;
	time_ms -= (time_ms % 1000);
	cb->when.tv_sec = now->tv_sec + time_ms / 1000;
	if (cb->when.tv_usec > 1000000)
	{
		cb->when.tv_usec = cb->when.tv_usec - 1000000;
		cb->when.tv_sec += 1;
	}
	return ERROR_OK;
}

static int target_call_timer_callback(target_timer_callback_t *cb,
		struct timeval *now)
{
	cb->callback(cb->priv);
1058

1059
1060
1061
1062
1063
1064
1065
1066
	if (cb->periodic)
		return target_timer_callback_periodic_restart(cb, now);

	return target_unregister_timer_callback(cb->callback, cb->priv);
}

static int target_call_timer_callbacks_check_time(int checktime)
{
oharboe's avatar
   
oharboe committed
1067
1068
	keep_alive();

1069
	struct timeval now;
1070
	gettimeofday(&now, NULL);
oharboe's avatar
oharboe committed
1071

1072
	target_timer_callback_t *callback = target_timer_callbacks;
1073
1074
	while (callback)
	{
1075
1076
1077
1078
1079
1080
1081
1082
		// cleaning up may unregister and free this callback
		target_timer_callback_t *next_callback = callback->next;

		bool call_it = callback->callback &&
			((!checktime && callback->periodic) ||
			  now.tv_sec > callback->when.tv_sec ||
			 (now.tv_sec == callback->when.tv_sec &&
			  now.tv_usec >= callback->when.tv_usec));
oharboe's avatar
oharboe committed
1083

1084
		if (call_it)
1085
		{
1086
1087
1088
			int retval = target_call_timer_callback(callback, &now);
			if (retval != ERROR_OK)
				return retval;
1089
		}
oharboe's avatar
oharboe committed
1090

1091
1092
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1093

1094
1095
1096
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1097
int target_call_timer_callbacks(void)
1098
1099
1100
1101
1102
{
	return target_call_timer_callbacks_check_time(1);
}

/* invoke periodic callbacks immediately */
oharboe's avatar
oharboe committed
1103
int target_call_timer_callbacks_now(void)
1104
{
oharboe's avatar
   
oharboe committed
1105
	return target_call_timer_callbacks_check_time(0);
1106
1107
}

1108
int target_alloc_working_area(struct target_s *target, uint32_t size, working_area_t **area)
1109
1110
1111
{
	working_area_t *c = target->working_areas;
	working_area_t *new_wa = NULL;
oharboe's avatar
oharboe committed
1112

1113
1114
1115
1116
1117
	/* Reevaluate working area address based on MMU state*/
	if (target->working_areas == NULL)
	{
		int retval;
		int enabled;
1118

1119
1120
1121
1122
1123
		retval = target->type->mmu(target, &enabled);
		if (retval != ERROR_OK)
		{
			return retval;
		}
1124

1125
1126
1127
1128
1129
		if (!enabled) {
			if (target->working_area_phys_spec) {
				LOG_DEBUG("MMU disabled, using physical "
					"address for working memory 0x%08x",
					(unsigned)target->working_area_phys);
1130
				target->working_area = target->working_area_phys;
1131
1132
1133
			} else {
				LOG_ERROR("No working memory available. "
					"Specify -work-area-phys to target.");
1134
1135
				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
			}
1136
1137
1138
1139
1140
		} else {
			if (target->working_area_virt_spec) {
				LOG_DEBUG("MMU enabled, using virtual "
					"address for working memory 0x%08x",
					(unsigned)target->working_area_virt);
1141
				target->working_area = target->working_area_virt;
1142
1143
1144
			} else {
				LOG_ERROR("No working memory available. "
					"Specify -work-area-virt to target.");
1145
1146
				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
			}
1147
1148
		}
	}
oharboe's avatar
oharboe committed
1149

1150
1151
1152
	/* only allocate multiples of 4 byte */
	if (size % 4)
	{
duane's avatar
duane committed
1153
1154
		LOG_ERROR("BUG: code tried to allocate unaligned number of bytes (0x%08x), padding", ((unsigned)(size)));
		size = (size + 3) & (~3);
1155
	}
oharboe's avatar
oharboe committed
1156

1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
	/* see if there's already a matching working area */
	while (c)
	{
		if ((c->free) && (c->size == size))
		{
			new_wa = c;
			break;
		}
		c = c->next;
	}
oharboe's avatar
oharboe committed
1167

1168
1169
1170
1171
	/* if not, allocate a new one */
	if (!new_wa)
	{
		working_area_t **p = &target->working_areas;
1172
1173
		uint32_t first_free = target->working_area;
		uint32_t free_size = target->working_area_size;
oharboe's avatar
oharboe committed
1174

1175
1176
1177
1178
1179
1180
1181
1182
		c = target->working_areas;
		while (c)
		{
			first_free += c->size;
			free_size -= c->size;
			p = &c->next;
			c = c->next;
		}
oharboe's avatar
oharboe committed
1183

1184
1185
		if (free_size < size)
		{
1186
			LOG_WARNING("not enough working area available(requested %u, free %u)",
duane's avatar
duane committed
1187
				    (unsigned)(size), (unsigned)(free_size));
1188
1189
			return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
		}
oharboe's avatar
oharboe committed
1190

1191
1192
		LOG_DEBUG("allocated new working area at address 0x%08x", (unsigned)first_free);

1193
1194
1195
1196
		new_wa = malloc(sizeof(working_area_t));
		new_wa->next = NULL;
		new_wa->size = size;
		new_wa->address = first_free;
oharboe's avatar
oharboe committed
1197

1198
1199
		if (target->backup_working_area)
		{
1200
			int retval;
1201
			new_wa->backup = malloc(new_wa->size);
zwelch's avatar
zwelch committed
1202
			if ((retval = target_read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
1203
1204
1205
1206
1207
			{
				free(new_wa->backup);
				free(new_wa);
				return retval;
			}
1208
1209
1210
1211
1212
		}
		else
		{
			new_wa->backup = NULL;
		}
oharboe's avatar
oharboe committed
1213

1214
1215
1216
		/* put new entry in list */
		*p = new_wa;
	}
oharboe's avatar
oharboe committed
1217

1218
1219
1220
	/* mark as used, and return the new (reused) area */
	new_wa->free = 0;
	*area = new_wa;
oharboe's avatar
oharboe committed
1221

1222
1223
	/* user pointer */
	new_wa->user = area;
oharboe's avatar
oharboe committed
1224

1225
1226
1227
	return ERROR_OK;
}

oharboe's avatar
   
oharboe committed
1228
int target_free_working_area_restore(struct target_s *target, working_area_t *area, int restore)
1229
1230
1231
{
	if (area->free)
		return ERROR_OK;
oharboe's avatar
oharboe committed
1232

zwelch's avatar
zwelch committed
1233
	if (restore && target->backup_working_area)
1234
1235
	{
		int retval;
zwelch's avatar
zwelch committed
1236
		if ((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
1237
1238
			return retval;
	}
oharboe's avatar
oharboe committed
1239

1240
	area->free = 1;
oharboe's avatar
oharboe committed
1241

1242
1243
1244
	/* mark user pointer invalid */
	*area->user = NULL;
	area->user = NULL;
oharboe's avatar
oharboe committed
1245

1246
1247
1248
	return ERROR_OK;
}

oharboe's avatar
   
oharboe committed
1249
1250
1251
1252
1253
int target_free_working_area(struct target_s *target, working_area_t *area)
{
	return target_free_working_area_restore(target, area, 1);
}

1254
1255
1256
1257
/* free resources and restore memory, if restoring memory fails,
 * free up resources anyway
 */
void target_free_all_working_areas_restore(struct target_s *target, int restore)
1258
1259
1260
1261
1262
1263
{
	working_area_t *c = target->working_areas;

	while (c)
	{
		working_area_t *next = c->next;
oharboe's avatar
   
oharboe committed
1264
		target_free_working_area_restore(target, c, restore);
oharboe's avatar
oharboe committed
1265

1266
1267
		if (c->backup)
			free(c->backup);
oharboe's avatar
oharboe committed
1268

1269
		free(c);
oharboe's avatar
oharboe committed
1270

1271
1272
		c = next;
	}
oharboe's avatar
oharboe committed
1273

1274
1275
1276
	target->working_areas = NULL;
}

1277
void target_free_all_working_areas(struct target_s *target)
oharboe's avatar
   
oharboe committed
1278
{
1279
	target_free_all_working_areas_restore(target, 1);
oharboe's avatar
   
oharboe committed
1280
1281
}

1282
1283
int target_register_commands(struct command_context_s *cmd_ctx)
{
1284

1285
1286
1287
1288
	register_command(cmd_ctx, NULL, "targets",
			handle_targets_command, COMMAND_EXEC,
			"change current command line target (one parameter) "
			"or list targets (no parameters)");
1289

1290
	register_jim(cmd_ctx, "target", jim_target, "configure target");
1291

1292
1293
1294
1295
1296
1297
	return ERROR_OK;
}

int target_arch_state(struct target_s *target)
{
	int retval;
zwelch's avatar
zwelch committed
1298
	if (target == NULL)
1299
	{
1300
		LOG_USER("No target has been configured");
1301
1302
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
1303

1304
	LOG_USER("target state: %s", target_state_name( target ));
oharboe's avatar
oharboe committed
1305

zwelch's avatar
zwelch committed
1306
	if (target->state != TARGET_HALTED)
1307
		return ERROR_OK;
oharboe's avatar
oharboe committed
1308

zwelch's avatar
zwelch committed
1309
	retval = target->type->arch_state(target);
1310
1311
1312
	return retval;
}

oharboe's avatar
oharboe committed
1313
1314
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1315
1316
 * possible
 */
1317
int target_write_buffer(struct target_s *target, uint32_t address, uint32_t size, uint8_t *buffer)
1318
1319
{
	int retval;
1320
	LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1321
		  (int)size, (unsigned)address);
1322

1323
	if (!target_was_examined(target))
1324
1325
1326
1327
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1328

1329
1330
1331
1332
	if (size == 0) {
		return ERROR_OK;
	}

1333
	if ((address + size - 1) < address)
1334
1335
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1336
1337
		LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
				  (unsigned)address,
duane's avatar
duane committed
1338
				  (unsigned)size);
1339
1340
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1341

1342
1343
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1344
		return target_write_memory(target, address, 2, 1, buffer);
1345
	}
oharboe's avatar
oharboe committed
1346

1347
1348
1349
	/* handle unaligned head bytes */
	if (address % 4)
	{
1350
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1351

1352
1353
1354
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1355
		if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1356
			return retval;
oharboe's avatar
oharboe committed
1357

1358
1359
1360
1361
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1362

1363
1364
1365
1366
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1367

1368
1369
1370
1371
1372
1373
1374
1375
		/* use bulk writes above a certain limit. This may have to be changed */
		if (aligned > 128)
		{
			if ((retval = target->type->bulk_write_memory(target, address, aligned / 4, buffer)) != ERROR_OK)
				return retval;
		}
		else
		{
zwelch's avatar
zwelch committed
1376
			if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1377
1378
				return retval;
		}
oharboe's avatar
oharboe committed
1379

1380
1381
1382
1383
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
oharboe's avatar
oharboe committed
1384

1385
1386
1387
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1388
		if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1389
1390
			return retval;
	}
oharboe's avatar
oharboe committed
1391

1392
1393
1394
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1395
1396
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1397
1398
 * possible
 */
1399
int target_read_buffer(struct target_s *target, uint32_t address, uint32_t size, uint8_t *buffer)
1400
1401
{
	int retval;
1402
	LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1403
			  (int)size, (unsigned)address);
1404

1405
	if (!target_was_examined(target))
1406
1407
1408
1409
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1410

1411
1412
1413
1414
	if (size == 0) {
		return ERROR_OK;
	}

1415
	if ((address + size - 1) < address)
1416
1417
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1418
1419
		LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
				  address,
duane's avatar
duane committed
1420
				  size);
1421
1422
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1423

1424
1425
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1426
		return target_read_memory(target, address, 2, 1, buffer);
1427
	}
oharboe's avatar
oharboe committed
1428

1429
1430
1431
	/* handle unaligned head bytes */
	if (address % 4)
	{
1432
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1433

1434
1435
1436
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1437
		if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1438
			return retval;
oharboe's avatar
oharboe committed
1439

1440
1441
1442
1443
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1444

1445
1446
1447
1448
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1449

zwelch's avatar
zwelch committed
1450
		if ((retval = target_read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1451
			return retval;
oharboe's avatar
oharboe committed
1452

1453
1454
1455
1456
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1457

1458
1459
1460
1461
1462
1463
1464
	/*prevent byte access when possible (avoid AHB access limitations in some cases)*/
	if(size	>=2)
	{
		int aligned = size - (size%2);
		retval = target_read_memory(target, address, 2, aligned / 2, buffer);
		if (retval != ERROR_OK)
			return retval;
oharboe's avatar
oharboe committed
1465

1466
1467
1468
1469
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1470
1471
1472
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1473
		if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1474
1475
			return retval;
	}
oharboe's avatar
oharboe committed
1476

1477
1478
1479
	return ERROR_OK;
}

1480
int target_checksum_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t* crc)
1481
{
1482
	uint8_t *buffer;
1483
	int retval;
1484
1485
	uint32_t i;
	uint32_t checksum = 0;
1486
	if (!target_was_examined(target))
1487
1488
1489
1490
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1491

1492
	if ((retval = target->type->checksum_memory(target, address,
1493
		size, &checksum)) != ERROR_OK)
1494
1495
1496
1497
	{
		buffer = malloc(size);
		if (buffer == NULL)
		{
duane's avatar
duane committed
1498
			LOG_ERROR("error allocating buffer for section (%d bytes)", (int)size);
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
			return ERROR_INVALID_ARGUMENTS;
		}
		retval = target_read_buffer(target, address, size, buffer);
		if (retval != ERROR_OK)
		{
			free(buffer);
			return retval;
		}

		/* convert to target endianess */
1509
		for (i = 0; i < (size/sizeof(uint32_t)); i++)
1510
		{
1511
1512
1513
			uint32_t target_data;
			target_data = target_buffer_get_u32(target, &buffer[i*sizeof(uint32_t)]);
			target_buffer_set_u32(target, &buffer[i*sizeof(uint32_t)], target_data);
1514
1515
		}

1516
		retval = image_calculate_checksum(buffer, size, &checksum);
1517
1518
		free(buffer);
	}
oharboe's avatar
oharboe committed
1519

1520
	*crc = checksum;
oharboe's avatar
oharboe committed
1521

1522
1523
	return retval;
}
1524

1525
int target_blank_check_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t* blank)
1526
1527
{
	int retval;
1528
	if (!target_was_examined(target))
1529
1530
1531
1532
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1533

1534
1535
	if (target->type->blank_check_memory == 0)
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
oharboe's avatar
oharboe committed
1536

1537
	retval = target->type->blank_check_memory(target, address, size, blank);
oharboe's avatar
oharboe committed
1538

1539
1540
	return retval;
}
1541

1542
int target_read_u32(struct target_s *target, uint32_t address, uint32_t *value)
1543
{
1544
	uint8_t value_buf[4];
1545
	if (!target_was_examined(target))
1546
1547
1548
1549
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1550

zwelch's avatar
zwelch committed
1551
	int retval = target_read_memory(target, address, 4, 1, value_buf);
oharboe's avatar
oharboe committed
1552

1553
1554
1555
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u32(target, value_buf);
1556
1557
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
				  address,
duane's avatar
duane committed
1558
				  *value);
1559
1560
1561
1562
	}
	else
	{
		*value = 0x0;
1563
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1564
				  address);
1565
	}
oharboe's avatar
oharboe committed
1566

1567
1568
1569
	return retval;
}

1570
int target_read_u16(struct target_s *target, uint32_t address, uint16_t *value)
1571
{
1572
	uint8_t value_buf[2];
1573
	if (!target_was_examined(target))
1574
1575
1576
1577
1578
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

zwelch's avatar
zwelch committed
1579
	int retval = target_read_memory(target, address, 2, 1, value_buf);
oharboe's avatar
oharboe committed
1580

1581
1582
1583
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u16(target, value_buf);
1584
1585
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
				  address,
duane's avatar
duane committed
1586
				  *value);
1587
1588
1589
1590
	}
	else
	{
		*value = 0x0;
1591
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1592
				  address);
1593
	}
oharboe's avatar
oharboe committed
1594

1595
1596
1597
	return retval;
}

1598
int target_read_u8(struct target_s *target, uint32_t address, uint8_t *value)
1599
{
zwelch's avatar
zwelch committed
1600
	int retval = target_read_memory(target, address, 1, 1, value);
1601
	if (!target_was_examined(target))
1602
1603
1604
1605
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1606
1607
1608

	if (retval == ERROR_OK)
	{
1609
1610
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
				  address,
duane's avatar
duane committed
1611
				  *value);
1612
1613
1614
1615
	}
	else
	{
		*value = 0x0;
1616
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1617
				  address);
1618
	}
oharboe's avatar
oharboe committed
1619

1620
1621
1622
	return retval;
}

1623
int target_write_u32(struct target_s *target, uint32_t address, uint32_t value)
1624
1625
{
	int retval;
1626
	uint8_t value_buf[4];
1627
	if (!target_was_examined(target))
1628
1629
1630
1631
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1632

1633
1634
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
			  address,
duane's avatar
duane committed
1635
			  value);
1636

oharboe's avatar
oharboe committed
1637
	target_buffer_set_u32(target, value_buf, value);
zwelch's avatar
zwelch committed
1638
	if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1639
	{
1640
		LOG_DEBUG("failed: %i", retval);
1641
	}
oharboe's avatar
oharboe committed
1642

1643
1644
1645
	return retval;
}

1646
int target_write_u16(struct target_s *target, uint32_t address, uint16_t value)
1647
1648
{
	int retval;
1649
	uint8_t value_buf[2];
1650
	if (!target_was_examined(target))
1651
1652
1653
1654
1655
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

1656
1657
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
			  address,
duane's avatar
duane committed
1658
			  value);
1659

oharboe's avatar
oharboe committed
1660
	target_buffer_set_u16(target, value_buf, value);
zwelch's avatar
zwelch committed
1661
	if ((retval = target_write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
1662
	{
1663
		LOG_DEBUG("failed: %i", retval);
1664
	}
oharboe's avatar
oharboe committed
1665

1666
1667
1668
	return retval;
}

1669
int target_write_u8(struct target_s *target, uint32_t address, uint8_t value)
1670
1671
{
	int retval;
1672
	if (!target_was_examined(target))
1673
1674
1675
1676
1677
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

1678
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
duane's avatar
duane committed
1679
			  address, value);
1680

zwelch's avatar
zwelch committed
1681
	if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
1682
	{
1683
		LOG_DEBUG("failed: %i", retval);
1684
	}
oharboe's avatar
oharboe committed
1685

1686
1687
1688
1689
1690
	return retval;
}

int target_register_user_commands(struct command_context_s *cmd_ctx)
{
1691
	int retval = ERROR_OK;
1692
1693
1694
1695


	/* script procedures */
	register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
zwelch's avatar
zwelch committed
1696
1697
	register_jim(cmd_ctx, "ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing <ARRAYNAME> <WIDTH = 32/16/8> <ADDRESS> <COUNT>");
	register_jim(cmd_ctx, "ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values  <ARRAYNAME> <WIDTH = 32/16/8> <ADDRESS> <COUNT>");
1698
1699
1700
1701
1702
1703
1704
1705
1706

	register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
			"same args as load_image, image stored in memory - mainly for profiling purposes");

	register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
			"loads active fast load image to current target - mainly for profiling purposes");


	register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
oharboe's avatar
oharboe committed
1707
	register_command(cmd_ctx,  NULL, "reg", handle_reg_command, COMMAND_EXEC, "display or set a register");
1708
1709
1710
1711
1712
	register_command(cmd_ctx,  NULL, "poll", handle_poll_command, COMMAND_EXEC, "poll target state");
	register_command(cmd_ctx,  NULL, "wait_halt", handle_wait_halt_command, COMMAND_EXEC, "wait for target halt [time (s)]");
	register_command(cmd_ctx,  NULL, "halt", handle_halt_command, COMMAND_EXEC, "halt target");
	register_command(cmd_ctx,  NULL, "resume", handle_resume_command, COMMAND_EXEC, "resume target [addr]");
	register_command(cmd_ctx,  NULL, "step", handle_step_command, COMMAND_EXEC, "step one instruction from current PC or [addr]");
zwelch's avatar
zwelch committed
1713
	register_command(cmd_ctx,  NULL, "reset", handle_reset_command, COMMAND_EXEC, "reset target [run | halt | init] - default is run");
1714
1715
	register_command(cmd_ctx,  NULL, "soft_reset_halt", handle_soft_reset_halt_command, COMMAND_EXEC, "halt the target and do a soft reset");

1716
1717
1718
	register_command(cmd_ctx,  NULL, "mdw", handle_md_command, COMMAND_EXEC, "display memory words [phys] <addr> [count]");
	register_command(cmd_ctx,  NULL, "mdh", handle_md_command, COMMAND_EXEC, "display memory half-words [phys] <addr> [count]");
	register_command(cmd_ctx,  NULL, "mdb", handle_md_command, COMMAND_EXEC, "display memory bytes [phys] <addr> [count]");
oharboe's avatar
oharboe committed
1719

1720
1721
1722
	register_command(cmd_ctx,  NULL, "mww", handle_mw_command, COMMAND_EXEC, "write memory word [phys]  <addr> <value> [count]");
	register_command(cmd_ctx,  NULL, "mwh", handle_mw_command, COMMAND_EXEC, "write memory half-word [phys]  <addr> <value> [count]");
	register_command(cmd_ctx,  NULL, "mwb", handle_mw_command, COMMAND_EXEC, "write memory byte [phys] <addr> <value> [count]");
oharboe's avatar
oharboe committed
1723

1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
	register_command(cmd_ctx,  NULL, "bp",
			handle_bp_command, COMMAND_EXEC,
			"list or set breakpoint [<address> <length> [hw]]");
	register_command(cmd_ctx,  NULL, "rbp",
			handle_rbp_command, COMMAND_EXEC,
			"remove breakpoint <address>");
	register_command(cmd_ctx,  NULL, "wp",
			handle_wp_command, COMMAND_EXEC,
			"list or set watchpoint "
				"[<address> <length> <r/w/a> [value] [mask]]");
	register_command(cmd_ctx,  NULL, "rwp",
			handle_rwp_command, COMMAND_EXEC,
			"remove watchpoint <address>");
oharboe's avatar
oharboe committed
1737

1738
	register_command(cmd_ctx,  NULL, "load_image", handle_load_image_command, COMMAND_EXEC, "load_image <file> <address> ['bin'|'ihex'|'elf'|'s19'] [min_address] [max_length]");
1739
1740
	register_command(cmd_ctx,  NULL, "dump_image", handle_dump_image_command, COMMAND_EXEC, "dump_image <file> <address> <size>");
	register_command(cmd_ctx,  NULL, "verify_image", handle_verify_image_command, COMMAND_EXEC, "verify_image <file> [offset] [type]");
oharboe's avatar
oharboe committed
1741
	register_command(cmd_ctx,  NULL, "test_image", handle_test_image_command, COMMAND_EXEC, "test_image <file> [offset] [type]");
oharboe's avatar
oharboe committed
1742

zwelch's avatar
zwelch committed
1743
	if ((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
1744
		return retval;
zwelch's avatar
zwelch committed
1745
	if ((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
1746
		return retval;
oharboe's avatar
oharboe committed
1747

1748
	return retval;
1749
1750
}

1751
static int handle_targets_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1752
{
1753
	target_t *target = all_targets;
oharboe's avatar
oharboe committed
1754

1755
1756
	if (argc == 1)
	{
1757
1758
		target = get_target(args[0]);
		if (target == NULL) {
1759
			command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0]);
1760
1761
			goto DumpTargets;
		}
oharboe's avatar
oharboe committed
1762
1763
1764
1765
1766
1767
		if (!target->tap->enabled) {
			command_print(cmd_ctx,"Target: TAP %s is disabled, "
					"can't be the current target\n",
					target->tap->dotted_name);
			return ERROR_FAIL;
		}
1768

1769
		cmd_ctx->current_target = target->target_number;
1770
1771
		return ERROR_OK;
	}
1772
DumpTargets:
oharboe's avatar
oharboe committed
1773

1774
	target = all_targets;
oharboe's avatar
oharboe committed
1775
1776
	command_print(cmd_ctx, "    TargetName         Type       Endian TapName            State       ");
	command_print(cmd_ctx, "--  ------------------ ---------- ------ ------------------ ------------");
1777
1778
	while (target)
	{
oharboe's avatar
oharboe committed
1779
1780
1781
1782
		const char *state;
		char marker = ' ';

		if (target->tap->enabled)
1783
			state = target_state_name( target );
oharboe's avatar
oharboe committed
1784
1785
1786
1787
1788
1789
1790
1791
		else
			state = "tap-disabled";

		if (cmd_ctx->current_target == target->target_number)
			marker = '*';

		/* keep columns lined up to match the headers above */
		command_print(cmd_ctx, "%2d%c %-18s %-10s %-6s %-18s %s",
1792
					  target->target_number,
oharboe's avatar
oharboe committed
1793
					  marker,
1794
					  target->cmd_name,
zwelch's avatar
zwelch committed
1795
					  target_get_name(target),
oharboe's avatar
oharboe committed
1796
1797
					  Jim_Nvp_value2name_simple(nvp_target_endian,
								target->endianness)->name,
1798
					  target->tap->dotted_name,
oharboe's avatar
oharboe committed
1799
					  state);
1800
1801
		target = target->next;
	}
oharboe's avatar
oharboe committed
1802

1803
1804
1805
	return ERROR_OK;
}

1806
/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1807
1808
1809
1810

static int powerDropout;
static int srstAsserted;

1811
1812
1813
1814
1815
static int runPowerRestore;
static int runPowerDropout;
static int runSrstAsserted;
static int runSrstDeasserted;

1816
static int sense_handler(void)
1817
1818
1819
1820
1821
{
	static int prevSrstAsserted = 0;
	static int prevPowerdropout = 0;

	int retval;
zwelch's avatar
zwelch committed
1822
	if ((retval = jtag_power_dropout(&powerDropout)) != ERROR_OK)
1823
1824
1825
1826
1827
1828
		return retval;

	int powerRestored;
	powerRestored = prevPowerdropout && !powerDropout;
	if (powerRestored)
	{
1829
		runPowerRestore = 1;
1830
1831
1832
1833
1834
1835
1836
	}

	long long current = timeval_ms();
	static long long lastPower = 0;
	int waitMore = lastPower + 2000 > current;
	if (powerDropout && !waitMore)
	{
1837
		runPowerDropout = 1;
1838
1839
1840
		lastPower = current;
	}

zwelch's avatar
zwelch committed
1841
	if ((retval = jtag_srst_asserted(&srstAsserted)) != ERROR_OK)
1842
1843
1844
1845
1846
1847
1848
1849
1850
		return retval;

	int srstDeasserted;
	srstDeasserted = prevSrstAsserted && !srstAsserted;

	static long long lastSrst = 0;
	waitMore = lastSrst + 2000 > current;
	if (srstDeasserted && !waitMore)
	{
1851
		runSrstDeasserted = 1;
1852
1853
1854
1855
1856
		lastSrst = current;
	}

	if (!prevSrstAsserted && srstAsserted)
	{
1857
		runSrstAsserted = 1;
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
	}

	prevSrstAsserted = srstAsserted;
	prevPowerdropout = powerDropout;

	if (srstDeasserted || powerRestored)
	{
		/* Other than logging the event we can't do anything here.
		 * Issuing a reset is a particularly bad idea as we might
		 * be inside a reset already.
		 */
	}

	return ERROR_OK;
}

1874
1875
1876
1877
1878
1879
1880
1881
1882
static void target_call_event_callbacks_all(enum target_event e) {
	target_t *target;
	target = all_targets;
	while (target) {
		target_call_event_callbacks(target, e);
		target = target->next;
	}
}

1883
1884
1885
/* process target state changes */
int handle_target(void *priv)
{
1886
	int retval = ERROR_OK;
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900

	/* we do not want to recurse here... */
	static int recursive = 0;
	if (! recursive)
	{
		recursive = 1;
		sense_handler();
		/* danger! running these procedures can trigger srst assertions and power dropouts.
		 * We need to avoid an infinite loop/recursion here and we do that by
		 * clearing the flags after running these events.
		 */
		int did_something = 0;
		if (runSrstAsserted)
		{
1901
			target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
1902
			Jim_Eval(interp, "srst_asserted");
1903
1904
1905
1906
			did_something = 1;
		}
		if (runSrstDeasserted)
		{
1907
			Jim_Eval(interp, "srst_deasserted");
1908
1909
1910
1911
			did_something = 1;
		}
		if (runPowerDropout)
		{
1912
			target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
1913
			Jim_Eval(interp, "power_dropout");
1914
1915
1916
1917
			did_something = 1;
		}
		if (runPowerRestore)
		{
1918
			Jim_Eval(interp, "power_restore");
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
			did_something = 1;
		}

		if (did_something)
		{
			/* clear detect flags */
			sense_handler();
		}

		/* clear action flags */

zwelch's avatar
zwelch committed
1930
1931
1932
1933
		runSrstAsserted = 0;
		runSrstDeasserted = 0;
		runPowerRestore = 0;
		runPowerDropout = 0;
oharboe's avatar