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
, enum target_signal 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;
87 static char *udi_config_id
;
89 CPUOffset IMemStart
= 0;
90 CPUSizeT IMemSize
= 0;
91 CPUOffset DMemStart
= 0;
92 CPUSizeT DMemSize
= 0;
93 CPUOffset RMemStart
= 0;
94 CPUSizeT RMemSize
= 0;
98 UDIMemoryRange address_ranges
[2]; /* Text and data */
99 UDIResource entry
= {0, 0}; /* Entry point */
100 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
102 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
105 typedef struct bkpt_entry_str
110 unsigned int BreakId
;
112 #define BKPT_TABLE_SIZE 40
113 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
114 extern char dfe_errmsg
[]; /* error string */
116 /* malloc'd name of the program on the remote system. */
117 static char *prog_name
= NULL
;
119 /* This is called not only when we first attach, but also when the
120 user types "run" after having attached. */
123 udi_create_inferior (execfile
, args
, env
)
132 if (prog_name
!= NULL
)
134 prog_name
= savestring (execfile
, strlen (execfile
));
136 else if (entry
.Offset
)
139 error ("No image loaded into target.");
141 if (udi_session_id
< 0)
143 /* If the TIP is not open, open it. */
144 if (UDIConnect (udi_config_id
, &udi_session_id
))
145 error("UDIConnect() failed: %s\n", dfe_errmsg
);
148 inferior_pid
= 40000;
151 download(execfile
, 0);
153 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
155 if (execfile
[0] == '\0')
157 /* It is empty. We need to quote it somehow, or else the target
158 will think there is no argument being passed here. According
159 to the UDI spec it is quoted "according to TIP OS rules" which
160 I guess means quoting it like the Unix shell should work
161 (sounds pretty bogus to me...). In fact it doesn't work (with
162 isstip anyway), but passing in two quotes as the argument seems
163 like a reasonable enough behavior anyway (I guess). */
165 strcpy (args1
, "''");
167 strcpy (args1
, execfile
);
169 strcat (args1
, args
);
171 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
172 (UDIInt
)2, /* NumberOfRanges */
173 entry
, /* EntryPoint */
174 stack_sizes
, /* *StackSizes */
175 (UDIInt
)2, /* NumberOfStacks */
176 args1
); /* ArgString */
178 init_wait_for_inferior ();
179 clear_proceed_status ();
180 proceed (-1, TARGET_SIGNAL_DEFAULT
, 0);
187 /* Requiring "target udi" each time you run is a major pain. I suspect
188 this was just blindy copied from remote.c, in which "target" and
189 "run" are combined. Having a udi target without an inferior seems
190 to work between "target udi" and "run", so why not now? */
191 pop_target (); /* Pop back to no-child state */
193 /* But if we're going to want to run it again, we better remove the
195 remove_breakpoints ();
196 generic_mourn_inferior ();
199 /******************************************************************** UDI_OPEN
200 ** Open a connection to remote TIP.
201 NAME is the socket domain used for communication with the TIP,
202 then a space and the socket name or TIP-host name.
203 '<udi_udi_config_id>' for example.
206 /* XXX - need cleanups for udiconnect for various failures!!! */
209 udi_open (name
, from_tty
)
216 UDIMemoryRange KnownMemory
[10];
217 UDIUInt32 ChipVersions
[10];
218 UDIInt NumberOfRanges
= 10;
219 UDIInt NumberOfChips
= 10;
221 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
223 target_preopen(from_tty
);
227 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
228 bkpt_table
[cnt
].Type
= 0;
231 free (udi_config_id
);
234 error("Usage: target udi config_id, where config_id appears in udi_soc file");
236 udi_config_id
= strdup (strtok (name
, " \t"));
238 if (UDIConnect (udi_config_id
, &udi_session_id
))
239 /* FIXME: Should set udi_session_id to -1 here. */
240 error("UDIConnect() failed: %s\n", dfe_errmsg
);
242 push_target (&udi_ops
);
245 ** Initialize target configuration structure (global)
247 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
248 ChipVersions
, &NumberOfChips
))
249 error ("UDIGetTargetConfig() failed");
250 if (NumberOfChips
> 2)
251 fprintf_unfiltered(gdb_stderr
,"Target has more than one processor\n");
252 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
254 switch(KnownMemory
[cnt
].Space
)
257 fprintf_unfiltered(gdb_stderr
, "UDIGetTargetConfig() unknown memory space\n");
261 case UDI29KIROMSpace
:
262 RMemStart
= KnownMemory
[cnt
].Offset
;
263 RMemSize
= KnownMemory
[cnt
].Size
;
265 case UDI29KIRAMSpace
:
266 IMemStart
= KnownMemory
[cnt
].Offset
;
267 IMemSize
= KnownMemory
[cnt
].Size
;
269 case UDI29KDRAMSpace
:
270 DMemStart
= KnownMemory
[cnt
].Offset
;
271 DMemSize
= KnownMemory
[cnt
].Size
;
276 a29k_get_processor_type ();
278 if (UDICreateProcess (&PId
))
279 fprintf_unfiltered(gdb_stderr
, "UDICreateProcess() failed\n");
281 /* Print out some stuff, letting the user now what's going on */
282 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
284 error ("UDICapabilities() failed");
287 printf_filtered ("Connected via UDI socket,\n\
288 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
289 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
290 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
291 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
296 /******************************************************************* UDI_CLOSE
297 Close the open connection to the TIP process.
298 Use this when you want to detach and do something else
301 udi_close (quitting
) /*FIXME: how is quitting used */
304 if (udi_session_id
< 0)
307 /* We should never get here if there isn't something valid in
310 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
313 warning ("UDIDisconnect() failed in udi_close");
315 error ("UDIDisconnect() failed in udi_close");
318 /* Do not try to close udi_session_id again, later in the program. */
322 printf_filtered (" Ending remote debugging\n");
325 /**************************************************************** UDI_ATACH */
326 /* Attach to a program that is already loaded and running
327 * Upon exiting the process's execution is stopped.
330 udi_attach (args
, from_tty
)
339 UDIBool HostEndian
= 0;
343 error_no_arg ("program to attach");
345 if (udi_session_id
< 0)
346 error ("UDI connection not opened yet, use the 'target udi' command.\n");
349 printf_unfiltered ("Attaching to remote program %s...\n", prog_name
);
352 From
.Space
= UDI29KSpecialRegs
;
354 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
355 error ("UDIRead failed in udi_attach");
356 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
358 /************************************************************* UDI_DETACH */
359 /* Terminate the open connection to the TIP process.
360 Use this when you want to detach and do something else
361 with your gdb. Leave remote process running (with no breakpoints set). */
363 udi_detach (args
,from_tty
)
368 remove_breakpoints(); /* Just in case there were any left in */
370 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
371 error ("UDIDisconnect() failed in udi_detach");
373 /* Don't try to UDIDisconnect it again in udi_close, which is called from
381 printf_unfiltered ("Detaching from TIP\n");
385 /****************************************************************** UDI_RESUME
386 ** Tell the remote machine to resume. */
389 udi_resume (pid
, step
, sig
)
391 enum target_signal sig
;
395 UDIStepType StepType
= UDIStepNatural
;
398 if (step
) /* step 1 instruction */
400 tip_error
= UDIStep (Steps
, StepType
, Range
);
404 fprintf_unfiltered (gdb_stderr
, "UDIStep() error = %d\n", tip_error
);
405 error ("failed in udi_resume");
409 error ("UDIExecute() failed in udi_resume");
412 /******************************************************************** UDI_WAIT
413 ** Wait until the remote machine stops, then return,
414 storing status in STATUS just as `wait' would. */
417 udi_wait (pid
, status
)
419 struct target_waitstatus
*status
;
425 int old_timeout
= timeout
;
426 int old_immediate_quit
= immediate_quit
;
429 status
->kind
= TARGET_WAITKIND_EXITED
;
430 status
->value
.integer
= 0;
432 /* wait for message to arrive. It should be:
433 If the target stops executing, udi_wait() should return.
435 timeout
= 0; /* Wait indefinetly for a message */
436 immediate_quit
= 1; /* Helps ability to QUIT */
441 MaxTime
= UDIWaitForever
;
442 UDIWait(MaxTime
, &PId
, &StopReason
);
443 QUIT
; /* Let user quit if they want */
445 switch (StopReason
& UDIGrossState
)
448 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
449 /* This is said to happen if the program tries to output
450 a whole bunch of output (more than SBUF_MAX, I would
451 guess). It doesn't seem to happen with the simulator. */
452 warning ("UDIGetStdout() failed in udi_wait");
453 fwrite (sbuf
, 1, CountDone
, gdb_stdout
);
454 gdb_flush(gdb_stdout
);
458 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
459 fwrite (sbuf
, 1, CountDone
, gdb_stderr
);
460 gdb_flush(gdb_stderr
);
473 } while (i
< SBUF_MAX
&& ch
!= '\n');
474 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
479 /* In spite of the fact that we told UDIWait to wait forever, it will
480 return spuriously sometimes. */
489 switch (StopReason
& UDIGrossState
)
492 printf_unfiltered("Am290*0 received vector number %d\n", StopReason
>> 24);
494 switch (StopReason
>> 8)
496 case 0: /* Illegal opcode */
497 printf_unfiltered(" (break point)\n");
498 status
->kind
= TARGET_WAITKIND_STOPPED
;
499 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
501 case 1: /* Unaligned Access */
502 status
->kind
= TARGET_WAITKIND_STOPPED
;
503 status
->value
.sig
= TARGET_SIGNAL_BUS
;
507 status
->kind
= TARGET_WAITKIND_STOPPED
;
508 status
->value
.sig
= TARGET_SIGNAL_FPE
;
510 case 5: /* Protection Violation */
511 status
->kind
= TARGET_WAITKIND_STOPPED
;
512 /* Why not SEGV? What is a Protection Violation? */
513 status
->value
.sig
= TARGET_SIGNAL_ILL
;
517 case 8: /* User Instruction Mapping Miss */
518 case 9: /* User Data Mapping Miss */
519 case 10: /* Supervisor Instruction Mapping Miss */
520 case 11: /* Supervisor Data Mapping Miss */
521 status
->kind
= TARGET_WAITKIND_STOPPED
;
522 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
526 status
->kind
= TARGET_WAITKIND_STOPPED
;
527 status
->value
.sig
= TARGET_SIGNAL_ILL
;
530 status
->kind
= TARGET_WAITKIND_STOPPED
;
531 status
->value
.sig
= TARGET_SIGNAL_ALRM
;
534 status
->kind
= TARGET_WAITKIND_STOPPED
;
535 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
540 case 19: /* INTR3/Internal */
543 status
->kind
= TARGET_WAITKIND_STOPPED
;
544 status
->value
.sig
= TARGET_SIGNAL_INT
;
546 case 22: /* Floating-Point Exception */
547 status
->kind
= TARGET_WAITKIND_STOPPED
;
549 status
->value
.sig
= TARGET_SIGNAL_ILL
;
551 case 77: /* assert 77 */
552 status
->kind
= TARGET_WAITKIND_STOPPED
;
553 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
556 status
->kind
= TARGET_WAITKIND_EXITED
;
557 status
->value
.integer
= 0;
560 case UDINotExecuting
:
561 status
->kind
= TARGET_WAITKIND_STOPPED
;
562 status
->value
.sig
= TARGET_SIGNAL_TERM
;
565 status
->kind
= TARGET_WAITKIND_STOPPED
;
566 status
->value
.sig
= TARGET_SIGNAL_TSTP
;
569 status
->kind
= TARGET_WAITKIND_STOPPED
;
570 status
->value
.sig
= TARGET_SIGNAL_URG
;
574 status
->kind
= TARGET_WAITKIND_STOPPED
;
575 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
578 status
->kind
= TARGET_WAITKIND_STOPPED
;
579 status
->value
.sig
= TARGET_SIGNAL_STOP
;
582 status
->kind
= TARGET_WAITKIND_STOPPED
;
583 status
->value
.sig
= TARGET_SIGNAL_KILL
;
587 status
->kind
= TARGET_WAITKIND_EXITED
;
588 status
->value
.integer
= 0;
591 timeout
= old_timeout
; /* Restore original timeout value */
592 immediate_quit
= old_immediate_quit
;
597 /* Handy for debugging */
605 UDIBool HostEndian
= 0;
608 unsigned long myregs
[256];
611 From
.Space
= UDI29KPC
;
613 To
= (UDIUInt32
*)pc
;
616 err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
);
618 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
619 err
, CountDone
, pc
[0], pc
[1]);
621 udi_fetch_registers(-1);
623 printf_unfiltered("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *)®isters
[4 * PC_REGNUM
],
624 *(int *)®isters
[4 * NPC_REGNUM
]);
626 /* Now, read all the registers globally */
628 From
.Space
= UDI29KGlobalRegs
;
630 err
= UDIRead(From
, myregs
, 256, 4, &CountDone
, HostEndian
);
632 printf ("err = %d, CountDone = %d\n", err
, CountDone
);
636 for (i
= 0; i
< 256; i
+= 2)
637 printf("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i
, myregs
[i
], myregs
[i
],
638 myregs
[i
+1], myregs
[i
+1]);
645 /********************************************************** UDI_FETCH_REGISTERS
646 * Read a remote register 'regno'.
647 * If regno==-1 then read all the registers.
650 udi_fetch_registers (regno
)
658 UDIBool HostEndian
= 0;
663 fetch_register(regno
);
669 From
.Space
= UDI29KGlobalRegs
;
671 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
673 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
674 error("UDIRead() failed in udi_fetch_registers");
676 register_valid
[GR1_REGNUM
] = 1;
678 #if defined(GR64_REGNUM) /* Read gr64-127 */
680 /* Global Registers gr64-gr95 */
682 From
.Space
= UDI29KGlobalRegs
;
684 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
686 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
687 error("UDIRead() failed in udi_fetch_registers");
689 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
690 register_valid
[i
] = 1;
692 #endif /* GR64_REGNUM */
694 /* Global Registers gr96-gr127 */
696 From
.Space
= UDI29KGlobalRegs
;
698 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
700 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
701 error("UDIRead() failed in udi_fetch_registers");
703 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
704 register_valid
[i
] = 1;
706 /* Local Registers */
708 From
.Space
= UDI29KLocalRegs
;
710 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
712 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
713 error("UDIRead() failed in udi_fetch_registers");
715 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
716 register_valid
[i
] = 1;
718 /* Protected Special Registers */
720 From
.Space
= UDI29KSpecialRegs
;
722 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
724 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
725 error("UDIRead() failed in udi_fetch_registers");
727 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
728 register_valid
[i
] = 1;
730 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
731 fetch_register(NPC_REGNUM
);
732 fetch_register(PC_REGNUM
);
733 fetch_register(PC2_REGNUM
);
735 /* Unprotected Special Registers sr128-sr135 */
737 From
.Space
= UDI29KSpecialRegs
;
739 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
741 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
742 error("UDIRead() failed in udi_fetch_registers");
744 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
745 register_valid
[i
] = 1;
750 printf_unfiltered("Fetching all registers\n");
751 printf_unfiltered("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
752 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
753 read_register(PC2_REGNUM
));
756 /* There doesn't seem to be any way to get these. */
759 supply_register (FPE_REGNUM
, (char *) &val
);
760 supply_register (INTE_REGNUM
, (char *) &val
);
761 supply_register (FPS_REGNUM
, (char *) &val
);
762 supply_register (EXO_REGNUM
, (char *) &val
);
767 /********************************************************* UDI_STORE_REGISTERS
768 ** Store register regno into the target.
769 * If regno==-1 then store all the registers.
773 udi_store_registers (regno
)
781 UDIBool HostEndian
= 0;
785 store_register(regno
);
791 printf_unfiltered("Storing all registers\n");
792 printf_unfiltered("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
793 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
798 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
799 To
.Space
= UDI29KGlobalRegs
;
802 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
803 error("UDIWrite() failed in udi_store_regisetrs");
805 #if defined(GR64_REGNUM)
807 /* Global registers gr64-gr95 */
809 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
810 To
.Space
= UDI29KGlobalRegs
;
813 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
814 error("UDIWrite() failed in udi_store_regisetrs");
816 #endif /* GR64_REGNUM */
818 /* Global registers gr96-gr127 */
820 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
821 To
.Space
= UDI29KGlobalRegs
;
824 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
825 error("UDIWrite() failed in udi_store_regisetrs");
827 /* Local Registers */
829 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
830 To
.Space
= UDI29KLocalRegs
;
833 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
834 error("UDIWrite() failed in udi_store_regisetrs");
837 /* Protected Special Registers */ /* VAB through TMR */
839 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
840 To
.Space
= UDI29KSpecialRegs
;
843 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
844 error("UDIWrite() failed in udi_store_regisetrs");
846 /* PC0, PC1, PC2 possibly as shadow registers */
848 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
849 To
.Space
= UDI29KSpecialRegs
;
852 To
.Offset
= 20; /* SPC0 */
854 To
.Offset
= 10; /* PC0 */
855 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
856 error("UDIWrite() failed in udi_store_regisetrs");
858 /* PC1 via UDI29KPC */
860 From
= (UDIUInt32
*)®isters
[4 * PC_REGNUM
];
862 To
.Offset
= 0; /* PC1 */
864 if (UDIWrite (From
, To
, Count
, Size
, &CountDone
, HostEndian
))
865 error ("UDIWrite() failed in udi_store_regisetrs");
869 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
870 To
.Space
= UDI29KSpecialRegs
;
873 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
874 error("UDIWrite() failed in udi_store_regisetrs");
876 /* Unprotected Special Registers */
878 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
879 To
.Space
= UDI29KSpecialRegs
;
882 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
883 error("UDIWrite() failed in udi_store_regisetrs");
885 registers_changed ();
888 /****************************************************** UDI_PREPARE_TO_STORE */
889 /* Get ready to modify the registers array. On machines which store
890 individual registers, this doesn't need to do anything. On machines
891 which store all the registers in one fell swoop, this makes sure
892 that registers contains all the registers from the program being
896 udi_prepare_to_store ()
898 /* Do nothing, since we can store individual regs */
901 /********************************************************** TRANSLATE_ADDR */
906 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
907 /* Check for a virtual address in the kernel */
908 /* Assume physical address of ublock is in paddr_u register */
909 /* FIXME: doesn't work for user virtual addresses */
910 if (addr
>= UVADDR
) {
911 /* PADDR_U register holds the physical address of the ublock */
912 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
913 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
921 /************************************************* UDI_XFER_INFERIOR_MEMORY */
922 /* FIXME! Merge these two. */
924 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
931 memaddr
= translate_addr(memaddr
);
934 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
936 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
939 /********************************************************** UDI_FILES_INFO */
943 printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id
);
944 if (prog_name
!= NULL
)
945 printf_unfiltered ("and running program %s", prog_name
);
946 printf_unfiltered (".\n");
949 /**************************************************** UDI_INSERT_BREAKPOINT */
951 udi_insert_breakpoint (addr
, contents_cache
)
953 char *contents_cache
;
958 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
959 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
962 if(cnt
>= BKPT_TABLE_SIZE
)
963 error("Too many breakpoints set");
965 bkpt_table
[cnt
].Addr
.Offset
= addr
;
966 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
967 bkpt_table
[cnt
].PassCount
= 1;
968 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
970 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
971 bkpt_table
[cnt
].PassCount
,
972 bkpt_table
[cnt
].Type
,
973 &bkpt_table
[cnt
].BreakId
);
975 if (err
== 0) return 0; /* Success */
977 bkpt_table
[cnt
].Type
= 0;
978 error("UDISetBreakpoint returned error code %d\n", err
);
981 /**************************************************** UDI_REMOVE_BREAKPOINT */
983 udi_remove_breakpoint (addr
, contents_cache
)
985 char *contents_cache
;
990 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
991 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
994 if(cnt
>= BKPT_TABLE_SIZE
)
995 error("Can't find breakpoint in table");
997 bkpt_table
[cnt
].Type
= 0;
999 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
1000 if (err
== 0) return 0; /* Success */
1002 error("UDIClearBreakpoint returned error code %d\n", err
);
1006 udi_kill(arg
,from_tty
)
1013 UDIStop does not really work as advertised. It causes the TIP to close it's
1014 connection, which usually results in GDB dying with a SIGPIPE. For now, we
1015 just invoke udi_close, which seems to get things right.
1019 udi_session_id
= -1;
1023 printf_unfiltered("Target has been stopped.");
1030 /* Keep the target around, e.g. so "run" can do the right thing when
1031 we are already debugging something. */
1033 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
1035 warning ("UDIDisconnect() failed");
1038 /* Do not try to close udi_session_id again, later in the program. */
1039 udi_session_id
= -1;
1044 Load a program into the target. Args are: `program {options}'. The options
1045 are used to control loading of the program, and are NOT passed onto the
1046 loaded code as arguments. (You need to use the `run' command to do that.)
1049 -ms %d Set mem stack size to %d
1050 -rs %d Set regular stack size to %d
1051 -i send init info (default)
1052 -noi don't send init info
1053 -[tT] Load Text section
1054 -[dD] Load Data section
1055 -[bB] Load BSS section
1056 -[lL] Load Lit section
1060 download(load_arg_string
, from_tty
)
1061 char *load_arg_string
;
1064 #define DEFAULT_MEM_STACK_SIZE 0x6000
1065 #define DEFAULT_REG_STACK_SIZE 0x2000
1072 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1074 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1075 address_ranges
[0].Offset
= 0xffffffff;
1076 address_ranges
[0].Size
= 0;
1078 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1079 address_ranges
[1].Offset
= 0xffffffff;
1080 address_ranges
[1].Size
= 0;
1082 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1083 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1087 filename
= strtok(load_arg_string
, " \t");
1089 error ("Must specify at least a file name with the load command");
1091 filename
= tilde_expand (filename
);
1092 make_cleanup (free
, filename
);
1094 while (token
= strtok (NULL
, " \t"))
1096 if (token
[0] == '-')
1100 if (STREQ (token
, "ms"))
1101 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1102 else if (STREQ (token
, "rs"))
1103 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1106 load_text
= load_data
= load_bss
= load_lit
= 0;
1129 error ("Unknown UDI load option -%s", token
-1);
1136 pbfd
= bfd_openr (filename
, gnutarget
);
1139 perror_with_name (filename
);
1141 make_cleanup (bfd_close
, pbfd
);
1146 if (!bfd_check_format (pbfd
, bfd_object
))
1147 error ("It doesn't seem to be an object file");
1149 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1151 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1155 unsigned long section_size
, section_end
;
1156 const char *section_name
;
1158 section_name
= bfd_get_section_name (pbfd
, section
);
1159 if (STREQ (section_name
, ".text") && !load_text
)
1161 else if (STREQ (section_name
, ".data") && !load_data
)
1163 else if (STREQ (section_name
, ".bss") && !load_bss
)
1165 else if (STREQ (section_name
, ".lit") && !load_lit
)
1168 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1169 section_size
= bfd_section_size (pbfd
, section
);
1170 section_end
= To
.Offset
+ section_size
;
1172 if (section_size
== 0)
1173 /* This is needed at least in the BSS case, where the code
1174 below starts writing before it even checks the size. */
1177 printf_unfiltered("[Loading section %s at %x (%d bytes)]\n",
1182 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1184 To
.Space
= UDI29KIRAMSpace
;
1186 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1188 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1190 - address_ranges
[0].Offset
);
1194 To
.Space
= UDI29KDRAMSpace
;
1196 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1198 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1200 - address_ranges
[1].Offset
);
1203 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1209 while (section_size
> 0)
1213 Count
= min (section_size
, 1024);
1215 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1218 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1221 (UDISizeT
)1, /* Size */
1222 &Count
, /* CountDone */
1223 (UDIBool
)0); /* HostEndian */
1225 error ("UDIWrite failed, error = %d", err
);
1229 section_size
-= Count
;
1235 unsigned long zero
= 0;
1237 /* Write a zero byte at the vma */
1238 /* FIXME: Broken for sections of 1-3 bytes (we test for
1240 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1242 (UDICount
)1, /* Count */
1243 (UDISizeT
)4, /* Size */
1244 &Count
, /* CountDone */
1245 (UDIBool
)0); /* HostEndian */
1247 error ("UDIWrite failed, error = %d", err
);
1252 /* Now, duplicate it for the length of the BSS */
1253 err
= UDICopy (From
, /* From */
1255 (UDICount
)(section_size
/4 - 1), /* Count */
1256 (UDISizeT
)4, /* Size */
1257 &Count
, /* CountDone */
1258 (UDIBool
)1); /* Direction */
1264 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1266 fprintf_unfiltered (gdb_stderr
, "Error is %s\n", message
);
1268 fprintf_unfiltered (gdb_stderr
, "xerr is %d\n", xerr
);
1269 error ("UDICopy failed, error = %d", err
);
1276 entry
.Space
= UDI29KIRAMSpace
;
1277 entry
.Offset
= bfd_get_start_address (pbfd
);
1282 /* User interface to download an image into the remote target. See download()
1283 * for details on args.
1287 udi_load(args
, from_tty
)
1291 download (args
, from_tty
);
1293 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1296 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1297 ** Copy LEN bytes of data from debugger memory at MYADDR
1298 to inferior's memory at MEMADDR. Returns number of bytes written. */
1300 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1310 UDICount CountDone
= 0;
1311 UDIBool HostEndian
= 0;
1313 To
.Space
= udi_memory_space(memaddr
);
1314 From
= (UDIUInt32
*)myaddr
;
1316 while (nwritten
< len
)
1317 { Count
= len
- nwritten
;
1318 if (Count
> MAXDATA
) Count
= MAXDATA
;
1319 To
.Offset
= memaddr
+ nwritten
;
1320 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1321 { error("UDIWrite() failed in udi_write_inferrior_memory");
1325 { nwritten
+= CountDone
;
1332 /**************************************************** UDI_READ_INFERIOR_MEMORY
1333 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1334 at debugger address MYADDR. Returns number of bytes read. */
1336 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1346 UDICount CountDone
= 0;
1347 UDIBool HostEndian
= 0;
1350 From
.Space
= udi_memory_space(memaddr
);
1351 To
= (UDIUInt32
*)myaddr
;
1354 { Count
= len
- nread
;
1355 if (Count
> MAXDATA
) Count
= MAXDATA
;
1356 From
.Offset
= memaddr
+ nread
;
1357 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1358 { error("UDIRead() failed in udi_read_inferrior_memory");
1362 { nread
+= CountDone
;
1369 /********************************************************************* WARNING
1374 error ("ERROR while loading program into remote TIP: $d\n", num
);
1378 /*****************************************************************************/
1379 /* Fetch a single register indicatated by 'regno'.
1380 * Returns 0/-1 on success/failure.
1383 fetch_register (regno
)
1391 UDIBool HostEndian
= 0;
1395 if (regno
== GR1_REGNUM
)
1397 From
.Space
= UDI29KGlobalRegs
;
1400 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1402 From
.Space
= UDI29KGlobalRegs
;
1403 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1406 #if defined(GR64_REGNUM)
1408 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1410 From
.Space
= UDI29KGlobalRegs
;
1411 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1414 #endif /* GR64_REGNUM */
1416 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1418 From
.Space
= UDI29KLocalRegs
;
1419 From
.Offset
= (regno
- LR0_REGNUM
);
1421 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1424 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1425 return; /* Pretend Success */
1429 From
.Space
= UDI29KSpecialRegs
;
1430 From
.Offset
= regnum_to_srnum(regno
);
1433 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1434 error("UDIRead() failed in udi_fetch_registers");
1436 supply_register(regno
, (char *) &To
);
1439 printf_unfiltered("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1441 /*****************************************************************************/
1442 /* Store a single register indicated by 'regno'.
1443 * Returns 0/-1 on success/failure.
1446 store_register (regno
)
1455 UDIBool HostEndian
= 0;
1457 From
= read_register (regno
); /* get data value */
1460 printf_unfiltered("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1462 if (regno
== GR1_REGNUM
)
1464 To
.Space
= UDI29KGlobalRegs
;
1466 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1467 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1468 * register cache. Do this *after* calling read_register, because we want
1469 * read_register to return the value that write_register has just stuffed
1470 * into the registers array, not the value of the register fetched from
1473 registers_changed ();
1475 #if defined(GR64_REGNUM)
1476 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1478 To
.Space
= UDI29KGlobalRegs
;
1479 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1480 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1482 #endif /* GR64_REGNUM */
1483 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1485 To
.Space
= UDI29KGlobalRegs
;
1486 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1487 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1489 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1491 To
.Space
= UDI29KLocalRegs
;
1492 To
.Offset
= (regno
- LR0_REGNUM
);
1493 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1495 else if (regno
>= FPE_REGNUM
&& regno
<= EXO_REGNUM
)
1496 return 0; /* Pretend Success */
1497 else if (regno
== PC_REGNUM
)
1499 /* PC1 via UDI29KPC */
1501 To
.Space
= UDI29KPC
;
1502 To
.Offset
= 0; /* PC1 */
1503 result
= UDIWrite (&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1505 /* Writing to this loc actually changes the values of pc0 & pc1 */
1507 register_valid
[PC_REGNUM
] = 0; /* pc1 */
1508 register_valid
[NPC_REGNUM
] = 0; /* pc0 */
1510 else /* An unprotected or protected special register */
1512 To
.Space
= UDI29KSpecialRegs
;
1513 To
.Offset
= regnum_to_srnum(regno
);
1514 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1518 error("UDIWrite() failed in store_registers");
1522 /********************************************************** REGNUM_TO_SRNUM */
1524 * Convert a gdb special register number to a 29000 special register number.
1527 regnum_to_srnum(regno
)
1531 case VAB_REGNUM
: return(0);
1532 case OPS_REGNUM
: return(1);
1533 case CPS_REGNUM
: return(2);
1534 case CFG_REGNUM
: return(3);
1535 case CHA_REGNUM
: return(4);
1536 case CHD_REGNUM
: return(5);
1537 case CHC_REGNUM
: return(6);
1538 case RBP_REGNUM
: return(7);
1539 case TMC_REGNUM
: return(8);
1540 case TMR_REGNUM
: return(9);
1541 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1542 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1543 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1544 case MMU_REGNUM
: return(13);
1545 case LRU_REGNUM
: return(14);
1546 case IPC_REGNUM
: return(128);
1547 case IPA_REGNUM
: return(129);
1548 case IPB_REGNUM
: return(130);
1549 case Q_REGNUM
: return(131);
1550 case ALU_REGNUM
: return(132);
1551 case BP_REGNUM
: return(133);
1552 case FC_REGNUM
: return(134);
1553 case CR_REGNUM
: return(135);
1554 case FPE_REGNUM
: return(160);
1555 case INTE_REGNUM
: return(161);
1556 case FPS_REGNUM
: return(162);
1557 case EXO_REGNUM
:return(164);
1559 return(255); /* Failure ? */
1562 /****************************************************************************/
1564 * Determine the Target memory space qualifier based on the addr.
1565 * FIXME: Can't distinguis I_ROM/D_ROM.
1566 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1569 udi_memory_space(addr
)
1572 UDIUInt32 tstart
= IMemStart
;
1573 UDIUInt32 tend
= tstart
+ IMemSize
;
1574 UDIUInt32 dstart
= DMemStart
;
1575 UDIUInt32 dend
= tstart
+ DMemSize
;
1576 UDIUInt32 rstart
= RMemStart
;
1577 UDIUInt32 rend
= tstart
+ RMemSize
;
1579 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1580 return UDI29KIRAMSpace
;
1581 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1582 return UDI29KDRAMSpace
;
1583 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1584 /* FIXME: how do we determine between D_ROM and I_ROM */
1585 return UDI29KIROMSpace
;
1586 } else /* FIXME: what do me do now? */
1587 return UDI29KDRAMSpace
; /* Hmmm! */
1589 /*********************************************************************** STUBS
1592 void convert16() {;}
1593 void convert32() {;}
1594 GDB_FILE
* EchoFile
= 0; /* used for debugging */
1595 int QuietMode
= 0; /* used for debugging */
1597 #ifdef NO_HIF_SUPPORT
1601 return(0); /* Emulate a failure */
1605 /* Target_ops vector. Not static because there does not seem to be
1606 any portable way to do a forward declaration of a static variable.
1607 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1608 /bin/cc doesn't like "static" twice. */
1610 struct target_ops udi_ops
= {
1612 "Remote UDI connected TIP",
1613 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1615 `configuration-id AF_INET hostname port-number'\n\
1616 To connect via the network, where hostname and port-number specify the\n\
1617 host and port where you can connect via UDI.\n\
1618 configuration-id is unused.\n\
1620 `configuration-id AF_UNIX socket-name tip-program'\n\
1621 To connect using a local connection to the \"tip.exe\" program which is\n\
1622 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1623 tip program must already be started; connect to it using that socket.\n\
1624 If not, start up tip-program, which should be the name of the tip\n\
1625 program. If appropriate, the PATH environment variable is searched.\n\
1626 configuration-id is unused.\n\
1628 `configuration-id'\n\
1629 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1630 are files containing lines in the above formats. configuration-id is\n\
1631 used to pick which line of the file to use.",
1638 udi_fetch_registers
,
1639 udi_store_registers
,
1640 udi_prepare_to_store
,
1641 udi_xfer_inferior_memory
,
1643 udi_insert_breakpoint
,
1644 udi_remove_breakpoint
,
1645 0, /* termial_init */
1646 0, /* terminal_inferior */
1647 0, /* terminal_ours_for_output */
1648 0, /* terminal_ours */
1649 0, /* terminal_info */
1650 udi_kill
, /* FIXME, kill */
1652 0, /* lookup_symbol */
1653 udi_create_inferior
,
1654 udi_mourn
, /* mourn_inferior FIXME */
1656 0, /* notice_signals */
1659 1, /* has_all_memory */
1662 1, /* has_registers */
1663 1, /* has_execution */
1665 0, /* sections_end */
1666 OPS_MAGIC
, /* Always the last thing */
1670 _initialize_remote_udi ()
1672 add_target (&udi_ops
);