Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / legion / src / simcore / dbgrif.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: dbgrif.c
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23
24/*
25 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
27 */
28
29#pragma ident "@(#)dbgrif.c 1.15 06/03/06 SMI"
30
31
32 /* FIXME: Currently this debugger interface is designed solely
33 * for supporting GDB. I have tried to make it as general
34 * as possible, but no doubt interface differences will remain
35 * for other debuggers.
36 * Ultimately, this interface will split into 2. A set of
37 * general interaction stubs will exist, and they
38 * will support loadable modules which inturn can be customised
39 * for each available debugger required.
40 */
41
42
43
44
45#include <sys/types.h>
46#include <sys/socket.h>
47/* #include <sys/conf.h> */
48#include <stropts.h>
49#include <signal.h>
50#include <netinet/in.h>
51#include <sys/un.h>
52#include <arpa/inet.h>
53#include <netdb.h>
54#include <stdio.h>
55#include <unistd.h>
56#include <fcntl.h>
57#include <string.h> /* for memset in FD_ZERO */
58#include <errno.h>
59#include <pthread.h>
60#include <stdlib.h>
61
62#include <assert.h>
63
64
65#include "basics.h"
66#include "hostcpu.h"
67#include "allocate.h"
68#include "strutil.h"
69#include "fatal.h"
70#include "createthr.h"
71#include "options.h"
72#include "simcore.h"
73#include "config.h"
74#include "regmap.h"
75#include "callback.h"
76
77
78#define MAX_PORT_STEP 10 /* DEFAULT_PORT to DEFAULT_PORT+9 */
79 /* allow upto 5 pending connections will never get that many */
80#define MAX_CONNECTIONS 5
81
82
83
84
85int port_offset_number; /* for more than one debugger */
86
87bool_t flag_remdeb_if = false;
88
89
90
91
92
93typedef enum DBGRSTATE {
94 DS_unattached, DS_stopped, DS_running
95#if 0
96 /*
97 * available for the sim to tell the debugger about a
98 * new symtab to load ...
99 * ... something else to do eventually
100 */
101 , DS_symtab_load
102#endif
103} dbgr_state_t;
104
105
106
107
108typedef struct DEBUGGER {
109 int socket;
110 dbgr_state_t state;
111
112 pthread_t pthread_id;
113
114 /* ID who we are attached to - if anything */
115
116 domain_t* domainp; /* so we can read memory etc. */
117 /* NOTE: have to go via CPU anyway if caches modeled*/
118 config_proc_t* config_procp; /* config proc */
119 void * pspecp; /* within that proc */
120
121
122 /* communication buffers */
123
124 uint8_t * send_buffer_p;
125 uint8_t * recv_buffer_p;
126 uint8_t * send_ptr;
127 uint8_t * recv_ptr;
128
129 pthread_mutex_t stop_lock;
130 pthread_cond_t stop_cv;
131} debugger_t;
132
133
134static debugger_t dbgr;
135
136
137
138typedef enum {
139 Receive_error = -1,
140 Dbgr_Command_Str = 0,
141 Sim_Command_Str_OK,
142 Dbgr_Attach,
143 Sim_Attach_OK,
144 Sim_Attach_Failed,
145 Dbgr_Read_Reg,
146 Sim_Reg_Value_Rtnd,
147 Dbgr_Write_Reg,
148 Sim_Reg_Written,
149 Sim_Reg_Write_Failed,
150 Dbgr_Set_Breakpoint,
151 Sim_Breakpoint_Set,
152 Dbgr_Clear_Breakpoint,
153 Sim_Breakpoint_Cleared,
154 Dbgr_Run,
155 Sim_Executing,
156 Dbgr_ReqStop,
157 Dbgr_Wait,
158 Sim_Stopped,
159 Sim_SimTab_Load,
160 Dbgr_Read_Mem,
161 Sim_Mem_Returned,
162 Sim_Mem_Read_Failed_No_Mem,
163 Dbgr_Write_Mem,
164 Sim_Mem_Write_OK,
165 Sim_Mem_Write_Failed_No_Mem,
166 Dbgr_Clear_Mem,
167 Sim_Mem_Clear_OK,
168 Sim_Mem_Clear_Failed_No_Mem,
169
170 Dbgr_Protocol_Count
171} protocol_t;
172
173
174
175
176#ifndef NDEBUG /* { */
177#define PD(s) { s, #s },
178struct {
179 int cmd;
180 char * name;
181} protodebug[]= {
182 PD(Dbgr_Command_Str)
183 PD(Sim_Command_Str_OK)
184 PD(Dbgr_Attach)
185 PD(Sim_Attach_OK)
186 PD(Sim_Attach_Failed)
187 PD(Dbgr_Read_Reg)
188 PD(Sim_Reg_Value_Rtnd)
189 PD(Dbgr_Write_Reg)
190 PD(Sim_Reg_Written)
191 PD(Sim_Reg_Write_Failed)
192 PD(Dbgr_Set_Breakpoint)
193 PD(Sim_Breakpoint_Set)
194 PD(Dbgr_Clear_Breakpoint)
195 PD(Sim_Breakpoint_Cleared)
196 PD(Dbgr_Run)
197 PD(Sim_Executing)
198 PD(Dbgr_ReqStop)
199 PD(Dbgr_Wait)
200 PD(Sim_Stopped)
201 PD(Sim_SimTab_Load)
202 PD(Dbgr_Read_Mem)
203 PD(Sim_Mem_Returned)
204 PD(Sim_Mem_Read_Failed_No_Mem)
205 PD(Dbgr_Write_Mem)
206 PD(Sim_Mem_Write_OK)
207 PD(Sim_Mem_Write_Failed_No_Mem)
208 PD(Dbgr_Clear_Mem)
209 PD(Sim_Mem_Clear_OK)
210 PD(Sim_Mem_Clear_Failed_No_Mem)
211 { -1, NULL },
212};
213
214#endif /* } */
215
216
217
218
219#define MAX_BUF_SIZE 8192
220static int do_recv(int skt, uint8_t * ptr, int expect);
221static protocol_t recv_buffer(debugger_t * dbgp, int * nrecvdp);
222static int send_buffer(debugger_t * dbgrp, protocol_t cmd, int num);
223
224static uint16_t get_uint16(uint8_t * bp);
225static void put_uint16(uint8_t * bp, uint16_t val);
226static uint32_t get_uint32(uint8_t * bp);
227static void put_uint32(uint8_t * bp, uint32_t val);
228static uint64_t get_uint64(uint8_t * bp);
229static void put_uint64(uint8_t * bp, uint64_t val);
230
231
232 /*
233 *--------------------------------------------
234 * Register re-map name table
235 * Get from the GDB numbering to the simulator
236 * register value ...
237 * ... for the moment this is for SPARC only
238 * but will eventually fix this ...
239 *--------------------------------------------
240 */
241
242
243static char * gdb_reg_name[] = {
244#define SPARC_REG_G0 0
245 "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", /*values 0-31*/
246 "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
247 "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
248 "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
249
250#define SPARC_REG_F0 32
251 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", /* 32-63 */
252 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
253 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
254 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
255
256#define SPARC_REG_F32 64
257 "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46", /* 64-79 */
258 "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
259
260#define SPARC_REG_PC 80
261 "pc", /* 80 */
262#define SPARC_REG_NPC 81
263 "npc", /* 81 */
264 "ccr", /* 82 */
265 "fsr", /* 83 */
266 "fprs", /* 84 */
267 "y", /* 85 */
268 "asi", /* 86 */
269 "ver", /* 87 */
270 "tick", /* 88 */
271 "pil", /* 89 */
272 "pstate", /* 90 */
273 "tstate", /* 91 */
274 "tba", /* 92 */
275 "tl", /* 93 */
276 "tt", /* 94 */
277 "tpc", /* 95 */
278 "tnpc", /* 96 */
279 "wstate", /* 97 */
280 "cwp", /* 98 */
281 "cansave", /* 99 */
282 "canrestore", /* 100 */
283 "cleanwin", /* 101 */
284 "otherwin", /* 102 */
285 "asr16", /* 103 */
286 "asr17", /* 104 */
287 "asr18", /* 105 */
288 "asr19", /* 106 */
289 "asr20", /* 107 */
290 "asr21", /* 108 */
291 "asr22", /* 109 */
292 "asr23", /* 110 */
293 "asr24", /* 111 */
294 "asr25", /* 112 */
295 "asr26", /* 113 */
296 "asr27", /* 114 */
297 "asr28", /* 115 */
298 "asr29", /* 116 */
299 "asr30", /* 117 */
300 "asr31", /* 118 */
301 "icc", /* 119 */
302 "xcc", /* 120 */
303 "fcc0", /* 121 */
304 "fcc1", /* 122 */
305 "fcc2", /* 123 */
306 "fcc3", /* 124 */
307
308 (char*)0
309};
310
311
312
313 /* Mapping for the GDB register numbering to the CPU models numbering */
314int * gdb_reg_map;
315
316
317
318
319
320static void if_exec_start(debugger_t * dbgrp);
321static void if_exec_wait(debugger_t * dbgrp);
322static uint64_t symtab_base;
323static char * symtab_fname;
324
325static void if_write_register(debugger_t * dbgrp);
326static void if_read_register(debugger_t * dbgrp);
327static void if_clear_breakpoint(debugger_t * dbgrp);
328static void if_set_breakpoint(debugger_t * dbgrp);
329static void if_read_memory(debugger_t * dbgrp);
330static void if_write_memory(debugger_t * dbgrp);
331static void if_clear_memory(debugger_t * dbgrp);
332
333
334#ifndef NDEBUG
335#define DBGRD(s) do { s } while (0)
336#else
337#define DBGRD(s) do { } while (0)
338#endif
339
340
341
342
343 /*
344 * Gah this builds a map from the GDB register numbers to
345 * those of the sparc processor being simulated ..
346 * .. based on the map exported for the given
347 * processor type. This should be done a better way,
348 * but this works for now : FIXME
349 */
350
351void init_gdb_reg_map(reg_map_t * reg_mapp)
352{
353 int count, idx;
354
355 /* for each GDB name, find and map the number the
356 * cpu core model expects to see
357 */
358
359 for (count=0; gdb_reg_name[count]!=(char*)0; count++) ;
360
361 gdb_reg_map = Xcalloc(count, int);
362
363 for (idx=0; idx<count; idx++) {
364 int j;
365 char * matchp;
366
367 matchp = gdb_reg_name[idx];
368
369 /* brute force search for name */
370 for (j=0; reg_mapp[j].namep != (char*)0; j++) {
371 if (streq(reg_mapp[j].namep, matchp)) break;
372 }
373 /* shouldnt have gdb names we dont know ! */
374 assert(reg_mapp[j].namep != (char*)0);
375
376 gdb_reg_map[idx] = reg_mapp[j].idx;
377 }
378}
379
380
381
382
383
384static void dbgrif_stop_cb(void *arg)
385{
386 debugger_t *dbgrp = (debugger_t *)arg;
387
388 DBGRD(printf("dbgrif_stop_cb()\n"););
389
390 dbgrp->state = DS_stopped;
391
392 pthread_mutex_lock(&dbgrp->stop_lock);
393 pthread_cond_broadcast(&dbgrp->stop_cv);
394 pthread_mutex_unlock(&dbgrp->stop_lock);
395}
396
397 /*
398 * This new thread is invoked once contact with a debugger is
399 * been established. This thread exits once that debugger
400 * connection vanishes.
401 *
402 * Any one debugger can stop the simulation, all are required
403 * to be active to continue simulation.
404 */
405
406void * dbgrif(void * argp)
407{
408 debugger_t * dbgrp = (debugger_t *)argp;
409 int res, length;
410
411 /*
412 * We have a potential contact, however we must
413 * setup the structures used for communication
414 */
415
416 dbgrp->recv_buffer_p = (uint8_t*)valloc(MAX_BUF_SIZE);
417 if (dbgrp->recv_buffer_p == (uint8_t*)0) fatal("allocating recv buffer");
418 dbgrp->send_buffer_p = (uint8_t*)valloc(MAX_BUF_SIZE);
419 if (dbgrp->send_buffer_p == (uint8_t*)0) fatal("allocating send buffer");
420
421 dbgrp->recv_ptr = dbgrp->recv_buffer_p + 3;
422 dbgrp->send_ptr = dbgrp->send_buffer_p + 3;
423
424 /*
425 * Veryify the protocols match ...
426 * .... by exchanging the max protocol value
427 *
428 * Really should use some version checksum ... FIXME
429 */
430
431 res = recv_buffer( dbgrp, &length );
432 send_buffer( dbgrp, Dbgr_Protocol_Count, 0 ); /* send regardless - will make other side fail too */
433 if (res!=Dbgr_Protocol_Count || length!=0) {
434 printf("Connection failed : received %d %d - debugger protocols do not match\n", res, length);
435 goto suicide;
436 }
437
438 /*
439 * OK we've established contact with a legitimate debugger
440 * run the command interface until we get the
441 * command to termnate this session
442 */
443
444
445 while (1) {
446 int recv_len;
447 protocol_t cmd = (protocol_t)recv_buffer(dbgrp, &recv_len);
448
449 if (cmd == Receive_error) {
450 perror("failed in communication");
451 continue;
452 }
453
454DBGRD( for (res = 0; protodebug[res].cmd!=-1 && protodebug[res].cmd!=cmd; res++) ;
455 printf("command [%d] : %s\n",(int)cmd,
456 protodebug[res].cmd != -1 ? protodebug[res].name : "illegal value"); );
457
458 switch ( cmd ) {
459 case Dbgr_Command_Str:
460 dbgrp->recv_ptr[recv_len] = '\0';
461DBGRD( printf("recvd: %s\n", dbgrp->recv_ptr); );
462#if 0
463 exec_cmds ( (char*)dbgrp->recv_ptr, cmd_ptr );
464#endif
465 send_buffer(dbgrp, Sim_Command_Str_OK, 0);
466 break;
467
468 case Dbgr_Attach:
469 /* FIXME: for now the simulator must be in virgin state */
470 assert( dbgrp->state == DS_unattached);
471 /* Make sure simulator is stopped and ready for attach */
472 /* FIXME: for now this is not compatible with the auto start mode */
473 assert( !options.flag_auto_start );
474#if 0
475 stop_cmd((char*)0, dbgrp->cmd_ptr); /* FIXME: prob. wrong too */
476 wait_for_simulation_stop(dbgrp->cmd_ptr);
477 if (cpu[0] == (void*)0) {
478 printf( "Looks like you forgot to init the architecture (file blazerc) before\n"
479 "you did the sttach - try again\n");
480 send_buffer(dbgrp->socket, Sim_Attach_Failed, 0);
481 dbgrp->exec_state = Exec_unattached; /* sanity */
482 } else {
483 send_buffer(dbgrp->socket, Sim_Attach_OK, 0);
484 dbgrp->cpup = cpu[0];
485 dbgrp->exec_state = Exec_stopped;
486 }
487#endif
488
489
490
491 /* Kludge an attach just to get something
492 * running .... FIXME
493 */
494
495 { system_t * sysp;
496 sysp = LIST_ENTRY( target_config.systems, 0 );
497 dbgrp->domainp = LIST_ENTRY(sysp->domains, 0 );
498 }
499 dbgrp->config_procp = LIST_ENTRY(dbgrp->domainp->procs, 0);
500 dbgrp->pspecp = dbgrp->config_procp->proc_typep->dbgr_attach(dbgrp->domainp, dbgrp->config_procp, "0:0");
501
502 ASSERT(dbgrp->config_procp->proc_typep->proc_magic == CPU_MAGIC);
503
504 init_gdb_reg_map(dbgrp->config_procp->proc_typep->reg_mapp); /* FIXME */
505
506 if (dbgrp->pspecp == NULL) {
507 send_buffer(dbgrp, Sim_Attach_Failed, 0);
508 break;
509 }
510
511 dbgrp->state = DS_stopped;
512
513 send_buffer(dbgrp, Sim_Attach_OK, 0);
514 break;
515
516 case Dbgr_Read_Reg:
517 if_read_register(dbgrp);
518 break;
519
520 case Dbgr_Write_Reg:
521 if_write_register(dbgrp);
522 break;
523
524 case Dbgr_Set_Breakpoint:
525 if_set_breakpoint(dbgrp);
526 break;
527
528 case Dbgr_Clear_Breakpoint:
529 if_clear_breakpoint(dbgrp);
530 break;
531
532 case Dbgr_Run:
533 if_exec_start(dbgrp);
534 break;
535
536 case Dbgr_ReqStop:
537 /* Cannot get here ... */
538 fatal("Dbgr_ReqStop unexpectedly received");
539
540 case Dbgr_Wait:
541 if_exec_wait(dbgrp);
542 break;
543
544 case Dbgr_Read_Mem:
545 if_read_memory(dbgrp);
546 break;
547
548 case Dbgr_Write_Mem:
549 if_write_memory(dbgrp);
550 break;
551
552 case Dbgr_Clear_Mem:
553 if_clear_memory(dbgrp);
554 break;
555
556
557 default:
558#ifndef NDEBUG /* { */
559 for (res = 0; protodebug[res].cmd != -1 && protodebug[res].cmd != cmd; res++) ;
560 warning("unexpected command [%d] : %s\n",(int)cmd,
561 protodebug[res].cmd != -1 ? protodebug[res].name : "illegal value");
562#else /* } { */
563 warning("unexpected command %d\n",(int)cmd);
564#endif /* } */
565 goto suicide;
566 }
567 }
568
569
570
571suicide:;
572 close(dbgrp->socket);
573
574 Xfree( dbgrp->recv_buffer_p );
575 Xfree( dbgrp->send_buffer_p );
576 Xfree( dbgrp );
577
578 /*
579 * Clean up this debuggers session ...
580 * ... remove any assigned breakpoints etc ...
581 */
582
583 /* FIXME */
584
585 /*
586 * Clean up debugger session count ?
587 */
588
589 pthread_exit((void*)0);
590
591 return (void*)0; /* compiler joy */
592}
593
594
595
596
597
598
599#if 0 /* { */
600
601 /*
602 * If a symtab message is pending build the response packet
603 * and send it back to the debugger
604 *
605 * The buffer format is quite simple:
606 * uint16 offset_to_filename { from buffer start }
607 * uint16 number_of_sections
608 * Then for each section:
609 * uint16 offset_to_section_name { from buffer start }
610 * uint64 section_load_vaddr
611 * Then the string table:
612 * .. until the end of the buffer.
613 * (each string is null terminated)
614 *
615 */
616
617static void if_send_symtab_info(debugger_t * dbgrp)
618{
619 int stridx, secidx, len;
620 sym_file_t * sfp;
621 int i;
622#define SEC_SIZE (2+8)
623
624 /* grab the file info */
625 sfp = (sym_file_t *)dbgrp->sym_filep;
626
627 /* First size the initial sections block */
628 secidx = 4;
629 stridx = secidx + SEC_SIZE*(sfp->num_pos);
630
631 /* copy in the map name */
632 /* and the number of sections */
633 put_uint16( dbgrp->send_ptr, stridx );
634 put_uint16( dbgrp->send_ptr+2, sfp->num_pos );
635
636 len = strlen( sfp->mapnamep );
637 strcpy( (char*)dbgrp->send_ptr + stridx, sfp->mapnamep );
638 stridx += len+1;
639
640 for (i=0; i<sfp->num_pos; i++) {
641 put_uint16( dbgrp->send_ptr + secidx, stridx );
642 put_uint64( dbgrp->send_ptr + secidx + 2, sfp->pos[i].address );
643
644 len = strlen( sfp->pos[i].namep );
645 strcpy( (char*)dbgrp->send_ptr + stridx, sfp->pos[i].namep );
646 stridx += len + 1;
647
648 secidx += SEC_SIZE;
649 }
650
651
652DBGRD( printf("\tif_exec_wait: returning Sim_SimTab_Load (%s)...\n", sfp->mapnamep););
653
654 send_buffer(dbgrp->socket, Sim_SimTab_Load, stridx);
655
656 symfile_cleanup(&dbgrp->sym_filep);
657}
658
659
660#endif /* } */
661
662
663
664
665
666
667
668 /*
669 * Start execution again ...
670 * ... this is non-blocking (use if_exec_wait to wait until stopped)
671 */
672
673static void if_exec_start(debugger_t * dbgrp)
674{
675DBGRD( printf("run!\n"););
676
677 dbgrp->state = DS_running;
678
679 simcore_start();
680
681 send_buffer(dbgrp, Sim_Executing, 0);
682}
683
684
685
686
687
688 /*
689 * Wait for execution to stop, and give the appropriate response
690 * to the debugger ...
691 * ... if execution stopepd to load a symbol table signal that back
692 * ... after which the debugger should initiate a new run request.
693 */
694
695static void if_exec_wait(debugger_t * dbgrp)
696{
697DBGRD( printf("wait until stopped...\n"););
698
699 pthread_mutex_lock(&dbgrp->stop_lock);
700 while (dbgrp->state != DS_stopped) {
701 pthread_cond_wait(&dbgrp->stop_cv, &dbgrp->stop_lock);
702 }
703 pthread_mutex_unlock(&dbgrp->stop_lock);
704
705DBGRD( printf("\tif_exec_wait: returning Sim_Stopped ...\n"););
706 send_buffer(dbgrp, Sim_Stopped, 0);
707}
708
709
710
711
712
713
714static void if_read_register(debugger_t * dbgrp)
715{
716 int regno;
717 uint64_t val;
718
719 regno = (dbgrp->recv_ptr[0]<<8) | dbgrp->recv_ptr[1];
720
721 if (!dbgrp->config_procp->proc_typep->regread(dbgrp->pspecp, gdb_reg_map[regno], &val)) {
722 warning("Register %d [%s] fetch failed", regno, gdb_reg_name[regno]);
723 send_buffer( dbgrp, Sim_Reg_Value_Rtnd, 0);
724 return;
725 }
726
727DBGRD( printf("read register %d : %s = 0x%llx\n",regno,gdb_reg_name[regno],val););
728
729 put_uint64(dbgrp->send_ptr, val);
730
731 send_buffer( dbgrp, Sim_Reg_Value_Rtnd, 8);
732}
733
734
735
736
737static void if_write_register(debugger_t * dbgrp)
738{
739 int regno;
740 uint64_t val;
741
742 regno = (dbgrp->recv_ptr[0]<<8) | dbgrp->recv_ptr[1];
743
744 val = get_uint64(dbgrp->recv_ptr + 2);
745
746DBGRD( printf("write register %d : %s = 0x%llx\n",regno,gdb_reg_name[regno],val););
747
748 if (!dbgrp->config_procp->proc_typep->regwrite(dbgrp->pspecp, gdb_reg_map[regno], val)) {
749 warning("Register %d [%s] write failed", regno, gdb_reg_name[regno]);
750 }
751
752 send_buffer( dbgrp, Sim_Reg_Written, 0);
753}
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768static void if_set_breakpoint(debugger_t * dbgrp)
769{
770 uint64_t val;
771
772 val = get_uint64(dbgrp->recv_ptr);
773
774DBGRD( printf("set breakpoint @ 0x%llx\n",val););
775
776 dbgrp->config_procp->proc_typep->dbgr_set_break(dbgrp->pspecp, val);
777
778 send_buffer( dbgrp, Sim_Breakpoint_Set, 0);
779}
780
781
782
783
784
785static void if_clear_breakpoint(debugger_t * dbgrp)
786{
787 uint64_t val;
788
789 val = get_uint64(dbgrp->recv_ptr);
790
791DBGRD( printf("clear breakpoint @ 0x%llx\n",val););
792
793 dbgrp->config_procp->proc_typep->dbgr_clear_break(dbgrp->pspecp, val);
794
795 send_buffer( dbgrp, Sim_Breakpoint_Cleared, 0);
796}
797
798
799
800
801
802
803
804
805
806
807static void if_read_memory(debugger_t * dbgrp)
808{
809 tvaddr_t vaddr;
810 uint32_t len, res;
811 uint64_t slen;
812 int offset;
813 int num;
814 bool_t is_physical_addr;
815 proc_type_t * ptp;
816
817 ptp = dbgrp->config_procp->proc_typep;
818
819 vaddr = get_uint64(dbgrp->recv_ptr);
820 len = get_uint32(dbgrp->recv_ptr + 8);
821 res = get_uint32(dbgrp->recv_ptr + 12);
822
823 is_physical_addr = (res == 1);
824
825DBGRD( printf("read %s memory @ 0x%llx [ 0x%x bytes]\n",
826 is_physical_addr ? "physical" : "virtual",
827 vaddr, len););
828
829 len = ptp->dbgr_mem_read(dbgrp->pspecp, vaddr, !is_physical_addr,
830 dbgrp->send_ptr, len);
831
832 if (len == 0) {
833DBGRD( fprintf(stdout, "Failed reading memory"); );
834 send_buffer( dbgrp, Sim_Mem_Read_Failed_No_Mem, 0);
835 return;
836 }
837
838 send_buffer( dbgrp, Sim_Mem_Returned, len);
839}
840
841
842
843
844
845
846
847static void if_write_memory(debugger_t * dbgrp)
848{
849 tvaddr_t vaddr;
850 uint32_t len, res;
851 int offset;
852 int num;
853 uint64_t slen;
854 bool_t is_physical_addr;
855 proc_type_t * ptp;
856
857 ptp = dbgrp->config_procp->proc_typep;
858
859 vaddr = get_uint64(dbgrp->recv_ptr);
860 len = get_uint32(dbgrp->recv_ptr + 8);
861 res = get_uint32(dbgrp->recv_ptr + 12);
862
863 is_physical_addr = (res == 1);
864
865DBGRD( printf("write %s memory @ 0x%llx [ 0x%x bytes]\n",
866 is_physical_addr ? "physical" : "virtual",
867 vaddr, len););
868
869 len = ptp->dbgr_mem_write(dbgrp->pspecp, vaddr, !is_physical_addr,
870 dbgrp->recv_ptr+16, len);
871
872 if (len == 0) {
873DBGRD( fprintf(stdout, "Failed reading memory"); );
874 send_buffer( dbgrp, Sim_Mem_Write_Failed_No_Mem, 0);
875 return;
876 }
877
878 send_buffer( dbgrp, Sim_Mem_Write_OK, 0);
879}
880
881
882
883
884
885
886static void if_clear_memory(debugger_t * dbgrp)
887{
888 tvaddr_t vaddr;
889 uint32_t len, res;
890 int offset;
891 int num;
892 uint64_t slen;
893 bool_t is_physical_addr;
894 proc_type_t * ptp;
895
896 ptp = dbgrp->config_procp->proc_typep;
897
898 vaddr = get_uint64(dbgrp->recv_ptr);
899 len = get_uint32(dbgrp->recv_ptr + 8);
900 res = get_uint32(dbgrp->recv_ptr + 12);
901
902 is_physical_addr = (res == 1);
903
904DBGRD( printf("clear %s memory @ 0x%llx [ 0x%x bytes]\n",
905 is_physical_addr ? "physical" : "virtual",
906 vaddr, len););
907
908 len = ptp->dbgr_mem_clear(dbgrp->pspecp, vaddr, !is_physical_addr, len);
909
910 if (len == 0) {
911DBGRD( fprintf(stdout, "Failed clearing memory"); );
912 send_buffer( dbgrp, Sim_Mem_Clear_Failed_No_Mem, 0);
913 return;
914 }
915
916 send_buffer( dbgrp, Sim_Mem_Clear_OK, 0);
917}
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932 /*
933 * We enter here with the main program thread
934 * to wait for user interface connections.
935 * we never leave this function.
936 *
937 * The simulator closes ungracefully using exit()
938 * to kill its threads ...
939 */
940
941void interface_wait()
942{
943 static fd_set comm_channels;
944 int tcp_attach_socket, res;
945 struct sockaddr_in tcp_server;
946 struct sockaddr_in from;
947 int fromlen;
948 int skt;
949 int fh, length, on=1;
950 int max_channel;
951 sigset_t sigs;
952 struct hostent * hp;
953 char * froms;
954 int retry_cnt=0;
955
956 sigfillset(&sigs);
957 pthread_sigmask(SIG_BLOCK, &sigs, NULL);
958
959 skt = socket(AF_INET, SOCK_STREAM, 0);
960 if (skt < 0) fatal("opening stream socket");
961
962 /* enable the reuse of this socket if this process dies */
963 if (setsockopt(skt,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on))<0)
964 fatal("turning on REUSEADDR");
965
966 /* bind it */
967retry:;
968 tcp_server.sin_family = AF_INET;
969 tcp_server.sin_addr.s_addr = INADDR_ANY;
970 tcp_server.sin_port = options.accept_port;
971 if (bind(skt, (struct sockaddr *)&tcp_server, sizeof(tcp_server)) < 0) {
972 switch (errno) {
973 case EAGAIN:
974 goto retry;
975
976 case EADDRINUSE:
977 printf("\nPort %d already in use ", options.accept_port);
978
979 /* user specific a port and it's not available, fatal */
980 if (options.specific_port) {
981 printf("\n");
982 fatal("Port %d already in use, try another",
983 options.accept_port);
984 }
985
986 /* check if we should retry another port */
987 if (retry_cnt >= options.port_retry_max) {
988 printf("\n");
989 fatal("Max no of retries (%d) reached, use -P -or -p ",
990 options.port_retry_max);
991 }
992
993 /* try the next port */
994 options.accept_port++;
995 retry_cnt++;
996 printf("- trying %d", options.accept_port);
997 goto retry;
998 default:
999 fatal("binding tcp stream socket");
1000 }
1001 }
1002
1003 /* this not necessary */
1004 length = sizeof(tcp_server);
1005 if (getsockname(skt, (struct sockaddr *) &tcp_server, &length)==-1)
1006 fatal("getting socket name");
1007 PRINTF(("\nWaiting for connection on port # %d\n",
1008 ntohs(tcp_server.sin_port)));
1009
1010 listen(skt, MAX_CONNECTIONS);
1011
1012 tcp_attach_socket = skt;
1013 max_channel = tcp_attach_socket;
1014 FD_ZERO(&comm_channels);
1015 FD_SET(tcp_attach_socket, &comm_channels);
1016
1017 /*
1018 * Wait for a control connection
1019 */
1020
1021 do {
1022 debugger_t * dbgrp;
1023
1024 res = select(max_channel+1, &comm_channels, (fd_set*)0, (fd_set*)0, (struct timeval*)0 /* stall */);
1025 if (res<0) fatal("select");
1026
1027 /*
1028 * accept the connection
1029 */
1030
1031 fromlen = sizeof(from);
1032 fh = accept(tcp_attach_socket,(struct sockaddr *)&from, (int*)&fromlen);
1033
1034
1035 hp = gethostbyaddr((char *)&from.sin_addr, 4, AF_INET);
1036 if (hp == (struct hostent *)0) {
1037 froms = inet_ntoa(from.sin_addr);
1038 fprintf(stderr,"cant resolve hostname for %s\n", froms);;
1039 } else {
1040 froms = hp->h_name;
1041 }
1042 fprintf(stderr,"connection from %s : port %d\n", froms, from.sin_port);
1043
1044
1045 /*
1046 * Create the thread to handle this debugger
1047 * connection. It cleans up after itself
1048 * if anything goes wrong.
1049 */
1050
1051 dbgrp = Xcalloc(1, debugger_t);
1052
1053 dbgrp->socket = fh;
1054 dbgrp->state = DS_unattached;
1055
1056 pthread_mutex_init(&dbgrp->stop_lock, NULL);
1057 pthread_cond_init(&dbgrp->stop_cv, NULL);
1058
1059 callback_register(CB_Breakpoint, dbgrif_stop_cb, (void *)dbgrp);
1060
1061 create_thread(dbgrif, (void*)dbgrp, &dbgrp->pthread_id);
1062
1063 } while (1);
1064}
1065
1066
1067
1068
1069
1070#if 0 /* { */
1071
1072 /*
1073 * These functions are called, not from the debugger IF thread,
1074 * but from the simulation execution thread. It is a callback
1075 * notification to the debugger - during simulation to load
1076 * a new symbol table file.
1077 */
1078
1079void remdeb_symtab_add_callback(sym_file_t * sym_filep)
1080{
1081 if (flag_remdeb_if) {
1082DBGRD( printf("load symtab %s\n",sym_filep->namep););
1083
1084 dbgr.exec_state = Exec_symtab_load;
1085 assert( dbgr.sym_filep == (sym_file_t *)0);
1086 dbgr.sym_filep = sym_filep;
1087
1088 stop_cmd((char*)0, dbgr.cmd_ptr);
1089 }
1090}
1091
1092
1093#endif /* } */
1094
1095
1096
1097
1098
1099
1100
1101#if 0
1102 /* Delete a block of symbols (object file)
1103 */
1104
1105void remdeb_symtab_delete_callback(uint64_t symtab_id)
1106{
1107 if (flag_remdeb_if) {
1108DBGRD( printf("delete symtab 0x%llx\n",symtab_id););
1109 }
1110}
1111 /* Change the offset on a block of symbols ...
1112 */
1113
1114void remdeb_symtab_offset_callback(uint64_t symtab_id, uint64_t offset, char * sectp)
1115{
1116 if (flag_remdeb_if) {
1117DBGRD( printf("change symtab 0x%llx : section [%s] offset 0x%llx\n",symtab_id, sectp ? sectp : "(NULL)", offset););
1118 }
1119}
1120#endif
1121
1122
1123
1124
1125
1126
1127
1128 /*
1129 * basic IO routines to help
1130 */
1131
1132
1133static int send_buffer(debugger_t * dbgrp, protocol_t cmd, int num)
1134{
1135 int res;
1136
1137 dbgrp->send_buffer_p[0] = num >> 8;
1138 dbgrp->send_buffer_p[1] = num & 0xff;
1139 dbgrp->send_buffer_p[2] = (unsigned char) cmd;
1140
1141 res = write(dbgrp->socket, dbgrp->send_buffer_p, 3+num);
1142
1143 return (res != 3+num) ? -1 : 0;
1144}
1145
1146
1147
1148
1149static protocol_t recv_buffer(debugger_t * dbgrp, int * nrecvdp)
1150{
1151 int len, num;
1152 len = do_recv(dbgrp->socket, dbgrp->recv_buffer_p, 3);
1153 if (len != 3) return Receive_error;
1154
1155 len = dbgrp->recv_buffer_p[1] + (dbgrp->recv_buffer_p[0]<<8); /* big endian network order */
1156
1157 num = do_recv(dbgrp->socket, dbgrp->recv_ptr, len);
1158
1159 if (num != len) return Receive_error;
1160
1161 if (nrecvdp != (void*)0) *nrecvdp = num;
1162
1163 return (protocol_t)dbgrp->recv_buffer_p[2];
1164}
1165
1166
1167
1168static int do_recv(int skt, unsigned char * ptr, int expect)
1169{
1170 int idx, num;
1171
1172 for (idx=0; idx<expect; idx+=num) {
1173 num = read(skt, ptr + idx, expect-idx);
1174 if (num<0) return -1;
1175 }
1176
1177 return idx;
1178}
1179
1180
1181
1182
1183static uint16_t get_uint16(uint8_t * bp)
1184{
1185 uint16_t val;
1186
1187 val = (uint16_t)bp[0];
1188 val = (val<<8) | (uint16_t)bp[1];
1189
1190 return val;
1191}
1192
1193static uint32_t get_uint32(uint8_t * bp)
1194{
1195 uint32_t val;
1196
1197 val = (uint32_t)bp[0];
1198 val = (val<<8) | (uint32_t)bp[1];
1199 val = (val<<8) | (uint32_t)bp[2];
1200 val = (val<<8) | (uint32_t)bp[3];
1201
1202 return val;
1203}
1204
1205static uint64_t get_uint64(uint8_t * bp)
1206{
1207 uint64_t val;
1208
1209 val = (uint64_t)bp[0];
1210 val = (val<<8) | (uint64_t)bp[1];
1211 val = (val<<8) | (uint64_t)bp[2];
1212 val = (val<<8) | (uint64_t)bp[3];
1213 val = (val<<8) | (uint64_t)bp[4];
1214 val = (val<<8) | (uint64_t)bp[5];
1215 val = (val<<8) | (uint64_t)bp[6];
1216 val = (val<<8) | (uint64_t)bp[7];
1217
1218 return val;
1219}
1220
1221
1222static void put_uint16(uint8_t * bp, uint16_t val)
1223{
1224 bp[0] = (uint8_t)(val >> 8);
1225 bp[1] = (uint8_t)(val);
1226}
1227
1228static void put_uint32(uint8_t * bp, uint32_t val)
1229{
1230 bp[0] = (uint8_t)(val >> 24);
1231 bp[1] = (uint8_t)(val >> 16);
1232 bp[2] = (uint8_t)(val >> 8);
1233 bp[3] = (uint8_t)(val);
1234}
1235
1236
1237static void put_uint64(uint8_t * bp, uint64_t val)
1238{
1239 bp[0] = (uint8_t)(val >> 56);
1240 bp[1] = (uint8_t)(val >> 48);
1241 bp[2] = (uint8_t)(val >> 40);
1242 bp[3] = (uint8_t)(val >> 32);
1243 bp[4] = (uint8_t)(val >> 24);
1244 bp[5] = (uint8_t)(val >> 16);
1245 bp[6] = (uint8_t)(val >> 8);
1246 bp[7] = (uint8_t)(val);
1247}
1248