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 remote_debug
;
54 extern int stop_soon_quietly
; /* for wait_for_inferior */
55 extern struct value
*call_function_by_hand();
56 static void udi_resume
PARAMS ((int pid
, int step
, int sig
));
57 static void udi_fetch_registers
PARAMS ((int regno
));
58 static void udi_load
PARAMS ((char *args
, int from_tty
));
59 static void fetch_register
PARAMS ((int regno
));
60 static void udi_store_registers
PARAMS ((int regno
));
61 static int store_register
PARAMS ((int regno
));
62 static int regnum_to_srnum
PARAMS ((int regno
));
63 static void udi_close
PARAMS ((int quitting
));
64 static CPUSpace udi_memory_space
PARAMS ((CORE_ADDR addr
));
65 static int udi_write_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
67 static int udi_read_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
69 static void download
PARAMS ((char *load_arg_string
, int from_tty
));
70 char CoffFileName
[100] = "";
72 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
73 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
75 /* FIXME: Replace with `set remotedebug'. Also, seems not to be used. */
76 #define LLOG_FILE "udi.log"
77 #if defined (LOG_FILE)
81 static int timeout
= 5;
82 extern struct target_ops udi_ops
; /* Forward declaration */
84 /* Special register enumeration.
87 /******************************************************************* UDI DATA*/
88 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
89 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
90 udi_open knows that we don't have a file open when the program
93 UDISessionId udi_session_id
= -1;
95 CPUOffset IMemStart
= 0;
96 CPUSizeT IMemSize
= 0;
97 CPUOffset DMemStart
= 0;
98 CPUSizeT DMemSize
= 0;
99 CPUOffset RMemStart
= 0;
100 CPUSizeT RMemSize
= 0;
104 UDIMemoryRange address_ranges
[2]; /* Text and data */
105 UDIResource entry
= {0, 0}; /* Entry point */
106 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
108 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
111 typedef struct bkpt_entry_str
116 unsigned int BreakId
;
118 #define BKPT_TABLE_SIZE 40
119 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
120 extern char dfe_errmsg
[]; /* error string */
122 /* malloc'd name of the program on the remote system. */
123 static char *prog_name
= NULL
;
125 /* Number of SIGTRAPs we need to simulate. That is, the next
126 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
127 SIGTRAP without actually waiting for anything. */
129 /* This is called not only when we first attach, but also when the
130 user types "run" after having attached. */
133 udi_create_inferior (execfile
, args
, env
)
142 if (prog_name
!= NULL
)
144 prog_name
= savestring (execfile
, strlen (execfile
));
146 else if (entry
.Offset
)
149 error ("No image loaded into target.");
151 if (udi_session_id
< 0)
153 printf("UDI connection not open yet.\n");
157 inferior_pid
= 40000;
160 download(execfile
, 0);
162 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
164 strcpy (args1
, execfile
);
166 strcat (args1
, args
);
168 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
169 (UDIInt
)2, /* NumberOfRanges */
170 entry
, /* EntryPoint */
171 stack_sizes
, /* *StackSizes */
172 (UDIInt
)2, /* NumberOfStacks */
173 args1
); /* ArgString */
175 init_wait_for_inferior ();
176 clear_proceed_status ();
184 /* Requiring "target udi" each time you run is a major pain. I suspect
185 this was just blindy copied from remote.c, in which "target" and
186 "run" are combined. Having a udi target without an inferior seems
187 to work between "target udi" and "run", so why not now? */
188 pop_target (); /* Pop back to no-child state */
190 generic_mourn_inferior ();
193 /******************************************************************** UDI_OPEN
194 ** Open a connection to remote TIP.
195 NAME is the socket domain used for communication with the TIP,
196 then a space and the socket name or TIP-host name.
197 '<udi_udi_config_id>' for example.
200 /* XXX - need cleanups for udiconnect for various failures!!! */
202 static char *udi_config_id
;
204 udi_open (name
, from_tty
)
211 UDIMemoryRange KnownMemory
[10];
212 UDIUInt32 ChipVersions
[10];
213 UDIInt NumberOfRanges
= 10;
214 UDIInt NumberOfChips
= 10;
216 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
218 target_preopen(from_tty
);
222 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
223 bkpt_table
[cnt
].Type
= 0;
226 free (udi_config_id
);
229 error("Usage: target udi config_id, where config_id appears in udi_soc file");
231 udi_config_id
= strdup (strtok (name
, " \t"));
233 if (UDIConnect (udi_config_id
, &udi_session_id
))
234 error("UDIConnect() failed: %s\n", dfe_errmsg
);
236 push_target (&udi_ops
);
238 #if defined (LOG_FILE)
239 log_file
= fopen (LOG_FILE
, "w");
240 if (log_file
== NULL
)
241 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
244 ** Initialize target configuration structure (global)
246 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
247 ChipVersions
, &NumberOfChips
))
248 error ("UDIGetTargetConfig() failed");
249 if (NumberOfChips
> 2)
250 fprintf(stderr
,"Target has more than one processor\n");
251 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
253 switch(KnownMemory
[cnt
].Space
)
256 fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
260 case UDI29KIROMSpace
:
261 RMemStart
= KnownMemory
[cnt
].Offset
;
262 RMemSize
= KnownMemory
[cnt
].Size
;
264 case UDI29KIRAMSpace
:
265 IMemStart
= KnownMemory
[cnt
].Offset
;
266 IMemSize
= KnownMemory
[cnt
].Size
;
268 case UDI29KDRAMSpace
:
269 DMemStart
= KnownMemory
[cnt
].Offset
;
270 DMemSize
= KnownMemory
[cnt
].Size
;
275 a29k_get_processor_type ();
277 if (UDICreateProcess (&PId
))
278 fprintf(stderr
, "UDICreateProcess() failed\n");
280 /* Print out some stuff, letting the user now what's going on */
281 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
283 error ("UDICapabilities() failed");
286 printf_filtered ("Connected via UDI socket,\n\
287 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
288 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
289 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
290 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
295 /******************************************************************* UDI_CLOSE
296 Close the open connection to the TIP process.
297 Use this when you want to detach and do something else
300 udi_close (quitting
) /*FIXME: how is quitting used */
303 if (udi_session_id
< 0)
306 /* We should never get here if there isn't something valid in
309 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
310 error ("UDIDisconnect() failed in udi_close");
312 /* Do not try to close udi_session_id again, later in the program. */
316 #if defined (LOG_FILE)
317 if (ferror (log_file
))
318 printf ("Error writing log file.\n");
319 if (fclose (log_file
) != 0)
320 printf ("Error closing log file.\n");
323 printf_filtered (" Ending remote debugging\n");
326 /**************************************************************** UDI_ATACH */
327 /* Attach to a program that is already loaded and running
328 * Upon exiting the process's execution is stopped.
331 udi_attach (args
, from_tty
)
340 UDIBool HostEndian
= 0;
343 if (udi_session_id
< 0)
344 error ("UDI connection not opened yet, use the 'target udi' command.\n");
347 printf ("Attaching to remote program %s...\n", prog_name
);
350 From
.Space
= UDI29KSpecialRegs
;
352 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
353 error ("UDIRead failed in udi_attach");
354 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
356 /************************************************************* UDI_DETACH */
357 /* Terminate the open connection to the TIP process.
358 Use this when you want to detach and do something else
359 with your gdb. Leave remote process running (with no breakpoints set). */
361 udi_detach (args
,from_tty
)
366 remove_breakpoints(); /* Just in case there were any left in */
368 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
369 error ("UDIDisconnect() failed in udi_detach");
371 pop_target(); /* calls udi_close to do the real work */
374 printf ("Ending remote debugging\n");
378 /****************************************************************** UDI_RESUME
379 ** Tell the remote machine to resume. */
382 udi_resume (pid
, step
, sig
)
387 UDIStepType StepType
= UDIStepNatural
;
390 if (step
) /* step 1 instruction */
392 tip_error
= UDIStep (Steps
, StepType
, Range
);
396 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
397 error ("failed in udi_resume");
401 error ("UDIExecute() failed in udi_resume");
404 /******************************************************************** UDI_WAIT
405 ** Wait until the remote machine stops, then return,
406 storing status in STATUS just as `wait' would. */
409 udi_wait (pid
, status
)
417 int old_timeout
= timeout
;
418 int old_immediate_quit
= immediate_quit
;
421 WSETEXIT ((*status
), 0);
423 /* wait for message to arrive. It should be:
424 If the target stops executing, udi_wait() should return.
426 timeout
= 0; /* Wait indefinetly for a message */
427 immediate_quit
= 1; /* Helps ability to QUIT */
432 MaxTime
= UDIWaitForever
;
433 UDIWait(MaxTime
, &PId
, &StopReason
);
434 QUIT
; /* Let user quit if they want */
436 switch (StopReason
& UDIGrossState
)
439 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
440 /* This is said to happen if the program tries to output
441 a whole bunch of output (more than SBUF_MAX, I would
442 guess). It doesn't seem to happen with the simulator. */
443 warning ("UDIGetStdout() failed in udi_wait");
444 fwrite (sbuf
, 1, CountDone
, stdout
);
448 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
449 fwrite (sbuf
, 1, CountDone
, stderr
);
463 } while (i
< SBUF_MAX
&& ch
!= '\n');
464 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
469 /* In spite of the fact that we told UDIWait to wait forever, it will
470 return spuriously sometimes. */
479 switch (StopReason
& UDIGrossState
)
482 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
484 switch (StopReason
>> 8)
486 case 0: /* Illegal opcode */
487 printf(" (break point)\n");
488 WSETSTOP ((*status
), SIGTRAP
);
490 case 1: /* Unaligned Access */
491 WSETSTOP ((*status
), SIGBUS
);
495 WSETSTOP ((*status
), SIGFPE
);
497 case 5: /* Protection Violation */
498 WSETSTOP ((*status
), SIGILL
);
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 WSETSTOP ((*status
), SIGSEGV
);
510 WSETSTOP ((*status
), SIGILL
);
513 WSETSTOP ((*status
), SIGALRM
);
516 WSETSTOP ((*status
), SIGTRAP
);
521 case 19: /* INTR3/Internal */
524 WSETSTOP ((*status
), SIGINT
);
526 case 22: /* Floating-Point Exception */
527 WSETSTOP ((*status
), SIGILL
);
529 case 77: /* assert 77 */
530 WSETSTOP ((*status
), SIGTRAP
);
533 WSETEXIT ((*status
), 0);
536 case UDINotExecuting
:
537 WSETSTOP ((*status
), SIGTERM
);
540 WSETSTOP ((*status
), SIGTSTP
);
543 WSETSTOP ((*status
), SIGURG
);
547 WSETSTOP ((*status
), SIGTRAP
);
550 WSETSTOP ((*status
), SIGSTOP
);
553 WSETSTOP ((*status
), SIGKILL
);
557 WSETEXIT ((*status
), 0);
560 timeout
= old_timeout
; /* Restore original timeout value */
561 immediate_quit
= old_immediate_quit
;
565 /********************************************************** UDI_FETCH_REGISTERS
566 * Read a remote register 'regno'.
567 * If regno==-1 then read all the registers.
570 udi_fetch_registers (regno
)
578 UDIBool HostEndian
= 0;
583 fetch_register(regno
);
589 From
.Space
= UDI29KGlobalRegs
;
591 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
593 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
594 error("UDIRead() failed in udi_fetch_registers");
596 register_valid
[GR1_REGNUM
] = 1;
598 #if defined(GR64_REGNUM) /* Read gr64-127 */
600 /* Global Registers gr64-gr95 */
602 From
.Space
= UDI29KGlobalRegs
;
604 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
606 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
607 error("UDIRead() failed in udi_fetch_registers");
609 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
610 register_valid
[i
] = 1;
612 #endif /* GR64_REGNUM */
614 /* Global Registers gr96-gr127 */
616 From
.Space
= UDI29KGlobalRegs
;
618 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
620 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
621 error("UDIRead() failed in udi_fetch_registers");
623 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
624 register_valid
[i
] = 1;
626 /* Local Registers */
628 From
.Space
= UDI29KLocalRegs
;
630 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
632 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
633 error("UDIRead() failed in udi_fetch_registers");
635 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
636 register_valid
[i
] = 1;
638 /* Protected Special Registers */
640 From
.Space
= UDI29KSpecialRegs
;
642 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
644 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
645 error("UDIRead() failed in udi_fetch_registers");
647 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
648 register_valid
[i
] = 1;
650 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
651 fetch_register(NPC_REGNUM
);
652 fetch_register(PC_REGNUM
);
653 fetch_register(PC2_REGNUM
);
655 /* Unprotected Special Registers sr128-sr135 */
657 From
.Space
= UDI29KSpecialRegs
;
659 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
661 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
662 error("UDIRead() failed in udi_fetch_registers");
664 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
665 register_valid
[i
] = 1;
670 printf("Fetching all registers\n");
671 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
672 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
673 read_register(PC2_REGNUM
));
676 /* There doesn't seem to be any way to get these. */
679 supply_register (FPE_REGNUM
, (char *) &val
);
680 supply_register (INTE_REGNUM
, (char *) &val
);
681 supply_register (FPS_REGNUM
, (char *) &val
);
682 supply_register (EXO_REGNUM
, (char *) &val
);
687 /********************************************************* UDI_STORE_REGISTERS
688 ** Store register regno into the target.
689 * If regno==-1 then store all the registers.
693 udi_store_registers (regno
)
701 UDIBool HostEndian
= 0;
705 store_register(regno
);
711 printf("Storing all registers\n");
712 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
713 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
718 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
719 To
.Space
= UDI29KGlobalRegs
;
722 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
723 error("UDIWrite() failed in udi_store_regisetrs");
725 #if defined(GR64_REGNUM)
727 /* Global registers gr64-gr95 */
729 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
730 To
.Space
= UDI29KGlobalRegs
;
733 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
734 error("UDIWrite() failed in udi_store_regisetrs");
736 #endif /* GR64_REGNUM */
738 /* Global registers gr96-gr127 */
740 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
741 To
.Space
= UDI29KGlobalRegs
;
744 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
745 error("UDIWrite() failed in udi_store_regisetrs");
747 /* Local Registers */
749 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
750 To
.Space
= UDI29KLocalRegs
;
753 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
754 error("UDIWrite() failed in udi_store_regisetrs");
757 /* Protected Special Registers */ /* VAB through TMR */
759 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
760 To
.Space
= UDI29KSpecialRegs
;
763 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
764 error("UDIWrite() failed in udi_store_regisetrs");
766 /* PC0, PC1, PC2 possibly as shadow registers */
768 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
769 To
.Space
= UDI29KSpecialRegs
;
772 To
.Offset
= 20; /* SPC0 */
774 To
.Offset
= 10; /* PC0 */
775 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
776 error("UDIWrite() failed in udi_store_regisetrs");
780 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
781 To
.Space
= UDI29KSpecialRegs
;
784 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
785 error("UDIWrite() failed in udi_store_regisetrs");
787 /* Unprotected Special Registers */
789 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
790 To
.Space
= UDI29KSpecialRegs
;
793 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
794 error("UDIWrite() failed in udi_store_regisetrs");
796 registers_changed ();
799 /****************************************************** UDI_PREPARE_TO_STORE */
800 /* Get ready to modify the registers array. On machines which store
801 individual registers, this doesn't need to do anything. On machines
802 which store all the registers in one fell swoop, this makes sure
803 that registers contains all the registers from the program being
807 udi_prepare_to_store ()
809 /* Do nothing, since we can store individual regs */
812 /********************************************************** TRANSLATE_ADDR */
817 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
818 /* Check for a virtual address in the kernel */
819 /* Assume physical address of ublock is in paddr_u register */
820 /* FIXME: doesn't work for user virtual addresses */
821 if (addr
>= UVADDR
) {
822 /* PADDR_U register holds the physical address of the ublock */
823 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
824 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
832 /************************************************* UDI_XFER_INFERIOR_MEMORY */
833 /* FIXME! Merge these two. */
835 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
842 memaddr
= translate_addr(memaddr
);
845 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
847 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
850 /********************************************************** UDI_FILES_INFO */
854 printf ("\tAttached to UDI socket to %s and running program %s.\n",
855 udi_config_id
, prog_name
);
858 /**************************************************** UDI_INSERT_BREAKPOINT */
860 udi_insert_breakpoint (addr
, contents_cache
)
862 char *contents_cache
;
867 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
868 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
871 if(cnt
>= BKPT_TABLE_SIZE
)
872 error("Too many breakpoints set");
874 bkpt_table
[cnt
].Addr
.Offset
= addr
;
875 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
876 bkpt_table
[cnt
].PassCount
= 1;
877 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
879 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
880 bkpt_table
[cnt
].PassCount
,
881 bkpt_table
[cnt
].Type
,
882 &bkpt_table
[cnt
].BreakId
);
884 if (err
== 0) return 0; /* Success */
886 bkpt_table
[cnt
].Type
= 0;
887 error("UDISetBreakpoint returned error code %d\n", err
);
890 /**************************************************** UDI_REMOVE_BREAKPOINT */
892 udi_remove_breakpoint (addr
, contents_cache
)
894 char *contents_cache
;
899 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
900 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
903 if(cnt
>= BKPT_TABLE_SIZE
)
904 error("Can't find breakpoint in table");
906 bkpt_table
[cnt
].Type
= 0;
908 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
909 if (err
== 0) return 0; /* Success */
911 error("UDIClearBreakpoint returned error code %d\n", err
);
915 udi_kill(arg
,from_tty
)
922 UDIStop does not really work as advertised. It causes the TIP to close it's
923 connection, which usually results in GDB dying with a SIGPIPE. For now, we
924 just invoke udi_close, which seems to get things right.
932 printf("Target has been stopped.");
940 Load a program into the target. Args are: `program {options}'. The options
941 are used to control loading of the program, and are NOT passed onto the
942 loaded code as arguments. (You need to use the `run' command to do that.)
945 -ms %d Set mem stack size to %d
946 -rs %d Set regular stack size to %d
947 -i send init info (default)
948 -noi don't send init info
949 -[tT] Load Text section
950 -[dD] Load Data section
951 -[bB] Load BSS section
952 -[lL] Load Lit section
956 download(load_arg_string
, from_tty
)
957 char *load_arg_string
;
960 #define DEFAULT_MEM_STACK_SIZE 0x6000
961 #define DEFAULT_REG_STACK_SIZE 0x2000
968 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
970 address_ranges
[0].Space
= UDI29KIRAMSpace
;
971 address_ranges
[0].Offset
= 0xffffffff;
972 address_ranges
[0].Size
= 0;
974 address_ranges
[1].Space
= UDI29KDRAMSpace
;
975 address_ranges
[1].Offset
= 0xffffffff;
976 address_ranges
[1].Size
= 0;
978 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
979 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
983 filename
= strtok(load_arg_string
, " \t");
985 error ("Must specify at least a file name with the load command");
987 filename
= tilde_expand (filename
);
988 make_cleanup (free
, filename
);
990 while (token
= strtok (NULL
, " \t"))
996 if (STREQ (token
, "ms"))
997 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
998 else if (STREQ (token
, "rs"))
999 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1002 load_text
= load_data
= load_bss
= load_lit
= 0;
1025 error ("Unknown UDI load option -%s", token
-1);
1032 pbfd
= bfd_openr (filename
, gnutarget
);
1035 perror_with_name (filename
);
1037 make_cleanup (bfd_close
, pbfd
);
1042 if (!bfd_check_format (pbfd
, bfd_object
))
1043 error ("It doesn't seem to be an object file");
1045 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1047 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1051 unsigned long section_size
, section_end
;
1052 const char *section_name
;
1054 section_name
= bfd_get_section_name (pbfd
, section
);
1055 if (STREQ (section_name
, ".text") && !load_text
)
1057 else if (STREQ (section_name
, ".data") && !load_data
)
1059 else if (STREQ (section_name
, ".bss") && !load_bss
)
1061 else if (STREQ (section_name
, ".lit") && !load_lit
)
1064 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1065 section_size
= bfd_section_size (pbfd
, section
);
1066 section_end
= To
.Offset
+ section_size
;
1068 if (section_size
== 0)
1069 /* This is needed at least in the BSS case, where the code
1070 below starts writing before it even checks the size. */
1073 printf("[Loading section %s at %x (%d bytes)]\n",
1078 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1080 To
.Space
= UDI29KIRAMSpace
;
1082 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1084 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1086 - address_ranges
[0].Offset
);
1090 To
.Space
= UDI29KDRAMSpace
;
1092 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1094 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1096 - address_ranges
[1].Offset
);
1099 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1105 while (section_size
> 0)
1109 Count
= min (section_size
, 1024);
1111 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1114 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1117 (UDISizeT
)1, /* Size */
1118 &Count
, /* CountDone */
1119 (UDIBool
)0); /* HostEndian */
1121 error ("UDIWrite failed, error = %d", err
);
1125 section_size
-= Count
;
1131 unsigned long zero
= 0;
1133 /* Write a zero byte at the vma */
1134 /* FIXME: Broken for sections of 1-3 bytes (we test for
1136 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1138 (UDICount
)1, /* Count */
1139 (UDISizeT
)4, /* Size */
1140 &Count
, /* CountDone */
1141 (UDIBool
)0); /* HostEndian */
1143 error ("UDIWrite failed, error = %d", err
);
1148 /* Now, duplicate it for the length of the BSS */
1149 err
= UDICopy (From
, /* From */
1151 (UDICount
)(section_size
/4 - 1), /* Count */
1152 (UDISizeT
)4, /* Size */
1153 &Count
, /* CountDone */
1154 (UDIBool
)1); /* Direction */
1160 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1162 fprintf (stderr
, "Error is %s\n", message
);
1164 fprintf (stderr
, "xerr is %d\n", xerr
);
1165 error ("UDICopy failed, error = %d", err
);
1172 entry
.Space
= UDI29KIRAMSpace
;
1173 entry
.Offset
= bfd_get_start_address (pbfd
);
1178 /* User interface to download an image into the remote target. See download()
1179 * for details on args.
1183 udi_load(args
, from_tty
)
1187 download (args
, from_tty
);
1189 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1192 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1193 ** Copy LEN bytes of data from debugger memory at MYADDR
1194 to inferior's memory at MEMADDR. Returns number of bytes written. */
1196 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1206 UDICount CountDone
= 0;
1207 UDIBool HostEndian
= 0;
1209 To
.Space
= udi_memory_space(memaddr
);
1210 From
= (UDIUInt32
*)myaddr
;
1212 while (nwritten
< len
)
1213 { Count
= len
- nwritten
;
1214 if (Count
> MAXDATA
) Count
= MAXDATA
;
1215 To
.Offset
= memaddr
+ nwritten
;
1216 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1217 { error("UDIWrite() failed in udi_write_inferrior_memory");
1221 { nwritten
+= CountDone
;
1228 /**************************************************** UDI_READ_INFERIOR_MEMORY
1229 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1230 at debugger address MYADDR. Returns number of bytes read. */
1232 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1242 UDICount CountDone
= 0;
1243 UDIBool HostEndian
= 0;
1246 From
.Space
= udi_memory_space(memaddr
);
1247 To
= (UDIUInt32
*)myaddr
;
1250 { Count
= len
- nread
;
1251 if (Count
> MAXDATA
) Count
= MAXDATA
;
1252 From
.Offset
= memaddr
+ nread
;
1253 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1254 { error("UDIRead() failed in udi_read_inferrior_memory");
1258 { nread
+= CountDone
;
1265 /********************************************************************* WARNING
1270 error ("ERROR while loading program into remote TIP: $d\n", num
);
1274 /*****************************************************************************/
1275 /* Fetch a single register indicatated by 'regno'.
1276 * Returns 0/-1 on success/failure.
1279 fetch_register (regno
)
1287 UDIBool HostEndian
= 0;
1291 if (regno
== GR1_REGNUM
)
1293 From
.Space
= UDI29KGlobalRegs
;
1296 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1298 From
.Space
= UDI29KGlobalRegs
;
1299 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1302 #if defined(GR64_REGNUM)
1304 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1306 From
.Space
= UDI29KGlobalRegs
;
1307 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1310 #endif /* GR64_REGNUM */
1312 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1314 From
.Space
= UDI29KLocalRegs
;
1315 From
.Offset
= (regno
- LR0_REGNUM
);
1317 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1320 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1321 return; /* Pretend Success */
1325 From
.Space
= UDI29KSpecialRegs
;
1326 From
.Offset
= regnum_to_srnum(regno
);
1329 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1330 error("UDIRead() failed in udi_fetch_registers");
1332 supply_register(regno
, (char *) &To
);
1335 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1337 /*****************************************************************************/
1338 /* Store a single register indicated by 'regno'.
1339 * Returns 0/-1 on success/failure.
1342 store_register (regno
)
1351 UDIBool HostEndian
= 0;
1353 From
= read_register (regno
); /* get data value */
1356 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1358 if (regno
== GR1_REGNUM
)
1359 { To
.Space
= UDI29KGlobalRegs
;
1361 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1362 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1363 * register cache. Do this *after* calling read_register, because we want
1364 * read_register to return the value that write_register has just stuffed
1365 * into the registers array, not the value of the register fetched from
1368 registers_changed ();
1370 #if defined(GR64_REGNUM)
1371 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1372 { To
.Space
= UDI29KGlobalRegs
;
1373 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1374 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1376 #endif /* GR64_REGNUM */
1377 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1378 { To
.Space
= UDI29KGlobalRegs
;
1379 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1380 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1382 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1383 { To
.Space
= UDI29KLocalRegs
;
1384 To
.Offset
= (regno
- LR0_REGNUM
);
1385 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1387 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1389 return 0; /* Pretend Success */
1391 else /* An unprotected or protected special register */
1392 { To
.Space
= UDI29KSpecialRegs
;
1393 To
.Offset
= regnum_to_srnum(regno
);
1394 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1399 error("UDIWrite() failed in store_registers");
1403 /********************************************************** REGNUM_TO_SRNUM */
1405 * Convert a gdb special register number to a 29000 special register number.
1408 regnum_to_srnum(regno
)
1412 case VAB_REGNUM
: return(0);
1413 case OPS_REGNUM
: return(1);
1414 case CPS_REGNUM
: return(2);
1415 case CFG_REGNUM
: return(3);
1416 case CHA_REGNUM
: return(4);
1417 case CHD_REGNUM
: return(5);
1418 case CHC_REGNUM
: return(6);
1419 case RBP_REGNUM
: return(7);
1420 case TMC_REGNUM
: return(8);
1421 case TMR_REGNUM
: return(9);
1422 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1423 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1424 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1425 case MMU_REGNUM
: return(13);
1426 case LRU_REGNUM
: return(14);
1427 case IPC_REGNUM
: return(128);
1428 case IPA_REGNUM
: return(129);
1429 case IPB_REGNUM
: return(130);
1430 case Q_REGNUM
: return(131);
1431 case ALU_REGNUM
: return(132);
1432 case BP_REGNUM
: return(133);
1433 case FC_REGNUM
: return(134);
1434 case CR_REGNUM
: return(135);
1435 case FPE_REGNUM
: return(160);
1436 case INTE_REGNUM
: return(161);
1437 case FPS_REGNUM
: return(162);
1438 case EXO_REGNUM
:return(164);
1440 return(255); /* Failure ? */
1443 /****************************************************************************/
1445 * Determine the Target memory space qualifier based on the addr.
1446 * FIXME: Can't distinguis I_ROM/D_ROM.
1447 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1450 udi_memory_space(addr
)
1453 UDIUInt32 tstart
= IMemStart
;
1454 UDIUInt32 tend
= tstart
+ IMemSize
;
1455 UDIUInt32 dstart
= DMemStart
;
1456 UDIUInt32 dend
= tstart
+ DMemSize
;
1457 UDIUInt32 rstart
= RMemStart
;
1458 UDIUInt32 rend
= tstart
+ RMemSize
;
1460 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1461 return UDI29KIRAMSpace
;
1462 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1463 return UDI29KDRAMSpace
;
1464 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1465 /* FIXME: how do we determine between D_ROM and I_ROM */
1466 return UDI29KIROMSpace
;
1467 } else /* FIXME: what do me do now? */
1468 return UDI29KDRAMSpace
; /* Hmmm! */
1470 /*********************************************************************** STUBS
1473 void convert16() {;}
1474 void convert32() {;}
1475 FILE* EchoFile
= 0; /* used for debugging */
1476 int QuietMode
= 0; /* used for debugging */
1478 /* Target_ops vector. Not static because there does not seem to be
1479 any portable way to do a forward declaration of a static variable.
1480 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1481 /bin/cc doesn't like "static" twice. */
1483 struct target_ops udi_ops
= {
1485 "Remote UDI connected TIP",
1486 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1488 `configuration-id AF_INET hostname port-number'\n\
1489 To connect via the network, where hostname and port-number specify the\n\
1490 host and port where you can connect via UDI.\n\
1491 configuration-id is unused.\n\
1493 `configuration-id AF_UNIX socket-name tip-program'\n\
1494 To connect using a local connection to the \"tip.exe\" program which is\n\
1495 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1496 tip program must already be started; connect to it using that socket.\n\
1497 If not, start up tip-program, which should be the name of the tip\n\
1498 program. If appropriate, the PATH environment variable is searched.\n\
1499 configuration-id is unused.\n\
1501 `configuration-id'\n\
1502 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1503 are files containing lines in the above formats. configuration-id is\n\
1504 used to pick which line of the file to use.",
1511 udi_fetch_registers
,
1512 udi_store_registers
,
1513 udi_prepare_to_store
,
1514 udi_xfer_inferior_memory
,
1516 udi_insert_breakpoint
,
1517 udi_remove_breakpoint
,
1518 0, /* termial_init */
1519 0, /* terminal_inferior */
1520 0, /* terminal_ours_for_output */
1521 0, /* terminal_ours */
1522 0, /* terminal_info */
1523 udi_kill
, /* FIXME, kill */
1525 0, /* lookup_symbol */
1526 udi_create_inferior
,
1527 udi_mourn
, /* mourn_inferior FIXME */
1529 0, /* notice_signals */
1532 1, /* has_all_memory */
1535 1, /* has_registers */
1536 1, /* has_execution */
1538 0, /* sections_end */
1539 OPS_MAGIC
, /* Always the last thing */
1542 void _initialize_remote_udi()
1544 add_target (&udi_ops
);
1547 #ifdef NO_HIF_SUPPORT
1551 return(0); /* Emulate a failure */