target.c 118 KB
Newer Older
4001
4002
4003
4004
4005
4006
			break;
		}

		/* convert to "bytes" */
		c = c * b;
		/* count is now in 'BYTES' */
zwelch's avatar
zwelch committed
4007
		while (c > 0) {
4008
			y = c;
zwelch's avatar
zwelch committed
4009
			if (y > 16) {
4010
4011
				y = 16;
			}
4012
			e = target_read_memory(target, a, b, y / b, target_buf);
zwelch's avatar
zwelch committed
4013
			if (e != ERROR_OK) {
4014
				Jim_SetResult_sprintf(interp, "error reading target @ 0x%08lx", (int)(a));
4015
4016
				return JIM_ERR;
			}
4017

4018
			Jim_fprintf(interp, interp->cookie_stdout, "0x%08x ", (int)(a));
zwelch's avatar
zwelch committed
4019
			switch (b) {
4020
			case 4:
zwelch's avatar
zwelch committed
4021
				for (x = 0 ; (x < 16) && (x < y) ; x += 4) {
4022
4023
					z = target_buffer_get_u32(target, &(target_buf[ x * 4 ]));
					Jim_fprintf(interp, interp->cookie_stdout, "%08x ", (int)(z));
4024
				}
zwelch's avatar
zwelch committed
4025
				for (; (x < 16) ; x += 4) {
4026
					Jim_fprintf(interp, interp->cookie_stdout, "         ");
4027
4028
4029
				}
				break;
			case 2:
zwelch's avatar
zwelch committed
4030
				for (x = 0 ; (x < 16) && (x < y) ; x += 2) {
4031
4032
					z = target_buffer_get_u16(target, &(target_buf[ x * 2 ]));
					Jim_fprintf(interp, interp->cookie_stdout, "%04x ", (int)(z));
4033
				}
zwelch's avatar
zwelch committed
4034
				for (; (x < 16) ; x += 2) {
4035
					Jim_fprintf(interp, interp->cookie_stdout, "     ");
4036
4037
4038
4039
				}
				break;
			case 1:
			default:
zwelch's avatar
zwelch committed
4040
				for (x = 0 ; (x < 16) && (x < y) ; x += 1) {
4041
4042
					z = target_buffer_get_u8(target, &(target_buf[ x * 4 ]));
					Jim_fprintf(interp, interp->cookie_stdout, "%02x ", (int)(z));
4043
				}
zwelch's avatar
zwelch committed
4044
				for (; (x < 16) ; x += 1) {
4045
					Jim_fprintf(interp, interp->cookie_stdout, "   ");
4046
4047
4048
4049
				}
				break;
			}
			/* ascii-ify the bytes */
zwelch's avatar
zwelch committed
4050
			for (x = 0 ; x < y ; x++) {
4051
				if ((target_buf[x] >= 0x20) &&
zwelch's avatar
zwelch committed
4052
					(target_buf[x] <= 0x7e)) {
4053
4054
4055
4056
4057
4058
4059
					/* good */
				} else {
					/* smack it */
					target_buf[x] = '.';
				}
			}
			/* space pad  */
zwelch's avatar
zwelch committed
4060
			while (x < 16) {
4061
4062
4063
4064
4065
4066
				target_buf[x] = ' ';
				x++;
			}
			/* terminate */
			target_buf[16] = 0;
			/* print - with a newline */
4067
			Jim_fprintf(interp, interp->cookie_stdout, "%s\n", target_buf);
4068
4069
4070
4071
4072
4073
			/* NEXT... */
			c -= 16;
			a += 16;
		}
		return JIM_OK;
	case TS_CMD_MEM2ARRAY:
4074
		return target_mem2array(goi.interp, target, goi.argc, goi.argv);
4075
4076
		break;
	case TS_CMD_ARRAY2MEM:
4077
		return target_array2mem(goi.interp, target, goi.argc, goi.argv);
4078
4079
		break;
	case TS_CMD_EXAMINE:
zwelch's avatar
zwelch committed
4080
		if (goi.argc) {
4081
			Jim_WrongNumArgs(goi.interp, 2, argv, "[no parameters]");
4082
4083
			return JIM_ERR;
		}
zwelch's avatar
zwelch committed
4084
4085
		if (!target->tap->enabled)
			goto err_tap_disabled;
