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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-udi.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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