OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [remote-udi.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
2
   Copyright 1990, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
   Written by Daniel Mann.  Contributed by AMD.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
/* This is like remote.c but uses the Universal Debug Interface (UDI) to
24
   talk to the target hardware (or simulator).  UDI is a TCP/IP based
25
   protocol; for hardware that doesn't run TCP, an interface adapter
26
   daemon talks UDI on one side, and talks to the hardware (typically
27
   over a serial port) on the other side.
28
 
29
   - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
30
   - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
31
   file to gdb 3.95.  I was unable to get this working on sun3os4
32
   with termio, only with sgtty.
33
   - Daniel Mann at AMD took the 3.95 adaptions above and replaced
34
   MiniMON interface with UDI-p interface.        */
35
 
36
#include "defs.h"
37
#include "frame.h"
38
#include "inferior.h"
39
#include "value.h"
40
#include <ctype.h>
41
#include <fcntl.h>
42
#include <errno.h>
43
#include "gdb_string.h"
44
#include "terminal.h"
45
#include "target.h"
46
#include "29k-share/udi/udiproc.h"
47
#include "gdbcmd.h"
48
#include "bfd.h"
49
#include "gdbcore.h"            /* For download function */
50
#include "regcache.h"
51
 
52
/* access the register store directly, without going through
53
   the normal handler functions. This avoids an extra data copy.  */
54
 
55
extern int stop_soon_quietly;   /* for wait_for_inferior */
56
extern struct value *call_function_by_hand ();
57
static void udi_resume (ptid_t ptid, int step, enum target_signal sig);
58
static void udi_fetch_registers (int regno);
59
static void udi_load (char *args, int from_tty);
60
static void fetch_register (int regno);
61
static void udi_store_registers (int regno);
62
static int store_register (int regno);
63
static int regnum_to_srnum (int regno);
64
static void udi_close (int quitting);
65
static CPUSpace udi_memory_space (CORE_ADDR addr);
66
static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr,
67
                                      int len);
68
static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr,
69
                                     int len);
70
static void download (char *load_arg_string, int from_tty);
71
char CoffFileName[100] = "";
72
 
73
#define FREEZE_MODE     (read_register(CPS_REGNUM) & 0x400)
74
#define USE_SHADOW_PC   ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
75
 
76
static int timeout = 5;
77
extern struct target_ops udi_ops;       /* Forward declaration */
78
 
79
/* Special register enumeration.
80
 */
81
 
82
/******************************************************************* UDI DATA*/
83
#define MAXDATA         2*1024  /* max UDI[read/write] byte size */
84
/* Descriptor for I/O to remote machine.  Initialize it to -1 so that
85
   udi_open knows that we don't have a file open when the program
86
   starts.  */
87
 
88
UDISessionId udi_session_id = -1;
89
static char *udi_config_id;
90
 
91
CPUOffset IMemStart = 0;
92
CPUSizeT IMemSize = 0;
93
CPUOffset DMemStart = 0;
94
CPUSizeT DMemSize = 0;
95
CPUOffset RMemStart = 0;
96
CPUSizeT RMemSize = 0;
97
UDIUInt32 CPUPRL;
98
UDIUInt32 CoProcPRL;
99
 
100
UDIMemoryRange address_ranges[2];       /* Text and data */
101
UDIResource entry =
102
{0, 0};                           /* Entry point */
103
CPUSizeT stack_sizes[2];        /* Regular and memory stacks */
104
 
105
#define SBUF_MAX        1024    /* maximum size of string handling buffer */
106
char sbuf[SBUF_MAX];
107
 
108
typedef struct bkpt_entry_str
109
  {
110
    UDIResource Addr;
111
    UDIUInt32 PassCount;
112
    UDIBreakType Type;
113
    unsigned int BreakId;
114
  }
115
bkpt_entry_t;
116
#define         BKPT_TABLE_SIZE 40
117
static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
118
extern char dfe_errmsg[];       /* error string */
119
 
120
/* malloc'd name of the program on the remote system.  */
121
static char *prog_name = NULL;
122
 
123
/* This is called not only when we first attach, but also when the
124
   user types "run" after having attached.  */
125
 
126
static void
127
udi_create_inferior (char *execfile, char *args, char **env)
128
{
129
  char *args1;
130
 
131
  if (execfile)
132
    {
133
      if (prog_name != NULL)
134
        xfree (prog_name);
135
      prog_name = savestring (execfile, strlen (execfile));
136
    }
137
  else if (entry.Offset)
138
    execfile = "";
139
  else
140
    error ("No image loaded into target.");
141
 
142
  if (udi_session_id < 0)
143
    {
144
      /* If the TIP is not open, open it.  */
145
      if (UDIConnect (udi_config_id, &udi_session_id))
146
        error ("UDIConnect() failed: %s\n", dfe_errmsg);
147
      /* We will need to download the program.  */
148
      entry.Offset = 0;
149
    }
150
 
151
  inferior_ptid = pid_to_ptid (40000);
152
 
153
  if (!entry.Offset)
154
    download (execfile, 0);
155
 
156
  args1 = alloca (strlen (execfile) + strlen (args) + 2);
157
 
158
  if (execfile[0] == '\0')
159
 
160
    /* It is empty.  We need to quote it somehow, or else the target
161
       will think there is no argument being passed here.  According
162
       to the UDI spec it is quoted "according to TIP OS rules" which
163
       I guess means quoting it like the Unix shell should work
164
       (sounds pretty bogus to me...).  In fact it doesn't work (with
165
       isstip anyway), but passing in two quotes as the argument seems
166
       like a reasonable enough behavior anyway (I guess).  */
167
 
168
    strcpy (args1, "''");
169
  else
170
    strcpy (args1, execfile);
171
  strcat (args1, " ");
172
  strcat (args1, args);
173
 
174
  UDIInitializeProcess (address_ranges,         /* ProcessMemory[] */
175
                        (UDIInt) 2,     /* NumberOfRanges */
176
                        entry,  /* EntryPoint */
177
                        stack_sizes,    /* *StackSizes */
178
                        (UDIInt) 2,     /* NumberOfStacks */
179
                        args1); /* ArgString */
180
 
181
  init_wait_for_inferior ();
182
  clear_proceed_status ();
183
  proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
184
}
185
 
186
static void
187
udi_mourn (void)
188
{
189
#if 0
190
  /* Requiring "target udi" each time you run is a major pain.  I suspect
191
     this was just blindy copied from remote.c, in which "target" and
192
     "run" are combined.  Having a udi target without an inferior seems
193
     to work between "target udi" and "run", so why not now?  */
194
  pop_target ();                /* Pop back to no-child state */
195
#endif
196
  /* But if we're going to want to run it again, we better remove the
197
     breakpoints...  */
198
  remove_breakpoints ();
199
  generic_mourn_inferior ();
200
}
201
 
202
/******************************************************************** UDI_OPEN
203
** Open a connection to remote TIP.
204
   NAME is the socket domain used for communication with the TIP,
205
   then a space and the socket name or TIP-host name.
206
   '<udi_udi_config_id>' for example.
207
 */
208
 
209
/* XXX - need cleanups for udiconnect for various failures!!! */
210
 
