target.c 118 KB
Newer Older
1001
			  event,
1002
			  Jim_Nvp_value2name_simple(nvp_target_event, event)->name);
oharboe's avatar
oharboe committed
1003

1004
	target_handle_event(target, event);
1005

1006
1007
1008
1009
1010
1011
	while (callback)
	{
		next_callback = callback->next;
		callback->callback(target, event, callback->priv);
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1012

1013
1014
1015
	return ERROR_OK;
}

1016
static int target_timer_callback_periodic_restart(
1017
		struct target_timer_callback *cb, struct timeval *now)
1018
{
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
	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;
}

1031
static int target_call_timer_callback(struct target_timer_callback *cb,
1032
1033
1034
		struct timeval *now)
{
	cb->callback(cb->priv);
1035

1036
1037
1038
1039
1040
1041
1042
1043
	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
1044
1045
	keep_alive();

1046
	struct timeval now;
1047
	gettimeofday(&now, NULL);
oharboe's avatar
oharboe committed
1048

1049
	struct target_timer_callback *callback = target_timer_callbacks;
1050
1051
	while (callback)
	{
1052
		// cleaning up may unregister and free this callback
1053
		struct target_timer_callback *next_callback = callback->next;
1054
1055
1056
1057
1058
1059

		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
1060

1061
		if (call_it)
1062
		{
1063
1064
1065
			int retval = target_call_timer_callback(callback, &now);
			if (retval != ERROR_OK)
				return retval;
1066
		}
oharboe's avatar
oharboe committed
1067

1068
1069
		callback = next_callback;
	}
oharboe's avatar
oharboe committed
1070

1071
1072
1073
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1074
int target_call_timer_callbacks(void)
1075
1076
1077
1078
1079
{
	return target_call_timer_callbacks_check_time(1);
}

/* invoke periodic callbacks immediately */
oharboe's avatar
oharboe committed
1080
int target_call_timer_callbacks_now(void)
1081
{
oharboe's avatar
   
oharboe committed
1082
	return target_call_timer_callbacks_check_time(0);
1083
1084
}

Zachary T Welch's avatar
Zachary T Welch committed
1085
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
1086
{
1087
1088
	struct working_area *c = target->working_areas;
	struct working_area *new_wa = NULL;
oharboe's avatar
oharboe committed
1089

1090
1091
1092
1093
1094
	/* Reevaluate working area address based on MMU state*/
	if (target->working_areas == NULL)
	{
		int retval;
		int enabled;
1095

1096
1097
1098
1099
1100
		retval = target->type->mmu(target, &enabled);
		if (retval != ERROR_OK)
		{
			return retval;
		}
1101

1102
1103
1104
1105
1106
		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);
1107
				target->working_area = target->working_area_phys;
1108
1109
1110
			} else {
				LOG_ERROR("No working memory available. "
					"Specify -work-area-phys to target.");
1111
1112
				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
			}
1113
1114
1115
1116
1117
		} else {
			if (target->working_area_virt_spec) {
				LOG_DEBUG("MMU enabled, using virtual "
					"address for working memory 0x%08x",
					(unsigned)target->working_area_virt);
1118
				target->working_area = target->working_area_virt;
1119
1120
1121
			} else {
				LOG_ERROR("No working memory available. "
					"Specify -work-area-virt to target.");
1122
1123
				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
			}
1124
1125
		}
	}
oharboe's avatar
oharboe committed
1126

1127
1128
1129
	/* only allocate multiples of 4 byte */
	if (size % 4)
	{
duane's avatar
duane committed
1130
1131
		LOG_ERROR("BUG: code tried to allocate unaligned number of bytes (0x%08x), padding", ((unsigned)(size)));
		size = (size + 3) & (~3);
1132
	}
oharboe's avatar
oharboe committed
1133