4086
		e = target->type->examine(target);
zwelch's avatar
zwelch committed
4087
		if (e != ERROR_OK) {
4088
			Jim_SetResult_sprintf(interp, "examine-fails: %d", e);
4089
4090
4091
4092
			return JIM_ERR;
		}
		return JIM_OK;
	case TS_CMD_POLL:
zwelch's avatar
zwelch committed
4093
		if (goi.argc) {
4094
			Jim_WrongNumArgs(goi.interp, 2, argv, "[no parameters]");
4095
4096
			return JIM_ERR;
		}
zwelch's avatar
zwelch committed
4097
4098
		if (!target->tap->enabled)
			goto err_tap_disabled;
zwelch's avatar
zwelch committed
4099
		if (!(target_was_examined(target))) {
4100
4101
			e = ERROR_TARGET_NOT_EXAMINED;
		} else {
4102
			e = target->type->poll(target);
4103
		}
zwelch's avatar
zwelch committed
4104
		if (e != ERROR_OK) {
4105
			Jim_SetResult_sprintf(interp, "poll-fails: %d", e);
4106
4107
4108
4109
4110
4111
			return JIM_ERR;
		} else {
			return JIM_OK;
		}
		break;
	case TS_CMD_RESET:
zwelch's avatar
zwelch committed
4112
		if (goi.argc != 2) {
4113
4114
			Jim_WrongNumArgs(interp, 2, argv,
					"([tT]|[fF]|assert|deassert) BOOL");
4115
4116
			return JIM_ERR;
		}
4117
		e = Jim_GetOpt_Nvp(&goi, nvp_assert, &n);
zwelch's avatar
zwelch committed
4118
		if (e != JIM_OK) {
4119
			Jim_GetOpt_NvpUnknown(&goi, nvp_assert, 1);
4120
4121
			return e;
		}
4122
		/* the halt or not param */
4123
		e = Jim_GetOpt_Wide(&goi, &a);
zwelch's avatar
zwelch committed
4124
		if (e != JIM_OK) {
4125
4126
			return e;
		}
zwelch's avatar
zwelch committed
4127
4128
		if (!target->tap->enabled)
			goto err_tap_disabled;
4129
4130
4131
4132
4133
4134
4135
		if (!target->type->assert_reset
				|| !target->type->deassert_reset) {
			Jim_SetResult_sprintf(interp,
					"No target-specific reset for %s",
					target->cmd_name);
			return JIM_ERR;
		}
4136
		/* determine if we should halt or not. */
4137
		target->reset_halt = !!a;
4138
		/* When this happens - all workareas are invalid. */
4139
4140
		target_free_all_working_areas_restore(target, 0);

4141
		/* do the assert */
zwelch's avatar
zwelch committed
4142
		if (n->value == NVP_ASSERT) {
4143
			e = target->type->assert_reset(target);
4144
		} else {
4145
			e = target->type->deassert_reset(target);
4146
		}
4147
		return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
4148
	case TS_CMD_HALT:
zwelch's avatar
zwelch committed
4149
		if (goi.argc) {
4150
			Jim_WrongNumArgs(goi.interp, 0, argv, "halt [no parameters]");
4151
4152
			return JIM_ERR;
		}
zwelch's avatar
zwelch committed
4153
4154
		if (!target->tap->enabled)
			goto err_tap_disabled;
4155
4156
		e = target->type->halt(target);
		return (e == ERROR_OK) ? JIM_OK : JIM_ERR;
4157
	case TS_CMD_WAITSTATE:
4158
		/* params:  <name>  statename timeoutmsecs */
zwelch's avatar
zwelch committed
4159
		if (goi.argc != 2) {
4160
			Jim_SetResult_sprintf(goi.interp, "%s STATENAME TIMEOUTMSECS", n->name);
4161
4162
			return JIM_ERR;
		}
4163
		e = Jim_GetOpt_Nvp(&goi, nvp_target_state, &n);
zwelch's avatar
zwelch committed
4164
		if (e != JIM_OK) {
4165
			Jim_GetOpt_NvpUnknown(&goi, nvp_target_state,1);
4166
4167
			return e;
		}
4168
		e = Jim_GetOpt_Wide(&goi, &a);