211
static void
212
udi_open (char *name, int from_tty)
213
{
214
  unsigned int prl;
215
  char *p;
216
  int cnt;
217
  UDIMemoryRange KnownMemory[10];
218
  UDIUInt32 ChipVersions[10];
219
  UDIInt NumberOfRanges = 10;
220
  UDIInt NumberOfChips = 10;
221
  UDIPId PId;
222
  UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
223
 
224
  target_preopen (from_tty);
225
 
226
  entry.Offset = 0;
227
 
228
  for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
229
    bkpt_table[cnt].Type = 0;
230
 
231
  if (udi_config_id)
232
    xfree (udi_config_id);
233
 
234
  if (!name)
235
    error ("Usage: target udi config_id, where config_id appears in udi_soc file");
236
 
237
  udi_config_id = xstrdup (strtok (name, " \t"));
238
 
239
  if (UDIConnect (udi_config_id, &udi_session_id))
240
    /* FIXME: Should set udi_session_id to -1 here.  */
241
    error ("UDIConnect() failed: %s\n", dfe_errmsg);
242
 
243
  push_target (&udi_ops);
244
 
245
  /*
246
     ** Initialize target configuration structure (global)
247
   */
248
  if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
249
                          ChipVersions, &NumberOfChips))
250
    error ("UDIGetTargetConfig() failed");
251
  if (NumberOfChips > 2)
252
    fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n");
253
  for (cnt = 0; cnt < NumberOfRanges; cnt++)
254
    {
255
      switch (KnownMemory[cnt].Space)
256
        {
257
        default:
258
          fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
259
          break;
260
        case UDI29KCP_S:
261
          break;
262
        case UDI29KIROMSpace:
263
          RMemStart = KnownMemory[cnt].Offset;
264
          RMemSize = KnownMemory[cnt].Size;
265
          break;
266
        case UDI29KIRAMSpace:
267
          IMemStart = KnownMemory[cnt].Offset;
268
          IMemSize = KnownMemory[cnt].Size;
269
          break;
270
        case UDI29KDRAMSpace:
271
          DMemStart = KnownMemory[cnt].Offset;
272
          DMemSize = KnownMemory[cnt].Size;
273
          break;
274
        }
275
    }
276
 
277
  a29k_get_processor_type ();
278
 
279
  if (UDICreateProcess (&PId))
280
    fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n");
281
 
282
  /* Print out some stuff, letting the user now what's going on */
283
  if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
284
                       &TIPIPCId, sbuf))
285
    error ("UDICapabilities() failed");
286
  if (from_tty)
287
    {
288
      printf_filtered ("Connected via UDI socket,\n\
289
 DFE-IPC version %x.%x.%x  TIP-IPC version %x.%x.%x  TIP version %x.%x.%x\n %s\n",
290
               (DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf,
291
               (TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf,
292
               (TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf,
293
                       sbuf);
294
    }
295
}
296
 
297
/******************************************************************* UDI_CLOSE
298
   Close the open connection to the TIP process.
299
   Use this when you want to detach and do something else
300
   with your gdb.  */
301
static void
302
udi_close (                     /*FIXME: how is quitting used */
303
            int quitting)
304
{
305
  if (udi_session_id < 0)
306
    return;
307
 
308
  /* We should never get here if there isn't something valid in
309
     udi_session_id.  */
310
 
311
  if (UDIDisconnect (udi_session_id, UDITerminateSession))
312
    {
313
      if (quitting)
314
        warning ("UDIDisconnect() failed in udi_close");
315
      else
316
        error ("UDIDisconnect() failed in udi_close");
317
    }
318
 
319
  /* Do not try to close udi_session_id again, later in the program.  */
320
  udi_session_id = -1;
321
  inferior_ptid = null_ptid;
322
 
323
  printf_filtered ("  Ending remote debugging\n");
324
}
325
 
326
/**************************************************************** UDI_ATACH */
327
/* Attach to a program that is already loaded and running
328
 * Upon exiting the process's execution is stopped.
329
 */
330
static void
331
udi_attach (char *args, int from_tty)
332
{
333
  UDIResource From;
334
  UDIInt32 PC_adds;
335
  UDICount Count = 1;
336
  UDISizeT Size = 4;
337
  UDICount CountDone;
338
  UDIBool HostEndian = 0;
339
  UDIError err;
340
 
341
  if (args == NULL)
342
    error_no_arg ("program to attach");
343
 
344
  if (udi_session_id < 0)
345
    error ("UDI connection not opened yet, use the 'target udi' command.\n");
346
 
347
  if (from_tty)
348
    printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
349
 
350
  UDIStop ();
351
  From.Space = UDI29KSpecialRegs;
352
  From.Offset = 11;
353
  if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian))
354
    error ("UDIRead failed in udi_attach");
355
  printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
356
}
357
/************************************************************* UDI_DETACH */
358
/* Terminate the open connection to the TIP process.
359
   Use this when you want to detach and do something else
360
   with your gdb.  Leave remote process running (with no breakpoints set). */
361
static void
362
udi_detach (char *args, int from_tty)
363
{
364
 
365
  remove_breakpoints ();        /* Just in case there were any left in */
366
 
367
  if (UDIDisconnect (udi_session_id, UDIContinueSession))
368
    error ("UDIDisconnect() failed in udi_detach");
369
 
370
  /* Don't try to UDIDisconnect it again in udi_close, which is called from
371
     pop_target.  */
372
  udi_session_id = -1;
373
  inferior_ptid = null_ptid;
374
 
375
  pop_target ();
376
 
377
  if (from_tty)
378
    printf_unfiltered ("Detaching from TIP\n");
379
}
380
 
381
 
382
/****************************************************************** UDI_RESUME
383
** Tell the remote machine to resume.  */
384
 
385
static void
386
udi_resume (ptid_t ptid, int step, enum target_signal sig)
387
{
388
  UDIError tip_error;
389
  UDIUInt32 Steps = 1;
390
  UDIStepType StepType = UDIStepNatural;
391
  UDIRange Range;
392
 
393
  if (step)                     /* step 1 instruction */
394
    {
395
      tip_error = UDIStep (Steps, StepType, Range);
396
      if (!tip_error)
397
        return;
398
 
399
      fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
400
      error ("failed in udi_resume");
401
    }
402
 
403
  if (UDIExecute ())
404
    error ("UDIExecute() failed in udi_resume");
405
}
406
 
407
/******************************************************************** UDI_WAIT
408
** Wait until the remote machine stops, then return,
409
   storing status in STATUS just as `wait' would.  */
410
 
411
static ptid_t
412
udi_wait (int ptid_t, struct target_waitstatus *status)
413
{
414
  UDIInt32 MaxTime;
415
  UDIPId PId;
416
  UDIInt32 StopReason;
417
  UDISizeT CountDone;
418
  int old_timeout = timeout;
419
  int old_immediate_quit = immediate_quit;
420
  int i;
421
 
422
  status->kind = TARGET_WAITKIND_EXITED;
423
  status->value.integer = 0;
424
 
425
/* wait for message to arrive. It should be:
426
   If the target stops executing, udi_wait() should return.
427
 */
428
  timeout = 0;                   /* Wait indefinetly for a message */
429
  immediate_quit = 1;           /* Helps ability to QUIT */
430
 
431
  while (1)
432
    {
433
      i = 0;
434
      MaxTime = UDIWaitForever;
435
      UDIWait (MaxTime, &PId, &StopReason);
436
      QUIT;                     /* Let user quit if they want */
437
 
438
      switch (StopReason & UDIGrossState)
439
        {
440
        case UDIStdoutReady:
441
          if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone))
442
            /* This is said to happen if the program tries to output
443
               a whole bunch of output (more than SBUF_MAX, I would
444
               guess).  It doesn't seem to happen with the simulator.  */
445
            warning ("UDIGetStdout() failed in udi_wait");
446
          fwrite (sbuf, 1, CountDone, stdout);
447
          gdb_flush (gdb_stdout);
448
          continue;
449
 
450
        case UDIStderrReady:
451
          UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone);
