target.c 123 KB
Newer Older
1001

Zachary T Welch's avatar
Zachary T Welch committed
1002
int target_call_event_callbacks(struct target *target, enum target_event event)
1003
{
1004
1005
	struct target_event_callback *callback = target_event_callbacks;
	struct target_event_callback *next_callback;
oharboe's avatar
oharboe committed
1006

1007
1008
1009
	if (event == TARGET_EVENT_HALTED)
	{
		/* execute early halted first */
1010
		target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
1011
1012
	}

1013
1014
	LOG_DEBUG("target event %i (%s)",
			  event,
1015
			  Jim_Nvp_value2name_simple(nvp_target_event, event)->name);
oharboe's avatar
oharboe committed
1016

1017
	target_handle_event(target, event);
1018

1019
1020
1021
1022
1023
1024
	while (callback)
	{
		next_callback = callback->next;
		callback->callback(target, event, callback->priv);
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1025

1026
1027
1028
	return ERROR_OK;
}

1029
static int target_timer_callback_periodic_restart(
1030
		struct target_timer_callback *cb, struct timeval *now)
1031
{
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
	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;
}

1044
static int target_call_timer_callback(struct target_timer_callback *cb,
1045
1046
1047
		struct timeval *now)
{
	cb->callback(cb->priv);
1048

1049
1050
1051
1052
1053
1054
1055
1056
	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
1057
1058
	keep_alive();

1059
	struct timeval now;
1060
	gettimeofday(&now, NULL);
oharboe's avatar
oharboe committed
1061

1062
	struct target_timer_callback *callback = target_timer_callbacks;
1063
1064
	while (callback)
	{
1065
		// cleaning up may unregister and free this callback
1066
		struct target_timer_callback *next_callback = callback->next;
1067
1068
1069
1070
1071
1072

		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
1073

1074
		if (call_it)
1075
		{
1076
1077
1078
			int retval = target_call_timer_callback(callback, &now);
			if (retval != ERROR_OK)
				return retval;
1079
		}
oharboe's avatar
oharboe committed
1080

1081
1082
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1083

1084
1085
1086
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1087
int target_call_timer_callbacks(void)
1088
1089
1090
1091
1092
{
	return target_call_timer_callbacks_check_time(1);
}

/* invoke periodic callbacks immediately */
oharboe's avatar
oharboe committed
1093
int target_call_timer_callbacks_now(void)
1094
{
oharboe's avatar
   
oharboe committed
1095
	return target_call_timer_callbacks_check_time(0);
1096
1097
}

Zachary T Welch's avatar
Zachary T Welch committed
1098
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
1099
{
1100
1101
	struct working_area *c = target->working_areas;
	struct working_area *new_wa = NULL;
oharboe's avatar
oharboe committed
1102

1103
1104
1105
1106
1107
	/* Reevaluate working area address based on MMU state*/
	if (target->working_areas == NULL)
	{
		int retval;
		int enabled;
1108

1109
1110
1111
1112
1113
		retval = target->type->mmu(target, &enabled);
		if (retval != ERROR_OK)
		{
			return retval;
		}
1114

1115
1116
1117
1118
1119
		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);
1120
				target->working_area = target->working_area_phys;
1121
1122
1123
			} else {
				LOG_ERROR("No working memory available. "
					"Specify -work-area-phys to target.");
1124
1125
				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
			}
1126
1127
1128
1129
1130
		} else {
			if (target->working_area_virt_spec) {
				LOG_DEBUG("MMU enabled, using virtual "
					"address for working memory 0x%08x",
					(unsigned)target->working_area_virt);
1131
				target->working_area = target->working_area_virt;
1132
1133
1134
			} else {
				LOG_ERROR("No working memory available. "
					"Specify -work-area-virt to target.");
1135
1136
				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
			}
1137
1138
		}
	}
oharboe's avatar
oharboe committed
1139

1140
1141
1142
	/* only allocate multiples of 4 byte */
	if (size % 4)
	{
duane's avatar
duane committed
1143
1144
		LOG_ERROR("BUG: code tried to allocate unaligned number of bytes (0x%08x), padding", ((unsigned)(size)));
		size = (size + 3) & (~3);
1145
	}
oharboe's avatar
oharboe committed
1146

1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
	/* 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
1157

1158
1159
1160
	/* if not, allocate a new one */
	if (!new_wa)
	{
1161
		struct working_area **p = &target->working_areas;
1162
1163
		uint32_t first_free = target->working_area;
		uint32_t free_size = target->working_area_size;
oharboe's avatar
oharboe committed
1164

1165
1166
1167
1168
1169
1170
1171
1172
		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
1173

1174
1175
		if (free_size < size)
		{
1176
			LOG_WARNING("not enough working area available(requested %u, free %u)",
duane's avatar
duane committed
1177
				    (unsigned)(size), (unsigned)(free_size));
1178
1179
			return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
		}
oharboe's avatar
oharboe committed
1180

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

1183
		new_wa = malloc(sizeof(struct working_area));
1184
1185
1186
		new_wa->next = NULL;
		new_wa->size = size;
		new_wa->address = first_free;
oharboe's avatar
oharboe committed
1187

1188
1189
		if (target->backup_working_area)
		{
1190
			int retval;
1191
			new_wa->backup = malloc(new_wa->size);
zwelch's avatar
zwelch committed
1192
			if ((retval = target_read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
1193
1194
1195
1196
1197
			{
				free(new_wa->backup);
				free(new_wa);
				return retval;
			}
1198
1199
1200
1201
1202
		}
		else
		{
			new_wa->backup = NULL;
		}
oharboe's avatar
oharboe committed
1203

1204
1205
1206
		/* put new entry in list */
		*p = new_wa;
	}
oharboe's avatar
oharboe committed
1207

1208
1209
1210
	/* mark as used, and return the new (reused) area */
	new_wa->free = 0;
	*area = new_wa;
oharboe's avatar
oharboe committed
1211

1212
1213
	/* user pointer */
	new_wa->user = area;
oharboe's avatar
oharboe committed
1214

1215
1216
1217
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1218
int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
1219
1220
1221
{
	if (area->free)
		return ERROR_OK;
oharboe's avatar
oharboe committed
1222

zwelch's avatar
zwelch committed
1223
	if (restore && target->backup_working_area)
1224
1225
	{
		int retval;
zwelch's avatar
zwelch committed
1226
		if ((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
1227
1228
			return retval;
	}
oharboe's avatar
oharboe committed
1229

1230
	area->free = 1;
oharboe's avatar
oharboe committed
1231

1232
1233
1234
	/* mark user pointer invalid */
	*area->user = NULL;
	area->user = NULL;
oharboe's avatar
oharboe committed
1235

1236
1237
1238
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1239
int target_free_working_area(struct target *target, struct working_area *area)
oharboe's avatar
   
oharboe committed
1240
1241
1242
1243
{
	return target_free_working_area_restore(target, area, 1);
}

1244
1245
1246
/* free resources and restore memory, if restoring memory fails,
 * free up resources anyway
 */
Zachary T Welch's avatar
Zachary T Welch committed
1247
void target_free_all_working_areas_restore(struct target *target, int restore)
1248
{
1249
	struct working_area *c = target->working_areas;
1250
1251
1252

	while (c)
	{
1253
		struct working_area *next = c->next;
oharboe's avatar
   
oharboe committed
1254
		target_free_working_area_restore(target, c, restore);
oharboe's avatar
oharboe committed
1255

1256
1257
		if (c->backup)
			free(c->backup);
oharboe's avatar
oharboe committed
1258

1259
		free(c);
oharboe's avatar
oharboe committed
1260

1261
1262
		c = next;
	}
oharboe's avatar
oharboe committed
1263

1264
1265
1266
	target->working_areas = NULL;
}

Zachary T Welch's avatar
Zachary T Welch committed
1267
void target_free_all_working_areas(struct target *target)
oharboe's avatar
   
oharboe committed
1268
{
1269
	target_free_all_working_areas_restore(target, 1);
oharboe's avatar
   
oharboe committed
1270
1271
}

Zachary T Welch's avatar
Zachary T Welch committed
1272
int target_arch_state(struct target *target)
1273
1274
{
	int retval;
zwelch's avatar
zwelch committed
1275
	if (target == NULL)
1276
	{
1277
		LOG_USER("No target has been configured");
1278
1279
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
1280

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

zwelch's avatar
zwelch committed
1283
	if (target->state != TARGET_HALTED)
1284
		return ERROR_OK;
oharboe's avatar
oharboe committed
1285

zwelch's avatar
zwelch committed
1286
	retval = target->type->arch_state(target);
1287
1288
1289
	return retval;
}

oharboe's avatar
oharboe committed
1290
1291
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1292
1293
 * possible
 */
Zachary T Welch's avatar
Zachary T Welch committed
1294
int target_write_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
1295
1296
{
	int retval;
1297
	LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1298
		  (int)size, (unsigned)address);
1299

1300
	if (!target_was_examined(target))
1301
1302
1303
1304
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1305

1306
1307
1308
1309
	if (size == 0) {
		return ERROR_OK;
	}

1310
	if ((address + size - 1) < address)
1311
1312
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1313
1314
		LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
				  (unsigned)address,
duane's avatar
duane committed
1315
				  (unsigned)size);
1316
1317
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1318

1319
1320
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1321
		return target_write_memory(target, address, 2, 1, buffer);
1322
	}
oharboe's avatar
oharboe committed
1323

1324
1325
1326
	/* handle unaligned head bytes */
	if (address % 4)
	{
1327
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1328

1329
1330
1331
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1332
		if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1333
			return retval;
oharboe's avatar
oharboe committed
1334

1335
1336
1337
1338
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1339

1340
1341
1342
1343
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1344

1345
1346
1347
1348
1349
1350
1351
1352
		/* 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
1353
			if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1354
1355
				return retval;
		}
oharboe's avatar
oharboe committed
1356

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

1362
1363
1364
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1365
		if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1366
1367
			return retval;
	}
oharboe's avatar
oharboe committed
1368

1369
1370
1371
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1372
1373
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1374
1375
 * possible
 */
Zachary T Welch's avatar
Zachary T Welch committed
1376
int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
1377
1378
{
	int retval;
1379
	LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1380
			  (int)size, (unsigned)address);
1381

1382
	if (!target_was_examined(target))
1383
1384
1385
1386
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1387

1388
1389
1390
1391
	if (size == 0) {
		return ERROR_OK;
	}

1392
	if ((address + size - 1) < address)
1393
1394
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1395
1396
		LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
				  address,
duane's avatar
duane committed
1397
				  size);
1398
1399
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1400

1401
1402
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1403
		return target_read_memory(target, address, 2, 1, buffer);
1404
	}
oharboe's avatar
oharboe committed
1405

1406
1407
1408
	/* handle unaligned head bytes */
	if (address % 4)
	{
1409
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1410

1411
1412
1413
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1414
		if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1415
			return retval;
oharboe's avatar
oharboe committed
1416

1417
1418
1419
1420
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1421

1422
1423
1424
1425
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1426

zwelch's avatar
zwelch committed
1427
		if ((retval = target_read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1428
			return retval;
oharboe's avatar
oharboe committed
1429

1430
1431
1432
1433
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1434

1435
1436
1437
1438
1439
1440
1441
	/*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
1442

1443
1444
1445
1446
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1447
1448
1449
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1450
		if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1451
1452
			return retval;
	}
oharboe's avatar
oharboe committed
1453

1454
1455
1456
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1457
int target_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* crc)
1458
{
1459
	uint8_t *buffer;
1460
	int retval;
1461
1462
	uint32_t i;
	uint32_t checksum = 0;
1463
	if (!target_was_examined(target))
1464
1465
1466
1467
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1468

1469
	if ((retval = target->type->checksum_memory(target, address,
1470
		size, &checksum)) != ERROR_OK)
1471
1472
1473
1474
	{
		buffer = malloc(size);
		if (buffer == NULL)
		{
duane's avatar
duane committed
1475
			LOG_ERROR("error allocating buffer for section (%d bytes)", (int)size);
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
			return ERROR_INVALID_ARGUMENTS;
		}
		retval = target_read_buffer(target, address, size, buffer);
		if (retval != ERROR_OK)
		{
			free(buffer);
			return retval;
		}

		/* convert to target endianess */
1486
		for (i = 0; i < (size/sizeof(uint32_t)); i++)
1487
		{
1488
1489
1490
			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);
1491
1492
		}

1493
		retval = image_calculate_checksum(buffer, size, &checksum);
1494
1495
		free(buffer);
	}
oharboe's avatar
oharboe committed
1496

1497
	*crc = checksum;
oharboe's avatar
oharboe committed
1498

1499
1500
	return retval;
}
1501

Zachary T Welch's avatar
Zachary T Welch committed
1502
int target_blank_check_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* blank)
1503
1504
{
	int retval;
1505
	if (!target_was_examined(target))
1506
1507
1508
1509
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1510

1511
1512
	if (target->type->blank_check_memory == 0)
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
oharboe's avatar
oharboe committed
1513

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

1516
1517
	return retval;
}
1518

Zachary T Welch's avatar
Zachary T Welch committed
1519
int target_read_u32(struct target *target, uint32_t address, uint32_t *value)
1520
{
1521
	uint8_t value_buf[4];
1522
	if (!target_was_examined(target))
1523
1524
1525
1526
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1527

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

1530
1531
1532
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u32(target, value_buf);
1533
1534
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
				  address,
duane's avatar
duane committed
1535
				  *value);
1536
1537
1538
1539
	}
	else
	{
		*value = 0x0;
1540
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1541
				  address);
1542
	}
oharboe's avatar
oharboe committed
1543

1544
1545
1546
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1547
int target_read_u16(struct target *target, uint32_t address, uint16_t *value)
1548
{
1549
	uint8_t value_buf[2];
1550
	if (!target_was_examined(target))
1551
1552
1553
1554
1555
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

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

1558
1559
1560
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u16(target, value_buf);
1561
1562
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
				  address,
duane's avatar
duane committed
1563
				  *value);
1564
1565
1566
1567
	}
	else
	{
		*value = 0x0;
1568
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1569
				  address);
