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 /* 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 strcpy (args1
, execfile
);
155 strcat (args1
, args
);
157 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
158 (UDIInt
)2, /* NumberOfRanges */
159 entry
, /* EntryPoint */
160 stack_sizes
, /* *StackSizes */
161 (UDIInt
)2, /* NumberOfStacks */
162 args1
); /* ArgString */
164 init_wait_for_inferior ();
165 clear_proceed_status ();
166 proceed (-1, TARGET_SIGNAL_DEFAULT
, 0);
173 /* Requiring "target udi" each time you run is a major pain. I suspect
174 this was just blindy copied from remote.c, in which "target" and
175 "run" are combined. Having a udi target without an inferior seems
176 to work between "target udi" and "run", so why not now? */
177 pop_target (); /* Pop back to no-child state */
179 /* But if we're going to want to run it again, we better remove the
181 remove_breakpoints ();
182 generic_mourn_inferior ();
185 /******************************************************************** UDI_OPEN
186 ** Open a connection to remote TIP.
187 NAME is the socket domain used for communication with the TIP,
188 then a space and the socket name or TIP-host name.
189 '<udi_udi_config_id>' for example.
192 /* XXX - need cleanups for udiconnect for various failures!!! */
194 static char *udi_config_id
;
196 udi_open (name
, from_tty
)
203 UDIMemoryRange KnownMemory
[10];
204 UDIUInt32 ChipVersions
[10];
205 UDIInt NumberOfRanges
= 10;
206 UDIInt NumberOfChips
= 10;
208 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
210 target_preopen(from_tty
);
214 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
215 bkpt_table
[cnt
].Type
= 0;
218 free (udi_config_id
);
221 error("Usage: target udi config_id, where config_id appears in udi_soc file");
223 udi_config_id
= strdup (strtok (name
, " \t"));
225 if (UDIConnect (udi_config_id
, &udi_session_id
))
226 error("UDIConnect() failed: %s\n", dfe_errmsg
);
228 push_target (&udi_ops
);
231 ** Initialize target configuration structure (global)
233 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
234 ChipVersions
, &NumberOfChips
))
235 error ("UDIGetTargetConfig() failed");
236 if (NumberOfChips
> 2)
237 fprintf_unfiltered(gdb_stderr
,"Target has more than one processor\n");
238 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
240 switch(KnownMemory
[cnt
].Space
)
243 fprintf_unfiltered(gdb_stderr
, "UDIGetTargetConfig() unknown memory space\n");
247 case UDI29KIROMSpace
:
248 RMemStart
= KnownMemory
[cnt
].Offset
;
249 RMemSize
= KnownMemory
[cnt
].Size
;
251 case UDI29KIRAMSpace
:
252 IMemStart
= KnownMemory
[cnt
].Offset
;
253 IMemSize
= KnownMemory
[cnt
].Size
;
255 case UDI29KDRAMSpace
:
256 DMemStart
= KnownMemory
[cnt
].Offset
;
257 DMemSize
= KnownMemory
[cnt
].Size
;
262 a29k_get_processor_type ();
264 if (UDICreateProcess (&PId
))
265 fprintf_unfiltered(gdb_stderr
, "UDICreateProcess() failed\n");
267 /* Print out some stuff, letting the user now what's going on */
268 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
270 error ("UDICapabilities() failed");
273 printf_filtered ("Connected via UDI socket,\n\
274 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
275 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
276 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
277 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
282 /******************************************************************* UDI_CLOSE
283 Close the open connection to the TIP process.
284 Use this when you want to detach and do something else
287 udi_close (quitting
) /*FIXME: how is quitting used */
290 if (udi_session_id
< 0)
293 /* We should never get here if there isn't something valid in
296 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
297 error ("UDIDisconnect() failed in udi_close");
299 /* Do not try to close udi_session_id again, later in the program. */
303 printf_filtered (" Ending remote debugging\n");
306 /**************************************************************** UDI_ATACH */
307 /* Attach to a program that is already loaded and running
308 * Upon exiting the process's execution is stopped.
311 udi_attach (args
, from_tty
)
320 UDIBool HostEndian
= 0;
323 if (udi_session_id
< 0)
324 error ("UDI connection not opened yet, use the 'target udi' command.\n");
327 printf_unfiltered ("Attaching to remote program %s...\n", prog_name
);
330 From
.Space
= UDI29KSpecialRegs
;
332 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
333 error ("UDIRead failed in udi_attach");
334 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
336 /************************************************************* UDI_DETACH */
337 /* Terminate the open connection to the TIP process.
338 Use this when you want to detach and do something else
339 with your gdb. Leave remote process running (with no breakpoints set). */
341 udi_detach (args
,from_tty
)
346 remove_breakpoints(); /* Just in case there were any left in */
348 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
349 error ("UDIDisconnect() failed in udi_detach");
351 pop_target(); /* calls udi_close to do the real work */
354 printf_unfiltered ("Ending remote debugging\n");
358 /****************************************************************** UDI_RESUME
359 ** Tell the remote machine to resume. */
362 udi_resume (pid
, step
, sig
)
364 enum target_signal sig
;
368 UDIStepType StepType
= UDIStepNatural
;
371 if (step
) /* step 1 instruction */
373 tip_error
= UDIStep (Steps
, StepType
, Range
);
377 fprintf_unfiltered (gdb_stderr
, "UDIStep() error = %d\n", tip_error
);
378 error ("failed in udi_resume");
382 error ("UDIExecute() failed in udi_resume");
385 /******************************************************************** UDI_WAIT
386 ** Wait until the remote machine stops, then return,
387 storing status in STATUS just as `wait' would. */
390 udi_wait (pid
, status
)
392 struct target_waitstatus
*status
;
398 int old_timeout
= timeout
;
399 int old_immediate_quit
= immediate_quit
;
402 status
->kind
= TARGET_WAITKIND_EXITED
;
403 status
->value
.integer
= 0;
405 /* wait for message to arrive. It should be:
406 If the target stops executing, udi_wait() should return.
408 timeout
= 0; /* Wait indefinetly for a message */
409 immediate_quit
= 1; /* Helps ability to QUIT */
414 MaxTime
= UDIWaitForever
;
415 UDIWait(MaxTime
, &PId
, &StopReason
);
416 QUIT
; /* Let user quit if they want */
418 switch (StopReason
& UDIGrossState
)
421 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
422 /* This is said to happen if the program tries to output
423 a whole bunch of output (more than SBUF_MAX, I would
424 guess). It doesn't seem to happen with the simulator. */
425 warning ("UDIGetStdout() failed in udi_wait");
426 fwrite (sbuf
, 1, CountDone
, gdb_stdout
);
427 gdb_flush(gdb_stdout
);
431 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
432 fwrite (sbuf
, 1, CountDone
, gdb_stderr
);
433 gdb_flush(gdb_stderr
);
446 } while (i
< SBUF_MAX
&& ch
!= '\n');
447 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
452 /* In spite of the fact that we told UDIWait to wait forever, it will
453 return spuriously sometimes. */
462 switch (StopReason
& UDIGrossState
)
465 printf_unfiltered("Am290*0 received vector number %d\n", StopReason
>> 24);
467 switch (StopReason
>> 8)
469 case 0: /* Illegal opcode */
470 printf_unfiltered(" (break point)\n");
471 status
->kind
= TARGET_WAITKIND_STOPPED
;
472 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
474 case 1: /* Unaligned Access */
475 status
->kind
= TARGET_WAITKIND_STOPPED
;
476 status
->value
.sig
= TARGET_SIGNAL_BUS
;
480 status
->kind
= TARGET_WAITKIND_STOPPED
;
481 status
->value
.sig
= TARGET_SIGNAL_FPE
;
483 case 5: /* Protection Violation */
484 status
->kind
= TARGET_WAITKIND_STOPPED
;
485 /* Why not SEGV? What is a Protection Violation? */
486 status
->value
.sig
= TARGET_SIGNAL_ILL
;
490 case 8: /* User Instruction Mapping Miss */
491 case 9: /* User Data Mapping Miss */
492 case 10: /* Supervisor Instruction Mapping Miss */
493 case 11: /* Supervisor Data Mapping Miss */
494 status
->kind
= TARGET_WAITKIND_STOPPED
;
495 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
499 status
->kind
= TARGET_WAITKIND_STOPPED
;
500 status
->value
.sig
= TARGET_SIGNAL_ILL
;
503 status
->kind
= TARGET_WAITKIND_STOPPED
;
504 status
->value
.sig
= TARGET_SIGNAL_ALRM
;
507 status
->kind
= TARGET_WAITKIND_STOPPED
;
508 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
513 case 19: /* INTR3/Internal */
516 status
->kind
= TARGET_WAITKIND_STOPPED
;
517 status
->value
.sig
= TARGET_SIGNAL_INT
;
519 case 22: /* Floating-Point Exception */
520 status
->kind
= TARGET_WAITKIND_STOPPED
;
522 status
->value
.sig
= TARGET_SIGNAL_ILL
;
524 case 77: /* assert 77 */
525 status
->kind
= TARGET_WAITKIND_STOPPED
;
526 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
529 status
->kind
= TARGET_WAITKIND_EXITED
;
530 status
->value
.integer
= 0;
533 case UDINotExecuting
:
534 status
->kind
= TARGET_WAITKIND_STOPPED
;
535 status
->value
.sig
= TARGET_SIGNAL_TERM
;
538 status
->kind
= TARGET_WAITKIND_STOPPED
;
539 status
->value
.sig
= TARGET_SIGNAL_TSTP
;
542 status
->kind
= TARGET_WAITKIND_STOPPED
;
543 status
->value
.sig
= TARGET_SIGNAL_URG
;
547 status
->kind
= TARGET_WAITKIND_STOPPED
;
548 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
551 status
->kind
= TARGET_WAITKIND_STOPPED
;
552 status
->value
.sig
= TARGET_SIGNAL_STOP
;
555 status
->kind
= TARGET_WAITKIND_STOPPED
;
556 status
->value
.sig
= TARGET_SIGNAL_KILL
;
560 status
->kind
= TARGET_WAITKIND_EXITED
;
561 status
->value
.integer
= 0;
564 timeout
= old_timeout
; /* Restore original timeout value */
565 immediate_quit
= old_immediate_quit
;
570 /* Handy for debugging */
578 UDIBool HostEndian
= 0;
581 unsigned long myregs
[256];
584 From
.Space
= UDI29KPC
;
586 To
= (UDIUInt32
*)pc
;
589 err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
);
591 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
592 err
, CountDone
, pc
[0], pc
[1]);
594 udi_fetch_registers(-1);
596 printf_unfiltered("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *)®isters
[4 * PC_REGNUM
],
597 *(int *)®isters
[4 * NPC_REGNUM
]);
599 /* Now, read all the registers globally */
601 From
.Space
= UDI29KGlobalRegs
;
603 err
= UDIRead(From
, myregs
, 256, 4, &CountDone
, HostEndian
);
605 printf ("err = %d, CountDone = %d\n", err
, CountDone
);
609 for (i
= 0; i
< 256; i
+= 2)
610 printf("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i
, myregs
[i
], myregs
[i
],
611 myregs
[i
+1], myregs
[i
+1]);
618 /********************************************************** UDI_FETCH_REGISTERS
619 * Read a remote register 'regno'.
620 * If regno==-1 then read all the registers.
623 udi_fetch_registers (regno
)
631 UDIBool HostEndian
= 0;
636 fetch_register(regno
);
642 From
.Space
= UDI29KGlobalRegs
;
644 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
646 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
647 error("UDIRead() failed in udi_fetch_registers");
649 register_valid
[GR1_REGNUM
] = 1;
651 #if defined(GR64_REGNUM) /* Read gr64-127 */
653 /* Global Registers gr64-gr95 */
655 From
.Space
= UDI29KGlobalRegs
;
657 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
659 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
660 error("UDIRead() failed in udi_fetch_registers");
662 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
663 register_valid
[i
] = 1;
665 #endif /* GR64_REGNUM */
667 /* Global Registers gr96-gr127 */
669 From
.Space
= UDI29KGlobalRegs
;
671 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
673 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
674 error("UDIRead() failed in udi_fetch_registers");
676 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
677 register_valid
[i
] = 1;
679 /* Local Registers */
681 From
.Space
= UDI29KLocalRegs
;
683 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
685 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
686 error("UDIRead() failed in udi_fetch_registers");
688 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
689 register_valid
[i
] = 1;
691 /* Protected Special Registers */
693 From
.Space
= UDI29KSpecialRegs
;
695 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
697 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
698 error("UDIRead() failed in udi_fetch_registers");
700 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
701 register_valid
[i
] = 1;
703 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
704 fetch_register(NPC_REGNUM
);
705 fetch_register(PC_REGNUM
);
706 fetch_register(PC2_REGNUM
);
708 /* Unprotected Special Registers sr128-sr135 */
710 From
.Space
= UDI29KSpecialRegs
;
712 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
714 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
715 error("UDIRead() failed in udi_fetch_registers");
717 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
718 register_valid
[i
] = 1;
723 printf_unfiltered("Fetching all registers\n");
724 printf_unfiltered("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
725 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
726 read_register(PC2_REGNUM
));
729 /* There doesn't seem to be any way to get these. */
732 supply_register (FPE_REGNUM
, (char *) &val
);
733 supply_register (INTE_REGNUM
, (char *) &val
);
734 supply_register (FPS_REGNUM
, (char *) &val
);
735 supply_register (EXO_REGNUM
, (char *) &val
);
740 /********************************************************* UDI_STORE_REGISTERS
741 ** Store register regno into the target.
742 * If regno==-1 then store all the registers.
746 udi_store_registers (regno
)
754 UDIBool HostEndian
= 0;
758 store_register(regno
);
764 printf_unfiltered("Storing all registers\n");
765 printf_unfiltered("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
766 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
771 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
772 To
.Space
= UDI29KGlobalRegs
;
775 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
776 error("UDIWrite() failed in udi_store_regisetrs");
778 #if defined(GR64_REGNUM)
780 /* Global registers gr64-gr95 */
782 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
783 To
.Space
= UDI29KGlobalRegs
;
786 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
787 error("UDIWrite() failed in udi_store_regisetrs");
789 #endif /* GR64_REGNUM */
791 /* Global registers gr96-gr127 */
793 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
794 To
.Space
= UDI29KGlobalRegs
;
797 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
798 error("UDIWrite() failed in udi_store_regisetrs");
800 /* Local Registers */
802 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
803 To
.Space
= UDI29KLocalRegs
;
806 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
807 error("UDIWrite() failed in udi_store_regisetrs");
810 /* Protected Special Registers */ /* VAB through TMR */
812 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
813 To
.Space
= UDI29KSpecialRegs
;
816 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
817 error("UDIWrite() failed in udi_store_regisetrs");
819 /* PC0, PC1, PC2 possibly as shadow registers */
821 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
822 To
.Space
= UDI29KSpecialRegs
;
825 To
.Offset
= 20; /* SPC0 */
827 To
.Offset
= 10; /* PC0 */
828 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
829 error("UDIWrite() failed in udi_store_regisetrs");
831 /* PC1 via UDI29KPC */
833 From
= (UDIUInt32
*)®isters
[4 * PC_REGNUM
];
835 To
.Offset
= 0; /* PC1 */
837 if (UDIWrite (From
, To
, Count
, Size
, &CountDone
, HostEndian
))
838 error ("UDIWrite() failed in udi_store_regisetrs");
842 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
843 To
.Space
= UDI29KSpecialRegs
;
846 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
847 error("UDIWrite() failed in udi_store_regisetrs");
849 /* Unprotected Special Registers */
851 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
852 To
.Space
= UDI29KSpecialRegs
;
855 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
856 error("UDIWrite() failed in udi_store_regisetrs");
858 registers_changed ();
861 /****************************************************** UDI_PREPARE_TO_STORE */
862 /* Get ready to modify the registers array. On machines which store
863 individual registers, this doesn't need to do anything. On machines
864 which store all the registers in one fell swoop, this makes sure
865 that registers contains all the registers from the program being
869 udi_prepare_to_store ()
871 /* Do nothing, since we can store individual regs */
874 /********************************************************** TRANSLATE_ADDR */
879 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
880 /* Check for a virtual address in the kernel */
881 /* Assume physical address of ublock is in paddr_u register */
882 /* FIXME: doesn't work for user virtual addresses */
883 if (addr
>= UVADDR
) {
884 /* PADDR_U register holds the physical address of the ublock */
885 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
886 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
894 /************************************************* UDI_XFER_INFERIOR_MEMORY */
895 /* FIXME! Merge these two. */
897 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
904 memaddr
= translate_addr(memaddr
);
907 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
909 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
912 /********************************************************** UDI_FILES_INFO */
916 printf_unfiltered ("\tAttached to UDI socket to %s and running program %s.\n",
917 udi_config_id
, prog_name
);
920 /**************************************************** UDI_INSERT_BREAKPOINT */
922 udi_insert_breakpoint (addr
, contents_cache
)
924 char *contents_cache
;
929 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
930 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
933 if(cnt
>= BKPT_TABLE_SIZE
)
934 error("Too many breakpoints set");
936 bkpt_table
[cnt
].Addr
.Offset
= addr
;
937 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
938 bkpt_table
[cnt
].PassCount
= 1;
939 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
941 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
942 bkpt_table
[cnt
].PassCount
,
943 bkpt_table
[cnt
].Type
,
944 &bkpt_table
[cnt
].BreakId
);
946 if (err
== 0) return 0; /* Success */
948 bkpt_table
[cnt
].Type
= 0;
949 error("UDISetBreakpoint returned error code %d\n", err
);
952 /**************************************************** UDI_REMOVE_BREAKPOINT */
954 udi_remove_breakpoint (addr
, contents_cache
)
956 char *contents_cache
;
961 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
962 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
965 if(cnt
>= BKPT_TABLE_SIZE
)
966 error("Can't find breakpoint in table");
968 bkpt_table
[cnt
].Type
= 0;
970 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
971 if (err
== 0) return 0; /* Success */
973 error("UDIClearBreakpoint returned error code %d\n", err
);
977 udi_kill(arg
,from_tty
)
984 UDIStop does not really work as advertised. It causes the TIP to close it's
985 connection, which usually results in GDB dying with a SIGPIPE. For now, we
986 just invoke udi_close, which seems to get things right.
994 printf_unfiltered("Target has been stopped.");
1001 /* Keep the target around, e.g. so "run" can do the right thing when
1002 we are already debugging something. */
1008 Load a program into the target. Args are: `program {options}'. The options
1009 are used to control loading of the program, and are NOT passed onto the
1010 loaded code as arguments. (You need to use the `run' command to do that.)
1013 -ms %d Set mem stack size to %d
1014 -rs %d Set regular stack size to %d
1015 -i send init info (default)
1016 -noi don't send init info
1017 -[tT] Load Text section
1018 -[dD] Load Data section
1019 -[bB] Load BSS section
1020 -[lL] Load Lit section
1024 download(load_arg_string
, from_tty
)
1025 char *load_arg_string
;
1028 #define DEFAULT_MEM_STACK_SIZE 0x6000
1029 #define DEFAULT_REG_STACK_SIZE 0x2000
1036 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1038 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1039 address_ranges
[0].Offset
= 0xffffffff;
1040 address_ranges
[0].Size
= 0;
1042 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1043 address_ranges
[1].Offset
= 0xffffffff;
1044 address_ranges
[1].Size
= 0;
1046 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1047 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1051 filename
= strtok(load_arg_string
, " \t");
1053 error ("Must specify at least a file name with the load command");
1055 filename
= tilde_expand (filename
);
1056 make_cleanup (free
, filename
);
1058 while (token
= strtok (NULL
, " \t"))
1060 if (token
[0] == '-')
1064 if (STREQ (token
, "ms"))
1065 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1066 else if (STREQ (token
, "rs"))
1067 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1070 load_text
= load_data
= load_bss
= load_lit
= 0;
1093 error ("Unknown UDI load option -%s", token
-1);
1100 pbfd
= bfd_openr (filename
, gnutarget
);
1103 perror_with_name (filename
);
1105 make_cleanup (bfd_close
, pbfd
);
1110 if (!bfd_check_format (pbfd
, bfd_object
))
1111 error ("It doesn't seem to be an object file");
1113 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1115 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1119 unsigned long section_size
, section_end
;
1120 const char *section_name
;
1122 section_name
= bfd_get_section_name (pbfd
, section
);
1123 if (STREQ (section_name
, ".text") && !load_text
)
1125 else if (STREQ (section_name
, ".data") && !load_data
)
1127 else if (STREQ (section_name
, ".bss") && !load_bss
)
1129 else if (STREQ (section_name
, ".lit") && !load_lit
)
1132 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1133 section_size
= bfd_section_size (pbfd
, section
);
1134 section_end
= To
.Offset
+ section_size
;
1136 if (section_size
== 0)
1137 /* This is needed at least in the BSS case, where the code
1138 below starts writing before it even checks the size. */
1141 printf_unfiltered("[Loading section %s at %x (%d bytes)]\n",
1146 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1148 To
.Space
= UDI29KIRAMSpace
;
1150 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1152 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1154 - address_ranges
[0].Offset
);
1158 To
.Space
= UDI29KDRAMSpace
;
1160 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1162 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1164 - address_ranges
[1].Offset
);
1167 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1173 while (section_size
> 0)
1177 Count
= min (section_size
, 1024);
1179 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1182 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1185 (UDISizeT
)1, /* Size */
1186 &Count
, /* CountDone */
1187 (UDIBool
)0); /* HostEndian */
1189 error ("UDIWrite failed, error = %d", err
);
1193 section_size
-= Count
;
1199 unsigned long zero
= 0;
1201 /* Write a zero byte at the vma */
1202 /* FIXME: Broken for sections of 1-3 bytes (we test for
1204 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1206 (UDICount
)1, /* Count */
1207 (UDISizeT
)4, /* Size */
1208 &Count
, /* CountDone */
1209 (UDIBool
)0); /* HostEndian */
1211 error ("UDIWrite failed, error = %d", err
);
1216 /* Now, duplicate it for the length of the BSS */
1217 err
= UDICopy (From
, /* From */
1219 (UDICount
)(section_size
/4 - 1), /* Count */
1220 (UDISizeT
)4, /* Size */
1221 &Count
, /* CountDone */
1222 (UDIBool
)1); /* Direction */
1228 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1230 fprintf_unfiltered (gdb_stderr
, "Error is %s\n", message
);
1232 fprintf_unfiltered (gdb_stderr
, "xerr is %d\n", xerr
);
1233 error ("UDICopy failed, error = %d", err
);
1240 entry
.Space
= UDI29KIRAMSpace
;
1241 entry
.Offset
= bfd_get_start_address (pbfd
);
1246 /* User interface to download an image into the remote target. See download()
1247 * for details on args.
1251 udi_load(args
, from_tty
)
1255 download (args
, from_tty
);
1257 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1260 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1261 ** Copy LEN bytes of data from debugger memory at MYADDR
1262 to inferior's memory at MEMADDR. Returns number of bytes written. */
1264 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1274 UDICount CountDone
= 0;
1275 UDIBool HostEndian
= 0;
1277 To
.Space
= udi_memory_space(memaddr
);
1278 From
= (UDIUInt32
*)myaddr
;
1280 while (nwritten
< len
)
1281 { Count
= len
- nwritten
;
1282 if (Count
> MAXDATA
) Count
= MAXDATA
;
1283 To
.Offset
= memaddr
+ nwritten
;
1284 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1285 { error("UDIWrite() failed in udi_write_inferrior_memory");
1289 { nwritten
+= CountDone
;
1296 /**************************************************** UDI_READ_INFERIOR_MEMORY
1297 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1298 at debugger address MYADDR. Returns number of bytes read. */
1300 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1310 UDICount CountDone
= 0;
1311 UDIBool HostEndian
= 0;
1314 From
.Space
= udi_memory_space(memaddr
);
1315 To
= (UDIUInt32
*)myaddr
;
1318 { Count
= len
- nread
;
1319 if (Count
> MAXDATA
) Count
= MAXDATA
;
1320 From
.Offset
= memaddr
+ nread
;
1321 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1322 { error("UDIRead() failed in udi_read_inferrior_memory");
1326 { nread
+= CountDone
;
1333 /********************************************************************* WARNING
1338 error ("ERROR while loading program into remote TIP: $d\n", num
);
1342 /*****************************************************************************/
1343 /* Fetch a single register indicatated by 'regno'.
1344 * Returns 0/-1 on success/failure.
1347 fetch_register (regno
)
1355 UDIBool HostEndian
= 0;
1359 if (regno
== GR1_REGNUM
)
1361 From
.Space
= UDI29KGlobalRegs
;
1364 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1366 From
.Space
= UDI29KGlobalRegs
;
1367 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1370 #if defined(GR64_REGNUM)
1372 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1374 From
.Space
= UDI29KGlobalRegs
;
1375 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1378 #endif /* GR64_REGNUM */
1380 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1382 From
.Space
= UDI29KLocalRegs
;
1383 From
.Offset
= (regno
- LR0_REGNUM
);
1385 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1388 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1389 return; /* Pretend Success */
1393 From
.Space
= UDI29KSpecialRegs
;
1394 From
.Offset
= regnum_to_srnum(regno
);
1397 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1398 error("UDIRead() failed in udi_fetch_registers");
1400 supply_register(regno
, (char *) &To
);
1403 printf_unfiltered("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1405 /*****************************************************************************/
1406 /* Store a single register indicated by 'regno'.
1407 * Returns 0/-1 on success/failure.
1410 store_register (regno
)
1419 UDIBool HostEndian
= 0;
1421 From
= read_register (regno
); /* get data value */
1424 printf_unfiltered("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1426 if (regno
== GR1_REGNUM
)
1428 To
.Space
= UDI29KGlobalRegs
;
1430 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1431 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1432 * register cache. Do this *after* calling read_register, because we want
1433 * read_register to return the value that write_register has just stuffed
1434 * into the registers array, not the value of the register fetched from
1437 registers_changed ();
1439 #if defined(GR64_REGNUM)
1440 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1442 To
.Space
= UDI29KGlobalRegs
;
1443 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1444 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1446 #endif /* GR64_REGNUM */
1447 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1449 To
.Space
= UDI29KGlobalRegs
;
1450 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1451 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1453 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1455 To
.Space
= UDI29KLocalRegs
;
1456 To
.Offset
= (regno
- LR0_REGNUM
);
1457 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1459 else if (regno
>= FPE_REGNUM
&& regno
<= EXO_REGNUM
)
1460 return 0; /* Pretend Success */
1461 else if (regno
== PC_REGNUM
)
1463 /* PC1 via UDI29KPC */
1465 To
.Space
= UDI29KPC
;
1466 To
.Offset
= 0; /* PC1 */
1467 result
= UDIWrite (&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1469 /* Writing to this loc actually changes the values of pc0 & pc1 */
1471 register_valid
[PC_REGNUM
] = 0; /* pc1 */
1472 register_valid
[NPC_REGNUM
] = 0; /* pc0 */
1474 else /* An unprotected or protected special register */
1476 To
.Space
= UDI29KSpecialRegs
;
1477 To
.Offset
= regnum_to_srnum(regno
);
1478 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1482 error("UDIWrite() failed in store_registers");
1486 /********************************************************** REGNUM_TO_SRNUM */
1488 * Convert a gdb special register number to a 29000 special register number.
1491 regnum_to_srnum(regno
)
1495 case VAB_REGNUM
: return(0);
1496 case OPS_REGNUM
: return(1);
1497 case CPS_REGNUM
: return(2);
1498 case CFG_REGNUM
: return(3);
1499 case CHA_REGNUM
: return(4);
1500 case CHD_REGNUM
: return(5);
1501 case CHC_REGNUM
: return(6);
1502 case RBP_REGNUM
: return(7);
1503 case TMC_REGNUM
: return(8);
1504 case TMR_REGNUM
: return(9);
1505 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1506 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1507 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1508 case MMU_REGNUM
: return(13);
1509 case LRU_REGNUM
: return(14);
1510 case IPC_REGNUM
: return(128);
1511 case IPA_REGNUM
: return(129);
1512 case IPB_REGNUM
: return(130);
1513 case Q_REGNUM
: return(131);
1514 case ALU_REGNUM
: return(132);
1515 case BP_REGNUM
: return(133);
1516 case FC_REGNUM
: return(134);
1517 case CR_REGNUM
: return(135);
1518 case FPE_REGNUM
: return(160);
1519 case INTE_REGNUM
: return(161);
1520 case FPS_REGNUM
: return(162);
1521 case EXO_REGNUM
:return(164);
1523 return(255); /* Failure ? */
1526 /****************************************************************************/
1528 * Determine the Target memory space qualifier based on the addr.
1529 * FIXME: Can't distinguis I_ROM/D_ROM.
1530 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1533 udi_memory_space(addr
)
1536 UDIUInt32 tstart
= IMemStart
;
1537 UDIUInt32 tend
= tstart
+ IMemSize
;
1538 UDIUInt32 dstart
= DMemStart
;
1539 UDIUInt32 dend
= tstart
+ DMemSize
;
1540 UDIUInt32 rstart
= RMemStart
;
1541 UDIUInt32 rend
= tstart
+ RMemSize
;
1543 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1544 return UDI29KIRAMSpace
;
1545 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1546 return UDI29KDRAMSpace
;
1547 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1548 /* FIXME: how do we determine between D_ROM and I_ROM */
1549 return UDI29KIROMSpace
;
1550 } else /* FIXME: what do me do now? */
1551 return UDI29KDRAMSpace
; /* Hmmm! */
1553 /*********************************************************************** STUBS
1556 void convert16() {;}
1557 void convert32() {;}
1558 GDB_FILE
* EchoFile
= 0; /* used for debugging */
1559 int QuietMode
= 0; /* used for debugging */
1561 #ifdef NO_HIF_SUPPORT
1565 return(0); /* Emulate a failure */
1569 /* Target_ops vector. Not static because there does not seem to be
1570 any portable way to do a forward declaration of a static variable.
1571 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1572 /bin/cc doesn't like "static" twice. */
1574 struct target_ops udi_ops
= {
1576 "Remote UDI connected TIP",
1577 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1579 `configuration-id AF_INET hostname port-number'\n\
1580 To connect via the network, where hostname and port-number specify the\n\
1581 host and port where you can connect via UDI.\n\
1582 configuration-id is unused.\n\
1584 `configuration-id AF_UNIX socket-name tip-program'\n\
1585 To connect using a local connection to the \"tip.exe\" program which is\n\
1586 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1587 tip program must already be started; connect to it using that socket.\n\
1588 If not, start up tip-program, which should be the name of the tip\n\
1589 program. If appropriate, the PATH environment variable is searched.\n\
1590 configuration-id is unused.\n\
1592 `configuration-id'\n\
1593 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1594 are files containing lines in the above formats. configuration-id is\n\
1595 used to pick which line of the file to use.",
1602 udi_fetch_registers
,
1603 udi_store_registers
,
1604 udi_prepare_to_store
,
1605 udi_xfer_inferior_memory
,
1607 udi_insert_breakpoint
,
1608 udi_remove_breakpoint
,
1609 0, /* termial_init */
1610 0, /* terminal_inferior */
1611 0, /* terminal_ours_for_output */
1612 0, /* terminal_ours */
1613 0, /* terminal_info */
1614 udi_kill
, /* FIXME, kill */
1616 0, /* lookup_symbol */
1617 udi_create_inferior
,
1618 udi_mourn
, /* mourn_inferior FIXME */
1620 0, /* notice_signals */
1623 1, /* has_all_memory */
1626 1, /* has_registers */
1627 1, /* has_execution */
1629 0, /* sections_end */
1630 OPS_MAGIC
, /* Always the last thing */
1634 _initialize_remote_udi ()
1636 add_target (&udi_ops
);