target.c 128 KB
Newer Older
1001
	}
oharboe's avatar
oharboe committed
1002

1003
1004
1005
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1006
int target_call_event_callbacks(struct target *target, enum target_event event)
1007
{
1008
1009
	struct target_event_callback *callback = target_event_callbacks;
	struct target_event_callback *next_callback;
oharboe's avatar
oharboe committed
1010

1011
1012
1013
	if (event == TARGET_EVENT_HALTED)
	{
		/* execute early halted first */
1014
		target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
1015
1016
	}

1017
1018
	LOG_DEBUG("target event %i (%s)",
			  event,
1019
			  Jim_Nvp_value2name_simple(nvp_target_event, event)->name);
oharboe's avatar
oharboe committed
1020

1021
	target_handle_event(target, event);
1022

1023
1024
1025
1026
1027
1028
	while (callback)
	{
		next_callback = callback->next;
		callback->callback(target, event, callback->priv);
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1029

1030
1031
1032
	return ERROR_OK;
}

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

1048
static int target_call_timer_callback(struct target_timer_callback *cb,
1049
1050
1051
		struct timeval *now)
{
	cb->callback(cb->priv);
1052

1053
1054
1055
1056
1057
1058
1059
1060
	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
1061
1062
	keep_alive();

1063
	struct timeval now;
1064
	gettimeofday(&now, NULL);
oharboe's avatar
oharboe committed
1065

1066
	struct target_timer_callback *callback = target_timer_callbacks;
1067
1068
	while (callback)
	{
1069
		// cleaning up may unregister and free this callback
1070
		struct target_timer_callback *next_callback = callback->next;
1071
1072
1073
1074
1075
1076

		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
1077

1078
		if (call_it)
1079
		{
1080
1081
1082
			int retval = target_call_timer_callback(callback, &now);
			if (retval != ERROR_OK)
				return retval;
1083
		}
oharboe's avatar
oharboe committed
1084

1085
1086
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1087

1088
1089
1090
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1091
int target_call_timer_callbacks(void)
1092
1093
1094
1095
1096
{
	return target_call_timer_callbacks_check_time(1);
}

/* invoke periodic callbacks immediately */
oharboe's avatar
oharboe committed
1097
int target_call_timer_callbacks_now(void)
1098
{
oharboe's avatar
   
oharboe committed
1099
	return target_call_timer_callbacks_check_time(0);
1100
1101
}

1102
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
1103
{
1104
1105
	struct working_area *c = target->working_areas;
	struct working_area *new_wa = NULL;
oharboe's avatar
oharboe committed
1106

1107
1108
1109
1110
1111
	/* Reevaluate working area address based on MMU state*/
	if (target->working_areas == NULL)
	{
		int retval;
		int enabled;
1112

1113
1114
1115
1116
1117
		retval = target->type->mmu(target, &enabled);
		if (retval != ERROR_OK)
		{
			return retval;
		}
1118

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

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

1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
	/* 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
1161

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

1169
1170
1171
1172
1173
1174
1175
1176
		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
1177

1178
1179
1180
1181
		if (free_size < size)
		{
			return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
		}
oharboe's avatar
oharboe committed
1182

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

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

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

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

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

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

1217
1218
1219
	return ERROR_OK;
}

1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
{
	int retval;

	retval = target_alloc_working_area_try(target, size, area);
	if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
	{
		LOG_WARNING("not enough working area available(requested %u)", (unsigned)(size));
	}
	return retval;

}

1233
static int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
1234
1235
1236
{
	if (area->free)
		return ERROR_OK;
oharboe's avatar
oharboe committed
1237

zwelch's avatar
zwelch committed
1238
	if (restore && target->backup_working_area)
1239
1240
	{
		int retval;
zwelch's avatar
zwelch committed
1241
		if ((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
1242
1243
			return retval;
	}
oharboe's avatar
oharboe committed
1244

1245
	area->free = 1;
oharboe's avatar
oharboe committed
1246

1247
1248
1249
	/* mark user pointer invalid */
	*area->user = NULL;
	area->user = NULL;
oharboe's avatar
oharboe committed
1250

1251
1252
1253
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1254
int target_free_working_area(struct target *target, struct working_area *area)
oharboe's avatar
   
oharboe committed
1255
1256
1257
1258
{
	return target_free_working_area_restore(target, area, 1);
}

1259
1260
1261
/* free resources and restore memory, if restoring memory fails,
 * free up resources anyway
 */
1262
static void target_free_all_working_areas_restore(struct target *target, int restore)
1263
{
1264
	struct working_area *c = target->working_areas;
1265
1266
1267

	while (c)
	{
1268
		struct working_area *next = c->next;
oharboe's avatar
   
oharboe committed
1269
		target_free_working_area_restore(target, c, restore);
oharboe's avatar
oharboe committed
1270

1271
1272
		if (c->backup)
			free(c->backup);
oharboe's avatar
oharboe committed
1273

1274
		free(c);
oharboe's avatar
oharboe committed
1275

1276
1277
		c = next;
	}
oharboe's avatar
oharboe committed
1278

1279
1280
1281
	target->working_areas = NULL;
}

Zachary T Welch's avatar
Zachary T Welch committed
1282
void target_free_all_working_areas(struct target *target)
oharboe's avatar
   
oharboe committed
1283
{
1284
	target_free_all_working_areas_restore(target, 1);
oharboe's avatar
   
oharboe committed
1285
1286
}

Zachary T Welch's avatar
Zachary T Welch committed
1287
int target_arch_state(struct target *target)
1288
1289
{
	int retval;
zwelch's avatar
zwelch committed
1290
	if (target == NULL)
1291
	{
1292
		LOG_USER("No target has been configured");
1293
1294
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
1295

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

zwelch's avatar
zwelch committed
1298
	if (target->state != TARGET_HALTED)
1299
		return ERROR_OK;
oharboe's avatar
oharboe committed
1300

zwelch's avatar
zwelch committed
1301
	retval = target->type->arch_state(target);
1302
1303
1304
	return retval;
}

oharboe's avatar
oharboe committed
1305
1306
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1307
1308
 * possible
 */
Zachary T Welch's avatar
Zachary T Welch committed
1309
int target_write_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
1310
1311
{
	int retval;
1312
	LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1313
		  (int)size, (unsigned)address);
1314

1315
	if (!target_was_examined(target))
1316
1317
1318
1319
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1320

1321
1322
1323
1324
	if (size == 0) {
		return ERROR_OK;
	}

1325
	if ((address + size - 1) < address)
1326
1327
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1328
1329
		LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
				  (unsigned)address,
duane's avatar
duane committed
1330
				  (unsigned)size);
1331
1332
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1333

1334
1335
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1336
		return target_write_memory(target, address, 2, 1, buffer);
1337
	}
oharboe's avatar
oharboe committed
1338

1339
1340
1341
	/* handle unaligned head bytes */
	if (address % 4)
	{
1342
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1343

1344
1345
1346
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1347
		if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1348
			return retval;
oharboe's avatar
oharboe committed
1349

1350
1351
1352
1353
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1354

1355
1356
1357
1358
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1359

1360
1361
1362
1363
1364
1365
1366
1367
		/* 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
1368
			if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1369
1370
				return retval;
		}
oharboe's avatar
oharboe committed
1371

1372
1373
1374
1375
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
oharboe's avatar
oharboe committed
1376

1377
1378
1379
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1380
		if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1381
1382
			return retval;
	}
oharboe's avatar
oharboe committed
1383

1384
1385
1386
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1387
1388
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1389
1390
 * possible
 */
Zachary T Welch's avatar
Zachary T Welch committed
1391
int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
1392
1393
{
	int retval;
1394
	LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1395
			  (int)size, (unsigned)address);
1396

1397
	if (!target_was_examined(target))
1398
1399
1400
1401
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1402

1403
1404
1405
1406
	if (size == 0) {
		return ERROR_OK;
	}

1407
	if ((address + size - 1) < address)
1408
1409
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1410
1411
		LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
				  address,
duane's avatar
duane committed
1412
				  size);
1413
1414
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1415

1416
1417
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1418
		return target_read_memory(target, address, 2, 1, buffer);
1419
	}
oharboe's avatar
oharboe committed
1420

1421
1422
1423
	/* handle unaligned head bytes */
	if (address % 4)
	{
1424
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1425

1426
1427
1428
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1429
		if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1430
			return retval;
oharboe's avatar
oharboe committed
1431

1432
1433
1434
1435
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1436

1437
1438
1439
1440
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1441

zwelch's avatar
zwelch committed
1442
		if ((retval = target_read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1443
			return retval;
oharboe's avatar
oharboe committed
1444

1445
1446
1447
1448
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1449

1450
1451
1452
1453
1454
1455
1456
	/*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
1457

1458
1459
1460
1461
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1462
1463
1464
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1465
		if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1466
1467
			return retval;
	}
oharboe's avatar
oharboe committed
1468

1469
1470
1471
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1472
int target_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* crc)
1473
{
1474
	uint8_t *buffer;
1475
	int retval;
1476
1477
	uint32_t i;
	uint32_t checksum = 0;
1478
	if (!target_was_examined(target))
1479
1480
1481
1482
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1483

1484
	if ((retval = target->type->checksum_memory(target, address,
1485
		size, &checksum)) != ERROR_OK)
1486
1487
1488
1489
	{
		buffer = malloc(size);
		if (buffer == NULL)
		{
duane's avatar
duane committed
1490
			LOG_ERROR("error allocating buffer for section (%d bytes)", (int)size);
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
			return ERROR_INVALID_ARGUMENTS;
		}
		retval = target_read_buffer(target, address, size, buffer);
		if (retval != ERROR_OK)
		{
			free(buffer);
			return retval;
		}

		/* convert to target endianess */
1501
		for (i = 0; i < (size/sizeof(uint32_t)); i++)
1502
		{
1503
1504
1505
			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);
1506
1507
		}

1508
		retval = image_calculate_checksum(buffer, size, &checksum);
1509
1510
		free(buffer);
	}
oharboe's avatar
oharboe committed
1511

1512
	*crc = checksum;
oharboe's avatar
oharboe committed
1513

1514
1515
	return retval;
}
1516

Zachary T Welch's avatar
Zachary T Welch committed
1517
int target_blank_check_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* blank)
1518
1519
{
	int retval;
1520
	if (!target_was_examined(target))
1521
1522
1523
1524
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1525

1526
1527
	if (target->type->blank_check_memory == 0)
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
oharboe's avatar
oharboe committed
1528

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

1531
1532
	return retval;
}
1533

Zachary T Welch's avatar
Zachary T Welch committed
1534
int target_read_u32(struct target *target, uint32_t address, uint32_t *value)
1535
{
1536
	uint8_t value_buf[4];
1537
	if (!target_was_examined(target))
1538
1539
1540
1541
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1542

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

1545
1546
1547
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u32(target, value_buf);
1548
1549
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
				  address,
duane's avatar
duane committed
1550
				  *value);
1551
1552
1553
1554
	}
	else
	{
		*value = 0x0;
1555
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1556
				  address);
1557
	}