1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
	/* 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
1144

1145
1146
1147
	/* if not, allocate a new one */
	if (!new_wa)
	{
1148
		struct working_area **p = &target->working_areas;
1149
1150
		uint32_t first_free = target->working_area;
		uint32_t free_size = target->working_area_size;
oharboe's avatar
oharboe committed
1151

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

1161
1162
		if (free_size < size)
		{
1163
			LOG_WARNING("not enough working area available(requested %u, free %u)",
duane's avatar
duane committed
1164
				    (unsigned)(size), (unsigned)(free_size));
1165
1166
			return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
		}
oharboe's avatar
oharboe committed
1167

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

1170
		new_wa = malloc(sizeof(struct working_area));
1171
1172
1173
		new_wa->next = NULL;
		new_wa->size = size;
		new_wa->address = first_free;
oharboe's avatar
oharboe committed
1174

1175
1176
		if (target->backup_working_area)
		{
1177
			int retval;
1178
			new_wa->backup = malloc(new_wa->size);
zwelch's avatar
zwelch committed
1179
			if ((retval = target_read_memory(target, new_wa->address, 4, new_wa->size / 4, new_wa->backup)) != ERROR_OK)
1180
1181
1182
1183
1184
			{
				free(new_wa->backup);
				free(new_wa);
				return retval;
			}
1185
1186
1187
1188
1189
		}
		else
		{
			new_wa->backup = NULL;
		}
oharboe's avatar
oharboe committed
1190

1191
1192
1193
		/* put new entry in list */
		*p = new_wa;
	}
oharboe's avatar
oharboe committed
1194

1195
1196
1197
	/* mark as used, and return the new (reused) area */
	new_wa->free = 0;
	*area = new_wa;
oharboe's avatar
oharboe committed
1198

1199
1200
	/* user pointer */
	new_wa->user = area;
oharboe's avatar
oharboe committed
1201

1202
1203
1204
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1205
int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)
1206
1207
1208
{
	if (area->free)
		return ERROR_OK;
oharboe's avatar
oharboe committed
1209

zwelch's avatar
zwelch committed
1210
	if (restore && target->backup_working_area)
1211
1212
	{
		int retval;
zwelch's avatar
zwelch committed
1213
		if ((retval = target_write_memory(target, area->address, 4, area->size / 4, area->backup)) != ERROR_OK)
1214
1215
			return retval;
	}
oharboe's avatar
oharboe committed
1216

1217
	area->free = 1;
oharboe's avatar
oharboe committed
1218

1219
1220
1221
	/* mark user pointer invalid */
	*area->user = NULL;
	area->user = NULL;
oharboe's avatar
oharboe committed
1222

1223
1224
1225
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1226
int target_free_working_area(struct target *target, struct working_area *area)
oharboe's avatar
   
oharboe committed
1227
1228
1229
1230
{
	return target_free_working_area_restore(target, area, 1);
}

1231
1232
1233
/* free resources and restore memory, if restoring memory fails,
 * free up resources anyway
 */
Zachary T Welch's avatar
Zachary T Welch committed
1234
void target_free_all_working_areas_restore(struct target *target, int restore)
1235
{
1236
	struct working_area *c = target->working_areas;
1237
1238
1239

	while (c)
	{
1240
		struct working_area *next = c->next;
oharboe's avatar
   
oharboe committed
1241
		target_free_working_area_restore(target, c, restore);
oharboe's avatar
oharboe committed
1242

1243
1244
		if (c->backup)
			free(c->backup);
oharboe's avatar
oharboe committed
1245

1246
		free(c);
oharboe's avatar
oharboe committed
1247

1248
1249
		c = next;
	}
oharboe's avatar
oharboe committed
1250

1251
1252
1253
	target->working_areas = NULL;
}

Zachary T Welch's avatar
Zachary T Welch committed
1254
void target_free_all_working_areas(struct target *target)
oharboe's avatar
   
oharboe committed
1255
{
1256
	target_free_all_working_areas_restore(target, 1);
oharboe's avatar
   
oharboe committed
1257
1258
}

Zachary T Welch's avatar
Zachary T Welch committed
1259
int target_arch_state(struct target *target)
1260
1261
{
	int retval;
zwelch's avatar
zwelch committed
1262
	if (target == NULL)
1263
	{
1264
		LOG_USER("No target has been configured");
1265
1266
		return ERROR_OK;
	}
oharboe's avatar
oharboe committed
1267

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

zwelch's avatar
zwelch committed
1270
	if (target->state != TARGET_HALTED)
1271
		return ERROR_OK;
oharboe's avatar
oharboe committed
1272

zwelch's avatar
zwelch committed
1273
	retval = target->type->arch_state(target);
1274
1275
1276
	return retval;
}

oharboe's avatar
oharboe committed
1277
1278
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1279
1280
 * possible
 */
Zachary T Welch's avatar
Zachary T Welch committed
1281
int target_write_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
1282
1283
{
	int retval;
1284
	LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1285
		  (int)size, (unsigned)address);
1286

1287
	if (!target_was_examined(target))
1288
1289
1290
1291
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1292

1293
1294
1295
1296
	if (size == 0) {
		return ERROR_OK;
	}

1297
	if ((address + size - 1) < address)
1298
1299
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1300
1301
		LOG_ERROR("address + size wrapped(0x%08x, 0x%08x)",
				  (unsigned)address,
duane's avatar
duane committed
1302
				  (unsigned)size);
1303
1304
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1305

1306
1307
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1308
		return target_write_memory(target, address, 2, 1, buffer);
1309
	}