452
          fwrite (sbuf, 1, CountDone, stderr);
453
          gdb_flush (gdb_stderr);
454
          continue;
455
 
456
        case UDIStdinNeeded:
457
          {
458
            int ch;
459
            i = 0;
460
            do
461
              {
462
                ch = getchar ();
463
                if (ch == EOF)
464
                  break;
465
                sbuf[i++] = ch;
466
              }
467
            while (i < SBUF_MAX && ch != '\n');
468
            UDIPutStdin (sbuf, (UDISizeT) i, &CountDone);
469
            continue;
470
          }
471
 
472
        case UDIRunning:
473
          /* In spite of the fact that we told UDIWait to wait forever, it will
474
             return spuriously sometimes.  */
475
        case UDIStdinModeX:
476
          continue;
477
        default:
478
          break;
479
        }
480
      break;
481
    }
482
 
483
  switch (StopReason & UDIGrossState)
484
    {
485
    case UDITrapped:
486
      printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24);
487
 
488
      switch ((StopReason >> 8) & 0xff)
489
        {
490
        case 0:          /* Illegal opcode */
491
          printf_unfiltered ("  (break point)\n");
492
          status->kind = TARGET_WAITKIND_STOPPED;
493
          status->value.sig = TARGET_SIGNAL_TRAP;
494
          break;
495
        case 1:         /* Unaligned Access */
496
          status->kind = TARGET_WAITKIND_STOPPED;
497
          status->value.sig = TARGET_SIGNAL_BUS;
498
          break;
499
        case 3:
500
        case 4:
501
          status->kind = TARGET_WAITKIND_STOPPED;
502
          status->value.sig = TARGET_SIGNAL_FPE;
503
          break;
504
        case 5:         /* Protection Violation */
505
          status->kind = TARGET_WAITKIND_STOPPED;
506
          /* Why not SEGV?  What is a Protection Violation?  */
507
          status->value.sig = TARGET_SIGNAL_ILL;
508
          break;
509
        case 6:
510
        case 7:
511
        case 8:         /* User Instruction Mapping Miss */
512
        case 9:         /* User Data Mapping Miss */
513
        case 10:                /* Supervisor Instruction Mapping Miss */
514
        case 11:                /* Supervisor Data Mapping Miss */
515
          status->kind = TARGET_WAITKIND_STOPPED;
516
          status->value.sig = TARGET_SIGNAL_SEGV;
517
          break;
518
        case 12:
519
        case 13:
520
          status->kind = TARGET_WAITKIND_STOPPED;
521
          status->value.sig = TARGET_SIGNAL_ILL;
522
          break;
523
        case 14:                /* Timer */
524
          status->kind = TARGET_WAITKIND_STOPPED;
525
          status->value.sig = TARGET_SIGNAL_ALRM;
526
          break;
527
        case 15:                /* Trace */
528
          status->kind = TARGET_WAITKIND_STOPPED;
529
          status->value.sig = TARGET_SIGNAL_TRAP;
530
          break;
531
        case 16:                /* INTR0 */
532
        case 17:                /* INTR1 */
533
        case 18:                /* INTR2 */
534
        case 19:                /* INTR3/Internal */
535
        case 20:                /* TRAP0 */
536
        case 21:                /* TRAP1 */
537
          status->kind = TARGET_WAITKIND_STOPPED;
538
          status->value.sig = TARGET_SIGNAL_INT;
539
          break;
540
        case 22:                /* Floating-Point Exception */
541
          status->kind = TARGET_WAITKIND_STOPPED;
542
          /* Why not FPE?  */
543
          status->value.sig = TARGET_SIGNAL_ILL;
544
          break;
545
        case 77:                /* assert 77 */
546
          status->kind = TARGET_WAITKIND_STOPPED;
547
          status->value.sig = TARGET_SIGNAL_TRAP;
548
          break;
549
        default:
550
          status->kind = TARGET_WAITKIND_EXITED;
551
          status->value.integer = 0;
552
        }
553
      break;
554
    case UDINotExecuting:
555
      status->kind = TARGET_WAITKIND_STOPPED;
556
      status->value.sig = TARGET_SIGNAL_TERM;
557
      break;
558
    case UDIStopped:
559
      status->kind = TARGET_WAITKIND_STOPPED;
560
      status->value.sig = TARGET_SIGNAL_TSTP;
561
      break;
562
    case UDIWarned:
563
      status->kind = TARGET_WAITKIND_STOPPED;
564
      status->value.sig = TARGET_SIGNAL_URG;
565
      break;
566
    case UDIStepped:
567
    case UDIBreak:
568
      status->kind = TARGET_WAITKIND_STOPPED;
569
      status->value.sig = TARGET_SIGNAL_TRAP;
570
      break;
571
    case UDIWaiting:
572
      status->kind = TARGET_WAITKIND_STOPPED;
573
      status->value.sig = TARGET_SIGNAL_STOP;
574
      break;
575
    case UDIHalted:
576
      status->kind = TARGET_WAITKIND_STOPPED;
577
      status->value.sig = TARGET_SIGNAL_KILL;
578
      break;
579
    case UDIExited:
580
    default:
581
      status->kind = TARGET_WAITKIND_EXITED;
582
      status->value.integer = 0;
583
    }
584
 
585
  timeout = old_timeout;        /* Restore original timeout value */
586
  immediate_quit = old_immediate_quit;
587
  return inferior_ptid;
588
}
589
 
590
#if 0
591
/* Handy for debugging */
592
udi_pc (void)
593
{
594
  UDIResource From;
595
  UDIUInt32 *To;
596
  UDICount Count;
597
  UDISizeT Size = 4;
598
  UDICount CountDone;
599
  UDIBool HostEndian = 0;
600
  UDIError err;
601
  int pc[2];
602
  unsigned long myregs[256];
603
  int i;
604
 
605
  From.Space = UDI29KPC;
606
  From.Offset = 0;
607
  To = (UDIUInt32 *) pc;
608
  Count = 2;
609
 
610
  err = UDIRead (From, To, Count, Size, &CountDone, HostEndian);
611
 
612
  printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
613
                     err, CountDone, pc[0], pc[1]);
614
 
615
  udi_fetch_registers (-1);
616
 
617
  printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) &registers[4 * PC_REGNUM],
618
                     *(int *) &registers[4 * NPC_REGNUM]);
619
 
620
  /* Now, read all the registers globally */
621
 
622
  From.Space = UDI29KGlobalRegs;
623
  From.Offset = 0;
624
  err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian);
625
 
626
  printf ("err = %d, CountDone = %d\n", err, CountDone);
627
 
628
  printf ("\n");
629
 
630
  for (i = 0; i < 256; i += 2)
631
    printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
632
            myregs[i + 1], myregs[i + 1]);