oharboe's avatar
oharboe committed
1558

1559
1560
1561
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1562
int target_read_u16(struct target *target, uint32_t address, uint16_t *value)
1563
{
1564
	uint8_t value_buf[2];
1565
	if (!target_was_examined(target))
1566
1567
1568
1569
1570
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

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

1573
1574
1575
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u16(target, value_buf);
1576
1577
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
				  address,
duane's avatar
duane committed
1578
				  *value);
1579
1580
1581
1582
	}
	else
	{
		*value = 0x0;
1583
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1584
				  address);
1585
	}
oharboe's avatar
oharboe committed
1586

1587
1588
1589
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1590
int target_read_u8(struct target *target, uint32_t address, uint8_t *value)
1591
{
zwelch's avatar
zwelch committed
1592
	int retval = target_read_memory(target, address, 1, 1, value);
1593
	if (!target_was_examined(target))
1594
1595
1596
1597
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1598
1599
1600

	if (retval == ERROR_OK)
	{
1601
1602
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
				  address,
duane's avatar
duane committed
1603
				  *value);
1604
1605
1606
1607
	}
	else
	{
		*value = 0x0;
1608
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1609
				  address);
1610
	}
oharboe's avatar
oharboe committed
1611

1612
1613
1614
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1615
int target_write_u32(struct target *target, uint32_t address, uint32_t value)
1616
1617
{
	int retval;
1618
	uint8_t value_buf[4];
1619
	if (!target_was_examined(target))
1620
1621
1622
1623
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1624

1625
1626
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
			  address,
duane's avatar
duane committed
1627
			  value);
