openocd.c 17.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/***************************************************************************
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#define OPENOCD_VERSION "Open On-Chip Debugger " VERSION " (" PKGBLDDATE ") svn:" PKGBLDREV

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "log.h"
#include "types.h"
#include "jtag.h"
#include "configuration.h"
#include "interpreter.h"
#include "xsvf.h"
#include "target.h"
#include "flash.h"
#include "nand.h"
#include "pld.h"

#include "command.h"
#include "server.h"
#include "telnet_server.h"
#include "gdb_server.h"
oharboe's avatar
oharboe committed
42
#include "tcl_server.h"
43
44
45
46
47
48
49
50
51
52

#include <sys/time.h>
#include <sys/types.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

ntfreak's avatar
ntfreak committed
53
54
55
56
57
58
#ifdef _WIN32
#include <malloc.h>
#else
#include <alloca.h>
#endif

oharboe's avatar
oharboe committed
59
60
61
62
#ifdef __ECOS
/* Jim is provied by eCos */
#include <cyg/jimtcl/jim.h>
#else
oharboe's avatar
oharboe committed
63
64
#define JIM_EMBEDDED
#include "jim.h"
oharboe's avatar
oharboe committed
65
66
#endif

ntfreak's avatar
ntfreak committed
67
#include "replacements.h"
oharboe's avatar
oharboe committed
68
69
70
71
72
73
74
75
76
77
78

int launchTarget(struct command_context_s *cmd_ctx)
{
	int retval;
	/* Try to examine & validate jtag chain, though this may require a reset first
	 * in which case we continue setup */
	jtag_init(cmd_ctx);

	/* try to examine target at this point. If it fails, perhaps a reset will
	 * bring it up later on via a telnet/gdb session */
	target_examine(cmd_ctx);
oharboe's avatar
oharboe committed
79

oharboe's avatar
oharboe committed
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
	retval=flash_init_drivers(cmd_ctx);
	if (retval!=ERROR_OK)
		return retval;
	LOG_DEBUG("flash init complete");

	retval=nand_init(cmd_ctx);
	if (retval!=ERROR_OK)
		return retval;
	LOG_DEBUG("NAND init complete");

	retval=pld_init(cmd_ctx);
	if (retval!=ERROR_OK)
		return retval;
	LOG_DEBUG("pld init complete");
	return retval;
}
oharboe's avatar
oharboe committed
96

97
98
99
100
101
102
103
104
/* Give TELNET a way to find out what version this is */
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	command_print(cmd_ctx, OPENOCD_VERSION);

	return ERROR_OK;
}

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
static int daemon_startup = 0;

int handle_daemon_startup_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
	if (argc==0)
		return ERROR_OK;
	if (argc > 1 )
		return ERROR_COMMAND_SYNTAX_ERROR;
	
	daemon_startup = strcmp("reset", args[0])==0;
	
	command_print(cmd_ctx, OPENOCD_VERSION);

	return ERROR_OK;
}

121
122
123
124
125
126
127
void exit_handler(void)
{
	/* close JTAG interface */
	if (jtag && jtag->quit)
		jtag->quit();
}

128
129
130
/* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
int handle_init_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
131
	int retval;
132
133
134
135
136
137
138
139
140
	static int initialized=0;
	if (initialized)
		return ERROR_OK;
	
	initialized=1;
	
	command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);

	atexit(exit_handler);
141
	
142
143
144
145
	if (target_init(cmd_ctx) != ERROR_OK)
		return ERROR_FAIL;
	LOG_DEBUG("target init complete");

146
147
148
149
150
151
152
153
	if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK)
	{
		/* we must be able to set up the jtag interface */
		return retval;
	}
	LOG_DEBUG("jtag interface init complete");

	/* Try to initialize & examine the JTAG chain at this point, but
154
	 * continue startup regardless */
155
156
157
158
159
160
161
162
	if (jtag_init(cmd_ctx) == ERROR_OK)
	{
		LOG_DEBUG("jtag init complete");
		if (target_examine(cmd_ctx) == ERROR_OK)
		{
			LOG_DEBUG("jtag examine complete");
		}
	}