633
  printf ("\n");
634
 
635
  return pc[0];
636
}
637
#endif
638
 
639
/********************************************************** UDI_FETCH_REGISTERS
640
 * Read a remote register 'regno'.
641
 * If regno==-1 then read all the registers.
642
 */
643
static void
644
udi_fetch_registers (int regno)
645
{
646
  UDIResource From;
647
  UDIUInt32 *To;
648
  UDICount Count;
649
  UDISizeT Size = 4;
650
  UDICount CountDone;
651
  UDIBool HostEndian = 0;
652
  UDIError err;
653
  int i;
654
 
655
  if (regno >= 0)
656
    {
657
      fetch_register (regno);
658
      return;
659
    }
660
 
661
/* Gr1/rsp */
662
 
663
  From.Space = UDI29KGlobalRegs;
664
  From.Offset = 1;
665
  To = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
666
  Count = 1;
667
  if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
668
    error ("UDIRead() failed in udi_fetch_registers");
669
 
670
  register_valid[GR1_REGNUM] = 1;
671
 
672
#if defined(GR64_REGNUM)        /* Read gr64-127 */
673
 
674
/* Global Registers gr64-gr95 */
675
 
676
  From.Space = UDI29KGlobalRegs;
677
  From.Offset = 64;
678
  To = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
679
  Count = 32;
680
  if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
681
    error ("UDIRead() failed in udi_fetch_registers");
682
 
683
  for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
684
    register_valid[i] = 1;
685
 
686
#endif /*  GR64_REGNUM */
687
 
688
/* Global Registers gr96-gr127 */
689
 
690
  From.Space = UDI29KGlobalRegs;
691
  From.Offset = 96;
692
  To = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
693
  Count = 32;
694
  if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
695
    error ("UDIRead() failed in udi_fetch_registers");
696
 
697
  for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
698
    register_valid[i] = 1;
699
 
700
/* Local Registers */
701
 
702
  From.Space = UDI29KLocalRegs;
703
  From.Offset = 0;
704
  To = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
705
  Count = 128;
706
  if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
707
    error ("UDIRead() failed in udi_fetch_registers");
708
 
709
  for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
710
    register_valid[i] = 1;
711
 
712
/* Protected Special Registers */
713
 
714
  From.Space = UDI29KSpecialRegs;
715
  From.Offset = 0;
716
  To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
717
  Count = 15;
718
  if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
719
    error ("UDIRead() failed in udi_fetch_registers");
720
 
721
  for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++)
722
    register_valid[i] = 1;
723
 
724
  if (USE_SHADOW_PC)
725
    {                           /* Let regno_to_srnum() handle the register number */
726
      fetch_register (NPC_REGNUM);
727
      fetch_register (PC_REGNUM);
728
      fetch_register (PC2_REGNUM);
729
 
730
/* Unprotected Special Registers sr128-sr135 */
731
 
732
      From.Space = UDI29KSpecialRegs;
733
      From.Offset = 128;
734
      To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
735
      Count = 135 - 128 + 1;
736
      if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
737
        error ("UDIRead() failed in udi_fetch_registers");
738
 
739
      for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++)
740
        register_valid[i] = 1;
741
    }
742
 
743
  if (remote_debug)
744
    {
745
      fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n");
746
      fprintf_unfiltered (gdb_stdlog,
747
                          "Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
748
                          read_register (NPC_REGNUM),
749
                          read_register (PC_REGNUM),
750
                          read_register (PC2_REGNUM));
751
    }
752
 
753
  /* There doesn't seem to be any way to get these.  */
754
  {
755
    int val = -1;
756
    supply_register (FPE_REGNUM, (char *) &val);
757
    supply_register (INTE_REGNUM, (char *) &val);
758
    supply_register (FPS_REGNUM, (char *) &val);
759
    supply_register (EXO_REGNUM, (char *) &val);
760
  }
761
}
762
 
763
 
764
/********************************************************* UDI_STORE_REGISTERS
765
** Store register regno into the target.
766
 * If regno==-1 then store all the registers.
767
 */
768
 
769
static void
770
udi_store_registers (int regno)
771
{
772
  UDIUInt32 *From;
773
  UDIResource To;
774
  UDICount Count;
775
  UDISizeT Size = 4;
776
  UDICount CountDone;
777
  UDIBool HostEndian = 0;
778
 
779
  if (regno >= 0)
780
    {
781
      store_register (regno);
782
      return;
783
    }
784
 
785
  if (remote_debug)
786
    {
787
      fprintf_unfiltered (gdb_stdlog, "Storing all registers\n");
788
      fprintf_unfiltered (gdb_stdlog,
789
                          "PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
790
                          read_register (NPC_REGNUM),
791
                          read_register (PC_REGNUM),
792
                          read_register (PC2_REGNUM));
793
    }
794
 
795
/* Gr1/rsp */
796
 
797
  From = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
798
  To.Space = UDI29KGlobalRegs;
799
  To.Offset = 1;
800
  Count = 1;
801
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
802
    error ("UDIWrite() failed in udi_store_regisetrs");
803
 
804
#if defined(GR64_REGNUM)
805
 
806
/* Global registers gr64-gr95 */
807
 
808
  From = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
809
  To.Space = UDI29KGlobalRegs;
810
  To.Offset = 64;
811
  Count = 32;
812
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
813
    error ("UDIWrite() failed in udi_store_regisetrs");
814
 
815
#endif /* GR64_REGNUM */
816
 
817
/* Global registers gr96-gr127 */
818
 
819
  From = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
820
  To.Space = UDI29KGlobalRegs;
821
  To.Offset = 96;
822
  Count = 32;
823
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
824
    error ("UDIWrite() failed in udi_store_regisetrs");
825
 
826
/* Local Registers */
827
 
828
  From = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
829
  To.Space = UDI29KLocalRegs;
830
  To.Offset = 0;
831
  Count = 128;
832
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
833
    error ("UDIWrite() failed in udi_store_regisetrs");
834
 
835
 
836
  /* Protected Special Registers *//* VAB through TMR */
837
 
838
  From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
839
  To.Space = UDI29KSpecialRegs;
840
  To.Offset = 0;
841
  Count = 10;
842
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
843
    error ("UDIWrite() failed in udi_store_regisetrs");
844
 
845
/* PC0, PC1, PC2 possibly as shadow registers */
846
 
847
  From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)];
848
  To.Space = UDI29KSpecialRegs;
849
  Count = 3;
850
  if (USE_SHADOW_PC)
851
    To.Offset = 20;             /* SPC0 */
852
  else
853
    To.Offset = 10;             /* PC0 */
854
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
855
    error ("UDIWrite() failed in udi_store_regisetrs");
856
 
857
/* PC1 via UDI29KPC */
858
 
859
  From = (UDIUInt32 *) & registers[4 * PC_REGNUM];
860
  To.Space = UDI29KPC;
861
  To.Offset = 0;         /* PC1 */
862
  Count = 1;
863
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
864
    error ("UDIWrite() failed in udi_store_regisetrs");
865
 
866
  /* LRU and MMU */
867
 
868
  From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)];
869
  To.Space = UDI29KSpecialRegs;
870
  To.Offset = 13;
871
  Count = 2;
872
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
873
    error ("UDIWrite() failed in udi_store_regisetrs");
874
 
875
/* Unprotected Special Registers */
876
 