zwelch's avatar
zwelch committed
4169
		if (e != JIM_OK) {
4170
4171
			return e;
		}
zwelch's avatar
zwelch committed
4172
4173
		if (!target->tap->enabled)
			goto err_tap_disabled;
4174
		e = target_wait_state(target, n->value, a);
zwelch's avatar
zwelch committed
4175
		if (e != ERROR_OK) {
4176
			Jim_SetResult_sprintf(goi.interp,
4177
								   "target: %s wait %s fails (%d) %s",
4178
4179
								   target->cmd_name,
								   n->name,
4180
								   e, target_strerror_safe(e));
4181
4182
4183
4184
4185
4186
4187
4188
4189
			return JIM_ERR;
		} else {
			return JIM_OK;
		}
	case TS_CMD_EVENTLIST:
		/* List for human, Events defined for this target.
		 * scripts/programs should use 'name cget -event NAME'
		 */
		{
4190
			struct target_event_action *teap;
4191
			teap = target->event_action;
4192
			command_print(cmd_ctx, "Event actions for target (%d) %s\n",
4193
						   target->target_number,
4194
						   target->cmd_name);
4195
4196
			command_print(cmd_ctx, "%-25s | Body", "Event");
			command_print(cmd_ctx, "------------------------- | ----------------------------------------");
zwelch's avatar
zwelch committed
4197
			while (teap) {
4198
				command_print(cmd_ctx,
4199
							   "%-25s | %s",
4200
4201
							   Jim_Nvp_value2name_simple(nvp_target_event, teap->event)->name,
							   Jim_GetString(teap->body, NULL));
4202
4203
				teap = teap->next;
			}
4204
			command_print(cmd_ctx, "***END***");
4205
4206
4207
			return JIM_OK;
		}
	case TS_CMD_CURSTATE:
zwelch's avatar
zwelch committed
4208
		if (goi.argc != 0) {
4209
			Jim_WrongNumArgs(goi.interp, 0, argv, "[no parameters]");
4210
4211
			return JIM_ERR;
		}
4212
		Jim_SetResultString(goi.interp,
4213
4214
							target_state_name( target ),
							-1);
4215
		return JIM_OK;
4216
	case TS_CMD_INVOKE_EVENT:
zwelch's avatar
zwelch committed
4217
		if (goi.argc != 1) {
4218
			Jim_SetResult_sprintf(goi.interp, "%s ?EVENTNAME?",n->name);
4219
4220
			return JIM_ERR;
		}
4221
		e = Jim_GetOpt_Nvp(&goi, nvp_target_event, &n);
zwelch's avatar
zwelch committed
4222
		if (e != JIM_OK) {
4223
			Jim_GetOpt_NvpUnknown(&goi, nvp_target_event, 1);
4224
4225
			return e;
		}
4226
		target_handle_event(target, n->value);
4227
		return JIM_OK;
4228
4229
	}
	return JIM_ERR;
zwelch's avatar
zwelch committed
4230
4231
4232
4233

err_tap_disabled:
	Jim_SetResult_sprintf(interp, "[TAP is disabled]");
	return JIM_ERR;
4234
4235
}