163
	
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
	if (flash_init_drivers(cmd_ctx) != ERROR_OK)
		return ERROR_FAIL;
	LOG_DEBUG("flash init complete");

	if (nand_init(cmd_ctx) != ERROR_OK)
		return ERROR_FAIL;
	LOG_DEBUG("NAND init complete");

	if (pld_init(cmd_ctx) != ERROR_OK)
		return ERROR_FAIL;
	LOG_DEBUG("pld init complete");

	/* initialize tcp server */
	server_init();

	/* initialize telnet subsystem */
	telnet_init("Open On-Chip Debugger");
	gdb_init();
182
	tcl_init(); /* allows tcl to just connect without going thru telnet */
183
184
185
186

	return ERROR_OK;
}

oharboe's avatar
oharboe committed
187
188
189
Jim_Interp *interp;
command_context_t *active_cmd_ctx;

ntfreak's avatar
ntfreak committed
190
static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
oharboe's avatar
oharboe committed
191
192
193
194
195
{
	char *namebuf;
	Jim_Obj *nameObjPtr, *valObjPtr;
	int result;

196
197
198
199
200
201
202
203
204
205
206
207
	namebuf = alloc_printf("%s(%d)", varname, idx);
	
	nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
	valObjPtr = Jim_NewIntObj(interp, val);
	Jim_IncrRefCount(nameObjPtr);
	Jim_IncrRefCount(valObjPtr);
	result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
	Jim_DecrRefCount(interp, nameObjPtr);
	Jim_DecrRefCount(interp, valObjPtr);
	free(namebuf);
	/* printf( "%s = 0%08x\n", namebuf, val ); */
	return result;
oharboe's avatar
oharboe committed
208
209
}

ntfreak's avatar
ntfreak committed
210
static int Jim_Command_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
oharboe's avatar
oharboe committed
211
212
213
214
215
216
217
218
219
220
{
	target_t *target;
	long l;
	u32 width;
	u32 len;
	u32 addr;
	u32 count;
	u32 v;
	const char *varname;
	u8 buffer[4096];
221
	int  i, n, e, retval;
oharboe's avatar
oharboe committed
222
223
224
225
226
227

	/* argv[1] = name of array to receive the data
	 * argv[2] = desired width
	 * argv[3] = memory address 
	 * argv[4] = length in bytes to read
	 */
228
229
	if (argc != 5) {
		Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
oharboe's avatar
oharboe committed
230
231
		return JIM_ERR;
	}
232
	varname = Jim_GetString(argv[1], &len);
oharboe's avatar
oharboe committed
233
234
	/* given "foo" get space for worse case "foo(%d)" .. add 20 */

235
	e = Jim_GetLong(interp, argv[2], &l);
oharboe's avatar
oharboe committed
236
	width = l;
237
	if (e != JIM_OK) {
oharboe's avatar
oharboe committed
238
239
240
		return e;
	}
	
241
	e = Jim_GetLong(interp, argv[3], &l);
oharboe's avatar
oharboe committed
242
	addr = l;
243
	if (e != JIM_OK) {
oharboe's avatar
oharboe committed
244
245
		return e;
	}
246
	e = Jim_GetLong(interp, argv[4], &l);
oharboe's avatar
oharboe committed
247
	len = l;
248
	if (e != JIM_OK) {
oharboe's avatar
oharboe committed
249
250
		return e;
	}
251
252
253
254
255
256
257
258
259
260
261
262
263
264
	switch (width) {
		case 8:
			width = 1;
			break;
		case 16:
			width = 2;
			break;
		case 32:
			width = 4;
			break;
		default:
			Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
			Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
			return JIM_ERR;
oharboe's avatar
oharboe committed
265
	}
266
267
268
	if (len == 0) {
		Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
		Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
oharboe's avatar
oharboe committed
269
270
		return JIM_ERR;
	}
271
272
273
	if ((addr + (len * width)) < addr) {
		Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
		Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
oharboe's avatar
oharboe committed
274
275
276
		return JIM_ERR;
	}
	/* absurd transfer size? */
277
278
279
	if (len > 65536) {
		Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
		Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
oharboe's avatar
oharboe committed
280
281
282
		return JIM_ERR;
	}		
		
283
	if ((width == 1) ||
oharboe's avatar
oharboe committed
284
		((width == 2) && ((addr & 1) == 0)) ||
285
		((width == 4) && ((addr & 3) == 0))) {
oharboe's avatar
oharboe committed
286
287
288
		/* all is well */
	} else {
		char buf[100];
289
290
291
		Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
		sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width); 
		Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
oharboe's avatar
oharboe committed
292
293
294
		return JIM_ERR;
	}