877
  From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
878
  To.Space = UDI29KSpecialRegs;
879
  To.Offset = 128;
880
  Count = 135 - 128 + 1;
881
  if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
882
    error ("UDIWrite() failed in udi_store_regisetrs");
883
 
884
  registers_changed ();
885
}
886
 
887
/****************************************************** UDI_PREPARE_TO_STORE */
888
/* Get ready to modify the registers array.  On machines which store
889
   individual registers, this doesn't need to do anything.  On machines
890
   which store all the registers in one fell swoop, this makes sure
891
   that registers contains all the registers from the program being
892
   debugged.  */
893
 
894
static void
895
udi_prepare_to_store (void)
896
{
897
  /* Do nothing, since we can store individual regs */
898
}
899
 
900
/********************************************************** TRANSLATE_ADDR */
901
static CORE_ADDR
902
translate_addr (CORE_ADDR addr)
903
{
904
#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
905
  /* Check for a virtual address in the kernel */
906
  /* Assume physical address of ublock is in  paddr_u register */
907
  /* FIXME: doesn't work for user virtual addresses */
908
  if (addr >= UVADDR)
909
    {
910
      /* PADDR_U register holds the physical address of the ublock */
911
      CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
912
      return (i + addr - (CORE_ADDR) UVADDR);
913
    }
914
  else
915
    {
916
      return (addr);
917
    }
918
#else
919
  return (addr);
920
#endif
921
}
922
/************************************************* UDI_XFER_INFERIOR_MEMORY */
923
/* FIXME!  Merge these two.  */
924
static int
925
udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
926
                          struct mem_attrib *attrib ATTRIBUTE_UNUSED,
927
                          struct target_ops *target ATTRIBUTE_UNUSED)
928
{
929
 
930
  memaddr = translate_addr (memaddr);
931
 
932
  if (write)
933
    return udi_write_inferior_memory (memaddr, myaddr, len);
934
  else
935
    return udi_read_inferior_memory (memaddr, myaddr, len);
936
}
937
 
938
/********************************************************** UDI_FILES_INFO */
939
static void
940
udi_files_info (struct target_ops *target)
941
{
942
  printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id);
943
  if (prog_name != NULL)
944
    printf_unfiltered ("and running program %s", prog_name);
945
  printf_unfiltered (".\n");
946
}
947
 
948
/**************************************************** UDI_INSERT_BREAKPOINT */
949
static int
950
udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
951
{
952
  int cnt;
953
  UDIError err;
954
 
955
  for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
956
    if (bkpt_table[cnt].Type == 0)       /* Find first free slot */
957
      break;
958
 
959
  if (cnt >= BKPT_TABLE_SIZE)
960
    error ("Too many breakpoints set");
961
 
962
  bkpt_table[cnt].Addr.Offset = addr;
963
  bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
964
  bkpt_table[cnt].PassCount = 1;
965
  bkpt_table[cnt].Type = UDIBreakFlagExecute;
966
 
967
  err = UDISetBreakpoint (bkpt_table[cnt].Addr,
968
                          bkpt_table[cnt].PassCount,
969
                          bkpt_table[cnt].Type,
970
                          &bkpt_table[cnt].BreakId);
971
 
972
  if (err == 0)
973
    return 0;                    /* Success */
974
 
975
  bkpt_table[cnt].Type = 0;
976
  error ("UDISetBreakpoint returned error code %d\n", err);
977
}
978
 
979
/**************************************************** UDI_REMOVE_BREAKPOINT */
980
static int
981
udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
982
{
983
  int cnt;
984
  UDIError err;
985
 
986
  for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
987
    if (bkpt_table[cnt].Addr.Offset == addr)    /* Find matching breakpoint */
988
      break;
989
 
990
  if (cnt >= BKPT_TABLE_SIZE)
991
    error ("Can't find breakpoint in table");
992
 
993
  bkpt_table[cnt].Type = 0;
994
 
995
  err = UDIClearBreakpoint (bkpt_table[cnt].BreakId);
996
  if (err == 0)
997
    return 0;                    /* Success */
998
 
999
  error ("UDIClearBreakpoint returned error code %d\n", err);
1000
}
1001
 
1002
static void
1003
udi_kill (void)
1004
{
1005
 
1006
#if 0
1007
/*
1008
   UDIStop does not really work as advertised.  It causes the TIP to close it's
1009
   connection, which usually results in GDB dying with a SIGPIPE.  For now, we
1010
   just invoke udi_close, which seems to get things right.
1011
 */
1012
  UDIStop ();
1013
 
1014
  udi_session_id = -1;
1015
  inferior_ptid = null_ptid;
1016
 
1017
  if (from_tty)
1018
    printf_unfiltered ("Target has been stopped.");
1019
#endif /* 0 */
1020
#if 0
1021
  udi_close (0);
1022
  pop_target ();
1023
#endif /* 0 */
1024
 
1025
  /* Keep the target around, e.g. so "run" can do the right thing when
1026
     we are already debugging something.  */
1027
 
1028
  if (UDIDisconnect (udi_session_id, UDITerminateSession))
1029
    {
1030
      warning ("UDIDisconnect() failed");
1031
    }
1032
 
1033
  /* Do not try to close udi_session_id again, later in the program.  */
1034
  udi_session_id = -1;
1035
  inferior_ptid = null_ptid;
1036
}
1037
 
1038
/*
1039
   Load a program into the target.  Args are: `program {options}'.  The options
1040
   are used to control loading of the program, and are NOT passed onto the
1041
   loaded code as arguments.  (You need to use the `run' command to do that.)
1042
 
1043
   The options are:
1044
   -ms %d       Set mem stack size to %d
1045
   -rs %d       Set regular stack size to %d
1046
   -i   send init info (default)
1047
   -noi don't send init info
1048
   -[tT]        Load Text section
1049
   -[dD]        Load Data section
1050
   -[bB]        Load BSS section
1051
   -[lL]        Load Lit section
1052
 */
1053
 