1570
	}
oharboe's avatar
oharboe committed
1571

1572
1573
1574
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1575
int target_read_u8(struct target *target, uint32_t address, uint8_t *value)
1576
{
zwelch's avatar
zwelch committed
1577
	int retval = target_read_memory(target, address, 1, 1, value);
1578
	if (!target_was_examined(target))
1579
1580
1581
1582
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1583
1584
1585

	if (retval == ERROR_OK)
	{
1586
1587
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
				  address,
duane's avatar
duane committed
1588
				  *value);
1589
1590
1591
1592
	}
	else
	{
		*value = 0x0;
1593
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1594
				  address);
1595
	}
oharboe's avatar
oharboe committed
1596

1597
1598
1599
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1600
int target_write_u32(struct target *target, uint32_t address, uint32_t value)
1601
1602
{
	int retval;
1603
	uint8_t value_buf[4];
1604
	if (!target_was_examined(target))
1605
1606
1607
1608
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1609

1610
1611
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
			  address,
duane's avatar
duane committed
1612
			  value);
1613

oharboe's avatar
oharboe committed
1614
	target_buffer_set_u32(target, value_buf, value);
zwelch's avatar
zwelch committed
1615
	if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1616
	{
1617
		LOG_DEBUG("failed: %i", retval);
1618
	}