295
	target = get_current_target(active_cmd_ctx);
oharboe's avatar
oharboe committed
296
297
298
299
300
301
302
	
	/* Transfer loop */

	/* index counter */
	n = 0;
	/* assume ok */
	e = JIM_OK;
303
	while (len) {
oharboe's avatar
oharboe committed
304
305
306
		/* Slurp... in buffer size chunks */
		
		count = len; /* in objects.. */
307
		if (count > (sizeof(buffer)/width)) {
oharboe's avatar
oharboe committed
308
309
310
			count = (sizeof(buffer)/width);
		}
		
311
		retval = target->type->read_memory( target, addr, width, count, buffer );
oharboe's avatar
oharboe committed
312

313
		if (retval != ERROR_OK) {
oharboe's avatar
oharboe committed
314
			/* BOO !*/
315
316
317
			LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
			Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
			Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
oharboe's avatar
oharboe committed
318
319
320
321
			e = JIM_ERR;
			len = 0;
		} else {
			v = 0; /* shut up gcc */
322
323
324
325
326
327
328
329
330
331
332
			for (i = 0 ;i < count ;i++, n++) {
				switch (width) {
					case 4:
						v = target_buffer_get_u32(target, &buffer[i*width]);
						break;
					case 2:
						v = target_buffer_get_u16(target, &buffer[i*width]);
						break;
					case 1:
						v = buffer[i] & 0x0ff;
						break;
oharboe's avatar
oharboe committed
333
				}
334
				new_int_array_element(interp, varname, n, v);
oharboe's avatar
oharboe committed
335
336
337
338
			}
			len -= count;
		}
	}
339
340
	
	Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
oharboe's avatar
oharboe committed
341
342
343
344

	return JIM_OK;
}

ntfreak's avatar
ntfreak committed
345
static void tcl_output(void *privData, const char *file, int line, const char *function, const char *string)
oharboe's avatar
oharboe committed
346
347
348
349
350
351
352
{		
	Jim_Obj *tclOutput=(Jim_Obj *)privData;

	Jim_AppendString(interp, tclOutput, string, strlen(string));
}

/* try to execute as Jim command, otherwise fall back to standard command.
353
354
 * Note that even if the Jim command caused an error, then we succeeded
 * to execute it, hence this fn pretty much always returns ERROR_OK. */
355
356
int jim_command(command_context_t *context, char *line)
{
oharboe's avatar
oharboe committed
357
358
359
	int retval=ERROR_OK;
	int retcode=Jim_Eval(interp, line);
	
360
	if (retcode == JIM_ERR) {
oharboe's avatar
oharboe committed
361
		Jim_PrintErrorMessage(interp);
362
363
364
365
366
367
	    long t;
	    if (Jim_GetLong(interp, Jim_GetVariableStr(interp, "openocd_result", JIM_ERRMSG), &t)==JIM_OK)
	    {
	    	return t;
	    }
	    return ERROR_FAIL;
oharboe's avatar
oharboe committed
368
369
370
371
372
373
	} 
	const char *result;
	int reslen;
	result = Jim_GetString(Jim_GetResult(interp), &reslen);
		
	if (retcode == JIM_EXIT) {
374
375
376
377
378
379
380
381
382
383
384
385
		/* ignore. */
	/* exit(Jim_GetExitCode(interp)); */
	} else {
		if (reslen) {
			int i;
			char buff[256+1];
			for (i = 0; i < reslen; i += 256)
			{
				int chunk;
				chunk = reslen - i;
				if (chunk > 256)
					chunk = 256;
oharboe's avatar
oharboe committed
386
        		strncpy(buff, result+i, chunk);
387
388
389
390
391
392
				buff[chunk] = 0; 
				LOG_USER_N("%s", buff);
			}
			LOG_USER_N("%s", "\n");
		}
	}
oharboe's avatar
oharboe committed
393
394
395
	return retval;
}

