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;
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 /* This is called not only when we first attach, but also when the
119 user types "run" after having attached. */
122 udi_create_inferior (execfile
, args
, env
)
131 if (prog_name
!= NULL
)
133 prog_name
= savestring (execfile
, strlen (execfile
));
135 else if (entry
.Offset
)
138 error ("No image loaded into target.");
140 if (udi_session_id
< 0)
142 printf_unfiltered("UDI connection not open yet.\n");
146 inferior_pid
= 40000;
149 download(execfile
, 0);
151 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
153 if (execfile
[0] == '\0')
155 /* It is empty. We need to quote it somehow, or else the target
156 will think there is no argument being passed here. According
157 to the UDI spec it is quoted "according to TIP OS rules" which
158 I guess means quoting it like the Unix shell should work
159 (sounds pretty bogus to me...). In fact it doesn't work (with
160 isstip anyway), but passing in two quotes as the argument seems
161 like a reasonable enough behavior anyway (I guess). */
163 strcpy (args1
, "''");
165 strcpy (args1
, execfile
);
167 strcat (args1
, args
);
169 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
170 (UDIInt
)2, /* NumberOfRanges */
171 entry
, /* EntryPoint */
172 stack_sizes
, /* *StackSizes */
173 (UDIInt
)2, /* NumberOfStacks */
174 args1
); /* ArgString */
176 init_wait_for_inferior ();
177 clear_proceed_status ();
178 proceed (-1, TARGET_SIGNAL_DEFAULT
, 0);
185 /* Requiring "target udi" each time you run is a major pain. I suspect
186 this was just blindy copied from remote.c, in which "target" and
187 "run" are combined. Having a udi target without an inferior seems
188 to work between "target udi" and "run", so why not now? */
189 pop_target (); /* Pop back to no-child state */
191 /* But if we're going to want to run it again, we better remove the
193 remove_breakpoints ();
194 generic_mourn_inferior ();
197 /******************************************************************** UDI_OPEN
198 ** Open a connection to remote TIP.
199 NAME is the socket domain used for communication with the TIP,
200 then a space and the socket name or TIP-host name.
201 '<udi_udi_config_id>' for example.
204 /* XXX - need cleanups for udiconnect for various failures!!! */
206 static char *udi_config_id
;
208 udi_open (name
, from_tty
)
215 UDIMemoryRange KnownMemory
[10];
216 UDIUInt32 ChipVersions
[10];
217 UDIInt NumberOfRanges
= 10;
218 UDIInt NumberOfChips
= 10;
220 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
222 target_preopen(from_tty
);
226 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
227 bkpt_table
[cnt
].Type
= 0;
230 free (udi_config_id
);
233 error("Usage: target udi config_id, where config_id appears in udi_soc file");
235 udi_config_id
= strdup (strtok (name
, " \t"));
237 if (UDIConnect (udi_config_id
, &udi_session_id
))
238 error("UDIConnect() failed: %s\n", dfe_errmsg
);
240 push_target (&udi_ops
);
243 ** Initialize target configuration structure (global)
245 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
246 ChipVersions
, &NumberOfChips
))
247 error ("UDIGetTargetConfig() failed");
248 if (NumberOfChips
> 2)
249 fprintf_unfiltered(gdb_stderr
,"Target has more than one processor\n");
250 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
252 switch(KnownMemory
[cnt
].Space
)
255 fprintf_unfiltered(gdb_stderr
, "UDIGetTargetConfig() unknown memory space\n");
259 case UDI29KIROMSpace
:
260 RMemStart
= KnownMemory
[cnt
].Offset
;
261 RMemSize
= KnownMemory
[cnt
].Size
;
263 case UDI29KIRAMSpace
:
264 IMemStart
= KnownMemory
[cnt
].Offset
;
265 IMemSize
= KnownMemory
[cnt
].Size
;
267 case UDI29KDRAMSpace
:
268 DMemStart
= KnownMemory
[cnt
].Offset
;
269 DMemSize
= KnownMemory
[cnt
].Size
;
274 a29k_get_processor_type ();
276 if (UDICreateProcess (&PId
))
277 fprintf_unfiltered(gdb_stderr
, "UDICreateProcess() failed\n");
279 /* Print out some stuff, letting the user now what's going on */
280 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
282 error ("UDICapabilities() failed");
285 printf_filtered ("Connected via UDI socket,\n\
286 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
287 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
288 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
289 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
294 /******************************************************************* UDI_CLOSE
295 Close the open connection to the TIP process.
296 Use this when you want to detach and do something else
299 udi_close (quitting
) /*FIXME: how is quitting used */
302 if (udi_session_id
< 0)
305 /* We should never get here if there isn't something valid in
308 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
309 error ("UDIDisconnect() failed in udi_close");
311 /* Do not try to close udi_session_id again, later in the program. */
315 printf_filtered (" Ending remote debugging\n");
318 /**************************************************************** UDI_ATACH */
319 /* Attach to a program that is already loaded and running
320 * Upon exiting the process's execution is stopped.
323 udi_attach (args
, from_tty
)
332 UDIBool HostEndian
= 0;
335 if (udi_session_id
< 0)
336 error ("UDI connection not opened yet, use the 'target udi' command.\n");
339 printf_unfiltered ("Attaching to remote program %s...\n", prog_name
);
342 From
.Space
= UDI29KSpecialRegs
;
344 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
345 error ("UDIRead failed in udi_attach");
346 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
348 /************************************************************* UDI_DETACH */
349 /* Terminate the open connection to the TIP process.
350 Use this when you want to detach and do something else
351 with your gdb. Leave remote process running (with no breakpoints set). */
353 udi_detach (args
,from_tty
)
358 remove_breakpoints(); /* Just in case there were any left in */
360 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
361 error ("UDIDisconnect() failed in udi_detach");
363 pop_target(); /* calls udi_close to do the real work */
366 printf_unfiltered ("Ending remote debugging\n");
370 /****************************************************************** UDI_RESUME
371 ** Tell the remote machine to resume. */
374 udi_resume (pid
, step
, sig
)
376 enum target_signal sig
;
380 UDIStepType StepType
= UDIStepNatural
;
383 if (step
) /* step 1 instruction */
385 tip_error
= UDIStep (Steps
, StepType
, Range
);
389 fprintf_unfiltered (gdb_stderr
, "UDIStep() error = %d\n", tip_error
);
390 error ("failed in udi_resume");
394 error ("UDIExecute() failed in udi_resume");
397 /******************************************************************** UDI_WAIT
398 ** Wait until the remote machine stops, then return,
399 storing status in STATUS just as `wait' would. */
402 udi_wait (pid
, status
)
404 struct target_waitstatus
*status
;
410 int old_timeout
= timeout
;
411 int old_immediate_quit
= immediate_quit
;
414 status
->kind
= TARGET_WAITKIND_EXITED
;
415 status
->value
.integer
= 0;
417 /* wait for message to arrive. It should be:
418 If the target stops executing, udi_wait() should return.
420 timeout
= 0; /* Wait indefinetly for a message */
421 immediate_quit
= 1; /* Helps ability to QUIT */
426 MaxTime
= UDIWaitForever
;
427 UDIWait(MaxTime
, &PId
, &StopReason
);
428 QUIT
; /* Let user quit if they want */
430 switch (StopReason
& UDIGrossState
)
433 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
434 /* This is said to happen if the program tries to output
435 a whole bunch of output (more than SBUF_MAX, I would
436 guess). It doesn't seem to happen with the simulator. */
437 warning ("UDIGetStdout() failed in udi_wait");
438 fwrite (sbuf
, 1, CountDone
, gdb_stdout
);
439 gdb_flush(gdb_stdout
);
443 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
444 fwrite (sbuf
, 1, CountDone
, gdb_stderr
);
445 gdb_flush(gdb_stderr
);
458 } while (i
< SBUF_MAX
&& ch
!= '\n');
459 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
464 /* In spite of the fact that we told UDIWait to wait forever, it will
465 return spuriously sometimes. */
474 switch (StopReason
& UDIGrossState
)
477 printf_unfiltered("Am290*0 received vector number %d\n", StopReason
>> 24);
479 switch (StopReason
>> 8)
481 case 0: /* Illegal opcode */
482 printf_unfiltered(" (break point)\n");
483 status
->kind
= TARGET_WAITKIND_STOPPED
;
484 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
486 case 1: /* Unaligned Access */
487 status
->kind
= TARGET_WAITKIND_STOPPED
;
488 status
->value
.sig
= TARGET_SIGNAL_BUS
;
492 status
->kind
= TARGET_WAITKIND_STOPPED
;
493 status
->value
.sig
= TARGET_SIGNAL_FPE
;
495 case 5: /* Protection Violation */
496 status
->kind
= TARGET_WAITKIND_STOPPED
;
497 /* Why not SEGV? What is a Protection Violation? */
498 status
->value
.sig
= TARGET_SIGNAL_ILL
;
502 case 8: /* User Instruction Mapping Miss */
503 case 9: /* User Data Mapping Miss */
504 case 10: /* Supervisor Instruction Mapping Miss */
505 case 11: /* Supervisor Data Mapping Miss */
506 status
->kind
= TARGET_WAITKIND_STOPPED
;
507 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
511 status
->kind
= TARGET_WAITKIND_STOPPED
;
512 status
->value
.sig
= TARGET_SIGNAL_ILL
;
515 status
->kind
= TARGET_WAITKIND_STOPPED
;
516 status
->value
.sig
= TARGET_SIGNAL_ALRM
;
519 status
->kind
= TARGET_WAITKIND_STOPPED
;
520 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
525 case 19: /* INTR3/Internal */
528 status
->kind
= TARGET_WAITKIND_STOPPED
;
529 status
->value
.sig
= TARGET_SIGNAL_INT
;
531 case 22: /* Floating-Point Exception */
532 status
->kind
= TARGET_WAITKIND_STOPPED
;
534 status
->value
.sig
= TARGET_SIGNAL_ILL
;
536 case 77: /* assert 77 */
537 status
->kind
= TARGET_WAITKIND_STOPPED
;
538 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
541 status
->kind
= TARGET_WAITKIND_EXITED
;
542 status
->value
.integer
= 0;
545 case UDINotExecuting
:
546 status
->kind
= TARGET_WAITKIND_STOPPED
;
547 status
->value
.sig
= TARGET_SIGNAL_TERM
;
550 status
->kind
= TARGET_WAITKIND_STOPPED
;
551 status
->value
.sig
= TARGET_SIGNAL_TSTP
;
554 status
->kind
= TARGET_WAITKIND_STOPPED
;
555 status
->value
.sig
= TARGET_SIGNAL_URG
;
559 status
->kind
= TARGET_WAITKIND_STOPPED
;
560 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
563 status
->kind
= TARGET_WAITKIND_STOPPED
;
564 status
->value
.sig
= TARGET_SIGNAL_STOP
;
567 status
->kind
= TARGET_WAITKIND_STOPPED
;
568 status
->value
.sig
= TARGET_SIGNAL_KILL
;
572 status
->kind
= TARGET_WAITKIND_EXITED
;
573 status
->value
.integer
= 0;
576 timeout
= old_timeout
; /* Restore original timeout value */
577 immediate_quit
= old_immediate_quit
;
582 /* Handy for debugging */
590 UDIBool HostEndian
= 0;
593 unsigned long myregs
[256];
596 From
.Space
= UDI29KPC
;
598 To
= (UDIUInt32
*)pc
;
601 err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
);
603 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
604 err
, CountDone
, pc
[0], pc
[1]);
606 udi_fetch_registers(-1);
608 printf_unfiltered("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *)®isters
[4 * PC_REGNUM
],
609 *(int *)®isters
[4 * NPC_REGNUM
]);
611 /* Now, read all the registers globally */
613 From
.Space
= UDI29KGlobalRegs
;
615 err
= UDIRead(From
, myregs
, 256, 4, &CountDone
, HostEndian
);
617 printf ("err = %d, CountDone = %d\n", err
, CountDone
);
621 for (i
= 0; i
< 256; i
+= 2)
622 printf("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i
, myregs
[i
], myregs
[i
],
623 myregs
[i
+1], myregs
[i
+1]);
630 /********************************************************** UDI_FETCH_REGISTERS
631 * Read a remote register 'regno'.
632 * If regno==-1 then read all the registers.
635 udi_fetch_registers (regno
)
643 UDIBool HostEndian
= 0;
648 fetch_register(regno
);
654 From
.Space
= UDI29KGlobalRegs
;
656 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
658 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
659 error("UDIRead() failed in udi_fetch_registers");
661 register_valid
[GR1_REGNUM
] = 1;
663 #if defined(GR64_REGNUM) /* Read gr64-127 */
665 /* Global Registers gr64-gr95 */
667 From
.Space
= UDI29KGlobalRegs
;
669 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
671 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
672 error("UDIRead() failed in udi_fetch_registers");
674 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
675 register_valid
[i
] = 1;
677 #endif /* GR64_REGNUM */
679 /* Global Registers gr96-gr127 */
681 From
.Space
= UDI29KGlobalRegs
;
683 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
685 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
686 error("UDIRead() failed in udi_fetch_registers");
688 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
689 register_valid
[i
] = 1;
691 /* Local Registers */
693 From
.Space
= UDI29KLocalRegs
;
695 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
697 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
698 error("UDIRead() failed in udi_fetch_registers");
700 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
701 register_valid
[i
] = 1;
703 /* Protected Special Registers */
705 From
.Space
= UDI29KSpecialRegs
;
707 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
709 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
710 error("UDIRead() failed in udi_fetch_registers");
712 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
713 register_valid
[i
] = 1;
715 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
716 fetch_register(NPC_REGNUM
);
717 fetch_register(PC_REGNUM
);
718 fetch_register(PC2_REGNUM
);
720 /* Unprotected Special Registers sr128-sr135 */
722 From
.Space
= UDI29KSpecialRegs
;
724 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
726 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
727 error("UDIRead() failed in udi_fetch_registers");
729 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
730 register_valid
[i
] = 1;
735 printf_unfiltered("Fetching all registers\n");
736 printf_unfiltered("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
737 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
738 read_register(PC2_REGNUM
));
741 /* There doesn't seem to be any way to get these. */
744 supply_register (FPE_REGNUM
, (char *) &val
);
745 supply_register (INTE_REGNUM
, (char *) &val
);
746 supply_register (FPS_REGNUM
, (char *) &val
);
747 supply_register (EXO_REGNUM
, (char *) &val
);
752 /********************************************************* UDI_STORE_REGISTERS
753 ** Store register regno into the target.
754 * If regno==-1 then store all the registers.
758 udi_store_registers (regno
)
766 UDIBool HostEndian
= 0;
770 store_register(regno
);
776 printf_unfiltered("Storing all registers\n");
777 printf_unfiltered("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
778 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
783 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
784 To
.Space
= UDI29KGlobalRegs
;
787 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
788 error("UDIWrite() failed in udi_store_regisetrs");
790 #if defined(GR64_REGNUM)
792 /* Global registers gr64-gr95 */
794 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
795 To
.Space
= UDI29KGlobalRegs
;
798 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
799 error("UDIWrite() failed in udi_store_regisetrs");
801 #endif /* GR64_REGNUM */
803 /* Global registers gr96-gr127 */
805 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
806 To
.Space
= UDI29KGlobalRegs
;
809 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
810 error("UDIWrite() failed in udi_store_regisetrs");
812 /* Local Registers */
814 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
815 To
.Space
= UDI29KLocalRegs
;
818 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
819 error("UDIWrite() failed in udi_store_regisetrs");
822 /* Protected Special Registers */ /* VAB through TMR */
824 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
825 To
.Space
= UDI29KSpecialRegs
;
828 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
829 error("UDIWrite() failed in udi_store_regisetrs");
831 /* PC0, PC1, PC2 possibly as shadow registers */
833 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
834 To
.Space
= UDI29KSpecialRegs
;
837 To
.Offset
= 20; /* SPC0 */
839 To
.Offset
= 10; /* PC0 */
840 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
841 error("UDIWrite() failed in udi_store_regisetrs");
843 /* PC1 via UDI29KPC */
845 From
= (UDIUInt32
*)®isters
[4 * PC_REGNUM
];
847 To
.Offset
= 0; /* PC1 */
849 if (UDIWrite (From
, To
, Count
, Size
, &CountDone
, HostEndian
))
850 error ("UDIWrite() failed in udi_store_regisetrs");
854 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
855 To
.Space
= UDI29KSpecialRegs
;
858 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
859 error("UDIWrite() failed in udi_store_regisetrs");
861 /* Unprotected Special Registers */
863 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
864 To
.Space
= UDI29KSpecialRegs
;
867 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
868 error("UDIWrite() failed in udi_store_regisetrs");
870 registers_changed ();
873 /****************************************************** UDI_PREPARE_TO_STORE */
874 /* Get ready to modify the registers array. On machines which store
875 individual registers, this doesn't need to do anything. On machines
876 which store all the registers in one fell swoop, this makes sure
877 that registers contains all the registers from the program being
881 udi_prepare_to_store ()
883 /* Do nothing, since we can store individual regs */
886 /********************************************************** TRANSLATE_ADDR */
891 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
892 /* Check for a virtual address in the kernel */
893 /* Assume physical address of ublock is in paddr_u register */
894 /* FIXME: doesn't work for user virtual addresses */
895 if (addr
>= UVADDR
) {
896 /* PADDR_U register holds the physical address of the ublock */
897 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
898 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
906 /************************************************* UDI_XFER_INFERIOR_MEMORY */
907 /* FIXME! Merge these two. */
909 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
916 memaddr
= translate_addr(memaddr
);
919 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
921 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
924 /********************************************************** UDI_FILES_INFO */
928 printf_unfiltered ("\tAttached to UDI socket to %s and running program %s.\n",
929 udi_config_id
, prog_name
);
932 /**************************************************** UDI_INSERT_BREAKPOINT */
934 udi_insert_breakpoint (addr
, contents_cache
)
936 char *contents_cache
;
941 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
942 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
945 if(cnt
>= BKPT_TABLE_SIZE
)
946 error("Too many breakpoints set");
948 bkpt_table
[cnt
].Addr
.Offset
= addr
;
949 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
950 bkpt_table
[cnt
].PassCount
= 1;
951 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
953 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
954 bkpt_table
[cnt
].PassCount
,
955 bkpt_table
[cnt
].Type
,
956 &bkpt_table
[cnt
].BreakId
);
958 if (err
== 0) return 0; /* Success */
960 bkpt_table
[cnt
].Type
= 0;
961 error("UDISetBreakpoint returned error code %d\n", err
);
964 /**************************************************** UDI_REMOVE_BREAKPOINT */
966 udi_remove_breakpoint (addr
, contents_cache
)
968 char *contents_cache
;
973 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
974 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
977 if(cnt
>= BKPT_TABLE_SIZE
)
978 error("Can't find breakpoint in table");
980 bkpt_table
[cnt
].Type
= 0;
982 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
983 if (err
== 0) return 0; /* Success */
985 error("UDIClearBreakpoint returned error code %d\n", err
);
989 udi_kill(arg
,from_tty
)
996 UDIStop does not really work as advertised. It causes the TIP to close it's
997 connection, which usually results in GDB dying with a SIGPIPE. For now, we
998 just invoke udi_close, which seems to get things right.
1002 udi_session_id
= -1;
1006 printf_unfiltered("Target has been stopped.");
1013 /* Keep the target around, e.g. so "run" can do the right thing when
1014 we are already debugging something. */
1020 Load a program into the target. Args are: `program {options}'. The options
1021 are used to control loading of the program, and are NOT passed onto the
1022 loaded code as arguments. (You need to use the `run' command to do that.)
1025 -ms %d Set mem stack size to %d
1026 -rs %d Set regular stack size to %d
1027 -i send init info (default)
1028 -noi don't send init info
1029 -[tT] Load Text section
1030 -[dD] Load Data section
1031 -[bB] Load BSS section
1032 -[lL] Load Lit section
1036 download(load_arg_string
, from_tty
)
1037 char *load_arg_string
;
1040 #define DEFAULT_MEM_STACK_SIZE 0x6000
1041 #define DEFAULT_REG_STACK_SIZE 0x2000
1048 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1050 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1051 address_ranges
[0].Offset
= 0xffffffff;
1052 address_ranges
[0].Size
= 0;
1054 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1055 address_ranges
[1].Offset
= 0xffffffff;
1056 address_ranges
[1].Size
= 0;
1058 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1059 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1063 filename
= strtok(load_arg_string
, " \t");
1065 error ("Must specify at least a file name with the load command");
1067 filename
= tilde_expand (filename
);
1068 make_cleanup (free
, filename
);
1070 while (token
= strtok (NULL
, " \t"))
1072 if (token
[0] == '-')
1076 if (STREQ (token
, "ms"))
1077 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1078 else if (STREQ (token
, "rs"))
1079 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1082 load_text
= load_data
= load_bss
= load_lit
= 0;
1105 error ("Unknown UDI load option -%s", token
-1);
1112 pbfd
= bfd_openr (filename
, gnutarget
);
1115 perror_with_name (filename
);
1117 make_cleanup (bfd_close
, pbfd
);
1122 if (!bfd_check_format (pbfd
, bfd_object
))
1123 error ("It doesn't seem to be an object file");
1125 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1127 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1131 unsigned long section_size
, section_end
;
1132 const char *section_name
;
1134 section_name
= bfd_get_section_name (pbfd
, section
);
1135 if (STREQ (section_name
, ".text") && !load_text
)
1137 else if (STREQ (section_name
, ".data") && !load_data
)
1139 else if (STREQ (section_name
, ".bss") && !load_bss
)
1141 else if (STREQ (section_name
, ".lit") && !load_lit
)
1144 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1145 section_size
= bfd_section_size (pbfd
, section
);
1146 section_end
= To
.Offset
+ section_size
;
1148 if (section_size
== 0)
1149 /* This is needed at least in the BSS case, where the code
1150 below starts writing before it even checks the size. */
1153 printf_unfiltered("[Loading section %s at %x (%d bytes)]\n",
1158 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1160 To
.Space
= UDI29KIRAMSpace
;
1162 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1164 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1166 - address_ranges
[0].Offset
);
1170 To
.Space
= UDI29KDRAMSpace
;
1172 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1174 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1176 - address_ranges
[1].Offset
);
1179 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1185 while (section_size
> 0)
1189 Count
= min (section_size
, 1024);
1191 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1194 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1197 (UDISizeT
)1, /* Size */
1198 &Count
, /* CountDone */
1199 (UDIBool
)0); /* HostEndian */
1201 error ("UDIWrite failed, error = %d", err
);
1205 section_size
-= Count
;
1211 unsigned long zero
= 0;
1213 /* Write a zero byte at the vma */
1214 /* FIXME: Broken for sections of 1-3 bytes (we test for
1216 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1218 (UDICount
)1, /* Count */
1219 (UDISizeT
)4, /* Size */
1220 &Count
, /* CountDone */
1221 (UDIBool
)0); /* HostEndian */
1223 error ("UDIWrite failed, error = %d", err
);
1228 /* Now, duplicate it for the length of the BSS */
1229 err
= UDICopy (From
, /* From */
1231 (UDICount
)(section_size
/4 - 1), /* Count */
1232 (UDISizeT
)4, /* Size */
1233 &Count
, /* CountDone */
1234 (UDIBool
)1); /* Direction */
1240 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1242 fprintf_unfiltered (gdb_stderr
, "Error is %s\n", message
);
1244 fprintf_unfiltered (gdb_stderr
, "xerr is %d\n", xerr
);
1245 error ("UDICopy failed, error = %d", err
);
1252 entry
.Space
= UDI29KIRAMSpace
;
1253 entry
.Offset
= bfd_get_start_address (pbfd
);
1258 /* User interface to download an image into the remote target. See download()
1259 * for details on args.
1263 udi_load(args
, from_tty
)
1267 download (args
, from_tty
);
1269 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1272 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1273 ** Copy LEN bytes of data from debugger memory at MYADDR
1274 to inferior's memory at MEMADDR. Returns number of bytes written. */
1276 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1286 UDICount CountDone
= 0;
1287 UDIBool HostEndian
= 0;
1289 To
.Space
= udi_memory_space(memaddr
);
1290 From
= (UDIUInt32
*)myaddr
;
1292 while (nwritten
< len
)
1293 { Count
= len
- nwritten
;
1294 if (Count
> MAXDATA
) Count
= MAXDATA
;
1295 To
.Offset
= memaddr
+ nwritten
;
1296 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1297 { error("UDIWrite() failed in udi_write_inferrior_memory");
1301 { nwritten
+= CountDone
;
1308 /**************************************************** UDI_READ_INFERIOR_MEMORY
1309 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1310 at debugger address MYADDR. Returns number of bytes read. */
1312 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1322 UDICount CountDone
= 0;
1323 UDIBool HostEndian
= 0;
1326 From
.Space
= udi_memory_space(memaddr
);
1327 To
= (UDIUInt32
*)myaddr
;
1330 { Count
= len
- nread
;
1331 if (Count
> MAXDATA
) Count
= MAXDATA
;
1332 From
.Offset
= memaddr
+ nread
;
1333 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1334 { error("UDIRead() failed in udi_read_inferrior_memory");
1338 { nread
+= CountDone
;
1345 /********************************************************************* WARNING
1350 error ("ERROR while loading program into remote TIP: $d\n", num
);
1354 /*****************************************************************************/
1355 /* Fetch a single register indicatated by 'regno'.
1356 * Returns 0/-1 on success/failure.
1359 fetch_register (regno
)
1367 UDIBool HostEndian
= 0;
1371 if (regno
== GR1_REGNUM
)
1373 From
.Space
= UDI29KGlobalRegs
;
1376 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1378 From
.Space
= UDI29KGlobalRegs
;
1379 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1382 #if defined(GR64_REGNUM)
1384 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1386 From
.Space
= UDI29KGlobalRegs
;
1387 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1390 #endif /* GR64_REGNUM */
1392 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1394 From
.Space
= UDI29KLocalRegs
;
1395 From
.Offset
= (regno
- LR0_REGNUM
);
1397 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1400 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1401 return; /* Pretend Success */
1405 From
.Space
= UDI29KSpecialRegs
;
1406 From
.Offset
= regnum_to_srnum(regno
);
1409 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1410 error("UDIRead() failed in udi_fetch_registers");
1412 supply_register(regno
, (char *) &To
);
1415 printf_unfiltered("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1417 /*****************************************************************************/
1418 /* Store a single register indicated by 'regno'.
1419 * Returns 0/-1 on success/failure.
1422 store_register (regno
)
1431 UDIBool HostEndian
= 0;
1433 From
= read_register (regno
); /* get data value */
1436 printf_unfiltered("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1438 if (regno
== GR1_REGNUM
)
1440 To
.Space
= UDI29KGlobalRegs
;
1442 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1443 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1444 * register cache. Do this *after* calling read_register, because we want
1445 * read_register to return the value that write_register has just stuffed
1446 * into the registers array, not the value of the register fetched from
1449 registers_changed ();
1451 #if defined(GR64_REGNUM)
1452 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1454 To
.Space
= UDI29KGlobalRegs
;
1455 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1456 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1458 #endif /* GR64_REGNUM */
1459 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1461 To
.Space
= UDI29KGlobalRegs
;
1462 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1463 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1465 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1467 To
.Space
= UDI29KLocalRegs
;
1468 To
.Offset
= (regno
- LR0_REGNUM
);
1469 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1471 else if (regno
>= FPE_REGNUM
&& regno
<= EXO_REGNUM
)
1472 return 0; /* Pretend Success */
1473 else if (regno
== PC_REGNUM
)
1475 /* PC1 via UDI29KPC */
1477 To
.Space
= UDI29KPC
;
1478 To
.Offset
= 0; /* PC1 */
1479 result
= UDIWrite (&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1481 /* Writing to this loc actually changes the values of pc0 & pc1 */
1483 register_valid
[PC_REGNUM
] = 0; /* pc1 */
1484 register_valid
[NPC_REGNUM
] = 0; /* pc0 */
1486 else /* An unprotected or protected special register */
1488 To
.Space
= UDI29KSpecialRegs
;
1489 To
.Offset
= regnum_to_srnum(regno
);
1490 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1494 error("UDIWrite() failed in store_registers");
1498 /********************************************************** REGNUM_TO_SRNUM */
1500 * Convert a gdb special register number to a 29000 special register number.
1503 regnum_to_srnum(regno
)
1507 case VAB_REGNUM
: return(0);
1508 case OPS_REGNUM
: return(1);
1509 case CPS_REGNUM
: return(2);
1510 case CFG_REGNUM
: return(3);
1511 case CHA_REGNUM
: return(4);
1512 case CHD_REGNUM
: return(5);
1513 case CHC_REGNUM
: return(6);
1514 case RBP_REGNUM
: return(7);
1515 case TMC_REGNUM
: return(8);
1516 case TMR_REGNUM
: return(9);
1517 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1518 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1519 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1520 case MMU_REGNUM
: return(13);
1521 case LRU_REGNUM
: return(14);
1522 case IPC_REGNUM
: return(128);
1523 case IPA_REGNUM
: return(129);
1524 case IPB_REGNUM
: return(130);
1525 case Q_REGNUM
: return(131);
1526 case ALU_REGNUM
: return(132);
1527 case BP_REGNUM
: return(133);
1528 case FC_REGNUM
: return(134);
1529 case CR_REGNUM
: return(135);
1530 case FPE_REGNUM
: return(160);
1531 case INTE_REGNUM
: return(161);
1532 case FPS_REGNUM
: return(162);
1533 case EXO_REGNUM
:return(164);
1535 return(255); /* Failure ? */
1538 /****************************************************************************/
1540 * Determine the Target memory space qualifier based on the addr.
1541 * FIXME: Can't distinguis I_ROM/D_ROM.
1542 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1545 udi_memory_space(addr
)
1548 UDIUInt32 tstart
= IMemStart
;
1549 UDIUInt32 tend
= tstart
+ IMemSize
;
1550 UDIUInt32 dstart
= DMemStart
;
1551 UDIUInt32 dend
= tstart
+ DMemSize
;
1552 UDIUInt32 rstart
= RMemStart
;
1553 UDIUInt32 rend
= tstart
+ RMemSize
;
1555 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1556 return UDI29KIRAMSpace
;
1557 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1558 return UDI29KDRAMSpace
;
1559 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1560 /* FIXME: how do we determine between D_ROM and I_ROM */
1561 return UDI29KIROMSpace
;
1562 } else /* FIXME: what do me do now? */
1563 return UDI29KDRAMSpace
; /* Hmmm! */
1565 /*********************************************************************** STUBS
1568 void convert16() {;}
1569 void convert32() {;}
1570 GDB_FILE
* EchoFile
= 0; /* used for debugging */
1571 int QuietMode
= 0; /* used for debugging */
1573 #ifdef NO_HIF_SUPPORT
1577 return(0); /* Emulate a failure */
1581 /* Target_ops vector. Not static because there does not seem to be
1582 any portable way to do a forward declaration of a static variable.
1583 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1584 /bin/cc doesn't like "static" twice. */
1586 struct target_ops udi_ops
= {
1588 "Remote UDI connected TIP",
1589 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1591 `configuration-id AF_INET hostname port-number'\n\
1592 To connect via the network, where hostname and port-number specify the\n\
1593 host and port where you can connect via UDI.\n\
1594 configuration-id is unused.\n\
1596 `configuration-id AF_UNIX socket-name tip-program'\n\
1597 To connect using a local connection to the \"tip.exe\" program which is\n\
1598 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1599 tip program must already be started; connect to it using that socket.\n\
1600 If not, start up tip-program, which should be the name of the tip\n\
1601 program. If appropriate, the PATH environment variable is searched.\n\
1602 configuration-id is unused.\n\
1604 `configuration-id'\n\
1605 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1606 are files containing lines in the above formats. configuration-id is\n\
1607 used to pick which line of the file to use.",
1614 udi_fetch_registers
,
1615 udi_store_registers
,
1616 udi_prepare_to_store
,
1617 udi_xfer_inferior_memory
,
1619 udi_insert_breakpoint
,
1620 udi_remove_breakpoint
,
1621 0, /* termial_init */
1622 0, /* terminal_inferior */
1623 0, /* terminal_ours_for_output */
1624 0, /* terminal_ours */
1625 0, /* terminal_info */
1626 udi_kill
, /* FIXME, kill */
1628 0, /* lookup_symbol */
1629 udi_create_inferior
,
1630 udi_mourn
, /* mourn_inferior FIXME */
1632 0, /* notice_signals */
1635 1, /* has_all_memory */
1638 1, /* has_registers */
1639 1, /* has_execution */
1641 0, /* sections_end */
1642 OPS_MAGIC
, /* Always the last thing */
1646 _initialize_remote_udi ()
1648 add_target (&udi_ops
);