oharboe's avatar
oharboe committed
1619

1620
1621
1622
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1623
int target_write_u16(struct target *target, uint32_t address, uint16_t value)
1624
1625
{
	int retval;
1626
	uint8_t value_buf[2];
1627
	if (!target_was_examined(target))
1628
1629
1630
1631
1632
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

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

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

1643
1644
1645
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1646
int target_write_u8(struct target *target, uint32_t address, uint8_t value)
1647
1648
{
	int retval;
1649
	if (!target_was_examined(target))
1650
1651
1652
1653
1654
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

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

zwelch's avatar
zwelch committed
1658
	if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
1659
	{
1660
		LOG_DEBUG("failed: %i", retval);
1661
	}
oharboe's avatar
oharboe committed
1662

1663
1664
1665
	return retval;
}

1666
COMMAND_HANDLER(handle_targets_command)
1667
{
Zachary T Welch's avatar
Zachary T Welch committed
1668
	struct target *target = all_targets;
oharboe's avatar
oharboe committed
1669

1670
	if (CMD_ARGC == 1)
1671
	{
1672
		target = get_target(CMD_ARGV[0]);
1673
		if (target == NULL) {
1674
			command_print(CMD_CTX,"Target: %s is unknown, try one of:\n", CMD_ARGV[0]);
1675
1676
			goto DumpTargets;
		}
oharboe's avatar
oharboe committed
1677
		if (!target->tap->enabled) {
1678
			command_print(CMD_CTX,"Target: TAP %s is disabled, "
oharboe's avatar
oharboe committed
1679
1680
1681
1682
					"can't be the current target\n",
					target->tap->dotted_name);
			return ERROR_FAIL;
		}
1683

1684
		CMD_CTX->current_target = target->target_number;
1685
1686
		return ERROR_OK;
	}
1687
DumpTargets:
oharboe's avatar
oharboe committed
1688

1689
	target = all_targets;
1690
1691
	command_print(CMD_CTX, "    TargetName         Type       Endian TapName            State       ");
	command_print(CMD_CTX, "--  ------------------ ---------- ------ ------------------ ------------");
1692
1693
	while (target)
	{
oharboe's avatar
oharboe committed
1694
1695
1696
1697
		const char *state;
		char marker = ' ';

		if (target->tap->enabled)
1698
			state = target_state_name( target );
oharboe's avatar
oharboe committed
1699
1700
1701
		else
			state = "tap-disabled";

1702
		if (CMD_CTX->current_target == target->target_number)
oharboe's avatar
oharboe committed
1703
1704
1705
			marker = '*';

		/* keep columns lined up to match the headers above */
1706
		command_print(CMD_CTX, "%2d%c %-18s %-10s %-6s %-18s %s",
1707
					  target->target_number,
oharboe's avatar
oharboe committed
1708
					  marker,
1709
					  target_name(target),
1710
					  target_type_name(target),
oharboe's avatar
oharboe committed
1711
1712
					  Jim_Nvp_value2name_simple(nvp_target_endian,
								target->endianness)->name,
1713
					  target->tap->dotted_name,
oharboe's avatar
oharboe committed
1714
					  state);
1715
1716
		target = target->next;
	}
oharboe's avatar
oharboe committed
1717

1718
1719
1720
	return ERROR_OK;
}

1721
/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1722
1723
1724
1725

static int powerDropout;
static int srstAsserted;

1726
1727
1728
1729
1730
static int runPowerRestore;
static int runPowerDropout;
static int runSrstAsserted;
static int runSrstDeasserted;

1731
static int sense_handler(void)
1732
1733
1734
1735
1736
{
	static int prevSrstAsserted = 0;
	static int prevPowerdropout = 0;

	int retval;
zwelch's avatar
zwelch committed
1737
	if ((retval = jtag_power_dropout(&powerDropout)) != ERROR_OK)
1738
1739
1740
1741
1742
1743
		return retval;

	int powerRestored;
	powerRestored = prevPowerdropout && !powerDropout;
	if (powerRestored)
	{
1744
		runPowerRestore = 1;
1745
1746
1747
1748
1749
1750
1751
	}

	long long current = timeval_ms();
	static long long lastPower = 0;
	int waitMore = lastPower + 2000 > current;
	if (powerDropout && !waitMore)
	{
1752
		runPowerDropout = 1;
1753
1754
1755
		lastPower = current;
	}

zwelch's avatar
zwelch committed
1756
	if ((retval = jtag_srst_asserted(&srstAsserted)) != ERROR_OK)
1757
1758
1759
1760
1761
1762
1763
1764
1765
		return retval;

	int srstDeasserted;
	srstDeasserted = prevSrstAsserted && !srstAsserted;

	static long long lastSrst = 0;
	waitMore = lastSrst + 2000 > current;
	if (srstDeasserted && !waitMore)
	{
1766
		runSrstDeasserted = 1;
1767
1768
1769
1770
1771
		lastSrst = current;
	}

	if (!prevSrstAsserted && srstAsserted)
	{
1772
		runSrstAsserted = 1;
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
	}

	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;
}

1789
static void target_call_event_callbacks_all(enum target_event e) {
Zachary T Welch's avatar
Zachary T Welch committed
1790
	struct target *target;
1791
1792
1793
1794
1795
1796
1797
	target = all_targets;
	while (target) {
		target_call_event_callbacks(target, e);
		target = target->next;
	}
}

1798
1799
1800
/* process target state changes */
int handle_target(void *priv)
{
1801
	int retval = ERROR_OK;
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815

	/* 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)
		{
1816
			target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
1817
			Jim_Eval(interp, "srst_asserted");
1818
1819
1820
1821
			did_something = 1;
		}
		if (runSrstDeasserted)
		{
1822
			Jim_Eval(interp, "srst_deasserted");
1823
1824
1825
1826
			did_something = 1;
		}
		if (runPowerDropout)
		{
1827
			target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
1828
			Jim_Eval(interp, "power_dropout");
1829
1830
1831
1832
			did_something = 1;
		}
		if (runPowerRestore)
		{
1833
			Jim_Eval(interp, "power_restore");
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
			did_something = 1;
		}

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

		/* clear action flags */

zwelch's avatar
zwelch committed
1845
1846
1847
1848
		runSrstAsserted = 0;
		runSrstDeasserted = 0;
		runPowerRestore = 0;
		runPowerDropout = 0;
1849
1850
1851
1852

		recursive = 0;
	}

zwelch's avatar
zwelch committed
1853
1854
1855
	/* Poll targets for state changes unless that's globally disabled.
	 * Skip targets that are currently disabled.
	 */
Zachary T Welch's avatar
Zachary T Welch committed
1856
	for (struct target *target = all_targets;
1857
			is_jtag_poll_safe() && target;
zwelch's avatar
zwelch committed
1858
			target = target->next)
1859
	{
zwelch's avatar
zwelch committed
1860
1861
		if (!target->tap->enabled)
			continue;
1862
1863

		/* only poll target if we've got power and srst isn't asserted */
zwelch's avatar
zwelch committed
1864
		if (!powerDropout && !srstAsserted)
1865
		{
1866
			/* polling may fail silently until the target has been examined */
zwelch's avatar
zwelch committed
1867
			if ((retval = target_poll(target)) != ERROR_OK)
1868
1869
			{
				target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
1870
				return retval;
1871
			}
1872
1873
		}
	}
oharboe's avatar
oharboe committed
1874

1875
	return retval;
1876
1877
}

1878
COMMAND_HANDLER(handle_reg_command)
1879
{
Zachary T Welch's avatar
Zachary T Welch committed
1880
	struct target *target;
Zachary T Welch's avatar
Zachary T Welch committed
1881
	struct reg *reg = NULL;
1882
	unsigned count = 0;