target.c 118 KB
Newer Older
4001
4002
		c = c * b;
		/* count is now in 'BYTES' */
zwelch's avatar
zwelch committed
4003
		while (c > 0) {
4004
			y = c;
zwelch's avatar
zwelch committed
4005
			if (y > 16) {
4006
4007
				y = 16;
			}
4008
			e = target_read_memory(target, a, b, y / b, target_buf);
zwelch's avatar
zwelch committed
4009
			if (e != ERROR_OK) {
4010
				Jim_SetResult_sprintf(interp, "error reading target @ 0x%08lx", (int)(a));
4011
4012
				return JIM_ERR;
			}
4013

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

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

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

4232
static int target_create(Jim_GetOptInfo *goi)
4233
{
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
	Jim_Obj *new_cmd;
	Jim_Cmd *cmd;
	const char *cp;
	char *cp2;
	int e;
	int x;
	target_t *target;
	struct command_context_s *cmd_ctx;

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

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

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

	/* Create it */
	target = calloc(1,sizeof(target_t));
	/* set target number */
	target->target_number = new_target_number();

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

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

4297
4298
4299
4300
4301
4302
4303
	/* 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;
4304

4305
4306
4307
4308
4309
4310
4311
	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;
4312

4313
4314
	target->display             = 1;

4315
4316
	target->halt_issued			= false;

4317
	/* initialize trace information */
Zachary T Welch's avatar
Zachary T Welch committed
4318
	target->trace_info = malloc(sizeof(struct trace));
4319
4320
4321
4322
4323
4324
4325
	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;
4326

4327
4328
4329
4330
4331
4332
4333
	target->dbgmsg          = NULL;
	target->dbg_msg_enabled = 0;

	target->endianness = TARGET_ENDIAN_UNKNOWN;

	/* Do the rest as "configure" options */
	goi->isconfigure = 1;
4334
	e = target_configure(goi, target);
4335
4336
4337

	if (target->tap == NULL)
	{
4338
		Jim_SetResultString(interp, "-chain-position required when creating target", -1);
zwelch's avatar
zwelch committed
4339
		e = JIM_ERR;
4340
4341
	}

zwelch's avatar
zwelch committed
4342
	if (e != JIM_OK) {
4343
4344
		free(target->type);
		free(target);
4345
4346
4347
		return e;
	}

zwelch's avatar
zwelch committed
4348
	if (target->endianness == TARGET_ENDIAN_UNKNOWN) {
4349
4350
4351
4352
		/* default endian to little if not specified */
		target->endianness = TARGET_LITTLE_ENDIAN;
	}

4353
4354
4355
	/* incase variant is not set */
	if (!target->variant)
		target->variant = strdup("");
4356

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

	/* append to end of list */
	{
		target_t **tpp;
		tpp = &(all_targets);
zwelch's avatar
zwelch committed
4369
		while (*tpp) {
4370
			tpp = &((*tpp)->next);
4371
4372
4373
4374
		}
		*tpp = target;
	}

4375
	cp = Jim_GetString(new_cmd, NULL);
4376
4377
4378
	target->cmd_name = strdup(cp);

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

	return e;
}

4389
static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
{
	int x,r,e;
	jim_wide w;
	struct command_context_s *cmd_ctx;
	target_t *target;
	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[] = {
4406
		"create", "types", "names", "current", "number",
4407
		"count",
4408
		NULL /* terminate */
4409
4410
4411
	};

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

4414
	cmd_ctx = Jim_GetAssocData(interp, "context");
4415

4416
	Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
4417

zwelch's avatar
zwelch committed
4418
	if (goi.argc == 0) {
4419
4420
4421
4422
		Jim_WrongNumArgs(interp, 1, argv, "missing: command ...");
		return JIM_ERR;
	}

4423
4424
	/* Jim_GetOpt_Debug(&goi); */
	r = Jim_GetOpt_Enum(&goi, target_cmds, &x);
zwelch's avatar
zwelch committed
4425
	if (r != JIM_OK) {
4426
4427
4428
		return r;
	}

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

	return JIM_ERR;
4507
}
4508
4509
4510
4511


struct FastLoad
{
4512
	uint32_t address;
4513
	uint8_t *data;
4514
4515
4516
4517
4518
4519
4520
	int length;

};

static int fastload_num;
static struct FastLoad *fastload;

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




4539
COMMAND_HANDLER(handle_fast_load_image_command)
4540
{
4541
	uint8_t *buffer;
4542
4543
	uint32_t buf_cnt;
	uint32_t image_size;
zwelch's avatar
zwelch committed
4544
4545
	uint32_t min_address = 0;
	uint32_t max_address = 0xffffffff;
4546
4547
	int i;

Zachary T Welch's avatar
Zachary T Welch committed
4548
	struct image image;
4549

4550
	int retval = CALL_COMMAND_HANDLER(parse_load_image_command_args,
4551
4552
4553
			&image, &min_address, &max_address);
	if (ERROR_OK != retval)
		return retval;
4554

Zachary T Welch's avatar
Zachary T Welch committed
4555
4556
	struct duration bench;
	duration_start(&bench);
4557
4558
4559
4560
4561
4562
4563
4564

	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
4565
4566
	fastload_num = image.num_sections;
	fastload = (struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
zwelch's avatar
zwelch committed
4567
	if (fastload == NULL)
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
	{
		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)
		{
4578
			command_print(cmd_ctx, "error allocating buffer for section (%d bytes)",
duane's avatar
duane committed
4579
						  (int)(image.sections[i].size));
4580
4581
4582
4583
4584
4585
4586
4587
4588
			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
4589
4590
		uint32_t offset = 0;
		uint32_t length = buf_cnt;
4591
4592
4593
4594


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

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

zwelch's avatar
zwelch committed
4605
			if (image.sections[i].base_address + buf_cnt > max_address)
4606
			{
zwelch's avatar
zwelch committed
4607
				length -= (image.sections[i].base_address + buf_cnt)-max_address;
4608
4609
			}

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

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

		free(buffer);
	}

Zachary T Welch's avatar
Zachary T Welch committed
4629
	if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK))
4630
	{
Zachary T Welch's avatar
Zachary T Welch committed
4631
4632
4633
4634
4635
4636
4637
		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.");
4638
4639
4640
4641
	}

	image_close(&image);

zwelch's avatar
zwelch committed
4642
	if (retval != ERROR_OK)
4643
4644
4645
4646
4647
4648
4649
	{
		free_fastload();
	}

	return retval;
}

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

4680
4681
4682
4683
4684
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
	command_context_t *context;
	target_t *target;
	int retval;
duane's avatar
duane committed
4685

4686
4687
4688
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
	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;
	}
4727
	CRn = l;
4728
4729
4730
4731
4732

	e = Jim_GetLong(interp, argv[4], &l);
	if (e != JIM_OK) {
		return e;
	}
4733
	CRm = l;
4734
4735
4736
4737
4738

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

	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;
}
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
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

int target_register_commands(struct command_context_s *cmd_ctx)
{

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

int target_register_user_commands(struct command_context_s *cmd_ctx)
{
	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
4810
	/** @todo don't register virt2phys() unless target supports it */
4811
4812
4813
	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
4814

4815
4816
4817
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
	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