Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / blaze / ui_utils.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: ui_utils.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21/*
22 * Copyright (C) 1991, Sun Microsystems, Inc.
23 */
24#pragma ident "@(#)1.14 06/01/25 ui_utils.cc"
25
26
27#include <sys/types.h>
28#include <assert.h>
29#include <stdio.h>
30#include <unistd.h>
31
32#include <stdio.h>
33#include <thread.h>
34#include <stdlib.h>
35#include <string.h>
36#include <sys/exec.h>
37#include <sys/stat.h>
38#include <sys/time.h>
39#include <sys/resource.h>
40#include <sys/procfs.h>
41#include <ctype.h>
42#include <dlfcn.h>
43
44#include "ui.h"
45#include "types.h"
46#include "blaze_globals.h"
47#include "system.h"
48
49#include "ui_utils.h"
50#include "sim_cmd_struct.h"
51#include "blaze_globals.h"
52#include "ui_cmd_struct.h"
53#include "ui_cmds.h"
54#include "blz_runtime.h"
55#include "macrolib.h"
56#include "scsi_ctrl.h"
57#include "remote.h"
58#include "tracemod.h"
59
60wd_thread_t *pwd_locker = NULL;
61time_thread_t *ptm_locker = NULL;
62
63
64#ifdef __cplusplus
65extern "C" {
66#endif
67 static void * wd_thread_start (void *);
68 static void * time_thread_start (void *);
69#ifdef __cplusplus
70}
71#endif
72
73
74
75
76///////////////////////////////////////////////////
77//
78// Create Remote Interface
79//
80
81void *remote_lib_handle = NULL;
82RemoteExInterface g_remote_ex_intf;
83RemoteConfig g_remote_config;
84char remote_help_str[] = "remote [port=<port#>] [debug_on=1]";
85
86
87int remote_cmd_action(void * /* usrdata */, int argc, char **argv)
88{
89 // parse config arguments
90 for (int i=1; i<argc; i++)
91 {
92 // get param name
93 char *name_value = argv[i];
94 char *name = strtok ( name_value, " =" );
95
96 if (name == NULL)
97 {
98 ui->error("cannot read remote interface param name %s\n", name_value);
99 continue;
100 }
101
102 // get param value
103 int value = 0;
104 char *param = strtok ( NULL, "\0" );
105 if (param == NULL)
106 {
107 ui->error("cannot read remote interface param value %s\n", name_value);
108 continue;
109 }
110 else
111 {
112 value = (int)strtol(param, NULL, 0);
113 }
114
115
116 if (strcmp ( name, "port") == 0 )
117 {
118 g_remote_config.port = value;
119 }
120 else if (strcmp ( name, "max_connections") == 0 )
121 {
122 g_remote_config.max_connections = value;
123 }
124 else if (strcmp ( name, "debug_on") == 0 )
125 {
126 g_remote_config.debug_on = value;
127 }
128
129 }
130
131 // start remote interface
132 g_remote_ex_intf.create(&g_remote_config);
133
134 return 1;
135}
136
137//
138// initialize remote debugger interface
139//
140int init_remote_debugger_interface (char* fname, char* modname, void* lib_handle)
141{
142 if (remote_lib_handle != 0)
143 {
144 ui->error("Remote Interface was loaded already %s\n", modname );
145 return 0;
146 }
147
148 remote_lib_handle = lib_handle;
149
150 if ( remote_lib_handle == NULL )
151 {
152 ui->error("cannot obtain a handle for Remote Interface library %s\n", fname );
153 return 0;
154 }
155
156 // extract lib exported interface
157 GetRemoteIntfFn get_interface = (GetRemoteIntfFn)dlsym ( remote_lib_handle, "get_ex_remote_interface" );
158
159 if (get_interface == NULL)
160 {
161 ui->error("cannot find remote exported interface, wrong libriry\n");
162 exit (1);
163 }
164
165 // obtain remote interface
166 get_interface ( &g_remote_ex_intf);
167
168 UI_register_cmd_2("remote", remote_help_str, remote_cmd_action, NULL);
169
170 // set defaults config params
171 g_remote_config.port = INTF_PORT;
172 g_remote_config.max_connections = MAX_CONNECTIONS;
173 g_remote_config.port_step = MAX_PORT_STEP;
174 g_remote_config.debug_on = 0;
175
176 return 1;
177}
178
179// update stop status for the remote client if any extern
180int update_remote_ui()
181{
182 if (g_remote_ex_intf.update_status)
183 g_remote_ex_intf.update_status(SIGNAL_BREAKPOINT);
184 return 0;
185}
186
187
188///////////////////////////////////////////////////////
189///////////////////////////////////////////////////////
190
191/*
192 * This routine parses thru a string. It sets wp to point to the first
193 * word in that string and returns a pointer to the rest of the line.
194 * It puts a null character after the first word.
195 * It eats leading white space characters. If string doesn't contain
196 * any text, it sets wp and the return value to point to a null character.
197 */
198
199char* ui_parsew(char* cp, char** wp)
200{
201 /* Eat leading white space. */
202 while (isspace(*cp))
203 cp++;
204
205 if(wp)
206 *wp = cp;
207
208 /* No words in string so return. */
209 if (*cp == '\0')
210 return (cp);
211
212 /* skip over first word */
213 while (!isspace(*cp) && *cp != '\0')
214 cp++; /* skip over word */
215
216 /* Put null char after first word in string. */
217 if (*cp != '\0') {
218 *cp++ = '\0';
219 }
220
221 /* Eat white space between first word and rest of line. */
222 while (isspace(*cp))
223 cp++;
224
225 /* Strip off any white space at end of first word. */
226 if(wp)
227 ui_remove_trailing_whitespace(*wp);
228
229 /* Strip off any white space at end of line. */
230 ui_remove_trailing_whitespace(cp);
231
232 return (cp);
233}
234
235///////////////////////////////////////////////////////
236
237/* Strip off any white space or newlines at end of string. */
238
239void ui_remove_trailing_whitespace(char* str)
240{
241 char *cp;
242
243 /* Null string. */
244 if (*str == '\0') {
245 return;
246 }
247
248 for (cp = str + strlen(str) - 1; (cp >= str) && (*cp == '\n' || isspace(*cp)); cp--) {
249 *cp = '\0';
250 }
251}
252
253// This function extracts a string from the buffer
254// passed in. Returned is a freshly allocated buffer
255// for the new string, which is null terminated.
256//
257// It is the caller's responsibility to eventually
258// free the allocated string.
259
260char * extract_string(char * cmd_str)
261{
262 int len;
263 char * p = cmd_str;
264 char * bufp;
265 bool_t is_quoted = false;
266 int c;
267 char * bp;
268
269 while (isspace(*p)) p++;
270
271 len = strlen(p);
272
273 // be lazy, allocate all the space for the buffer
274 assert(bufp = (char*)malloc(len+1));
275
276 if (*p == '\"') {
277 is_quoted = true;
278 p++;
279 }
280
281 bp = bufp;
282 do {
283 c = p[0];
284 switch (c) {
285 case '\0':
286 if (is_quoted) {
287 ui->error("Missing closing quote at end of string: %s\n",cmd_str);
288 goto fail;
289 }
290 goto success;
291
292 case '\\':
293 c = p[1];
294 switch (c) {
295 case '\0':
296 ui->error("Illegal escape at end of string: %s\n",cmd_str);
297 goto fail;
298 case 'n': c = '\n'; break;
299 case 'r': c = '\r'; break;
300 case 't': c = '\t'; break;
301 case '"': c = '"'; break;
302 case '\\': c = '\\'; break;
303 default:
304 ui->error("Unknown escape in string: %s\n",cmd_str);
305 goto fail;
306 }
307 p++;
308 break;
309
310 case '"':
311 if (is_quoted) goto success;
312 ui->error("Quotes need to be escaped in the string: %s\n",cmd_str);
313 goto fail;
314
315 case ' ':
316 case '\t':
317 if (!is_quoted) goto success;
318 break;
319
320 default:
321 break;
322 }
323 *bp++ = c;
324 p++;
325 } while (true);
326
327success:
328 bp[0]='\0';
329 return bufp;
330
331
332fail:
333 free(bufp);
334 return (char *)0;
335}
336
337///////////////////////////////////////////////////////
338
339//
340// SL (09/07/2001)
341// Added new routine for BLAZE UI parsing
342//
343
344// returns ARGV pointer, sets *ARGC
345
346char **
347ui_argv_argc_parse (char *cmd, int *neval)
348{
349 int argc = 4; /* *neval; using neval is dumb, requires user init */
350 int nargc = 0;
351 char **pargv = (char**) calloc (argc, sizeof(char*));
352 char * cmdcopy = (char*) strdup(cmd);
353 char *s = cmdcopy;
354 char *ps;
355 int inquotes = 0; /* flag when we're inside a " quoted string */
356 int backslash = 0; /* yet another flag... */
357
358 if (pargv == NULL)
359 return NULL;
360
361 // remove leading spaces if any
362
363 while (isspace(*s)) {
364 if ((*s == '\0') || (*s == '\n')) {
365 *neval = 0;
366 return NULL;
367 }
368 ++s;
369 }
370
371
372 ps = s;
373 for (;;) {
374
375 inquotes = 0;
376 while (!isspace(*s) || inquotes) {
377 if (*s == '"')
378 inquotes = ! inquotes;
379 ++s;
380 if (*s == '\0')
381 goto EOLINE;
382
383#if 0 /* not yet debugged, and needs to be before the ++s */
384
385 if (*s == '"' && ! backslash) inquotes = ! inquotes;
386 if (backslash)
387 backslash = 0;
388 else
389 if (*s == '\\') backslash = 1;
390#endif
391 }
392
393 // copy parsed arg into argv
394 *s = '\0';
395 pargv[nargc++] = (char*) strdup (ps);
396 ++s;
397
398 // re-allocate argv if we have too many args
399 //
400 if (nargc >= argc) {
401 argc <<= 1;
402 pargv = (char**) realloc (pargv, sizeof(char*) * argc);
403 }
404
405 //
406 // skip (insignificant) white-spaces between words
407 //
408 while (isspace(*s)) {
409 ++s;
410 }
411 if ((*s == '\0') || (*s == '\n'))
412 goto DONE;
413 ps = s;
414 }
415
416EOLINE:
417 pargv[nargc++] = (char*) strdup (ps);
418DONE:
419 free(cmdcopy);
420
421 *neval = nargc;
422 return pargv;
423}
424
425
426void ui_argv_free(int argc, char **argv)
427{
428 int i;
429 for (i=0; i<argc; i++) {
430 free(argv[i]);
431 }
432 free(argv);
433} // ui_argv_free()
434
435///////////////////////////////////////////////////////
436
437bool_t redirect_stdout (int target_fd)
438{
439 int dup_fd = dup (fileno(stdout));
440
441 close( fileno(stdout) );
442 if (dup( target_fd ) <= -1) {
443 ui->perror("dup");
444 return FALSE;
445 }
446 close (target_fd);
447 store_stdout_fd (dup_fd);
448 return TRUE;
449}
450
451///////////////////////////////////////////////////////
452
453bool_t redirect_back ()
454{
455
456 int dup_fd = get_stdout_fd ();
457 if (dup_fd <= -1) {
458 ui->error("STDOUT has not been redirected\n");
459 return FALSE;
460 }
461 close( fileno(stdout) );
462 if (dup (dup_fd) <= -1) {
463 ui->perror("dup");
464 return FALSE;
465 }
466 close(dup_fd);
467 store_stdout_fd (-1);
468 return TRUE;
469}