oharboe's avatar
oharboe committed
1310

1311
1312
1313
	/* handle unaligned head bytes */
	if (address % 4)
	{
1314
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1315

1316
1317
1318
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1319
		if ((retval = target_write_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1320
			return retval;
oharboe's avatar
oharboe committed
1321

1322
1323
1324
1325
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1326

1327
1328
1329
1330
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1331

1332
1333
1334
1335
1336
1337
1338
1339
		/* 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
1340
			if ((retval = target_write_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK)
1341
1342
				return retval;
		}
oharboe's avatar
oharboe committed
1343

1344
1345
1346
1347
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
oharboe's avatar
oharboe committed
1348

1349
1350
1351
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1352
		if ((retval = target_write_memory(target, address, 1, size, buffer)) != ERROR_OK)
1353
1354
			return retval;
	}
oharboe's avatar
oharboe committed
1355

1356
1357
1358
	return ERROR_OK;
}

oharboe's avatar
oharboe committed
1359
1360
/* Single aligned words are guaranteed to use 16 or 32 bit access
 * mode respectively, otherwise data is handled as quickly as
1361
1362
 * possible
 */
Zachary T Welch's avatar
Zachary T Welch committed
1363
int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
1364
1365
{
	int retval;
1366
	LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
duane's avatar
duane committed
1367
			  (int)size, (unsigned)address);
1368

1369
	if (!target_was_examined(target))
1370
1371
1372
1373
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1374

1375
1376
1377
1378
	if (size == 0) {
		return ERROR_OK;
	}

1379
	if ((address + size - 1) < address)
1380
1381
	{
		/* GDB can request this when e.g. PC is 0xfffffffc*/
1382
1383
		LOG_ERROR("address + size wrapped(0x%08" PRIx32 ", 0x%08" PRIx32 ")",
				  address,
duane's avatar
duane committed
1384
				  size);
1385
1386
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1387

1388
1389
	if (((address % 2) == 0) && (size == 2))
	{
zwelch's avatar
zwelch committed
1390
		return target_read_memory(target, address, 2, 1, buffer);
1391
	}
oharboe's avatar
oharboe committed
1392

1393
1394
1395
	/* handle unaligned head bytes */
	if (address % 4)
	{
1396
		uint32_t unaligned = 4 - (address % 4);
oharboe's avatar
oharboe committed
1397

1398
1399
1400
		if (unaligned > size)
			unaligned = size;

zwelch's avatar
zwelch committed
1401
		if ((retval = target_read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK)
1402
			return retval;
oharboe's avatar
oharboe committed
1403

1404
1405
1406
1407
		buffer += unaligned;
		address += unaligned;
		size -= unaligned;
	}
oharboe's avatar
oharboe committed
1408

1409
1410
1411
1412
	/* handle aligned words */
	if (size >= 4)
	{
		int aligned = size - (size % 4);
oharboe's avatar
oharboe committed
1413

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

1417
1418
1419
1420
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1421

1422
1423
1424
1425
1426
1427
1428
	/*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
1429

1430
1431
1432
1433
		buffer += aligned;
		address += aligned;
		size -= aligned;
	}
1434
1435
1436
	/* handle tail writes of less than 4 bytes */
	if (size > 0)
	{
zwelch's avatar
zwelch committed
1437
		if ((retval = target_read_memory(target, address, 1, size, buffer)) != ERROR_OK)
1438
1439
			return retval;
	}
oharboe's avatar
oharboe committed
1440

1441
1442
1443
	return ERROR_OK;
}

Zachary T Welch's avatar
Zachary T Welch committed
1444
int target_checksum_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* crc)
1445
{
1446
	uint8_t *buffer;
1447
	int retval;
1448
1449
	uint32_t i;
	uint32_t checksum = 0;
1450
	if (!target_was_examined(target))
1451
1452
1453
1454
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1455

1456
	if ((retval = target->type->checksum_memory(target, address,
1457
		size, &checksum)) != ERROR_OK)
1458
1459
1460
1461
	{
		buffer = malloc(size);
		if (buffer == NULL)
		{
duane's avatar
duane committed
1462
			LOG_ERROR("error allocating buffer for section (%d bytes)", (int)size);
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
			return ERROR_INVALID_ARGUMENTS;
		}
		retval = target_read_buffer(target, address, size, buffer);
		if (retval != ERROR_OK)
		{
			free(buffer);
			return retval;
		}

		/* convert to target endianess */
1473
		for (i = 0; i < (size/sizeof(uint32_t)); i++)
1474
		{
1475
1476
1477
			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);
1478
1479
		}

1480
		retval = image_calculate_checksum(buffer, size, &checksum);
1481
1482
		free(buffer);
	}
oharboe's avatar
oharboe committed
1483

1484
	*crc = checksum;
oharboe's avatar
oharboe committed
1485

1486
1487
	return retval;
}
1488

Zachary T Welch's avatar
Zachary T Welch committed
1489
int target_blank_check_memory(struct target *target, uint32_t address, uint32_t size, uint32_t* blank)
1490
1491
{
	int retval;
1492
	if (!target_was_examined(target))
1493
1494
1495
1496
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
oharboe's avatar
oharboe committed
1497

1498
1499
	if (target->type->blank_check_memory == 0)
		return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
oharboe's avatar
oharboe committed
1500

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

1503
1504
	return retval;
}
1505

Zachary T Welch's avatar
Zachary T Welch committed
1506
int target_read_u32(struct target *target, uint32_t address, uint32_t *value)
1507
{
1508
	uint8_t value_buf[4];
1509
	if (!target_was_examined(target))
1510
1511
1512
1513
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1514

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

1517
1518
1519
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u32(target, value_buf);
1520
1521
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
				  address,
duane's avatar
duane committed
1522
				  *value);
1523
1524
1525
1526
	}
	else
	{
		*value = 0x0;
1527
		LOG_DEBUG("address: 0x%8.8" PRIx32 " failed",
duane's avatar
duane committed
1528
				  address);
1529
	}
oharboe's avatar
oharboe committed
1530

1531
1532
1533
	return retval;
}

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

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

1545
1546
1547
	if (retval == ERROR_OK)
	{
		*value = target_buffer_get_u16(target, value_buf);
1548
1549
		LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%4.4x",
				  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_u8(struct target *target, uint32_t address, uint8_t *value)
1563
{
zwelch's avatar
zwelch committed
1564
	int retval = target_read_memory(target, address, 1, 1, value);
1565
	if (!target_was_examined(target))
1566
1567
1568
1569
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1570
1571
1572

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

1584
1585
1586
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1587
int target_write_u32(struct target *target, uint32_t address, uint32_t value)
1588
1589
{
	int retval;
1590
	uint8_t value_buf[4];
1591
	if (!target_was_examined(target))
1592
1593
1594
1595
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}
1596

1597
1598
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8" PRIx32 "",
			  address,
duane's avatar
duane committed
1599
			  value);
1600

oharboe's avatar
oharboe committed
1601
	target_buffer_set_u32(target, value_buf, value);
zwelch's avatar
zwelch committed
1602
	if ((retval = target_write_memory(target, address, 4, 1, value_buf)) != ERROR_OK)
1603
	{
1604
		LOG_DEBUG("failed: %i", retval);
1605
	}
oharboe's avatar
oharboe committed
1606

1607
1608
1609
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1610
int target_write_u16(struct target *target, uint32_t address, uint16_t value)
1611
1612
{
	int retval;
1613
	uint8_t value_buf[2];
1614
	if (!target_was_examined(target))
1615
1616
1617
1618
1619
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

1620
1621
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%8.8x",
			  address,
duane's avatar
duane committed
1622
			  value);
1623

oharboe's avatar
oharboe committed
1624
	target_buffer_set_u16(target, value_buf, value);
zwelch's avatar
zwelch committed
1625
	if ((retval = target_write_memory(target, address, 2, 1, value_buf)) != ERROR_OK)
1626
	{
1627
		LOG_DEBUG("failed: %i", retval);
1628
	}
oharboe's avatar
oharboe committed
1629

1630
1631
1632
	return retval;
}

Zachary T Welch's avatar
Zachary T Welch committed
1633
int target_write_u8(struct target *target, uint32_t address, uint8_t value)
1634
1635
{
	int retval;
1636
	if (!target_was_examined(target))
1637
1638
1639
1640
1641
	{
		LOG_ERROR("Target not examined yet");
		return ERROR_FAIL;
	}

1642
	LOG_DEBUG("address: 0x%8.8" PRIx32 ", value: 0x%2.2x",
duane's avatar
duane committed
1643
			  address, value);
1644

zwelch's avatar
zwelch committed
1645
	if ((retval = target_write_memory(target, address, 1, 1, &value)) != ERROR_OK)
1646
	{
1647
		LOG_DEBUG("failed: %i", retval);
1648
	}
oharboe's avatar
oharboe committed
1649

1650
1651
1652
	return retval;
}

1653
COMMAND_HANDLER(handle_targets_command)
1654
{
Zachary T Welch's avatar
Zachary T Welch committed
1655
	struct target *target = all_targets;
oharboe's avatar
oharboe committed
1656

1657
1658
	if (argc == 1)
	{
1659
1660
		target = get_target(args[0]);
		if (target == NULL) {
1661
			command_print(cmd_ctx,"Target: %s is unknown, try one of:\n", args[0]);
1662
1663
			goto DumpTargets;
		}
oharboe's avatar
oharboe committed
1664
1665
1666
1667
1668
1669
		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;
		}
1670

1671
		cmd_ctx->current_target = target->target_number;
1672
1673
		return ERROR_OK;
	}
1674
DumpTargets:
oharboe's avatar
oharboe committed
1675

1676
	target = all_targets;
oharboe's avatar
oharboe committed
1677
1678
	command_print(cmd_ctx, "    TargetName         Type       Endian TapName            State       ");
	command_print(cmd_ctx, "--  ------------------ ---------- ------ ------------------ ------------");
1679
1680
	while (target)
	{
oharboe's avatar
oharboe committed
1681
1682
1683
1684
		const char *state;
		char marker = ' ';

		if (target->tap->enabled)
1685
			state = target_state_name( target );
oharboe's avatar
oharboe committed
1686
1687
1688
1689
1690
1691
1692
1693
		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",
1694
					  target->target_number,
oharboe's avatar
oharboe committed
1695
					  marker,
1696
					  target->cmd_name,
zwelch's avatar
zwelch committed
1697
					  target_get_name(target),
oharboe's avatar
oharboe committed
1698
1699
					  Jim_Nvp_value2name_simple(nvp_target_endian,
								target->endianness)->name,
1700
					  target->tap->dotted_name,
oharboe's avatar
oharboe committed
1701
					  state);
1702
1703
		target = target->next;
	}