396
int startLoop = 0;
oharboe's avatar
oharboe committed
397

ntfreak's avatar
ntfreak committed
398
static int Jim_Command_openocd_ignore(Jim_Interp *interp, int argc, Jim_Obj *const *argv, int ignore)
oharboe's avatar
oharboe committed
399
400
{
	int retval;
401
402
403
404
405
406
407
408
409
	char *cmd = (char*)Jim_GetString(argv[1], NULL);
	
	Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
	
	if (startLoop)
	{
		/* We don't know whether or not the telnet/gdb server is running... */
		target_call_timer_callbacks_now();
	}
oharboe's avatar
oharboe committed
410
411
	
	log_add_callback(tcl_output, tclOutput);
412
	retval=command_run_line_internal(active_cmd_ctx, cmd);
413
414
415
416
417
418
419

	/* we need to be able to get at the retval, so we store in a variable
	 */
	Jim_Obj *resultvar=Jim_NewIntObj(interp, retval);
	Jim_IncrRefCount(resultvar);
	Jim_SetGlobalVariableStr(interp, "openocd_result", resultvar);
	Jim_DecrRefCount(interp, resultvar);
420
421
422
423
424
	
	if (startLoop)
	{
		target_call_timer_callbacks_now();
	}
oharboe's avatar
oharboe committed
425
	log_remove_callback(tcl_output, tclOutput);
426
	
oharboe's avatar
oharboe committed
427
	Jim_SetResult(interp, tclOutput);
428
429
	
	return (ignore||(retval==ERROR_OK))?JIM_OK:JIM_ERR;
oharboe's avatar
oharboe committed
430
431
}

