1 /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
2 Copyright 1990, 1992 Free Software Foundation, Inc.
3 Written by Daniel Mann. Contributed by AMD.
5 This file is part of GDB.
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This is like remote.c but uses the Universal Debug Interface (UDI) to
22 talk to the target hardware (or simulator). UDI is a TCP/IP based
23 protocol; for hardware that doesn't run TCP, an interface adapter
24 daemon talks UDI on one side, and talks to the hardware (typically
25 over a serial port) on the other side.
27 - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
28 - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
29 file to gdb 3.95. I was unable to get this working on sun3os4
30 with termio, only with sgtty.
31 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
32 MiniMON interface with UDI-p interface. */
45 #include "29k-share/udi/udiproc.h"
48 #include "gdbcore.h" /* For download function */
50 /* access the register store directly, without going through
51 the normal handler functions. This avoids an extra data copy. */
53 extern int stop_soon_quietly
; /* for wait_for_inferior */
54 extern struct value
*call_function_by_hand();
55 static void udi_resume
PARAMS ((int pid
, int step
, int sig
));
56 static void udi_fetch_registers
PARAMS ((int regno
));
57 static void udi_load
PARAMS ((char *args
, int from_tty
));
58 static void fetch_register
PARAMS ((int regno
));
59 static void udi_store_registers
PARAMS ((int regno
));
60 static int store_register
PARAMS ((int regno
));
61 static int regnum_to_srnum
PARAMS ((int regno
));
62 static void udi_close
PARAMS ((int quitting
));
63 static CPUSpace udi_memory_space
PARAMS ((CORE_ADDR addr
));
64 static int udi_write_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
66 static int udi_read_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
68 static void download
PARAMS ((char *load_arg_string
, int from_tty
));
69 char CoffFileName
[100] = "";
71 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
72 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
74 static int timeout
= 5;
75 extern struct target_ops udi_ops
; /* Forward declaration */
77 /* Special register enumeration.
80 /******************************************************************* UDI DATA*/
81 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
82 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
83 udi_open knows that we don't have a file open when the program
86 UDISessionId udi_session_id
= -1;
88 CPUOffset IMemStart
= 0;
89 CPUSizeT IMemSize
= 0;
90 CPUOffset DMemStart
= 0;
91 CPUSizeT DMemSize
= 0;
92 CPUOffset RMemStart
= 0;
93 CPUSizeT RMemSize
= 0;
97 UDIMemoryRange address_ranges
[2]; /* Text and data */
98 UDIResource entry
= {0, 0}; /* Entry point */
99 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
101 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
104 typedef struct bkpt_entry_str
109 unsigned int BreakId
;
111 #define BKPT_TABLE_SIZE 40
112 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
113 extern char dfe_errmsg
[]; /* error string */
115 /* malloc'd name of the program on the remote system. */
116 static char *prog_name
= NULL
;
118 /* Number of SIGTRAPs we need to simulate. That is, the next
119 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
120 SIGTRAP without actually waiting for anything. */
122 /* This is called not only when we first attach, but also when the
123 user types "run" after having attached. */
126 udi_create_inferior (execfile
, args
, env
)
135 if (prog_name
!= NULL
)
137 prog_name
= savestring (execfile
, strlen (execfile
));
139 else if (entry
.Offset
)
142 error ("No image loaded into target.");
144 if (udi_session_id
< 0)
146 printf_unfiltered("UDI connection not open yet.\n");
150 inferior_pid
= 40000;
153 download(execfile
, 0);
155 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
157 strcpy (args1
, execfile
);
159 strcat (args1
, args
);
161 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
162 (UDIInt
)2, /* NumberOfRanges */
163 entry
, /* EntryPoint */
164 stack_sizes
, /* *StackSizes */
165 (UDIInt
)2, /* NumberOfStacks */
166 args1
); /* ArgString */
168 init_wait_for_inferior ();
169 clear_proceed_status ();
170 proceed (-1, TARGET_SIGNAL_DEFAULT
, 0);
177 /* Requiring "target udi" each time you run is a major pain. I suspect
178 this was just blindy copied from remote.c, in which "target" and
179 "run" are combined. Having a udi target without an inferior seems
180 to work between "target udi" and "run", so why not now? */
181 pop_target (); /* Pop back to no-child state */
183 generic_mourn_inferior ();
186 /******************************************************************** UDI_OPEN
187 ** Open a connection to remote TIP.
188 NAME is the socket domain used for communication with the TIP,
189 then a space and the socket name or TIP-host name.
190 '<udi_udi_config_id>' for example.
193 /* XXX - need cleanups for udiconnect for various failures!!! */
195 static char *udi_config_id
;
197 udi_open (name
, from_tty
)
204 UDIMemoryRange KnownMemory
[10];
205 UDIUInt32 ChipVersions
[10];
206 UDIInt NumberOfRanges
= 10;
207 UDIInt NumberOfChips
= 10;
209 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
211 target_preopen(from_tty
);
215 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
216 bkpt_table
[cnt
].Type
= 0;
219 free (udi_config_id
);
222 error("Usage: target udi config_id, where config_id appears in udi_soc file");
224 udi_config_id
= strdup (strtok (name
, " \t"));
226 if (UDIConnect (udi_config_id
, &udi_session_id
))
227 error("UDIConnect() failed: %s\n", dfe_errmsg
);
229 push_target (&udi_ops
);
232 ** Initialize target configuration structure (global)
234 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
235 ChipVersions
, &NumberOfChips
))
236 error ("UDIGetTargetConfig() failed");
237 if (NumberOfChips
> 2)
238 fprintf_unfiltered(gdb_stderr
,"Target has more than one processor\n");
239 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
241 switch(KnownMemory
[cnt
].Space
)
244 fprintf_unfiltered(gdb_stderr
, "UDIGetTargetConfig() unknown memory space\n");
248 case UDI29KIROMSpace
:
249 RMemStart
= KnownMemory
[cnt
].Offset
;
250 RMemSize
= KnownMemory
[cnt
].Size
;
252 case UDI29KIRAMSpace
:
253 IMemStart
= KnownMemory
[cnt
].Offset
;
254 IMemSize
= KnownMemory
[cnt
].Size
;
256 case UDI29KDRAMSpace
:
257 DMemStart
= KnownMemory
[cnt
].Offset
;
258 DMemSize
= KnownMemory
[cnt
].Size
;
263 a29k_get_processor_type ();
265 if (UDICreateProcess (&PId
))
266 fprintf_unfiltered(gdb_stderr
, "UDICreateProcess() failed\n");
268 /* Print out some stuff, letting the user now what's going on */
269 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
271 error ("UDICapabilities() failed");
274 printf_filtered ("Connected via UDI socket,\n\
275 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
276 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
277 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
278 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
283 /******************************************************************* UDI_CLOSE
284 Close the open connection to the TIP process.
285 Use this when you want to detach and do something else
288 udi_close (quitting
) /*FIXME: how is quitting used */
291 if (udi_session_id
< 0)
294 /* We should never get here if there isn't something valid in
297 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
298 error ("UDIDisconnect() failed in udi_close");
300 /* Do not try to close udi_session_id again, later in the program. */
304 printf_filtered (" Ending remote debugging\n");
307 /**************************************************************** UDI_ATACH */
308 /* Attach to a program that is already loaded and running
309 * Upon exiting the process's execution is stopped.
312 udi_attach (args
, from_tty
)
321 UDIBool HostEndian
= 0;
324 if (udi_session_id
< 0)
325 error ("UDI connection not opened yet, use the 'target udi' command.\n");
328 printf_unfiltered ("Attaching to remote program %s...\n", prog_name
);
331 From
.Space
= UDI29KSpecialRegs
;
333 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
334 error ("UDIRead failed in udi_attach");
335 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
337 /************************************************************* UDI_DETACH */
338 /* Terminate the open connection to the TIP process.
339 Use this when you want to detach and do something else
340 with your gdb. Leave remote process running (with no breakpoints set). */
342 udi_detach (args
,from_tty
)
347 remove_breakpoints(); /* Just in case there were any left in */
349 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
350 error ("UDIDisconnect() failed in udi_detach");
352 pop_target(); /* calls udi_close to do the real work */
355 printf_unfiltered ("Ending remote debugging\n");
359 /****************************************************************** UDI_RESUME
360 ** Tell the remote machine to resume. */
363 udi_resume (pid
, step
, sig
)
365 enum target_signal sig
;
369 UDIStepType StepType
= UDIStepNatural
;
372 if (step
) /* step 1 instruction */
374 tip_error
= UDIStep (Steps
, StepType
, Range
);
378 fprintf_unfiltered (gdb_stderr
, "UDIStep() error = %d\n", tip_error
);
379 error ("failed in udi_resume");
383 error ("UDIExecute() failed in udi_resume");
386 /******************************************************************** UDI_WAIT
387 ** Wait until the remote machine stops, then return,
388 storing status in STATUS just as `wait' would. */
391 udi_wait (pid
, status
)
393 struct target_waitstatus
*status
;
399 int old_timeout
= timeout
;
400 int old_immediate_quit
= immediate_quit
;
403 status
->kind
= TARGET_WAITKIND_EXITED
;
404 status
->value
.integer
= 0;
406 /* wait for message to arrive. It should be:
407 If the target stops executing, udi_wait() should return.
409 timeout
= 0; /* Wait indefinetly for a message */
410 immediate_quit
= 1; /* Helps ability to QUIT */
415 MaxTime
= UDIWaitForever
;
416 UDIWait(MaxTime
, &PId
, &StopReason
);
417 QUIT
; /* Let user quit if they want */
419 switch (StopReason
& UDIGrossState
)
422 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
423 /* This is said to happen if the program tries to output
424 a whole bunch of output (more than SBUF_MAX, I would
425 guess). It doesn't seem to happen with the simulator. */
426 warning ("UDIGetStdout() failed in udi_wait");
427 fwrite (sbuf
, 1, CountDone
, gdb_stdout
);
428 gdb_flush(gdb_stdout
);
432 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
433 fwrite (sbuf
, 1, CountDone
, gdb_stderr
);
434 gdb_flush(gdb_stderr
);
447 } while (i
< SBUF_MAX
&& ch
!= '\n');
448 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
453 /* In spite of the fact that we told UDIWait to wait forever, it will
454 return spuriously sometimes. */
463 switch (StopReason
& UDIGrossState
)
466 printf_unfiltered("Am290*0 received vector number %d\n", StopReason
>> 24);
468 switch (StopReason
>> 8)
470 case 0: /* Illegal opcode */
471 printf_unfiltered(" (break point)\n");
472 status
->kind
= TARGET_WAITKIND_STOPPED
;
473 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
475 case 1: /* Unaligned Access */
476 status
->kind
= TARGET_WAITKIND_STOPPED
;
477 status
->value
.sig
= TARGET_SIGNAL_BUS
;
481 status
->kind
= TARGET_WAITKIND_STOPPED
;
482 status
->value
.sig
= TARGET_SIGNAL_FPE
;
484 case 5: /* Protection Violation */
485 status
->kind
= TARGET_WAITKIND_STOPPED
;
486 /* Why not SEGV? What is a Protection Violation? */
487 status
->value
.sig
= TARGET_SIGNAL_ILL
;
491 case 8: /* User Instruction Mapping Miss */
492 case 9: /* User Data Mapping Miss */
493 case 10: /* Supervisor Instruction Mapping Miss */
494 case 11: /* Supervisor Data Mapping Miss */
495 status
->kind
= TARGET_WAITKIND_STOPPED
;
496 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
500 status
->kind
= TARGET_WAITKIND_STOPPED
;
501 status
->value
.sig
= TARGET_SIGNAL_ILL
;
504 status
->kind
= TARGET_WAITKIND_STOPPED
;
505 status
->value
.sig
= TARGET_SIGNAL_ALRM
;
508 status
->kind
= TARGET_WAITKIND_STOPPED
;
509 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
514 case 19: /* INTR3/Internal */
517 status
->kind
= TARGET_WAITKIND_STOPPED
;
518 status
->value
.sig
= TARGET_SIGNAL_INT
;
520 case 22: /* Floating-Point Exception */
521 status
->kind
= TARGET_WAITKIND_STOPPED
;
523 status
->value
.sig
= TARGET_SIGNAL_ILL
;
525 case 77: /* assert 77 */
526 status
->kind
= TARGET_WAITKIND_STOPPED
;
527 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
530 status
->kind
= TARGET_WAITKIND_EXITED
;
531 status
->value
.integer
= 0;
534 case UDINotExecuting
:
535 status
->kind
= TARGET_WAITKIND_STOPPED
;
536 status
->value
.sig
= TARGET_SIGNAL_TERM
;
539 status
->kind
= TARGET_WAITKIND_STOPPED
;
540 status
->value
.sig
= TARGET_SIGNAL_TSTP
;
543 status
->kind
= TARGET_WAITKIND_STOPPED
;
544 status
->value
.sig
= TARGET_SIGNAL_URG
;
548 status
->kind
= TARGET_WAITKIND_STOPPED
;
549 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
552 status
->kind
= TARGET_WAITKIND_STOPPED
;
553 status
->value
.sig
= TARGET_SIGNAL_STOP
;
556 status
->kind
= TARGET_WAITKIND_STOPPED
;
557 status
->value
.sig
= TARGET_SIGNAL_KILL
;
561 status
->kind
= TARGET_WAITKIND_EXITED
;
562 status
->value
.integer
= 0;
565 timeout
= old_timeout
; /* Restore original timeout value */
566 immediate_quit
= old_immediate_quit
;
571 /* Handy for debugging */
579 UDIBool HostEndian
= 0;
582 unsigned long myregs
[256];
585 From
.Space
= UDI29KPC
;
587 To
= (UDIUInt32
*)pc
;
590 err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
);
592 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
593 err
, CountDone
, pc
[0], pc
[1]);
595 udi_fetch_registers(-1);
597 printf_unfiltered("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *)®isters
[4 * PC_REGNUM
],
598 *(int *)®isters
[4 * NPC_REGNUM
]);
600 /* Now, read all the registers globally */
602 From
.Space
= UDI29KGlobalRegs
;
604 err
= UDIRead(From
, myregs
, 256, 4, &CountDone
, HostEndian
);
606 printf ("err = %d, CountDone = %d\n", err
, CountDone
);
610 for (i
= 0; i
< 256; i
+= 2)
611 printf("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i
, myregs
[i
], myregs
[i
],
612 myregs
[i
+1], myregs
[i
+1]);
619 /********************************************************** UDI_FETCH_REGISTERS
620 * Read a remote register 'regno'.
621 * If regno==-1 then read all the registers.
624 udi_fetch_registers (regno
)
632 UDIBool HostEndian
= 0;
637 fetch_register(regno
);
643 From
.Space
= UDI29KGlobalRegs
;
645 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
647 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
648 error("UDIRead() failed in udi_fetch_registers");
650 register_valid
[GR1_REGNUM
] = 1;
652 #if defined(GR64_REGNUM) /* Read gr64-127 */
654 /* Global Registers gr64-gr95 */
656 From
.Space
= UDI29KGlobalRegs
;
658 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
660 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
661 error("UDIRead() failed in udi_fetch_registers");
663 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
664 register_valid
[i
] = 1;
666 #endif /* GR64_REGNUM */
668 /* Global Registers gr96-gr127 */
670 From
.Space
= UDI29KGlobalRegs
;
672 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
674 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
675 error("UDIRead() failed in udi_fetch_registers");
677 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
678 register_valid
[i
] = 1;
680 /* Local Registers */
682 From
.Space
= UDI29KLocalRegs
;
684 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
686 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
687 error("UDIRead() failed in udi_fetch_registers");
689 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
690 register_valid
[i
] = 1;
692 /* Protected Special Registers */
694 From
.Space
= UDI29KSpecialRegs
;
696 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
698 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
699 error("UDIRead() failed in udi_fetch_registers");
701 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
702 register_valid
[i
] = 1;
704 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
705 fetch_register(NPC_REGNUM
);
706 fetch_register(PC_REGNUM
);
707 fetch_register(PC2_REGNUM
);
709 /* Unprotected Special Registers sr128-sr135 */
711 From
.Space
= UDI29KSpecialRegs
;
713 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
715 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
716 error("UDIRead() failed in udi_fetch_registers");
718 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
719 register_valid
[i
] = 1;
724 printf_unfiltered("Fetching all registers\n");
725 printf_unfiltered("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
726 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
727 read_register(PC2_REGNUM
));
730 /* There doesn't seem to be any way to get these. */
733 supply_register (FPE_REGNUM
, (char *) &val
);
734 supply_register (INTE_REGNUM
, (char *) &val
);
735 supply_register (FPS_REGNUM
, (char *) &val
);
736 supply_register (EXO_REGNUM
, (char *) &val
);
741 /********************************************************* UDI_STORE_REGISTERS
742 ** Store register regno into the target.
743 * If regno==-1 then store all the registers.
747 udi_store_registers (regno
)
755 UDIBool HostEndian
= 0;
759 store_register(regno
);
765 printf_unfiltered("Storing all registers\n");
766 printf_unfiltered("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
767 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
772 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
773 To
.Space
= UDI29KGlobalRegs
;
776 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
777 error("UDIWrite() failed in udi_store_regisetrs");
779 #if defined(GR64_REGNUM)
781 /* Global registers gr64-gr95 */
783 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
784 To
.Space
= UDI29KGlobalRegs
;
787 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
788 error("UDIWrite() failed in udi_store_regisetrs");
790 #endif /* GR64_REGNUM */
792 /* Global registers gr96-gr127 */
794 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
795 To
.Space
= UDI29KGlobalRegs
;
798 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
799 error("UDIWrite() failed in udi_store_regisetrs");
801 /* Local Registers */
803 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
804 To
.Space
= UDI29KLocalRegs
;
807 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
808 error("UDIWrite() failed in udi_store_regisetrs");
811 /* Protected Special Registers */ /* VAB through TMR */
813 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
814 To
.Space
= UDI29KSpecialRegs
;
817 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
818 error("UDIWrite() failed in udi_store_regisetrs");
820 /* PC0, PC1, PC2 possibly as shadow registers */
822 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
823 To
.Space
= UDI29KSpecialRegs
;
826 To
.Offset
= 20; /* SPC0 */
828 To
.Offset
= 10; /* PC0 */
829 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
830 error("UDIWrite() failed in udi_store_regisetrs");
832 /* PC1 via UDI29KPC */
834 From
= (UDIUInt32
*)®isters
[4 * PC_REGNUM
];
836 To
.Offset
= 0; /* PC1 */
838 if (UDIWrite (From
, To
, Count
, Size
, &CountDone
, HostEndian
))
839 error ("UDIWrite() failed in udi_store_regisetrs");
843 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
844 To
.Space
= UDI29KSpecialRegs
;
847 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
848 error("UDIWrite() failed in udi_store_regisetrs");
850 /* Unprotected Special Registers */
852 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
853 To
.Space
= UDI29KSpecialRegs
;
856 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
857 error("UDIWrite() failed in udi_store_regisetrs");
859 registers_changed ();
862 /****************************************************** UDI_PREPARE_TO_STORE */
863 /* Get ready to modify the registers array. On machines which store
864 individual registers, this doesn't need to do anything. On machines
865 which store all the registers in one fell swoop, this makes sure
866 that registers contains all the registers from the program being
870 udi_prepare_to_store ()
872 /* Do nothing, since we can store individual regs */
875 /********************************************************** TRANSLATE_ADDR */
880 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
881 /* Check for a virtual address in the kernel */
882 /* Assume physical address of ublock is in paddr_u register */
883 /* FIXME: doesn't work for user virtual addresses */
884 if (addr
>= UVADDR
) {
885 /* PADDR_U register holds the physical address of the ublock */
886 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
887 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
895 /************************************************* UDI_XFER_INFERIOR_MEMORY */
896 /* FIXME! Merge these two. */
898 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
905 memaddr
= translate_addr(memaddr
);
908 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
910 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
913 /********************************************************** UDI_FILES_INFO */
917 printf_unfiltered ("\tAttached to UDI socket to %s and running program %s.\n",
918 udi_config_id
, prog_name
);
921 /**************************************************** UDI_INSERT_BREAKPOINT */
923 udi_insert_breakpoint (addr
, contents_cache
)
925 char *contents_cache
;
930 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
931 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
934 if(cnt
>= BKPT_TABLE_SIZE
)
935 error("Too many breakpoints set");
937 bkpt_table
[cnt
].Addr
.Offset
= addr
;
938 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
939 bkpt_table
[cnt
].PassCount
= 1;
940 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
942 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
943 bkpt_table
[cnt
].PassCount
,
944 bkpt_table
[cnt
].Type
,
945 &bkpt_table
[cnt
].BreakId
);
947 if (err
== 0) return 0; /* Success */
949 bkpt_table
[cnt
].Type
= 0;
950 error("UDISetBreakpoint returned error code %d\n", err
);
953 /**************************************************** UDI_REMOVE_BREAKPOINT */
955 udi_remove_breakpoint (addr
, contents_cache
)
957 char *contents_cache
;
962 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
963 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
966 if(cnt
>= BKPT_TABLE_SIZE
)
967 error("Can't find breakpoint in table");
969 bkpt_table
[cnt
].Type
= 0;
971 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
972 if (err
== 0) return 0; /* Success */
974 error("UDIClearBreakpoint returned error code %d\n", err
);
978 udi_kill(arg
,from_tty
)
985 UDIStop does not really work as advertised. It causes the TIP to close it's
986 connection, which usually results in GDB dying with a SIGPIPE. For now, we
987 just invoke udi_close, which seems to get things right.
995 printf_unfiltered("Target has been stopped.");
1003 Load a program into the target. Args are: `program {options}'. The options
1004 are used to control loading of the program, and are NOT passed onto the
1005 loaded code as arguments. (You need to use the `run' command to do that.)
1008 -ms %d Set mem stack size to %d
1009 -rs %d Set regular stack size to %d
1010 -i send init info (default)
1011 -noi don't send init info
1012 -[tT] Load Text section
1013 -[dD] Load Data section
1014 -[bB] Load BSS section
1015 -[lL] Load Lit section
1019 download(load_arg_string
, from_tty
)
1020 char *load_arg_string
;
1023 #define DEFAULT_MEM_STACK_SIZE 0x6000
1024 #define DEFAULT_REG_STACK_SIZE 0x2000
1031 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1033 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1034 address_ranges
[0].Offset
= 0xffffffff;
1035 address_ranges
[0].Size
= 0;
1037 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1038 address_ranges
[1].Offset
= 0xffffffff;
1039 address_ranges
[1].Size
= 0;
1041 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1042 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1046 filename
= strtok(load_arg_string
, " \t");
1048 error ("Must specify at least a file name with the load command");
1050 filename
= tilde_expand (filename
);
1051 make_cleanup (free
, filename
);
1053 while (token
= strtok (NULL
, " \t"))
1055 if (token
[0] == '-')
1059 if (STREQ (token
, "ms"))
1060 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1061 else if (STREQ (token
, "rs"))
1062 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1065 load_text
= load_data
= load_bss
= load_lit
= 0;
1088 error ("Unknown UDI load option -%s", token
-1);
1095 pbfd
= bfd_openr (filename
, gnutarget
);
1098 perror_with_name (filename
);
1100 make_cleanup (bfd_close
, pbfd
);
1105 if (!bfd_check_format (pbfd
, bfd_object
))
1106 error ("It doesn't seem to be an object file");
1108 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1110 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1114 unsigned long section_size
, section_end
;
1115 const char *section_name
;
1117 section_name
= bfd_get_section_name (pbfd
, section
);
1118 if (STREQ (section_name
, ".text") && !load_text
)
1120 else if (STREQ (section_name
, ".data") && !load_data
)
1122 else if (STREQ (section_name
, ".bss") && !load_bss
)
1124 else if (STREQ (section_name
, ".lit") && !load_lit
)
1127 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1128 section_size
= bfd_section_size (pbfd
, section
);
1129 section_end
= To
.Offset
+ section_size
;
1131 if (section_size
== 0)
1132 /* This is needed at least in the BSS case, where the code
1133 below starts writing before it even checks the size. */
1136 printf_unfiltered("[Loading section %s at %x (%d bytes)]\n",
1141 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1143 To
.Space
= UDI29KIRAMSpace
;
1145 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1147 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1149 - address_ranges
[0].Offset
);
1153 To
.Space
= UDI29KDRAMSpace
;
1155 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1157 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1159 - address_ranges
[1].Offset
);
1162 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1168 while (section_size
> 0)
1172 Count
= min (section_size
, 1024);
1174 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1177 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1180 (UDISizeT
)1, /* Size */
1181 &Count
, /* CountDone */
1182 (UDIBool
)0); /* HostEndian */
1184 error ("UDIWrite failed, error = %d", err
);
1188 section_size
-= Count
;
1194 unsigned long zero
= 0;
1196 /* Write a zero byte at the vma */
1197 /* FIXME: Broken for sections of 1-3 bytes (we test for
1199 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1201 (UDICount
)1, /* Count */
1202 (UDISizeT
)4, /* Size */
1203 &Count
, /* CountDone */
1204 (UDIBool
)0); /* HostEndian */
1206 error ("UDIWrite failed, error = %d", err
);
1211 /* Now, duplicate it for the length of the BSS */
1212 err
= UDICopy (From
, /* From */
1214 (UDICount
)(section_size
/4 - 1), /* Count */
1215 (UDISizeT
)4, /* Size */
1216 &Count
, /* CountDone */
1217 (UDIBool
)1); /* Direction */
1223 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1225 fprintf_unfiltered (gdb_stderr
, "Error is %s\n", message
);
1227 fprintf_unfiltered (gdb_stderr
, "xerr is %d\n", xerr
);
1228 error ("UDICopy failed, error = %d", err
);
1235 entry
.Space
= UDI29KIRAMSpace
;
1236 entry
.Offset
= bfd_get_start_address (pbfd
);
1241 /* User interface to download an image into the remote target. See download()
1242 * for details on args.
1246 udi_load(args
, from_tty
)
1250 download (args
, from_tty
);
1252 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1255 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1256 ** Copy LEN bytes of data from debugger memory at MYADDR
1257 to inferior's memory at MEMADDR. Returns number of bytes written. */
1259 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1269 UDICount CountDone
= 0;
1270 UDIBool HostEndian
= 0;
1272 To
.Space
= udi_memory_space(memaddr
);
1273 From
= (UDIUInt32
*)myaddr
;
1275 while (nwritten
< len
)
1276 { Count
= len
- nwritten
;
1277 if (Count
> MAXDATA
) Count
= MAXDATA
;
1278 To
.Offset
= memaddr
+ nwritten
;
1279 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1280 { error("UDIWrite() failed in udi_write_inferrior_memory");
1284 { nwritten
+= CountDone
;
1291 /**************************************************** UDI_READ_INFERIOR_MEMORY
1292 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1293 at debugger address MYADDR. Returns number of bytes read. */
1295 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1305 UDICount CountDone
= 0;
1306 UDIBool HostEndian
= 0;
1309 From
.Space
= udi_memory_space(memaddr
);
1310 To
= (UDIUInt32
*)myaddr
;
1313 { Count
= len
- nread
;
1314 if (Count
> MAXDATA
) Count
= MAXDATA
;
1315 From
.Offset
= memaddr
+ nread
;
1316 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1317 { error("UDIRead() failed in udi_read_inferrior_memory");
1321 { nread
+= CountDone
;
1328 /********************************************************************* WARNING
1333 error ("ERROR while loading program into remote TIP: $d\n", num
);
1337 /*****************************************************************************/
1338 /* Fetch a single register indicatated by 'regno'.
1339 * Returns 0/-1 on success/failure.
1342 fetch_register (regno
)
1350 UDIBool HostEndian
= 0;
1354 if (regno
== GR1_REGNUM
)
1356 From
.Space
= UDI29KGlobalRegs
;
1359 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1361 From
.Space
= UDI29KGlobalRegs
;
1362 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1365 #if defined(GR64_REGNUM)
1367 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1369 From
.Space
= UDI29KGlobalRegs
;
1370 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1373 #endif /* GR64_REGNUM */
1375 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1377 From
.Space
= UDI29KLocalRegs
;
1378 From
.Offset
= (regno
- LR0_REGNUM
);
1380 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1383 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1384 return; /* Pretend Success */
1388 From
.Space
= UDI29KSpecialRegs
;
1389 From
.Offset
= regnum_to_srnum(regno
);
1392 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1393 error("UDIRead() failed in udi_fetch_registers");
1395 supply_register(regno
, (char *) &To
);
1398 printf_unfiltered("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1400 /*****************************************************************************/
1401 /* Store a single register indicated by 'regno'.
1402 * Returns 0/-1 on success/failure.
1405 store_register (regno
)
1414 UDIBool HostEndian
= 0;
1416 From
= read_register (regno
); /* get data value */
1419 printf_unfiltered("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1421 if (regno
== GR1_REGNUM
)
1423 To
.Space
= UDI29KGlobalRegs
;
1425 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1426 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1427 * register cache. Do this *after* calling read_register, because we want
1428 * read_register to return the value that write_register has just stuffed
1429 * into the registers array, not the value of the register fetched from
1432 registers_changed ();
1434 #if defined(GR64_REGNUM)
1435 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1437 To
.Space
= UDI29KGlobalRegs
;
1438 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1439 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1441 #endif /* GR64_REGNUM */
1442 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1444 To
.Space
= UDI29KGlobalRegs
;
1445 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1446 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1448 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1450 To
.Space
= UDI29KLocalRegs
;
1451 To
.Offset
= (regno
- LR0_REGNUM
);
1452 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1454 else if (regno
>= FPE_REGNUM
&& regno
<= EXO_REGNUM
)
1455 return 0; /* Pretend Success */
1456 else if (regno
== PC_REGNUM
)
1458 /* PC1 via UDI29KPC */
1460 To
.Space
= UDI29KPC
;
1461 To
.Offset
= 0; /* PC1 */
1462 result
= UDIWrite (&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1464 /* Writing to this loc actually changes the values of pc0 & pc1 */
1466 register_valid
[PC_REGNUM
] = 0; /* pc1 */
1467 register_valid
[NPC_REGNUM
] = 0; /* pc0 */
1469 else /* An unprotected or protected special register */
1471 To
.Space
= UDI29KSpecialRegs
;
1472 To
.Offset
= regnum_to_srnum(regno
);
1473 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1477 error("UDIWrite() failed in store_registers");
1481 /********************************************************** REGNUM_TO_SRNUM */
1483 * Convert a gdb special register number to a 29000 special register number.
1486 regnum_to_srnum(regno
)
1490 case VAB_REGNUM
: return(0);
1491 case OPS_REGNUM
: return(1);
1492 case CPS_REGNUM
: return(2);
1493 case CFG_REGNUM
: return(3);
1494 case CHA_REGNUM
: return(4);
1495 case CHD_REGNUM
: return(5);
1496 case CHC_REGNUM
: return(6);
1497 case RBP_REGNUM
: return(7);
1498 case TMC_REGNUM
: return(8);
1499 case TMR_REGNUM
: return(9);
1500 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1501 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1502 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1503 case MMU_REGNUM
: return(13);
1504 case LRU_REGNUM
: return(14);
1505 case IPC_REGNUM
: return(128);
1506 case IPA_REGNUM
: return(129);
1507 case IPB_REGNUM
: return(130);
1508 case Q_REGNUM
: return(131);
1509 case ALU_REGNUM
: return(132);
1510 case BP_REGNUM
: return(133);
1511 case FC_REGNUM
: return(134);
1512 case CR_REGNUM
: return(135);
1513 case FPE_REGNUM
: return(160);
1514 case INTE_REGNUM
: return(161);
1515 case FPS_REGNUM
: return(162);
1516 case EXO_REGNUM
:return(164);
1518 return(255); /* Failure ? */
1521 /****************************************************************************/
1523 * Determine the Target memory space qualifier based on the addr.
1524 * FIXME: Can't distinguis I_ROM/D_ROM.
1525 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1528 udi_memory_space(addr
)
1531 UDIUInt32 tstart
= IMemStart
;
1532 UDIUInt32 tend
= tstart
+ IMemSize
;
1533 UDIUInt32 dstart
= DMemStart
;
1534 UDIUInt32 dend
= tstart
+ DMemSize
;
1535 UDIUInt32 rstart
= RMemStart
;
1536 UDIUInt32 rend
= tstart
+ RMemSize
;
1538 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1539 return UDI29KIRAMSpace
;
1540 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1541 return UDI29KDRAMSpace
;
1542 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1543 /* FIXME: how do we determine between D_ROM and I_ROM */
1544 return UDI29KIROMSpace
;
1545 } else /* FIXME: what do me do now? */
1546 return UDI29KDRAMSpace
; /* Hmmm! */
1548 /*********************************************************************** STUBS
1551 void convert16() {;}
1552 void convert32() {;}
1553 GDB_FILE
* EchoFile
= 0; /* used for debugging */
1554 int QuietMode
= 0; /* used for debugging */
1556 #ifdef NO_HIF_SUPPORT
1560 return(0); /* Emulate a failure */
1564 /* Target_ops vector. Not static because there does not seem to be
1565 any portable way to do a forward declaration of a static variable.
1566 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1567 /bin/cc doesn't like "static" twice. */
1569 struct target_ops udi_ops
= {
1571 "Remote UDI connected TIP",
1572 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1574 `configuration-id AF_INET hostname port-number'\n\
1575 To connect via the network, where hostname and port-number specify the\n\
1576 host and port where you can connect via UDI.\n\
1577 configuration-id is unused.\n\
1579 `configuration-id AF_UNIX socket-name tip-program'\n\
1580 To connect using a local connection to the \"tip.exe\" program which is\n\
1581 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1582 tip program must already be started; connect to it using that socket.\n\
1583 If not, start up tip-program, which should be the name of the tip\n\
1584 program. If appropriate, the PATH environment variable is searched.\n\
1585 configuration-id is unused.\n\
1587 `configuration-id'\n\
1588 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1589 are files containing lines in the above formats. configuration-id is\n\
1590 used to pick which line of the file to use.",
1597 udi_fetch_registers
,
1598 udi_store_registers
,
1599 udi_prepare_to_store
,
1600 udi_xfer_inferior_memory
,
1602 udi_insert_breakpoint
,
1603 udi_remove_breakpoint
,
1604 0, /* termial_init */
1605 0, /* terminal_inferior */
1606 0, /* terminal_ours_for_output */
1607 0, /* terminal_ours */
1608 0, /* terminal_info */
1609 udi_kill
, /* FIXME, kill */
1611 0, /* lookup_symbol */
1612 udi_create_inferior
,
1613 udi_mourn
, /* mourn_inferior FIXME */
1615 0, /* notice_signals */
1618 1, /* has_all_memory */
1621 1, /* has_registers */
1622 1, /* has_execution */
1624 0, /* sections_end */
1625 OPS_MAGIC
, /* Always the last thing */
1629 _initialize_remote_udi ()
1631 add_target (&udi_ops
);