4236
static int target_create(Jim_GetOptInfo *goi)
4237
{
4238
4239
4240
4241
4242
4243
	Jim_Obj *new_cmd;
	Jim_Cmd *cmd;
	const char *cp;
	char *cp2;
	int e;
	int x;
Zachary T Welch's avatar
Zachary T Welch committed
4244
	struct target *target;
4245
	struct command_context *cmd_ctx;
4246
4247

	cmd_ctx = Jim_GetAssocData(goi->interp, "context");
zwelch's avatar
zwelch committed
4248
	if (goi->argc < 3) {
4249
		Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ?type? ..options...");
4250
4251
4252
4253
		return JIM_ERR;
	}

	/* COMMAND */
4254
	Jim_GetOpt_Obj(goi, &new_cmd);
4255
	/* does this command exist? */
4256
	cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
zwelch's avatar
zwelch committed
4257
	if (cmd) {
4258
		cp = Jim_GetString(new_cmd, NULL);
4259
4260
4261
		Jim_SetResult_sprintf(goi->interp, "Command/target: %s Exists", cp);
		return JIM_ERR;
	}
4262

4263
	/* TYPE */
4264
	e = Jim_GetOpt_String(goi, &cp2, NULL);
4265
4266
	cp = cp2;
	/* now does target type exist */
zwelch's avatar
zwelch committed
4267
4268
	for (x = 0 ; target_types[x] ; x++) {
		if (0 == strcmp(cp, target_types[x]->name)) {
4269
4270
4271
4272
			/* found */
			break;
		}
	}
zwelch's avatar
zwelch committed
4273
	if (target_types[x] == NULL) {
4274
		Jim_SetResult_sprintf(goi->interp, "Unknown target type %s, try one of ", cp);
zwelch's avatar
zwelch committed
4275
4276
		for (x = 0 ; target_types[x] ; x++) {
			if (target_types[x + 1]) {
4277
				Jim_AppendStrings(goi->interp,
4278
4279
4280
4281
								   Jim_GetResult(goi->interp),
								   target_types[x]->name,
								   ", ", NULL);
			} else {
4282
				Jim_AppendStrings(goi->interp,
4283
4284
								   Jim_GetResult(goi->interp),
								   " or ",
4285
								   target_types[x]->name,NULL);
4286
4287
4288
4289
4290
4291
			}
		}
		return JIM_ERR;
	}

	/* Create it */
Zachary T Welch's avatar
Zachary T Welch committed
4292
	target = calloc(1,sizeof(struct target));
4293
4294
4295
4296
	/* set target number */
	target->target_number = new_target_number();

	/* allocate memory for each unique target type */
4297
	target->type = (struct target_type*)calloc(1,sizeof(struct target_type));
4298

4299
	memcpy(target->type, target_types[x], sizeof(struct target_type));
4300

4301
4302
4303
4304
4305
4306
4307
	/* will be set by "-endian" */
	target->endianness = TARGET_ENDIAN_UNKNOWN;

	target->working_area        = 0x0;
	target->working_area_size   = 0x0;
	target->working_areas       = NULL;
	target->backup_working_area = 0;
4308

4309
4310
4311
4312
4313
4314
4315
	target->state               = TARGET_UNKNOWN;
	target->debug_reason        = DBG_REASON_UNDEFINED;
	target->reg_cache           = NULL;
	target->breakpoints         = NULL;
	target->watchpoints         = NULL;
	target->next                = NULL;
	target->arch_info           = NULL;
4316

4317
4318
	target->display             = 1;

4319
4320
	target->halt_issued			= false;

4321
	/* initialize trace information */
Zachary T Welch's avatar
Zachary T Welch committed
4322
	target->trace_info = malloc(sizeof(struct trace));
4323
4324
4325
4326
4327
4328
4329
	target->trace_info->num_trace_points         = 0;
	target->trace_info->trace_points_size        = 0;
	target->trace_info->trace_points             = NULL;
	target->trace_info->trace_history_size       = 0;
	target->trace_info->trace_history            = NULL;
	target->trace_info->trace_history_pos        = 0;
	target->trace_info->trace_history_overflowed = 0;
4330

4331
4332
4333
4334
4335
4336
4337
	target->dbgmsg          = NULL;
	target->dbg_msg_enabled = 0;

	target->endianness = TARGET_ENDIAN_UNKNOWN;

	/* Do the rest as "configure" options */
	goi->isconfigure = 1;
4338
	e = target_configure(goi, target);
4339
4340
4341

	if (target->tap == NULL)
	{
4342
		Jim_SetResultString(interp, "-chain-position required when creating target", -1);
zwelch's avatar
zwelch committed
4343
		e = JIM_ERR;
4344
4345
	}

zwelch's avatar
zwelch committed
4346
	if (e != JIM_OK) {
4347
4348
		free(target->type);
		free(target);
4349
4350
4351
		return e;
	}

zwelch's avatar
zwelch committed
4352
	if (target->endianness == TARGET_ENDIAN_UNKNOWN) {
4353
4354
4355
4356
		/* default endian to little if not specified */
		target->endianness = TARGET_LITTLE_ENDIAN;
	}

4357
4358
4359
	/* incase variant is not set */
	if (!target->variant)
		target->variant = strdup("");
4360

4361
	/* create the target specific commands */
zwelch's avatar
zwelch committed
4362
	if (target->type->register_commands) {
4363
		(*(target->type->register_commands))(cmd_ctx);
4364
	}
zwelch's avatar
zwelch committed
4365
	if (target->type->target_create) {
4366
		(*(target->type->target_create))(target, goi->interp);
4367
4368
4369
4370
	}

	/* append to end of list */
	{
Zachary T Welch's avatar
Zachary T Welch committed
4371
		struct target **tpp;
4372
		tpp = &(all_targets);
zwelch's avatar
zwelch committed
4373
		while (*tpp) {
4374
			tpp = &((*tpp)->next);
4375
4376
4377
4378
		}
		*tpp = target;
	}

4379
	cp = Jim_GetString(new_cmd, NULL);
4380
4381
4382
	target->cmd_name = strdup(cp);

	/* now - create the new target name command */
4383
	e = Jim_CreateCommand(goi->interp,
4384
4385
4386
4387
						   /* name */
						   cp,
						   tcl_target_func, /* C function */
						   target, /* private data */
4388
						   NULL); /* no del proc */
4389
4390
4391
4392

	return e;
}

