openocd.c 7.6 KB
Newer Older
1
2
3
4
/***************************************************************************
 *   Copyright (C) 2005 by Dominic Rath                                    *
 *   Dominic.Rath@gmx.de                                                   *
 *                                                                         *
5
6
7
 *   Copyright (C) 2007,2008 Øyvind Harboe                                 *
 *   oyvind.harboe@zylin.com                                               *
 *                                                                         *
8
9
10
 *   Copyright (C) 2008 Richard Missenden                                  *
 *   richard.missenden@googlemail.com                                      *
 *                                                                         *
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
42
43
44
45
46
 *   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 "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
47
#include "tcl_server.h"
48
49
50
51
52
53
54
55
56
57

#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
58
59
60
61
62
63
64
#ifdef _WIN32
#include <malloc.h>
#else
#include <alloca.h>
#endif

#include "replacements.h"
oharboe's avatar
oharboe committed
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93





void print_version()
{
	/* 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 */
}









94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* 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;
}

void exit_handler(void)
{
	/* close JTAG interface */
	if (jtag && jtag->quit)
		jtag->quit();
}

109
110
111
112
113
114
115
116
117
118
119
120
121
122
static int log_target_callback_event_handler(struct target_s *target, enum target_event event, void *priv)
{
	switch (event)
	{
		case TARGET_EVENT_HALTED:
			target_arch_state(target);
			break;
		default:
			break;
	}

	return ERROR_OK;
}

123
124
125
/* 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)
{
126
	int retval;
127
128
129
130
131
132
133
	static int initialized=0;
	if (initialized)
		return ERROR_OK;
	
	initialized=1;
	
	atexit(exit_handler);
134
	
135
136
137
138
	if (target_init(cmd_ctx) != ERROR_OK)
		return ERROR_FAIL;
	LOG_DEBUG("target init complete");

139
140
141
142
143
144
145
146
	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
147
	 * continue startup regardless */
148
149
150
	if (jtag_init(cmd_ctx) == ERROR_OK)
	{
		LOG_DEBUG("jtag init complete");
ntfreak's avatar
ntfreak committed
151
		if (target_examine() == ERROR_OK)
152
153
154
155
		{
			LOG_DEBUG("jtag examine complete");
		}
	}
156
	
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
	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();
175
	tcl_init(); /* allows tcl to just connect without going thru telnet */
176

177
178
	target_register_event_callback(log_target_callback_event_handler, cmd_ctx);
	
179
180
181
	return ERROR_OK;
}

182
183
command_context_t *global_cmd_ctx;

184
command_context_t *setup_command_handler(void)
oharboe's avatar
oharboe committed
185
186
{
	command_context_t *cmd_ctx;
oharboe's avatar
oharboe committed
187
	
188
	global_cmd_ctx = cmd_ctx = command_init();
oharboe's avatar
oharboe committed
189
	
190
191
	register_command(cmd_ctx, NULL, "version", handle_version_command,
					 COMMAND_EXEC, "show OpenOCD version");
192
	
193
194
195
196
	/* register subsystem commands */
	server_register_commands(cmd_ctx);
	telnet_register_commands(cmd_ctx);
	gdb_register_commands(cmd_ctx);
197
	tcl_register_commands(cmd_ctx); /* tcl server commands */
198
199
200
201
202
203
204
205
206
	log_register_commands(cmd_ctx);
	jtag_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
207
208
209
	{
		exit(-1);
	}
210
	LOG_DEBUG("log init complete");
oharboe's avatar
oharboe committed
211

212
	LOG_OUTPUT( OPENOCD_VERSION "\n" );
213
	
214
215
216
	register_command(cmd_ctx, NULL, "init", handle_init_command,
					 COMMAND_ANY, "initializes target and servers - nop on subsequent invocations");

oharboe's avatar
oharboe committed
217
218
219
	return cmd_ctx;
}

220
221
222
/* 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
223
224
int openocd_main(int argc, char *argv[])
{
225
226
	int ret;

oharboe's avatar
oharboe committed
227
228
	/* initialize commandline interface */
	command_context_t *cmd_ctx;
229
230

	cmd_ctx = setup_command_handler();
231
232
	
	LOG_OUTPUT( "\n\nBUGS? Read http://svn.berlios.de/svnroot/repos/openocd/trunk/BUGS\n\n\n");
233

234
235
	print_version();
	
236
237
	command_context_mode(cmd_ctx, COMMAND_CONFIG);
	command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
238

239
	if (parse_cmdline_args(cmd_ctx, argc, argv) != ERROR_OK)
240
241
		return EXIT_FAILURE;
	
242
243
	ret = parse_config_file(cmd_ctx);
	if ( (ret != ERROR_OK) && (ret != ERROR_COMMAND_CLOSE_CONNECTION) )
244
245
		return EXIT_FAILURE;

246
247
248
249
250
	if (ret != ERROR_COMMAND_CLOSE_CONNECTION) 
	{
		command_context_mode(cmd_ctx, COMMAND_EXEC);
		if (command_run_line(cmd_ctx, "init")!=ERROR_OK)
			return EXIT_FAILURE;
251
	
252
253
254
		/* handle network connections */
		server_loop(cmd_ctx);
	}
255
256
257
258

	/* shut server down */
	server_quit();

259
260
	unregister_all_commands(cmd_ctx);
	
261
262
263
264
265
	/* free commandline interface */
	command_done(cmd_ctx);

	return EXIT_SUCCESS;
}