1054
static void
1055
download (char *load_arg_string, int from_tty)
1056
{
1057
#define DEFAULT_MEM_STACK_SIZE          0x6000
1058
#define DEFAULT_REG_STACK_SIZE          0x2000
1059
 
1060
  char *token;
1061
  char *filename;
1062
  asection *section;
1063
  bfd *pbfd;
1064
  UDIError err;
1065
  int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1066
 
1067
  address_ranges[0].Space = UDI29KIRAMSpace;
1068
  address_ranges[0].Offset = 0xffffffff;
1069
  address_ranges[0].Size = 0;
1070
 
1071
  address_ranges[1].Space = UDI29KDRAMSpace;
1072
  address_ranges[1].Offset = 0xffffffff;
1073
  address_ranges[1].Size = 0;
1074
 
1075
  stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1076
  stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1077
 
1078
  dont_repeat ();
1079
 
1080
  filename = strtok (load_arg_string, " \t");
1081
  if (!filename)
1082
    error ("Must specify at least a file name with the load command");
1083
 
1084
  filename = tilde_expand (filename);
1085
  make_cleanup (xfree, filename);
1086
 
1087
  while (token = strtok (NULL, " \t"))
1088
    {
1089
      if (token[0] == '-')
1090
        {
1091
          token++;
1092
 
1093
          if (STREQ (token, "ms"))
1094
            stack_sizes[1] = atol (strtok (NULL, " \t"));
1095
          else if (STREQ (token, "rs"))
1096
            stack_sizes[0] = atol (strtok (NULL, " \t"));
1097
          else
1098
            {
1099
              load_text = load_data = load_bss = load_lit = 0;
1100
 
1101
              while (*token)
1102
                {
1103
                  switch (*token++)
1104
                    {
1105
                    case 't':
1106
                    case 'T':
1107
                      load_text = 1;
1108
                      break;
1109
                    case 'd':
1110
                    case 'D':
1111
                      load_data = 1;
1112
                      break;
1113
                    case 'b':
1114
                    case 'B':
1115
                      load_bss = 1;
1116
                      break;
1117
                    case 'l':
1118
                    case 'L':
1119
                      load_lit = 1;
1120
                      break;
1121
                    default:
1122
                      error ("Unknown UDI load option -%s", token - 1);
1123
                    }
1124
                }
1125
            }
1126
        }
1127
    }
1128
 
1129
  pbfd = bfd_openr (filename, gnutarget);
1130
 
1131
  if (!pbfd)
1132
    /* FIXME: should be using bfd_errmsg, not assuming it was
1133
       bfd_error_system_call.  */
1134
    perror_with_name (filename);
1135
 
1136
  /* FIXME: should be checking for errors from bfd_close (for one thing,
1137
     on error it does not free all the storage associated with the
1138
     bfd).  */
1139
  make_cleanup_bfd_close (pbfd);
1140
 
1141
  QUIT;
1142
  immediate_quit++;
1143
 
1144
  if (!bfd_check_format (pbfd, bfd_object))
1145
    error ("It doesn't seem to be an object file");
1146
 
1147
  for (section = pbfd->sections; section; section = section->next)
1148
    {
1149
      if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1150
        {
1151
          UDIResource To;
1152
          UDICount Count;
1153
          unsigned long section_size, section_end;
1154
          const char *section_name;
1155
 
1156
          section_name = bfd_get_section_name (pbfd, section);
1157
          if (STREQ (section_name, ".text") && !load_text)
1158
            continue;
1159
          else if (STREQ (section_name, ".data") && !load_data)
1160
            continue;
1161
          else if (STREQ (section_name, ".bss") && !load_bss)
1162
            continue;
1163
          else if (STREQ (section_name, ".lit") && !load_lit)
1164
            continue;
1165
 
1166
          To.Offset = bfd_get_section_vma (pbfd, section);
1167
          section_size = bfd_section_size (pbfd, section);
1168
          section_end = To.Offset + section_size;
1169
 
1170
          if (section_size == 0)
1171
            /* This is needed at least in the BSS case, where the code
1172
               below starts writing before it even checks the size.  */
1173
            continue;
1174
 
1175
          printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n",
1176
                             section_name,
1177
                             To.Offset,
1178
                             section_size);
1179
 
1180
          if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1181
            {
1182
              To.Space = UDI29KIRAMSpace;
1183
 
1184
              address_ranges[0].Offset = min (address_ranges[0].Offset,
1185
                                              To.Offset);
1186
              address_ranges[0].Size = max (address_ranges[0].Size,
1187
                                            section_end
1188
                                            - address_ranges[0].Offset);
1189
            }
1190
          else
1191
            {
1192
              To.Space = UDI29KDRAMSpace;
1193
 
1194
              address_ranges[1].Offset = min (address_ranges[1].Offset,
1195
                                              To.Offset);
1196
              address_ranges[1].Size = max (address_ranges[1].Size,
1197
                                            section_end
1198
                                            - address_ranges[1].Offset);
1199
            }
1200
 
1201
          if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)         /* Text, data or lit */
1202
            {
1203
              file_ptr fptr;
1204
 
1205
              fptr = 0;
1206
 
1207
              while (section_size > 0)
1208
                {
1209
                  char buffer[1024];
1210
 
1211
                  Count = min (section_size, 1024);
1212
 
1213
                  bfd_get_section_contents (pbfd, section, buffer, fptr,
1214
                                            Count);
1215
 
1216
                  err = UDIWrite ((UDIHostMemPtr) buffer,       /* From */
1217
                                  To,   /* To */
1218
                                  Count,        /* Count */
1219
                                  (UDISizeT) 1,         /* Size */
1220
                                  &Count,       /* CountDone */
1221
                                  (UDIBool) 0);          /* HostEndian */
1222
                  if (err)
1223
                    error ("UDIWrite failed, error = %d", err);
1224
 
1225
                  To.Offset += Count;
1226
                  fptr += Count;
1227
                  section_size -= Count;
1228
                }
1229
            }
1230
          else
1231
            /* BSS */
1232
            {
1233
              UDIResource From;
1234
              unsigned long zero = 0;
1235
 
1236
              /* Write a zero byte at the vma */
1237
              /* FIXME: Broken for sections of 1-3 bytes (we test for
1238
                 zero above).  */
1239
              err = UDIWrite ((UDIHostMemPtr) & zero,   /* From */
1240
                              To,       /* To */
1241
                              (UDICount) 1,     /* Count */
1242
                              (UDISizeT) 4,     /* Size */
1243
                              &Count,   /* CountDone */
1244
                              (UDIBool) 0);      /* HostEndian */
1245
              if (err)
1246
                error ("UDIWrite failed, error = %d", err);
1247
 
1248
              From = To;
1249
              To.Offset += 4;
1250
 
1251
              /* Now, duplicate it for the length of the BSS */
1252
              err = UDICopy (From,      /* From */
1253
                             To,        /* To */
1254
                             (UDICount) (section_size / 4 - 1),         /* Count */
1255
                             (UDISizeT) 4,      /* Size */
1256
                             &Count,    /* CountDone */
1257
                             (UDIBool) 1);      /* Direction */
1258
              if (err)
1259
                {
1260
                  char message[100];
1261
                  int xerr;
1262
 
1263
                  xerr = UDIGetErrorMsg (err, 100, message, &Count);
1264
                  if (!xerr)
1265
                    fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
1266
                  else
1267
                    fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
1268
                  error ("UDICopy failed, error = %d", err);
1269
                }
1270
            }
1271
 
1272
        }
1273
    }
1274
 
1275
  entry.Space = UDI29KIRAMSpace;
1276
  entry.Offset = bfd_get_start_address (pbfd);
1277
 
1278
  immediate_quit--;
1279
}
1280
 
1281
/* Function to download an image into the remote target.  */
1282
 
1283
static void
1284
udi_load (char *args, int from_tty)
1285
{
1286
  download (args, from_tty);
1287
 
1288
  /* As a convenience, pick up any symbol info that is in the program
1289
     being loaded.  Note that we assume that the program is the``mainline'';
1290
     if this is not always true, then this code will need to be augmented.  */
1291
  symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0);
1292
 
1293
  /* Getting new symbols may change our opinion about what is
1294
     frameless.  */
1295
  reinit_frame_cache ();
1296
}
1297
 
1298
/*************************************************** UDI_WRITE_INFERIOR_MEMORY
1299
** Copy LEN bytes of data from debugger memory at MYADDR
1300
   to inferior's memory at MEMADDR.  Returns number of bytes written.  */