4393
static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
4394
4395
4396
{
	int x,r,e;
	jim_wide w;
4397
	struct command_context *cmd_ctx;
Zachary T Welch's avatar
Zachary T Welch committed
4398
	struct target *target;
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
	Jim_GetOptInfo goi;
	enum tcmd {
		/* TG = target generic */
		TG_CMD_CREATE,
		TG_CMD_TYPES,
		TG_CMD_NAMES,
		TG_CMD_CURRENT,
		TG_CMD_NUMBER,
		TG_CMD_COUNT,
	};
	const char *target_cmds[] = {
4410
		"create", "types", "names", "current", "number",
4411
		"count",
4412
		NULL /* terminate */
4413
4414
4415
	};

	LOG_DEBUG("Target command params:");
4416
	LOG_DEBUG("%s", Jim_Debug_ArgvString(interp, argc, argv));
4417

4418
	cmd_ctx = Jim_GetAssocData(interp, "context");
4419

4420
	Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
4421

zwelch's avatar
zwelch committed
4422
	if (goi.argc == 0) {
4423
4424
4425
4426
		Jim_WrongNumArgs(interp, 1, argv, "missing: command ...");
		return JIM_ERR;
	}

4427
4428
	/* Jim_GetOpt_Debug(&goi); */
	r = Jim_GetOpt_Enum(&goi, target_cmds, &x);
zwelch's avatar
zwelch committed
4429
	if (r != JIM_OK) {
4430
4431
4432
		return r;
	}

zwelch's avatar
zwelch committed
4433
	switch (x) {
4434
4435
4436
4437
	default:
		Jim_Panic(goi.interp,"Why am I here?");
		return JIM_ERR;
	case TG_CMD_CURRENT:
zwelch's avatar
zwelch committed
4438
		if (goi.argc != 0) {
4439
			Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
4440
4441
			return JIM_ERR;
		}
4442
		Jim_SetResultString(goi.interp, get_current_target(cmd_ctx)->cmd_name, -1);
4443
4444
		return JIM_OK;
	case TG_CMD_TYPES:
zwelch's avatar
zwelch committed
4445
		if (goi.argc != 0) {
4446
			Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
4447
4448
			return JIM_ERR;
		}
4449
		Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
zwelch's avatar
zwelch committed
4450
		for (x = 0 ; target_types[x] ; x++) {
4451
			Jim_ListAppendElement(goi.interp,
4452
								   Jim_GetResult(goi.interp),
4453
								   Jim_NewStringObj(goi.interp, target_types[x]->name, -1));
4454
4455
4456
		}
		return JIM_OK;
	case TG_CMD_NAMES:
zwelch's avatar
zwelch committed
4457
		if (goi.argc != 0) {
4458
			Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many parameters");
4459
4460
			return JIM_ERR;
		}
4461
		Jim_SetResult(goi.interp, Jim_NewListObj(goi.interp, NULL, 0));
4462
		target = all_targets;
zwelch's avatar
zwelch committed
4463
		while (target) {
4464
			Jim_ListAppendElement(goi.interp,
4465
								   Jim_GetResult(goi.interp),
4466
								   Jim_NewStringObj(goi.interp, target->cmd_name, -1));
4467
4468
			target = target->next;
		}
4469
		return JIM_OK;
4470
	case TG_CMD_CREATE:
zwelch's avatar
zwelch committed
4471
		if (goi.argc < 3) {
4472
			Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, "?name  ... config options ...");
4473
4474
			return JIM_ERR;
		}
4475
		return target_create(&goi);
4476
4477
		break;
	case TG_CMD_NUMBER:
4478
4479
		/* It's OK to remove this mechanism sometime after August 2010 or so */
		LOG_WARNING("don't use numbers as target identifiers; use names");
zwelch's avatar
zwelch committed
4480
		if (goi.argc != 1) {
4481
			Jim_SetResult_sprintf(goi.interp, "expected: target number ?NUMBER?");
4482
4483
			return JIM_ERR;
		}
4484
		e = Jim_GetOpt_Wide(&goi, &w);
zwelch's avatar
zwelch committed
4485
		if (e != JIM_OK) {
4486
4487
			return JIM_ERR;
		}
4488
4489
4490
		for (x = 0, target = all_targets; target; target = target->next, x++) {
			if (target->target_number == w)
				break;
4491
		}
4492
4493
4494
4495
4496
4497
4498
		if (target == NULL) {
			Jim_SetResult_sprintf(goi.interp,
					"Target: number %d does not exist", (int)(w));
			return JIM_ERR;
		}
		Jim_SetResultString(goi.interp, target->cmd_name, -1);
		return JIM_OK;
4499
	case TG_CMD_COUNT:
zwelch's avatar
zwelch committed
4500
		if (goi.argc != 0) {
4501
			Jim_WrongNumArgs(goi.interp, 0, goi.argv, "<no parameters>");
4502
4503
			return JIM_ERR;
		}
4504
4505
4506
		for (x = 0, target = all_targets; target; target = target->next, x++)
			continue;
		Jim_SetResult(goi.interp, Jim_NewIntObj(goi.interp, x));
4507
4508
		return JIM_OK;
	}