1628

oharboe's avatar
oharboe committed
1629
	target_buffer_set_u32(target, value_buf, value);
zwelch's avatar
zwelch committed
1630
	if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1631
	{
1632
		LOG_DEBUG("failed: %i", retval);
1633
	}
oharboe's avatar
oharboe committed
1634

1635
1636
1637
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1638
int target_write_u16(struct target *target, uint32_t address, uint16_t value)
1639
1640
{
	int retval;
1641
	uint8_t value_buf[2];
1642
	if (!target_was_examined(target))
1643
1644
1645
1646
1647
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

1648
1649
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
			  address,
duane's avatar
duane committed
1650
			  value);
1651

oharboe's avatar
oharboe committed
1652
	target_buffer_set_u16(target, value_buf, value);
zwelch's avatar
zwelch committed
1653
	if ((retval = target_write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
1654
	{
1655
		LOG_DEBUG("failed: %i", retval);
1656
	}
oharboe's avatar
oharboe committed
1657

1658
1659
1660
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1661
int target_write_u8(struct target *target, uint32_t address, uint8_t value)
1662
1663
{
	int retval;
1664
	if (!target_was_examined(target))
1665
1666
1667
1668
1669
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

1670
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
duane's avatar
duane committed
1671
			  address, value);
1672

zwelch's avatar
zwelch committed
1673
	if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
1674
	{
1675
		LOG_DEBUG("failed: %i", retval);
1676
	}
oharboe's avatar
oharboe committed
1677

1678
1679
1680
	return retval;
}

1681
COMMAND_HANDLER(handle_targets_command)
1682
{
Zachary T Welch's avatar
Zachary T Welch committed
1683
	struct target *target = all_targets;
oharboe's avatar
oharboe committed
1684

1685
	if (CMD_ARGC == 1)
1686
	{
1687
		target = get_target(CMD_ARGV[0]);
1688
		if (target == NULL) {
1689
			command_print(CMD_CTX,"Target: %s is unknown, try one of:\n", CMD_ARGV[0]);
1690
1691
			goto DumpTargets;
		}
oharboe's avatar
oharboe committed
1692
		if (!target->tap->enabled) {
1693
			command_print(CMD_CTX,"Target: TAP %s is disabled, "
oharboe's avatar
oharboe committed
1694
1695
1696
1697
					"can't be the current target\n",
					target->tap->dotted_name);
			return ERROR_FAIL;
		}
1698

1699
		CMD_CTX->current_target = target->target_number;
1700
1701
		return ERROR_OK;
	}
1702
DumpTargets:
oharboe's avatar
oharboe committed
1703

1704
	target = all_targets;
1705
1706
	command_print(CMD_CTX, "    TargetName         Type       Endian TapName            State       ");
	command_print(CMD_CTX, "--  ------------------ ---------- ------ ------------------ ------------");
1707
1708
	while (target)
	{
oharboe's avatar
oharboe committed
1709
1710
1711
1712
		const char *state;
		char marker = ' ';

		if (target->tap->enabled)
1713
			state = target_state_name( target );
oharboe's avatar
oharboe committed
1714
1715
1716
		else
			state = "tap-disabled";

1717
		if (CMD_CTX->current_target == target->target_number)
oharboe's avatar
oharboe committed
1718
1719
1720
			marker = '*';

		/* keep columns lined up to match the headers above */
1721
		command_print(CMD_CTX, "%2d%c %-18s %-10s %-6s %-18s %s",
1722
					  target->target_number,
oharboe's avatar
oharboe committed
1723
					  marker,
1724
					  target_name(target),
1725
					  target_type_name(target),
oharboe's avatar
oharboe committed
1726
1727
					  Jim_Nvp_value2name_simple(nvp_target_endian,
								target->endianness)->name,
1728
					  target->tap->dotted_name,
oharboe's avatar
oharboe committed
1729
					  state);
1730
1731
		target = target->next;
	}
oharboe's avatar
oharboe committed
1732

1733
1734
1735
	return ERROR_OK;
}

1736
/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1737
1738
1739
1740

static int powerDropout;
static int srstAsserted;

1741
1742
1743
1744
1745
static int runPowerRestore;
static int runPowerDropout;
static int runSrstAsserted;
static int runSrstDeasserted;

1746
static int sense_handler(void)
1747
1748
1749
1750
1751
{
	static int prevSrstAsserted = 0;
	static int prevPowerdropout = 0;

	int retval;
zwelch's avatar
zwelch committed
1752
	if ((retval = jtag_power_dropout(&powerDropout)) != ERROR_OK)
1753
1754
1755
1756
1757
1758
		return retval;

	int powerRestored;
	powerRestored = prevPowerdropout && !powerDropout;
	if (powerRestored)
	{
1759
		runPowerRestore = 1;
1760
1761
1762
1763
1764
1765
1766
	}

	long long current = timeval_ms();
	static long long lastPower = 0;
	int waitMore = lastPower + 2000 > current;
	if (powerDropout && !waitMore)
	{
1767
		runPowerDropout = 1;
1768
1769
1770
		lastPower = current;
	}

zwelch's avatar
zwelch committed
1771
	if ((retval = jtag_srst_asserted(&srstAsserted)) != ERROR_OK)
1772
1773
1774
1775
1776
1777
1778
1779
1780
		return retval;

	int srstDeasserted;
	srstDeasserted = prevSrstAsserted && !srstAsserted;

	static long long lastSrst = 0;
	waitMore = lastSrst + 2000 > current;
	if (srstDeasserted && !waitMore)
	{
1781
		runSrstDeasserted = 1;
1782
1783
1784
1785
1786
		lastSrst = current;
	}

	if (!prevSrstAsserted && srstAsserted)
	{
1787
		runSrstAsserted = 1;
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
	}

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

1804
1805
1806
static int backoff_times = 0;
static int backoff_count = 0;

1807
/* process target state changes */
1808
static int handle_target(void *priv)
1809
{
1810
	Jim_Interp *interp = (Jim_Interp *)priv;
1811
	int retval = ERROR_OK;
1812

Øyvind Harboe's avatar
Øyvind Harboe committed
1813
1814
1815
1816
1817
1818
	if (!is_jtag_poll_safe())
	{
		/* polling is disabled currently */
		return ERROR_OK;
	}

1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
	/* 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)
		{
1832
			LOG_INFO("srst asserted detected, running srst_asserted proc.");
1833
			Jim_Eval(interp, "srst_asserted");
1834
1835
1836
1837
			did_something = 1;
		}
		if (runSrstDeasserted)
		{
1838
			Jim_Eval(interp, "srst_deasserted");
1839
1840
1841
1842
			did_something = 1;
		}
		if (runPowerDropout)
		{
1843
			LOG_INFO("Power dropout detected, running power_dropout proc.");
1844
			Jim_Eval(interp, "power_dropout");
1845
1846
1847
1848
			did_something = 1;
		}
		if (runPowerRestore)
		{
1849
			Jim_Eval(interp, "power_restore");
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
			did_something = 1;
		}

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

		/* clear action flags */

zwelch's avatar
zwelch committed
1861
1862
1863
1864
		runSrstAsserted = 0;
		runSrstDeasserted = 0;
		runPowerRestore = 0;
		runPowerDropout = 0;
1865
1866
1867
1868

		recursive = 0;
	}

1869
1870
1871
1872
1873
1874
1875
1876
	if (backoff_times > backoff_count)
	{
		/* do not poll this time as we failed previously */
		backoff_count++;
		return ERROR_OK;
	}
	backoff_count = 0;

zwelch's avatar
zwelch committed
1877
1878
1879
	/* 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
1880
	for (struct target *target = all_targets;
1881
			is_jtag_poll_safe() && target;
zwelch's avatar
zwelch committed
1882
			target = target->next)
1883
	{
zwelch's avatar
zwelch committed
1884
1885
		if (!target->tap->enabled)
			continue;
1886
1887

		/* only poll target if we've got power and srst isn't asserted */
zwelch's avatar
zwelch committed
1888
		if (!powerDropout && !srstAsserted)
1889
		{
1890
			/* polling may fail silently until the target has been examined */
zwelch's avatar
zwelch committed
1891
			if ((retval = target_poll(target)) != ERROR_OK)
1892
			{
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
				/* 100ms polling interval. Increase interval between polling up to 5000ms */
				if (backoff_times * polling_interval < 5000)
				{
					backoff_times *= 2;
					backoff_times++;
				}
				LOG_USER("Polling target failed, GDB will be halted. Polling again in %dms", backoff_times * polling_interval);

				/* Tell GDB to halt the debugger. This allows the user to
				 * run monitor commands to handle the situation.
1903
				 */
1904
				target_call_event_callbacks(target, TARGET