1301
static int
1302
udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1303
{
1304
  int nwritten = 0;
1305
  UDIUInt32 *From;
1306
  UDIResource To;
1307
  UDICount Count;
1308
  UDISizeT Size = 1;
1309
  UDICount CountDone = 0;
1310
  UDIBool HostEndian = 0;
1311
 
1312
  To.Space = udi_memory_space (memaddr);
1313
  From = (UDIUInt32 *) myaddr;
1314
 
1315
  while (nwritten < len)
1316
    {
1317
      Count = len - nwritten;
1318
      if (Count > MAXDATA)
1319
        Count = MAXDATA;
1320
      To.Offset = memaddr + nwritten;
1321
      if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
1322
        {
1323
          error ("UDIWrite() failed in udi_write_inferior_memory");
1324
          break;
1325
        }
1326
      else
1327
        {
1328
          nwritten += CountDone;
1329
          From += CountDone;
1330
        }
1331
    }
1332
  return (nwritten);
1333
}
1334
 
1335
/**************************************************** UDI_READ_INFERIOR_MEMORY
1336
** Read LEN bytes from inferior memory at MEMADDR.  Put the result
1337
   at debugger address MYADDR.  Returns number of bytes read.  */
1338
static int
1339
udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1340
{
1341
  int nread = 0;
1342
  UDIResource From;
1343
  UDIUInt32 *To;
1344
  UDICount Count;
1345
  UDISizeT Size = 1;
1346
  UDICount CountDone = 0;
1347
  UDIBool HostEndian = 0;
1348
  UDIError err;
1349
 
1350
  From.Space = udi_memory_space (memaddr);
1351
  To = (UDIUInt32 *) myaddr;
1352
 
1353
  while (nread < len)
1354
    {
1355
      Count = len - nread;
1356
      if (Count > MAXDATA)
1357
        Count = MAXDATA;
1358
      From.Offset = memaddr + nread;
1359
      if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
1360
        {
1361
          error ("UDIRead() failed in udi_read_inferior_memory");
1362
          break;
1363
        }
1364
      else
1365
        {
1366
          nread += CountDone;
1367
          To += CountDone;
1368
        }
1369
    }
1370
  return (nread);
1371
}
1372
 
1373
/********************************************************************* WARNING
1374
*/
1375
udi_warning (int num)
1376
{
1377
  error ("ERROR while loading program into remote TIP: $d\n", num);
1378
}
1379
 
1380
 
1381
/*****************************************************************************/
1382
/* Fetch a single register indicatated by 'regno'.
1383
 * Returns 0/-1 on success/failure.
1384
 */
1385
static void
1386
fetch_register (int regno)
1387
{
1388
  UDIResource From;
1389
  UDIUInt32 To;
1390
  UDICount Count = 1;
1391
  UDISizeT Size = 4;
1392
  UDICount CountDone;
1393
  UDIBool HostEndian = 0;
1394
  UDIError err;
1395
  int result;
1396
 
1397
  if (regno == GR1_REGNUM)
1398
    {
1399
      From.Space = UDI29KGlobalRegs;
1400
      From.Offset = 1;
1401
    }
1402
  else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1403
    {
1404
      From.Space = UDI29KGlobalRegs;
1405
      From.Offset = (regno - GR96_REGNUM) + 96;;
1406
    }
1407
 
1408
#if defined(GR64_REGNUM)
1409
 
1410
  else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1411
    {
1412
      From.Space = UDI29KGlobalRegs;
1413
      From.Offset = (regno - GR64_REGNUM) + 64;
1414
    }
1415
 
1416
#endif /* GR64_REGNUM */
1417
 
1418
  else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1419
    {
1420
      From.Space = UDI29KLocalRegs;
1421
      From.Offset = (regno - LR0_REGNUM);
1422
    }
1423
  else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1424
    {
1425
      int val = -1;
1426
      /*supply_register(160 + (regno - FPE_REGNUM),(char *) &val); */
1427
      supply_register (regno, (char *) &val);
1428
      return;                   /* Pretend Success */
1429
    }
1430
  else
1431
    {
1432
      From.Space = UDI29KSpecialRegs;
1433
      From.Offset = regnum_to_srnum (regno);
1434
    }
1435
 
1436
  if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian))
1437
    error ("UDIRead() failed in udi_fetch_registers");
1438
 
1439
  supply_register (regno, (char *) &To);
1440
 
1441
  if (remote_debug)
1442
    fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n",
1443
                        REGISTER_NAME (regno), To);
1444
}
1445
/*****************************************************************************/
1446
/* Store a single register indicated by 'regno'.
1447
 * Returns 0/-1 on success/failure.
1448
 */
1449
static int
1450
store_register (int regno)
1451
{
1452
  int result;
1453
  UDIUInt32 From;
1454
  UDIResource To;
1455
  UDICount Count = 1;
1456
  UDISizeT Size = 4;
1457
  UDICount CountDone;
1458
  UDIBool HostEndian = 0;
1459
 
1460
  From = read_register (regno); /* get data value */
1461
 
1462
  if (remote_debug)
1463
    fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n",
1464
                        REGISTER_NAME (regno), From);
1465
 
1466
  if (regno == GR1_REGNUM)
1467
    {
1468
      To.Space = UDI29KGlobalRegs;
1469
      To.Offset = 1;
1470
      result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1471
      /* Setting GR1 changes the numbers of all the locals, so invalidate the
1472
       * register cache.  Do this *after* calling read_register, because we want
1473
       * read_register to return the value that write_register has just stuffed
1474
       * into the registers array, not the value of the register fetched from
1475
       * the inferior.
1476
       */
1477
      registers_changed ();
1478
    }
1479
#if defined(GR64_REGNUM)
1480
  else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1481
    {
1482
      To.Space = UDI29KGlobalRegs;
1483
      To.Offset = (regno - GR64_REGNUM) + 64;
1484
      result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1485
    }
1486
#endif /* GR64_REGNUM */
1487
  else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1488
    {
1489
      To.Space = UDI29KGlobalRegs;
1490
      To.Offset = (regno - GR96_REGNUM) + 96;
1491
      result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1492
    }
1493
  else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1494
    {
1495
      To.Space = UDI29KLocalRegs;
1496
      To.Offset = (regno - LR0_REGNUM);
1497
      result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1498
    }
1499
  else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1500
    return 0;                    /* Pretend Success */
1501
  else if (regno == PC_REGNUM)
1502
    {
1503
      /* PC1 via UDI29KPC */
1504
 
1505
      To.Space = UDI29KPC;
1506
      To.Offset = 0;             /* PC1 */
1507
      result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1508
 
1509
      /* Writing to this loc actually changes the values of pc0 & pc1 */
1510
 
1511
      register_valid[PC_REGNUM] = 0;     /* pc1 */
1512
      register_valid[NPC_REGNUM] = 0;    /* pc0 */
1513
    }
1514
  else
1515
    /* An unprotected or protected special register */
1516
    {
1517
      To.Space = UDI29KSpecialRegs;
1518
      To.Offset = regnum_to_srnum (regno);
1519
      result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1520
    }
1521
 
1522
  if (result != 0)
1523
    error ("UDIWrite() failed in store_registers");
1524
 
1525
  return 0;
1526
}
1527
/********************************************************** REGNUM_TO_SRNUM */
1528
/*
1529
 * Convert a gdb special register number to a 29000 special register number.
1530
 */