4509
4510

	return JIM_ERR;
4511
}
4512
4513
4514
4515


struct FastLoad
{
4516
	uint32_t address;
4517
	uint8_t *data;
4518
4519
4520
4521
4522
4523
4524
	int length;

};

static int fastload_num;
static struct FastLoad *fastload;

4525
static void free_fastload(void)
4526
{
zwelch's avatar
zwelch committed
4527
	if (fastload != NULL)
4528
4529
	{
		int i;
zwelch's avatar
zwelch committed
4530
		for (i = 0; i < fastload_num; i++)
4531
4532
4533
4534
4535
		{
			if (fastload[i].data)
				free(fastload[i].data);
		}
		free(fastload);
zwelch's avatar
zwelch committed
4536
		fastload = NULL;
4537
4538
4539
4540
4541
4542
	}
}




4543
COMMAND_HANDLER(handle_fast_load_image_command)
4544
{
4545
	uint8_t *buffer;
4546
4547
	uint32_t buf_cnt;
	uint32_t image_size;
zwelch's avatar
zwelch committed
4548
4549
	uint32_t min_address = 0;
	uint32_t max_address = 0xffffffff;
4550
4551
	int i;

Zachary T Welch's avatar
Zachary T Welch committed
4552
	struct image image;
4553

4554
	int retval = CALL_COMMAND_HANDLER(parse_load_image_command_args,
4555
4556
4557
			&image, &min_address, &max_address);
	if (ERROR_OK != retval)
		return retval;
4558

Zachary T Welch's avatar
Zachary T Welch committed
4559
4560
	struct duration bench;
	duration_start(&bench);
4561
4562
4563
4564
4565
4566
4567
4568

	if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
	{
		return ERROR_OK;
	}

	image_size = 0x0;
	retval = ERROR_OK;
zwelch's avatar
zwelch committed
4569
4570
	fastload_num = image.num_sections;
	fastload = (struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
zwelch's avatar
zwelch committed
4571
	if (fastload == NULL)
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
	{
		image_close(&image);
		return ERROR_FAIL;
	}
	memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
	for (i = 0; i < image.num_sections; i++)
	{
		buffer = malloc(image.sections[i].size);
		if (buffer == NULL)
		{
4582
			command_print(cmd_ctx, "error allocating buffer for section (%d bytes)",
duane's avatar
duane committed
4583
						  (int)(image.sections[i].size));
4584
4585
4586
4587
4588
4589
4590
4591
4592
			break;
		}

		if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
		{
			free(buffer);
			break;
		}

zwelch's avatar
zwelch committed
4593
4594
		uint32_t offset = 0;
		uint32_t length = buf_cnt;
4595
4596
4597
4598


		/* DANGER!!! beware of unsigned comparision here!!! */

zwelch's avatar
zwelch committed
4599
		if ((image.sections[i].base_address + buf_cnt >= min_address)&&
zwelch's avatar
zwelch committed
4600
				(image.sections[i].base_address < max_address))
4601
		{
zwelch's avatar
zwelch committed
4602
			if (image.sections[i].base_address < min_address)
4603
4604
			{
				/* clip addresses below */
zwelch's avatar
zwelch committed
4605
				offset += min_address-image.sections[i].base_address;
zwelch's avatar
zwelch committed
4606
				length -= offset;
4607
4608
			}

zwelch's avatar
zwelch committed
4609
			if (image.sections[i].base_address + buf_cnt > max_address)
4610
			{
zwelch's avatar
zwelch committed
4611
				length -= (image.sections[i].base_address + buf_cnt)-max_address;
4612
4613
			}

zwelch's avatar
zwelch committed
4614
			fastload[i].address = image.sections[i].base_address + offset;
zwelch's avatar
zwelch committed
4615
			fastload[i].data = malloc(length);
zwelch's avatar
zwelch committed
4616
			if (fastload[i].data == NULL)
4617
4618
4619
4620
			{
				free(buffer);
				break;
			}
zwelch's avatar
zwelch committed
4621
			memcpy(fastload[i].data, buffer + offset, length);
zwelch's avatar
zwelch committed
4622
			fastload[i].length = length;
4623
4624

			image_size += length;
oharboe's avatar
oharboe committed
4625
			command_print(cmd_ctx, "%u bytes written at address 0x%8.8x",
4626
						  (unsigned int)length,
zwelch's avatar
zwelch committed
4627
						  ((unsigned int)(image.sections[i].base_address + offset)));
4628
4629
4630
4631
4632
		}

		free(buffer);
	}

Zachary T Welch's avatar
Zachary T Welch committed
4633
	if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
4634
	{
Zachary T Welch's avatar
Zachary T Welch committed
4635
4636
4637
4638
4639
4640
4641
		command_print(cmd_ctx, "Loaded %" PRIu32 " bytes "
				"in %fs (%0.3f kb/s)", image_size, 
				duration_elapsed(&bench), duration_kbps(&bench, image_size));

		command_print(cmd_ctx,
				"WARNING: image has not been loaded to target!"
				"You can issue a 'fast_load' to finish loading.");
4642
4643
4644
4645
	}

	image_close(&image);

zwelch's avatar
zwelch committed
4646
	if (retval != ERROR_OK)
4647
4648
4649
4650
4651
4652
4653
	{
		free_fastload();
	}

	return retval;
}

4654
COMMAND_HANDLER(handle_fast_load_command)
4655
{
zwelch's avatar
zwelch committed
4656
	if (argc > 0)
4657
		return ERROR_COMMAND_SYNTAX_ERROR;
zwelch's avatar
zwelch committed
4658
	if (fastload == NULL)
4659
4660
4661
4662
4663
	{
		LOG_ERROR("No image in memory");
		return ERROR_FAIL;
	}
	int i;
zwelch's avatar
zwelch committed
4664
4665
4666
	int ms = timeval_ms();
	int size = 0;
	int retval = ERROR_OK;
zwelch's avatar
zwelch committed
4667
	for (i = 0; i < fastload_num;i++)
4668
	{
Zachary T Welch's avatar
Zachary T Welch committed
4669
		struct target *target = get_current_target(cmd_ctx);
4670
4671
		command_print(cmd_ctx, "Write to 0x%08x, length 0x%08x",
					  (unsigned int)(fastload[i].address),
duane's avatar
duane committed
4672
					  (unsigned int)(fastload[i].length));
zwelch's avatar
zwelch committed
4673
		if (retval == ERROR_OK)
4674
		{
oharboe's avatar
oharboe committed
4675
			retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
4676
		}
zwelch's avatar
zwelch committed
4677
		size += fastload[i].length;
4678
	}
zwelch's avatar
zwelch committed
4679
	int after = timeval_ms();
4680
	command_print(cmd_ctx, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
oharboe's avatar
oharboe committed
4681
	return retval;
4682
}
duane's avatar
duane committed
4683

4684
4685
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
4686
	struct command_context *context;
Zachary T Welch's avatar
Zachary T Welch committed
4687
	struct target *target;
4688
	int retval;
duane's avatar
duane committed
4689

4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
	context = Jim_GetAssocData(interp, "context");
	if (context == NULL) {
		LOG_ERROR("array2mem: no command context");
		return JIM_ERR;
	}
	target = get_current_target(context);
	if (target == NULL) {
		LOG_ERROR("array2mem: no current target");
		return JIM_ERR;
	}

	if ((argc < 6) || (argc > 7))
	{
		return JIM_ERR;
	}

	int cpnum;
	uint32_t op1;
	uint32_t op2;
	uint32_t CRn;
	uint32_t CRm;
	uint32_t value;

	int e;
	long l;
	e = Jim_GetLong(interp, argv[1], &l);
	if (e != JIM_OK) {
		return e;
	}
	cpnum = l;

	e = Jim_GetLong(interp, argv[2], &l);
	if (e != JIM_OK) {
		return e;
	}
	op1 = l;

	e = Jim_GetLong(interp, argv[3], &l);
	if (e != JIM_OK) {
		return e;
	}
4731
	CRn = l;
4732
4733
4734
4735
4736

	e = Jim_GetLong(interp, argv[4], &l);
	if (e != JIM_OK) {
		return e;
	}
4737
	CRm = l;
4738
4739
4740
4741
4742

	e = Jim_GetLong(interp, argv[5], &l);
	if (e != JIM_OK) {
		return e;
	}
4743
	op2 = l;
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768

	value = 0;

	if (argc == 7)
	{
		e = Jim_GetLong(interp, argv[6], &l);
		if (e != JIM_OK) {
			return e;
		}
		value = l;

		retval = target_mcr(target, cpnum, op1, op2, CRn, CRm, value);
		if (retval != ERROR_OK)
			return JIM_ERR;
	} else
	{
		retval = target_mrc(target, cpnum, op1, op2, CRn, CRm, &value);
		if (retval != ERROR_OK)
			return JIM_ERR;

		Jim_SetResult(interp, Jim_NewIntObj(interp, value));
	}

	return JIM_OK;
}
4769

4770
int target_register_commands(struct command_context *cmd_ctx)
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
{

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

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

	return ERROR_OK;
}

4783
int target_register_user_commands(struct command_context *cmd_ctx)
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
{
	int retval = ERROR_OK;
	if ((retval = target_request_register_commands(cmd_ctx)) != ERROR_OK)
		return retval;

	if ((retval = trace_register_commands(cmd_ctx)) != ERROR_OK)
		return retval;

	register_command(cmd_ctx, NULL, "profile",
			handle_profile_command, COMMAND_EXEC,
			"profiling samples the CPU PC");

	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>");

	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");

David Brownell's avatar
David Brownell committed
4814
	/** @todo don't register virt2phys() unless target supports it */
4815
4816
4817
	register_command(cmd_ctx, NULL, "virt2phys",
			handle_virt2phys_command, COMMAND_ANY,
			"translate a virtual address into a physical address");
David Brownell's avatar
David Brownell committed
4818

4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
	register_command(cmd_ctx,  NULL, "reg",
			handle_reg_command, COMMAND_EXEC,
			"display or set a register");

	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, "reset",
			handle_reset_command, COMMAND_EXEC,
			"reset target [run | halt | init] - default is run");
	register_command(cmd_ctx,  NULL, "soft_reset_halt",
			handle_soft_reset_halt_command, COMMAND_EXEC,
			"halt the target and do a soft reset");

	register_command(cmd_ctx,  NULL, "step",
			handle_step_command, COMMAND_EXEC,
			"step one instruction from current PC or [addr]");

	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]");

	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]");

	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>");

	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]");
	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]");
	register_command(cmd_ctx,  NULL, "test_image",
			handle_test_image_command, COMMAND_EXEC,
			"test_image <file> [offset] [type]");

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