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 /* FIXME: Replace with `set remotedebug'. Also, seems not to be used. */
75 #define LLOG_FILE "udi.log"
76 #if defined (LOG_FILE)
80 static int timeout
= 5;
81 extern struct target_ops udi_ops
; /* Forward declaration */
83 /* Special register enumeration.
86 /******************************************************************* UDI DATA*/
87 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
88 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
89 udi_open knows that we don't have a file open when the program
92 UDISessionId udi_session_id
= -1;
94 CPUOffset IMemStart
= 0;
95 CPUSizeT IMemSize
= 0;
96 CPUOffset DMemStart
= 0;
97 CPUSizeT DMemSize
= 0;
98 CPUOffset RMemStart
= 0;
99 CPUSizeT RMemSize
= 0;
103 UDIMemoryRange address_ranges
[2]; /* Text and data */
104 UDIResource entry
= {0, 0}; /* Entry point */
105 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
107 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
110 typedef struct bkpt_entry_str
115 unsigned int BreakId
;
117 #define BKPT_TABLE_SIZE 40
118 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
119 extern char dfe_errmsg
[]; /* error string */
121 /* malloc'd name of the program on the remote system. */
122 static char *prog_name
= NULL
;
124 /* Number of SIGTRAPs we need to simulate. That is, the next
125 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
126 SIGTRAP without actually waiting for anything. */
128 /* This is called not only when we first attach, but also when the
129 user types "run" after having attached. */
132 udi_create_inferior (execfile
, args
, env
)
141 if (prog_name
!= NULL
)
143 prog_name
= savestring (execfile
, strlen (execfile
));
145 else if (entry
.Offset
)
148 error ("No image loaded into target.");
150 if (udi_session_id
< 0)
152 printf("UDI connection not open yet.\n");
156 inferior_pid
= 40000;
159 download(execfile
, 0);
161 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
163 strcpy (args1
, execfile
);
165 strcat (args1
, args
);
167 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
168 (UDIInt
)2, /* NumberOfRanges */
169 entry
, /* EntryPoint */
170 stack_sizes
, /* *StackSizes */
171 (UDIInt
)2, /* NumberOfStacks */
172 args1
); /* ArgString */
174 init_wait_for_inferior ();
175 clear_proceed_status ();
183 /* Requiring "target udi" each time you run is a major pain. I suspect
184 this was just blindy copied from remote.c, in which "target" and
185 "run" are combined. Having a udi target without an inferior seems
186 to work between "target udi" and "run", so why not now? */
187 pop_target (); /* Pop back to no-child state */
189 generic_mourn_inferior ();
192 /******************************************************************** UDI_OPEN
193 ** Open a connection to remote TIP.
194 NAME is the socket domain used for communication with the TIP,
195 then a space and the socket name or TIP-host name.
196 '<udi_udi_config_id>' for example.
199 /* XXX - need cleanups for udiconnect for various failures!!! */
201 static char *udi_config_id
;
203 udi_open (name
, from_tty
)
210 UDIMemoryRange KnownMemory
[10];
211 UDIUInt32 ChipVersions
[10];
212 UDIInt NumberOfRanges
= 10;
213 UDIInt NumberOfChips
= 10;
215 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
217 target_preopen(from_tty
);
221 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
222 bkpt_table
[cnt
].Type
= 0;
225 free (udi_config_id
);
228 error("Usage: target udi config_id, where config_id appears in udi_soc file");
230 udi_config_id
= strdup (strtok (name
, " \t"));
232 if (UDIConnect (udi_config_id
, &udi_session_id
))
233 error("UDIConnect() failed: %s\n", dfe_errmsg
);
235 push_target (&udi_ops
);
237 #if defined (LOG_FILE)
238 log_file
= fopen (LOG_FILE
, "w");
239 if (log_file
== NULL
)
240 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
243 ** Initialize target configuration structure (global)
245 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
246 ChipVersions
, &NumberOfChips
))
247 error ("UDIGetTargetConfig() failed");
248 if (NumberOfChips
> 2)
249 fprintf(stderr
,"Target has more than one processor\n");
250 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
252 switch(KnownMemory
[cnt
].Space
)
255 fprintf(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(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 #if defined (LOG_FILE)
316 if (ferror (log_file
))
317 printf ("Error writing log file.\n");
318 if (fclose (log_file
) != 0)
319 printf ("Error closing log file.\n");
322 printf_filtered (" Ending remote debugging\n");
325 /**************************************************************** UDI_ATACH */
326 /* Attach to a program that is already loaded and running
327 * Upon exiting the process's execution is stopped.
330 udi_attach (args
, from_tty
)
339 UDIBool HostEndian
= 0;
342 if (udi_session_id
< 0)
343 error ("UDI connection not opened yet, use the 'target udi' command.\n");
346 printf ("Attaching to remote program %s...\n", prog_name
);
349 From
.Space
= UDI29KSpecialRegs
;
351 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
352 error ("UDIRead failed in udi_attach");
353 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
355 /************************************************************* UDI_DETACH */
356 /* Terminate the open connection to the TIP process.
357 Use this when you want to detach and do something else
358 with your gdb. Leave remote process running (with no breakpoints set). */
360 udi_detach (args
,from_tty
)
365 remove_breakpoints(); /* Just in case there were any left in */
367 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
368 error ("UDIDisconnect() failed in udi_detach");
370 pop_target(); /* calls udi_close to do the real work */
373 printf ("Ending remote debugging\n");
377 /****************************************************************** UDI_RESUME
378 ** Tell the remote machine to resume. */
381 udi_resume (pid
, step
, sig
)
386 UDIStepType StepType
= UDIStepNatural
;
389 if (step
) /* step 1 instruction */
391 tip_error
= UDIStep (Steps
, StepType
, Range
);
395 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
396 error ("failed in udi_resume");
400 error ("UDIExecute() failed in udi_resume");
403 /******************************************************************** UDI_WAIT
404 ** Wait until the remote machine stops, then return,
405 storing status in STATUS just as `wait' would. */
408 udi_wait (pid
, status
)
416 int old_timeout
= timeout
;
417 int old_immediate_quit
= immediate_quit
;
420 WSETEXIT ((*status
), 0);
422 /* wait for message to arrive. It should be:
423 If the target stops executing, udi_wait() should return.
425 timeout
= 0; /* Wait indefinetly for a message */
426 immediate_quit
= 1; /* Helps ability to QUIT */
431 MaxTime
= UDIWaitForever
;
432 UDIWait(MaxTime
, &PId
, &StopReason
);
433 QUIT
; /* Let user quit if they want */
435 switch (StopReason
& UDIGrossState
)
438 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
439 /* This is said to happen if the program tries to output
440 a whole bunch of output (more than SBUF_MAX, I would
441 guess). It doesn't seem to happen with the simulator. */
442 warning ("UDIGetStdout() failed in udi_wait");
443 fwrite (sbuf
, 1, CountDone
, stdout
);
447 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
448 fwrite (sbuf
, 1, CountDone
, stderr
);
462 } while (i
< SBUF_MAX
&& ch
!= '\n');
463 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
468 /* In spite of the fact that we told UDIWait to wait forever, it will
469 return spuriously sometimes. */
478 switch (StopReason
& UDIGrossState
)
481 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
483 switch (StopReason
>> 8)
485 case 0: /* Illegal opcode */
486 printf(" (break point)\n");
487 WSETSTOP ((*status
), SIGTRAP
);
489 case 1: /* Unaligned Access */
490 WSETSTOP ((*status
), SIGBUS
);
494 WSETSTOP ((*status
), SIGFPE
);
496 case 5: /* Protection Violation */
497 WSETSTOP ((*status
), SIGILL
);
501 case 8: /* User Instruction Mapping Miss */
502 case 9: /* User Data Mapping Miss */
503 case 10: /* Supervisor Instruction Mapping Miss */
504 case 11: /* Supervisor Data Mapping Miss */
505 WSETSTOP ((*status
), SIGSEGV
);
509 WSETSTOP ((*status
), SIGILL
);
512 WSETSTOP ((*status
), SIGALRM
);
515 WSETSTOP ((*status
), SIGTRAP
);
520 case 19: /* INTR3/Internal */
523 WSETSTOP ((*status
), SIGINT
);
525 case 22: /* Floating-Point Exception */
526 WSETSTOP ((*status
), SIGILL
);
528 case 77: /* assert 77 */
529 WSETSTOP ((*status
), SIGTRAP
);
532 WSETEXIT ((*status
), 0);
535 case UDINotExecuting
:
536 WSETSTOP ((*status
), SIGTERM
);
539 WSETSTOP ((*status
), SIGTSTP
);
542 WSETSTOP ((*status
), SIGURG
);
546 WSETSTOP ((*status
), SIGTRAP
);
549 WSETSTOP ((*status
), SIGSTOP
);
552 WSETSTOP ((*status
), SIGKILL
);
556 WSETEXIT ((*status
), 0);
559 timeout
= old_timeout
; /* Restore original timeout value */
560 immediate_quit
= old_immediate_quit
;
564 /********************************************************** UDI_FETCH_REGISTERS
565 * Read a remote register 'regno'.
566 * If regno==-1 then read all the registers.
569 udi_fetch_registers (regno
)
577 UDIBool HostEndian
= 0;
582 fetch_register(regno
);
588 From
.Space
= UDI29KGlobalRegs
;
590 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
592 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
593 error("UDIRead() failed in udi_fetch_registers");
595 register_valid
[GR1_REGNUM
] = 1;
597 #if defined(GR64_REGNUM) /* Read gr64-127 */
599 /* Global Registers gr64-gr95 */
601 From
.Space
= UDI29KGlobalRegs
;
603 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
605 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
606 error("UDIRead() failed in udi_fetch_registers");
608 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
609 register_valid
[i
] = 1;
611 #endif /* GR64_REGNUM */
613 /* Global Registers gr96-gr127 */
615 From
.Space
= UDI29KGlobalRegs
;
617 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
619 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
620 error("UDIRead() failed in udi_fetch_registers");
622 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
623 register_valid
[i
] = 1;
625 /* Local Registers */
627 From
.Space
= UDI29KLocalRegs
;
629 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
631 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
632 error("UDIRead() failed in udi_fetch_registers");
634 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
635 register_valid
[i
] = 1;
637 /* Protected Special Registers */
639 From
.Space
= UDI29KSpecialRegs
;
641 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
643 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
644 error("UDIRead() failed in udi_fetch_registers");
646 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
647 register_valid
[i
] = 1;
649 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
650 fetch_register(NPC_REGNUM
);
651 fetch_register(PC_REGNUM
);
652 fetch_register(PC2_REGNUM
);
654 /* Unprotected Special Registers sr128-sr135 */
656 From
.Space
= UDI29KSpecialRegs
;
658 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
660 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
661 error("UDIRead() failed in udi_fetch_registers");
663 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
664 register_valid
[i
] = 1;
669 printf("Fetching all registers\n");
670 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
671 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
672 read_register(PC2_REGNUM
));
675 /* There doesn't seem to be any way to get these. */
678 supply_register (FPE_REGNUM
, (char *) &val
);
679 supply_register (INTE_REGNUM
, (char *) &val
);
680 supply_register (FPS_REGNUM
, (char *) &val
);
681 supply_register (EXO_REGNUM
, (char *) &val
);
686 /********************************************************* UDI_STORE_REGISTERS
687 ** Store register regno into the target.
688 * If regno==-1 then store all the registers.
692 udi_store_registers (regno
)
700 UDIBool HostEndian
= 0;
704 store_register(regno
);
710 printf("Storing all registers\n");
711 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
712 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
717 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
718 To
.Space
= UDI29KGlobalRegs
;
721 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
722 error("UDIWrite() failed in udi_store_regisetrs");
724 #if defined(GR64_REGNUM)
726 /* Global registers gr64-gr95 */
728 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
729 To
.Space
= UDI29KGlobalRegs
;
732 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
733 error("UDIWrite() failed in udi_store_regisetrs");
735 #endif /* GR64_REGNUM */
737 /* Global registers gr96-gr127 */
739 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
740 To
.Space
= UDI29KGlobalRegs
;
743 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
744 error("UDIWrite() failed in udi_store_regisetrs");
746 /* Local Registers */
748 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
749 To
.Space
= UDI29KLocalRegs
;
752 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
753 error("UDIWrite() failed in udi_store_regisetrs");
756 /* Protected Special Registers */ /* VAB through TMR */
758 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
759 To
.Space
= UDI29KSpecialRegs
;
762 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
763 error("UDIWrite() failed in udi_store_regisetrs");
765 /* PC0, PC1, PC2 possibly as shadow registers */
767 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
768 To
.Space
= UDI29KSpecialRegs
;
771 To
.Offset
= 20; /* SPC0 */
773 To
.Offset
= 10; /* PC0 */
774 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
775 error("UDIWrite() failed in udi_store_regisetrs");
779 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
780 To
.Space
= UDI29KSpecialRegs
;
783 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
784 error("UDIWrite() failed in udi_store_regisetrs");
786 /* Unprotected Special Registers */
788 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
789 To
.Space
= UDI29KSpecialRegs
;
792 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
793 error("UDIWrite() failed in udi_store_regisetrs");
795 registers_changed ();
798 /****************************************************** UDI_PREPARE_TO_STORE */
799 /* Get ready to modify the registers array. On machines which store
800 individual registers, this doesn't need to do anything. On machines
801 which store all the registers in one fell swoop, this makes sure
802 that registers contains all the registers from the program being
806 udi_prepare_to_store ()
808 /* Do nothing, since we can store individual regs */
811 /********************************************************** TRANSLATE_ADDR */
816 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
817 /* Check for a virtual address in the kernel */
818 /* Assume physical address of ublock is in paddr_u register */
819 /* FIXME: doesn't work for user virtual addresses */
820 if (addr
>= UVADDR
) {
821 /* PADDR_U register holds the physical address of the ublock */
822 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
823 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
831 /************************************************* UDI_XFER_INFERIOR_MEMORY */
832 /* FIXME! Merge these two. */
834 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
841 memaddr
= translate_addr(memaddr
);
844 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
846 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
849 /********************************************************** UDI_FILES_INFO */
853 printf ("\tAttached to UDI socket to %s and running program %s.\n",
854 udi_config_id
, prog_name
);
857 /**************************************************** UDI_INSERT_BREAKPOINT */
859 udi_insert_breakpoint (addr
, contents_cache
)
861 char *contents_cache
;
866 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
867 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
870 if(cnt
>= BKPT_TABLE_SIZE
)
871 error("Too many breakpoints set");
873 bkpt_table
[cnt
].Addr
.Offset
= addr
;
874 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
875 bkpt_table
[cnt
].PassCount
= 1;
876 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
878 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
879 bkpt_table
[cnt
].PassCount
,
880 bkpt_table
[cnt
].Type
,
881 &bkpt_table
[cnt
].BreakId
);
883 if (err
== 0) return 0; /* Success */
885 bkpt_table
[cnt
].Type
= 0;
886 error("UDISetBreakpoint returned error code %d\n", err
);
889 /**************************************************** UDI_REMOVE_BREAKPOINT */
891 udi_remove_breakpoint (addr
, contents_cache
)
893 char *contents_cache
;
898 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
899 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
902 if(cnt
>= BKPT_TABLE_SIZE
)
903 error("Can't find breakpoint in table");
905 bkpt_table
[cnt
].Type
= 0;
907 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
908 if (err
== 0) return 0; /* Success */
910 error("UDIClearBreakpoint returned error code %d\n", err
);
914 udi_kill(arg
,from_tty
)
921 UDIStop does not really work as advertised. It causes the TIP to close it's
922 connection, which usually results in GDB dying with a SIGPIPE. For now, we
923 just invoke udi_close, which seems to get things right.
931 printf("Target has been stopped.");
939 Load a program into the target. Args are: `program {options}'. The options
940 are used to control loading of the program, and are NOT passed onto the
941 loaded code as arguments. (You need to use the `run' command to do that.)
944 -ms %d Set mem stack size to %d
945 -rs %d Set regular stack size to %d
946 -i send init info (default)
947 -noi don't send init info
948 -[tT] Load Text section
949 -[dD] Load Data section
950 -[bB] Load BSS section
951 -[lL] Load Lit section
955 download(load_arg_string
, from_tty
)
956 char *load_arg_string
;
959 #define DEFAULT_MEM_STACK_SIZE 0x6000
960 #define DEFAULT_REG_STACK_SIZE 0x2000
967 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
969 address_ranges
[0].Space
= UDI29KIRAMSpace
;
970 address_ranges
[0].Offset
= 0xffffffff;
971 address_ranges
[0].Size
= 0;
973 address_ranges
[1].Space
= UDI29KDRAMSpace
;
974 address_ranges
[1].Offset
= 0xffffffff;
975 address_ranges
[1].Size
= 0;
977 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
978 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
982 filename
= strtok(load_arg_string
, " \t");
984 error ("Must specify at least a file name with the load command");
986 filename
= tilde_expand (filename
);
987 make_cleanup (free
, filename
);
989 while (token
= strtok (NULL
, " \t"))
995 if (STREQ (token
, "ms"))
996 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
997 else if (STREQ (token
, "rs"))
998 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1001 load_text
= load_data
= load_bss
= load_lit
= 0;
1024 error ("Unknown UDI load option -%s", token
-1);
1031 pbfd
= bfd_openr (filename
, gnutarget
);
1034 perror_with_name (filename
);
1036 make_cleanup (bfd_close
, pbfd
);
1041 if (!bfd_check_format (pbfd
, bfd_object
))
1042 error ("It doesn't seem to be an object file");
1044 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1046 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1050 unsigned long section_size
, section_end
;
1051 const char *section_name
;
1053 section_name
= bfd_get_section_name (pbfd
, section
);
1054 if (STREQ (section_name
, ".text") && !load_text
)
1056 else if (STREQ (section_name
, ".data") && !load_data
)
1058 else if (STREQ (section_name
, ".bss") && !load_bss
)
1060 else if (STREQ (section_name
, ".lit") && !load_lit
)
1063 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1064 section_size
= bfd_section_size (pbfd
, section
);
1065 section_end
= To
.Offset
+ section_size
;
1067 if (section_size
== 0)
1068 /* This is needed at least in the BSS case, where the code
1069 below starts writing before it even checks the size. */
1072 printf("[Loading section %s at %x (%d bytes)]\n",
1077 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1079 To
.Space
= UDI29KIRAMSpace
;
1081 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1083 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1085 - address_ranges
[0].Offset
);
1089 To
.Space
= UDI29KDRAMSpace
;
1091 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1093 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1095 - address_ranges
[1].Offset
);
1098 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1104 while (section_size
> 0)
1108 Count
= min (section_size
, 1024);
1110 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1113 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1116 (UDISizeT
)1, /* Size */
1117 &Count
, /* CountDone */
1118 (UDIBool
)0); /* HostEndian */
1120 error ("UDIWrite failed, error = %d", err
);
1124 section_size
-= Count
;
1130 unsigned long zero
= 0;
1132 /* Write a zero byte at the vma */
1133 /* FIXME: Broken for sections of 1-3 bytes (we test for
1135 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1137 (UDICount
)1, /* Count */
1138 (UDISizeT
)4, /* Size */
1139 &Count
, /* CountDone */
1140 (UDIBool
)0); /* HostEndian */
1142 error ("UDIWrite failed, error = %d", err
);
1147 /* Now, duplicate it for the length of the BSS */
1148 err
= UDICopy (From
, /* From */
1150 (UDICount
)(section_size
/4 - 1), /* Count */
1151 (UDISizeT
)4, /* Size */
1152 &Count
, /* CountDone */
1153 (UDIBool
)1); /* Direction */
1159 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1161 fprintf (stderr
, "Error is %s\n", message
);
1163 fprintf (stderr
, "xerr is %d\n", xerr
);
1164 error ("UDICopy failed, error = %d", err
);
1171 entry
.Space
= UDI29KIRAMSpace
;
1172 entry
.Offset
= bfd_get_start_address (pbfd
);
1177 /* User interface to download an image into the remote target. See download()
1178 * for details on args.
1182 udi_load(args
, from_tty
)
1186 download (args
, from_tty
);
1188 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1191 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1192 ** Copy LEN bytes of data from debugger memory at MYADDR
1193 to inferior's memory at MEMADDR. Returns number of bytes written. */
1195 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1205 UDICount CountDone
= 0;
1206 UDIBool HostEndian
= 0;
1208 To
.Space
= udi_memory_space(memaddr
);
1209 From
= (UDIUInt32
*)myaddr
;
1211 while (nwritten
< len
)
1212 { Count
= len
- nwritten
;
1213 if (Count
> MAXDATA
) Count
= MAXDATA
;
1214 To
.Offset
= memaddr
+ nwritten
;
1215 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1216 { error("UDIWrite() failed in udi_write_inferrior_memory");
1220 { nwritten
+= CountDone
;
1227 /**************************************************** UDI_READ_INFERIOR_MEMORY
1228 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1229 at debugger address MYADDR. Returns number of bytes read. */
1231 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1241 UDICount CountDone
= 0;
1242 UDIBool HostEndian
= 0;
1245 From
.Space
= udi_memory_space(memaddr
);
1246 To
= (UDIUInt32
*)myaddr
;
1249 { Count
= len
- nread
;
1250 if (Count
> MAXDATA
) Count
= MAXDATA
;
1251 From
.Offset
= memaddr
+ nread
;
1252 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1253 { error("UDIRead() failed in udi_read_inferrior_memory");
1257 { nread
+= CountDone
;
1264 /********************************************************************* WARNING
1269 error ("ERROR while loading program into remote TIP: $d\n", num
);
1273 /*****************************************************************************/
1274 /* Fetch a single register indicatated by 'regno'.
1275 * Returns 0/-1 on success/failure.
1278 fetch_register (regno
)
1286 UDIBool HostEndian
= 0;
1290 if (regno
== GR1_REGNUM
)
1292 From
.Space
= UDI29KGlobalRegs
;
1295 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1297 From
.Space
= UDI29KGlobalRegs
;
1298 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1301 #if defined(GR64_REGNUM)
1303 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1305 From
.Space
= UDI29KGlobalRegs
;
1306 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1309 #endif /* GR64_REGNUM */
1311 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1313 From
.Space
= UDI29KLocalRegs
;
1314 From
.Offset
= (regno
- LR0_REGNUM
);
1316 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1319 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1320 return; /* Pretend Success */
1324 From
.Space
= UDI29KSpecialRegs
;
1325 From
.Offset
= regnum_to_srnum(regno
);
1328 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1329 error("UDIRead() failed in udi_fetch_registers");
1331 supply_register(regno
, (char *) &To
);
1334 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1336 /*****************************************************************************/
1337 /* Store a single register indicated by 'regno'.
1338 * Returns 0/-1 on success/failure.
1341 store_register (regno
)
1350 UDIBool HostEndian
= 0;
1352 From
= read_register (regno
); /* get data value */
1355 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1357 if (regno
== GR1_REGNUM
)
1358 { To
.Space
= UDI29KGlobalRegs
;
1360 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1361 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1362 * register cache. Do this *after* calling read_register, because we want
1363 * read_register to return the value that write_register has just stuffed
1364 * into the registers array, not the value of the register fetched from
1367 registers_changed ();
1369 #if defined(GR64_REGNUM)
1370 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1371 { To
.Space
= UDI29KGlobalRegs
;
1372 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1373 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1375 #endif /* GR64_REGNUM */
1376 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1377 { To
.Space
= UDI29KGlobalRegs
;
1378 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1379 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1381 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1382 { To
.Space
= UDI29KLocalRegs
;
1383 To
.Offset
= (regno
- LR0_REGNUM
);
1384 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1386 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1388 return 0; /* Pretend Success */
1390 else /* An unprotected or protected special register */
1391 { To
.Space
= UDI29KSpecialRegs
;
1392 To
.Offset
= regnum_to_srnum(regno
);
1393 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1398 error("UDIWrite() failed in store_registers");
1402 /********************************************************** REGNUM_TO_SRNUM */
1404 * Convert a gdb special register number to a 29000 special register number.
1407 regnum_to_srnum(regno
)
1411 case VAB_REGNUM
: return(0);
1412 case OPS_REGNUM
: return(1);
1413 case CPS_REGNUM
: return(2);
1414 case CFG_REGNUM
: return(3);
1415 case CHA_REGNUM
: return(4);
1416 case CHD_REGNUM
: return(5);
1417 case CHC_REGNUM
: return(6);
1418 case RBP_REGNUM
: return(7);
1419 case TMC_REGNUM
: return(8);
1420 case TMR_REGNUM
: return(9);
1421 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1422 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1423 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1424 case MMU_REGNUM
: return(13);
1425 case LRU_REGNUM
: return(14);
1426 case IPC_REGNUM
: return(128);
1427 case IPA_REGNUM
: return(129);
1428 case IPB_REGNUM
: return(130);
1429 case Q_REGNUM
: return(131);
1430 case ALU_REGNUM
: return(132);
1431 case BP_REGNUM
: return(133);
1432 case FC_REGNUM
: return(134);
1433 case CR_REGNUM
: return(135);
1434 case FPE_REGNUM
: return(160);
1435 case INTE_REGNUM
: return(161);
1436 case FPS_REGNUM
: return(162);
1437 case EXO_REGNUM
:return(164);
1439 return(255); /* Failure ? */
1442 /****************************************************************************/
1444 * Determine the Target memory space qualifier based on the addr.
1445 * FIXME: Can't distinguis I_ROM/D_ROM.
1446 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1449 udi_memory_space(addr
)
1452 UDIUInt32 tstart
= IMemStart
;
1453 UDIUInt32 tend
= tstart
+ IMemSize
;
1454 UDIUInt32 dstart
= DMemStart
;
1455 UDIUInt32 dend
= tstart
+ DMemSize
;
1456 UDIUInt32 rstart
= RMemStart
;
1457 UDIUInt32 rend
= tstart
+ RMemSize
;
1459 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1460 return UDI29KIRAMSpace
;
1461 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1462 return UDI29KDRAMSpace
;
1463 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1464 /* FIXME: how do we determine between D_ROM and I_ROM */
1465 return UDI29KIROMSpace
;
1466 } else /* FIXME: what do me do now? */
1467 return UDI29KDRAMSpace
; /* Hmmm! */
1469 /*********************************************************************** STUBS
1472 void convert16() {;}
1473 void convert32() {;}
1474 FILE* EchoFile
= 0; /* used for debugging */
1475 int QuietMode
= 0; /* used for debugging */
1477 /* Target_ops vector. Not static because there does not seem to be
1478 any portable way to do a forward declaration of a static variable.
1479 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1480 /bin/cc doesn't like "static" twice. */
1482 struct target_ops udi_ops
= {
1484 "Remote UDI connected TIP",
1485 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1487 `configuration-id AF_INET hostname port-number'\n\
1488 To connect via the network, where hostname and port-number specify the\n\
1489 host and port where you can connect via UDI.\n\
1490 configuration-id is unused.\n\
1492 `configuration-id AF_UNIX socket-name tip-program'\n\
1493 To connect using a local connection to the \"tip.exe\" program which is\n\
1494 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1495 tip program must already be started; connect to it using that socket.\n\
1496 If not, start up tip-program, which should be the name of the tip\n\
1497 program. If appropriate, the PATH environment variable is searched.\n\
1498 configuration-id is unused.\n\
1500 `configuration-id'\n\
1501 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1502 are files containing lines in the above formats. configuration-id is\n\
1503 used to pick which line of the file to use.",
1510 udi_fetch_registers
,
1511 udi_store_registers
,
1512 udi_prepare_to_store
,
1513 udi_xfer_inferior_memory
,
1515 udi_insert_breakpoint
,
1516 udi_remove_breakpoint
,
1517 0, /* termial_init */
1518 0, /* terminal_inferior */
1519 0, /* terminal_ours_for_output */
1520 0, /* terminal_ours */
1521 0, /* terminal_info */
1522 udi_kill
, /* FIXME, kill */
1524 0, /* lookup_symbol */
1525 udi_create_inferior
,
1526 udi_mourn
, /* mourn_inferior FIXME */
1528 0, /* notice_signals */
1531 1, /* has_all_memory */
1534 1, /* has_registers */
1535 1, /* has_execution */
1537 0, /* sections_end */
1538 OPS_MAGIC
, /* Always the last thing */
1541 void _initialize_remote_udi()
1543 add_target (&udi_ops
);
1546 #ifdef NO_HIF_SUPPORT
1550 return(0); /* Emulate a failure */