1531
static int
1532
regnum_to_srnum (int regno)
1533
{
1534
  switch (regno)
1535
    {
1536
    case VAB_REGNUM:
1537
      return (0);
1538
    case OPS_REGNUM:
1539
      return (1);
1540
    case CPS_REGNUM:
1541
      return (2);
1542
    case CFG_REGNUM:
1543
      return (3);
1544
    case CHA_REGNUM:
1545
      return (4);
1546
    case CHD_REGNUM:
1547
      return (5);
1548
    case CHC_REGNUM:
1549
      return (6);
1550
    case RBP_REGNUM:
1551
      return (7);
1552
    case TMC_REGNUM:
1553
      return (8);
1554
    case TMR_REGNUM:
1555
      return (9);
1556
    case NPC_REGNUM:
1557
      return (USE_SHADOW_PC ? (20) : (10));
1558
    case PC_REGNUM:
1559
      return (USE_SHADOW_PC ? (21) : (11));
1560
    case PC2_REGNUM:
1561
      return (USE_SHADOW_PC ? (22) : (12));
1562
    case MMU_REGNUM:
1563
      return (13);
1564
    case LRU_REGNUM:
1565
      return (14);
1566
    case IPC_REGNUM:
1567
      return (128);
1568
    case IPA_REGNUM:
1569
      return (129);
1570
    case IPB_REGNUM:
1571
      return (130);
1572
    case Q_REGNUM:
1573
      return (131);
1574
    case ALU_REGNUM:
1575
      return (132);
1576
    case BP_REGNUM:
1577
      return (133);
1578
    case FC_REGNUM:
1579
      return (134);
1580
    case CR_REGNUM:
1581
      return (135);
1582
    case FPE_REGNUM:
1583
      return (160);
1584
    case INTE_REGNUM:
1585
      return (161);
1586
    case FPS_REGNUM:
1587
      return (162);
1588
    case EXO_REGNUM:
1589
      return (164);
1590
    default:
1591
      return (255);             /* Failure ? */
1592
    }
1593
}
1594
/****************************************************************************/
1595
/*
1596
 * Determine the Target memory space qualifier based on the addr.
1597
 * FIXME: Can't distinguis I_ROM/D_ROM.
1598
 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1599
 */
1600
static CPUSpace
1601
udi_memory_space (CORE_ADDR addr)
1602
{
1603
  UDIUInt32 tstart = IMemStart;
1604
  UDIUInt32 tend = tstart + IMemSize;
1605
  UDIUInt32 dstart = DMemStart;
1606
  UDIUInt32 dend = tstart + DMemSize;
1607
  UDIUInt32 rstart = RMemStart;
1608
  UDIUInt32 rend = tstart + RMemSize;
1609
 
1610
  if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend))
1611
    {
1612
      return UDI29KIRAMSpace;
1613
    }
1614
  else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend))
1615
    {
1616
      return UDI29KDRAMSpace;
1617
    }
1618
  else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend))
1619
    {
1620
      /* FIXME: how do we determine between D_ROM and I_ROM */
1621
      return UDI29KIROMSpace;
1622
    }
1623
  else                          /* FIXME: what do me do now? */
1624
    return UDI29KDRAMSpace;     /* Hmmm! */
1625
}
1626
/*********************************************************************** STUBS
1627
*/
1628
 
1629
void
1630
convert16 (void)
1631
{;
1632
}
1633
void
1634
convert32 (void)
1635
{;
1636
}
1637
struct ui_file *EchoFile = 0;    /* used for debugging */
1638
int QuietMode = 0;               /* used for debugging */
1639
 
1640
#ifdef NO_HIF_SUPPORT
1641
service_HIF (union msg_t *msg)
1642
{
1643
  return (0);                    /* Emulate a failure */
1644
}
1645
#endif
1646
 
1647
/* Target_ops vector.  Not static because there does not seem to be
1648
   any portable way to do a forward declaration of a static variable.
1649
   The RS/6000 doesn't like "extern" followed by "static"; SunOS
1650
   /bin/cc doesn't like "static" twice.  */
1651
 
1652
struct target_ops udi_ops;
1653
 
1654
static void
1655
init_udi_ops (void)
1656
{
1657
  udi_ops.to_shortname = "udi";
1658
  udi_ops.to_longname = "Remote UDI connected TIP";
1659
  udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1660
Arguments are\n\
1661
`configuration-id AF_INET hostname port-number'\n\
1662
To connect via the network, where hostname and port-number specify the\n\
1663
host and port where you can connect via UDI.\n\
1664
configuration-id is unused.\n\
1665
\n\
1666
`configuration-id AF_UNIX socket-name tip-program'\n\
1667
To connect using a local connection to the \"tip.exe\" program which is\n\
1668
    supplied by AMD.  If socket-name specifies an AF_UNIX socket then the\n\
1669
    tip program must already be started; connect to it using that socket.\n\
1670
    If not, start up tip-program, which should be the name of the tip\n\
1671
    program.  If appropriate, the PATH environment variable is searched.\n\
1672
    configuration-id is unused.\n\
1673
\n\
1674
`configuration-id'\n\
1675
    Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1676
    are files containing lines in the above formats.  configuration-id is\n\
1677
    used to pick which line of the file to use.";
1678
  udi_ops.to_open = udi_open;
1679
  udi_ops.to_close = udi_close;
1680
  udi_ops.to_attach = udi_attach;
1681
  udi_ops.to_detach = udi_detach;
1682
  udi_ops.to_resume = udi_resume;
1683
  udi_ops.to_wait = udi_wait;
1684
  udi_ops.to_fetch_registers = udi_fetch_registers;
1685
  udi_ops.to_store_registers = udi_store_registers;
1686
  udi_ops.to_prepare_to_store = udi_prepare_to_store;
1687
  udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
1688
  udi_ops.to_files_info = udi_files_info;
1689
  udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
1690
  udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
1691
  udi_ops.to_terminal_init = 0;
1692
  udi_ops.to_terminal_inferior = 0;
1693
  udi_ops.to_terminal_ours_for_output = 0;
1694
  udi_ops.to_terminal_ours = 0;
1695
  udi_ops.to_terminal_info = 0;
1696
  udi_ops.to_kill = udi_kill;
1697
  udi_ops.to_load = udi_load;
1698
  udi_ops.to_lookup_symbol = 0;
1699
  udi_ops.to_create_inferior = udi_create_inferior;
1700
  udi_ops.to_mourn_inferior = udi_mourn;
1701
  udi_ops.to_can_run = 0;
1702
  udi_ops.to_notice_signals = 0;
1703
  udi_ops.to_thread_alive = 0;
1704
  udi_ops.to_stop = 0;
1705
  udi_ops.to_stratum = process_stratum;
1706
  udi_ops.DONT_USE = 0;
1707
  udi_ops.to_has_all_memory = 1;
1708
  udi_ops.to_has_memory = 1;
1709
  udi_ops.to_has_stack = 1;
1710
  udi_ops.to_has_registers = 1;
1711
  udi_ops.to_has_execution = 1;
1712
  udi_ops.to_sections = 0;
1713
  udi_ops.to_sections_end = 0;
1714
  udi_ops.to_magic = OPS_MAGIC;
1715
};
1716
 
1717
void
1718
_initialize_remote_udi (void)
1719
{
1720
  init_udi_ops ();
1721
  add_target (&udi_ops);
1722
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.