ntfreak's avatar
ntfreak committed
432
static int Jim_Command_openocd(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
oharboe's avatar
oharboe committed
433
434
435
436
{
	return Jim_Command_openocd_ignore(interp, argc, argv, 1); 
}

ntfreak's avatar
ntfreak committed
437
static int Jim_Command_openocd_throw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
oharboe's avatar
oharboe committed
438
439
440
441
442
{
	return Jim_Command_openocd_ignore(interp, argc, argv, 0); 
}

/* find full path to file */
ntfreak's avatar
ntfreak committed
443
static int Jim_Command_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
oharboe's avatar
oharboe committed
444
{
445
	if (argc != 2)
oharboe's avatar
oharboe committed
446
447
		return JIM_ERR;
	char *file = (char*)Jim_GetString(argv[1], NULL);
448
449
	char *full_path = find_file(file);
	if (full_path == NULL)
oharboe's avatar
oharboe committed
450
		return JIM_ERR;
451
452
453
	Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
	free(full_path);
	
oharboe's avatar
oharboe committed
454
455
456
457
	Jim_SetResult(interp, result);
	return JIM_OK;
}

ntfreak's avatar
ntfreak committed
458
static int Jim_Command_echo(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
459
{
460
	if (argc != 2)
461
462
463
464
465
		return JIM_ERR;
	char *str = (char*)Jim_GetString(argv[1], NULL);
	LOG_USER("%s", str);
	return JIM_OK;
}
oharboe's avatar
oharboe committed
466

ntfreak's avatar
ntfreak committed
467
static size_t openocd_jim_fwrite(const void *_ptr, size_t size, size_t n, void *cookie)
oharboe's avatar
oharboe committed
468
469
470
471
472
473
474
475
{
	size_t nbytes;
	const char *ptr;

	/* make it a char easier to read code */
	ptr = _ptr;

	nbytes = size * n;
476
	if (nbytes == 0) {
oharboe's avatar
oharboe committed
477
478
479
		return 0;
	}

480
481
	if (!active_cmd_ctx) {
		/* TODO: Where should this go? */		
oharboe's avatar
oharboe committed
482
483
484
485
		return n;
	}

	/* do we have to chunk it? */
486
	if (ptr[nbytes] == 0) {
oharboe's avatar
oharboe committed
487
		/* no it is a C style string */
488
		command_output_text(active_cmd_ctx, ptr);
oharboe's avatar
oharboe committed
489
		return strlen(ptr);
oharboe's avatar
oharboe committed
490
491
	}
	/* GRR we must chunk - not null terminated */
492
	while (nbytes) {
oharboe's avatar
oharboe committed
493
494
495
496
		char chunk[128+1];
		int x;

		x = nbytes;
497
		if (x > 128) {
oharboe's avatar
oharboe committed
498
499
500
			x = 128;
		}
		/* copy it */
501
		memcpy(chunk, ptr, x);
oharboe's avatar
oharboe committed
502
503
504
		/* terminate it */
		chunk[n] = 0;
		/* output it */
505
		command_output_text(active_cmd_ctx, chunk);
oharboe's avatar
oharboe committed
506
507
508
509
510
511
512
		ptr += x;
		nbytes -= x;
	}
	
	return n;
}

ntfreak's avatar
ntfreak committed
513
static size_t openocd_jim_fread(void *ptr, size_t size, size_t n, void *cookie )
oharboe's avatar
oharboe committed
514
515
516
517
518
{
	/* TCL wants to read... tell him no */
	return 0;
}

ntfreak's avatar
ntfreak committed
519
static int openocd_jim_vfprintf(void *cookie, const char *fmt, va_list ap)
oharboe's avatar
oharboe committed
520
521
522
523
524
{
	char *cp;
	int n;
	
	n = -1;
525
526
527
528
	if (active_cmd_ctx) {
		cp = alloc_vprintf(fmt, ap);
		if (cp) {
			command_output_text(active_cmd_ctx, cp);
oharboe's avatar
oharboe committed
529
530
531
532
533
534
535
			n = strlen(cp);
			free(cp);
		}
	}
	return n;
}

ntfreak's avatar
ntfreak committed
536
static int openocd_jim_fflush(void *cookie)
oharboe's avatar
oharboe committed
537
538
539
540
541
{
	/* nothing to flush */
	return 0;
}

ntfreak's avatar
ntfreak committed
542
static char* openocd_jim_fgets(char *s, int size, void *cookie)
oharboe's avatar
oharboe committed
543
544
545
546
547
548
{
	/* not supported */
	errno = ENOTSUP;
	return NULL;
}

oharboe's avatar
oharboe committed
549
550
void initJim(void)
{
551
552
553
554
555
556
	Jim_CreateCommand(interp, "openocd", Jim_Command_openocd, NULL, NULL);
	Jim_CreateCommand(interp, "openocd_throw", Jim_Command_openocd_throw, NULL, NULL);
	Jim_CreateCommand(interp, "find", Jim_Command_find, NULL, NULL);
	Jim_CreateCommand(interp, "echo", Jim_Command_echo, NULL, NULL);
	Jim_CreateCommand(interp, "mem2array", Jim_Command_mem2array, NULL, NULL );
	
oharboe's avatar
oharboe committed
557
	/* Set Jim's STDIO */
558
	interp->cookie_stdin = NULL;
oharboe's avatar
oharboe committed
559
560
	interp->cookie_stdout = NULL;
	interp->cookie_stderr = NULL;
561
562
563
564
565
	interp->cb_fwrite = openocd_jim_fwrite;
	interp->cb_fread = openocd_jim_fread ;
	interp->cb_vfprintf = openocd_jim_vfprintf;
	interp->cb_fflush = openocd_jim_fflush;
	interp->cb_fgets = openocd_jim_fgets;
566
}
567

oharboe's avatar
oharboe committed
568
569
/* after command line parsing */
void initJim2(void)
570
{
oharboe's avatar
oharboe committed
571
572
573
	Jim_Eval(interp, "source [find tcl/commands.tcl]");
}

574
command_context_t *setup_command_handler(void)
oharboe's avatar
oharboe committed
575
576
{
	command_context_t *cmd_ctx;
oharboe's avatar
oharboe committed
577
	
578
579
580
581
	cmd_ctx = command_init();

	register_command(cmd_ctx, NULL, "version", handle_version_command,
					 COMMAND_EXEC, "show OpenOCD version");
582
583
584
	register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG, 
			"deprecated - use \"init\" and \"reset\" at end of startup script instead");
	
585
586
587
588
	/* register subsystem commands */
	server_register_commands(cmd_ctx);
	telnet_register_commands(cmd_ctx);
	gdb_register_commands(cmd_ctx);
589
	tcl_register_commands(cmd_ctx); /* tcl server commands */
590
591
592
593
594
595
596
597
598
599
	log_register_commands(cmd_ctx);
	jtag_register_commands(cmd_ctx);
	interpreter_register_commands(cmd_ctx);
	xsvf_register_commands(cmd_ctx);
	target_register_commands(cmd_ctx);
	flash_register_commands(cmd_ctx);
	nand_register_commands(cmd_ctx);
	pld_register_commands(cmd_ctx);
	
	if (log_init(cmd_ctx) != ERROR_OK)
oharboe's avatar
oharboe committed
600
601
602
	{
		exit(-1);
	}
603
	LOG_DEBUG("log init complete");
oharboe's avatar
oharboe committed
604

605
	LOG_OUTPUT( OPENOCD_VERSION "\n" );
606
607
	
	
608
609
610
	register_command(cmd_ctx, NULL, "init", handle_init_command,
					 COMMAND_ANY, "initializes target and servers - nop on subsequent invocations");

oharboe's avatar
oharboe committed
611
612
613
	return cmd_ctx;
}

614
615
616
/* normally this is the main() function entry, but if OpenOCD is linked
 * into application, then this fn will not be invoked, but rather that
 * application will have it's own implementation of main(). */
oharboe's avatar
oharboe committed
617
618
619
620
int openocd_main(int argc, char *argv[])
{
#ifdef JIM_EMBEDDED
	Jim_InitEmbedded();
621
622
623
624
	/* Create an interpreter */
	interp = Jim_CreateInterp();
	/* Add all the Jim core commands */
	Jim_RegisterCoreCommands(interp);
oharboe's avatar
oharboe committed
625
#endif
626
	
oharboe's avatar
oharboe committed
627
628
629
630
631
632
	initJim();
	
	/* initialize commandline interface */
	command_context_t *cmd_ctx;
	cmd_ctx=setup_command_handler();
	
oharboe's avatar
oharboe committed
633
634
635
636
637
638
639
640
641
642
643
644
	/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
	LOG_OUTPUT( "$URL$\n");
	/* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line above does not appear in a patch, do not remove */
	/* DANGER!!! make sure that the line above does not appear in a patch, do not remove */

oharboe's avatar
oharboe committed
645
	command_context_t *cfg_cmd_ctx;
646
647
648
649
	cfg_cmd_ctx = copy_command_context(cmd_ctx);
	cfg_cmd_ctx->mode = COMMAND_CONFIG;
	command_set_output_handler(cfg_cmd_ctx, configuration_output_handler, NULL);
	
oharboe's avatar
oharboe committed
650
651
	active_cmd_ctx=cfg_cmd_ctx;
	
652
653
654
	if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
		return EXIT_FAILURE;

oharboe's avatar
oharboe committed
655
	initJim2();
oharboe's avatar
oharboe committed
656

657
658
659
	if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
		return EXIT_FAILURE;
	
oharboe's avatar
oharboe committed
660
661
	active_cmd_ctx=cmd_ctx;
	
662
663
	command_done(cfg_cmd_ctx);

664
	if (command_run_line(cmd_ctx, "init")!=ERROR_OK)
665
		return EXIT_FAILURE;
666
667
668
	
	if (daemon_startup)
		command_run_line(cmd_ctx, "reset");
ntfreak's avatar
ntfreak committed
669
	
oharboe's avatar
oharboe committed
670
671
	startLoop=1;

672
673
674
675
676
677
	/* handle network connections */
	server_loop(cmd_ctx);

	/* shut server down */
	server_quit();

678
679
	unregister_all_commands(cmd_ctx);
	
680
681
682
683
684
	/* free commandline interface */
	command_done(cmd_ctx);

	return EXIT_SUCCESS;
}