oharboe's avatar
oharboe committed
1704

1705
1706
1707
	return ERROR_OK;
}

1708
/* every 300ms we check for reset & powerdropout and issue a "reset halt" if so. */
1709
1710
1711
1712

static int powerDropout;
static int srstAsserted;

1713
1714
1715
1716
1717
static int runPowerRestore;
static int runPowerDropout;
static int runSrstAsserted;
static int runSrstDeasserted;

1718
static int sense_handler(void)
1719
1720
1721
1722
1723
{
	static int prevSrstAsserted = 0;
	static int prevPowerdropout = 0;

	int retval;
zwelch's avatar
zwelch committed
1724
	if ((retval = jtag_power_dropout(&powerDropout)) != ERROR_OK)
1725
1726
1727
1728
1729
1730
		return retval;

	int powerRestored;
	powerRestored = prevPowerdropout && !powerDropout;
	if (powerRestored)
	{
1731
		runPowerRestore = 1;
1732
1733
1734
1735
1736
1737
1738
	}

	long long current = timeval_ms();
	static long long lastPower = 0;
	int waitMore = lastPower + 2000 > current;
	if (powerDropout && !waitMore)
	{
1739
		runPowerDropout = 1;
1740
1741
1742
		lastPower = current;
	}

zwelch's avatar
zwelch committed
1743
	if ((retval = jtag_srst_asserted(&srstAsserted)) != ERROR_OK)
1744
1745
1746
1747
1748
1749
1750
1751
1752
		return retval;

	int srstDeasserted;
	srstDeasserted = prevSrstAsserted && !srstAsserted;

	static long long lastSrst = 0;
	waitMore = lastSrst + 2000 > current;
	if (srstDeasserted && !waitMore)
	{
1753
		runSrstDeasserted = 1;
1754
1755
1756
1757
1758
		lastSrst = current;
	}

	if (!prevSrstAsserted && srstAsserted)
	{
1759
		runSrstAsserted = 1;
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
	}

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

1776
static void target_call_event_callbacks_all(enum target_event e) {
Zachary T Welch's avatar
Zachary T Welch committed
1777
	struct target *target;
1778
1779
1780
1781
1782
1783
1784
	target = all_targets;
	while (target) {
		target_call_event_callbacks(target, e);
		target = target->next;
	}
}

1785
1786
1787
/* process target state changes */
int handle_target(void *priv)
{
1788
	int retval = ERROR_OK;
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802

	/* 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)
		{
1803
			target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
1804
			Jim_Eval(interp, "srst_asserted");
1805
1806
1807
1808
			did_something = 1;
		}
		if (runSrstDeasserted)
		{
1809
			Jim_Eval(interp, "srst_deasserted");
1810
1811
1812
1813
			did_something = 1;
		}
		if (runPowerDropout)
		{
1814
			target_call_event_callbacks_all(TARGET_EVENT_GDB_HALT);
1815
			Jim_Eval(interp, "power_dropout");
1816
1817
1818
1819
			did_something = 1;
		}
		if (runPowerRestore)
		{
1820
			Jim_Eval(interp, "power_restore");
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
			did_something = 1;
		}

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

		/* clear action flags */

zwelch's avatar
zwelch committed
1832
1833
1834
1835
		runSrstAsserted = 0;
		runSrstDeasserted = 0;
		runPowerRestore = 0;
		runPowerDropout = 0;
1836
1837
1838
1839

		recursive = 0;
	}

zwelch's avatar
zwelch committed
1840
1841
1842
	/* 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
1843
	for (struct target *target = all_targets;
1844
			is_jtag_poll_safe() && target;
zwelch's avatar
zwelch committed
1845
			target = target->next)
1846
	{
zwelch's avatar
zwelch committed
1847
1848
		if (!target->tap->enabled)
			continue;
1849
1850

		/* only poll target if we've got power and srst isn't asserted */
zwelch's avatar
zwelch committed
1851
		if (!powerDropout && !srstAsserted)
1852
		{
1853
			/* polling may fail silently until the target has been examined */
zwelch's avatar
zwelch committed
1854
			if ((retval = target_poll(target)) != ERROR_OK)
1855
1856
			{
				target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);
1857
				return retval;
1858
			}
1859
1860
		}
	}
oharboe's avatar
oharboe committed
1861

1862
	return retval;
1863
1864
}

1865
COMMAND_HANDLER(handle_reg_command)
1866
{
Zachary T Welch's avatar
Zachary T Welch committed
1867
	struct target *target;
Zachary T Welch's avatar
Zachary T Welch committed
1868
	struct reg *reg = NULL;
1869
1870
	int count = 0;
	char *value;
oharboe's avatar
oharboe committed
1871

1872
	LOG_DEBUG("-");
oharboe's avatar
oharboe committed
1873

1874
	target = get_current_target(cmd_ctx);
oharboe's avatar
oharboe committed
1875

1876
1877
1878
	/* list all available registers for the current target */
	if (argc == 0)
	{
1879
		struct reg_cache *cache = target->reg_cache;
oharboe's avatar
oharboe committed
1880

1881
		count = 0;
zwelch's avatar
zwelch committed
1882
		while (cache)
1883
1884
		{
			int i;
1885

1886
1887
			command_print(cmd_ctx, "===== %s", cache->name);

1888
1889
1890
			for (i = 0, reg = cache->reg_list;
					i <