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 /* Number of SIGTRAPs we need to simulate. That is, the next
119 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
120 SIGTRAP without actually waiting for anything. */
122 /* This is called not only when we first attach, but also when the
123 user types "run" after having attached. */
126 udi_create_inferior (execfile
, args
, env
)
135 if (prog_name
!= NULL
)
137 prog_name
= savestring (execfile
, strlen (execfile
));
139 else if (entry
.Offset
)
142 error ("No image loaded into target.");
144 if (udi_session_id
< 0)
146 printf_unfiltered("UDI connection not open yet.\n");
150 inferior_pid
= 40000;
153 download(execfile
, 0);
155 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
157 strcpy (args1
, execfile
);
159 strcat (args1
, args
);
161 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
162 (UDIInt
)2, /* NumberOfRanges */
163 entry
, /* EntryPoint */
164 stack_sizes
, /* *StackSizes */
165 (UDIInt
)2, /* NumberOfStacks */
166 args1
); /* ArgString */
168 init_wait_for_inferior ();
169 clear_proceed_status ();
177 /* Requiring "target udi" each time you run is a major pain. I suspect
178 this was just blindy copied from remote.c, in which "target" and
179 "run" are combined. Having a udi target without an inferior seems
180 to work between "target udi" and "run", so why not now? */
181 pop_target (); /* Pop back to no-child state */
183 generic_mourn_inferior ();
186 /******************************************************************** UDI_OPEN
187 ** Open a connection to remote TIP.
188 NAME is the socket domain used for communication with the TIP,
189 then a space and the socket name or TIP-host name.
190 '<udi_udi_config_id>' for example.
193 /* XXX - need cleanups for udiconnect for various failures!!! */
195 static char *udi_config_id
;
197 udi_open (name
, from_tty
)
204 UDIMemoryRange KnownMemory
[10];
205 UDIUInt32 ChipVersions
[10];
206 UDIInt NumberOfRanges
= 10;
207 UDIInt NumberOfChips
= 10;
209 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
211 target_preopen(from_tty
);
215 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
216 bkpt_table
[cnt
].Type
= 0;
219 free (udi_config_id
);
222 error("Usage: target udi config_id, where config_id appears in udi_soc file");
224 udi_config_id
= strdup (strtok (name
, " \t"));
226 if (UDIConnect (udi_config_id
, &udi_session_id
))
227 error("UDIConnect() failed: %s\n", dfe_errmsg
);
229 push_target (&udi_ops
);
232 ** Initialize target configuration structure (global)
234 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
235 ChipVersions
, &NumberOfChips
))
236 error ("UDIGetTargetConfig() failed");
237 if (NumberOfChips
> 2)
238 fprintf_unfiltered(gdb_stderr
,"Target has more than one processor\n");
239 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
241 switch(KnownMemory
[cnt
].Space
)
244 fprintf_unfiltered(gdb_stderr
, "UDIGetTargetConfig() unknown memory space\n");
248 case UDI29KIROMSpace
:
249 RMemStart
= KnownMemory
[cnt
].Offset
;
250 RMemSize
= KnownMemory
[cnt
].Size
;
252 case UDI29KIRAMSpace
:
253 IMemStart
= KnownMemory
[cnt
].Offset
;
254 IMemSize
= KnownMemory
[cnt
].Size
;
256 case UDI29KDRAMSpace
:
257 DMemStart
= KnownMemory
[cnt
].Offset
;
258 DMemSize
= KnownMemory
[cnt
].Size
;
263 a29k_get_processor_type ();
265 if (UDICreateProcess (&PId
))
266 fprintf_unfiltered(gdb_stderr
, "UDICreateProcess() failed\n");
268 /* Print out some stuff, letting the user now what's going on */
269 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
271 error ("UDICapabilities() failed");
274 printf_filtered ("Connected via UDI socket,\n\
275 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
276 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
277 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
278 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
283 /******************************************************************* UDI_CLOSE
284 Close the open connection to the TIP process.
285 Use this when you want to detach and do something else
288 udi_close (quitting
) /*FIXME: how is quitting used */
291 if (udi_session_id
< 0)
294 /* We should never get here if there isn't something valid in
297 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
298 error ("UDIDisconnect() failed in udi_close");
300 /* Do not try to close udi_session_id again, later in the program. */
304 printf_filtered (" Ending remote debugging\n");
307 /**************************************************************** UDI_ATACH */
308 /* Attach to a program that is already loaded and running
309 * Upon exiting the process's execution is stopped.
312 udi_attach (args
, from_tty
)
321 UDIBool HostEndian
= 0;
324 if (udi_session_id
< 0)
325 error ("UDI connection not opened yet, use the 'target udi' command.\n");
328 printf_unfiltered ("Attaching to remote program %s...\n", prog_name
);
331 From
.Space
= UDI29KSpecialRegs
;
333 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
334 error ("UDIRead failed in udi_attach");
335 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
337 /************************************************************* UDI_DETACH */
338 /* Terminate the open connection to the TIP process.
339 Use this when you want to detach and do something else
340 with your gdb. Leave remote process running (with no breakpoints set). */
342 udi_detach (args
,from_tty
)
347 remove_breakpoints(); /* Just in case there were any left in */
349 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
350 error ("UDIDisconnect() failed in udi_detach");
352 pop_target(); /* calls udi_close to do the real work */
355 printf_unfiltered ("Ending remote debugging\n");
359 /****************************************************************** UDI_RESUME
360 ** Tell the remote machine to resume. */
363 udi_resume (pid
, step
, 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
)
398 int old_timeout
= timeout
;
399 int old_immediate_quit
= immediate_quit
;
402 WSETEXIT ((*status
), 0);
404 /* wait for message to arrive. It should be:
405 If the target stops executing, udi_wait() should return.
407 timeout
= 0; /* Wait indefinetly for a message */
408 immediate_quit
= 1; /* Helps ability to QUIT */
413 MaxTime
= UDIWaitForever
;
414 UDIWait(MaxTime
, &PId
, &StopReason
);
415 QUIT
; /* Let user quit if they want */
417 switch (StopReason
& UDIGrossState
)
419 case UDIGdb_StdoutReady
:
420 if (UDIGetGdb_Stdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
421 /* This is said to happen if the program tries to output
422 a whole bunch of output (more than SBUF_MAX, I would
423 guess). It doesn't seem to happen with the simulator. */
424 warning ("UDIGetGdb_Stdout() failed in udi_wait");
425 fwrite (sbuf
, 1, CountDone
, gdb_stdout
);
426 gdb_flush(gdb_stdout
);
428 case UDIGdb_StderrReady
:
429 UDIGetGdb_Stderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
430 fwrite (sbuf
, 1, CountDone
, gdb_stderr
);
431 gdb_flush(gdb_stderr
);
444 } while (i
< SBUF_MAX
&& ch
!= '\n');
445 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
450 /* In spite of the fact that we told UDIWait to wait forever, it will
451 return spuriously sometimes. */
460 switch (StopReason
& UDIGrossState
)
463 printf_unfiltered("Am290*0 received vector number %d\n", StopReason
>> 24);
465 switch (StopReason
>> 8)
467 case 0: /* Illegal opcode */
468 printf_unfiltered(" (break point)\n");
469 WSETSTOP ((*status
), SIGTRAP
);
471 case 1: /* Unaligned Access */
472 WSETSTOP ((*status
), SIGBUS
);
476 WSETSTOP ((*status
), SIGFPE
);
478 case 5: /* Protection Violation */
479 WSETSTOP ((*status
), SIGILL
);
483 case 8: /* User Instruction Mapping Miss */
484 case 9: /* User Data Mapping Miss */
485 case 10: /* Supervisor Instruction Mapping Miss */
486 case 11: /* Supervisor Data Mapping Miss */
487 WSETSTOP ((*status
), SIGSEGV
);
491 WSETSTOP ((*status
), SIGILL
);
494 WSETSTOP ((*status
), SIGALRM
);
497 WSETSTOP ((*status
), SIGTRAP
);
502 case 19: /* INTR3/Internal */
505 WSETSTOP ((*status
), SIGINT
);
507 case 22: /* Floating-Point Exception */
508 WSETSTOP ((*status
), SIGILL
);
510 case 77: /* assert 77 */
511 WSETSTOP ((*status
), SIGTRAP
);
514 WSETEXIT ((*status
), 0);
517 case UDINotExecuting
:
518 WSETSTOP ((*status
), SIGTERM
);
521 WSETSTOP ((*status
), SIGTSTP
);
524 WSETSTOP ((*status
), SIGURG
);
528 WSETSTOP ((*status
), SIGTRAP
);
531 WSETSTOP ((*status
), SIGSTOP
);
534 WSETSTOP ((*status
), SIGKILL
);
538 WSETEXIT ((*status
), 0);
541 timeout
= old_timeout
; /* Restore original timeout value */
542 immediate_quit
= old_immediate_quit
;
547 /* Handy for debugging */
555 UDIBool HostEndian
= 0;
558 unsigned long myregs
[256];
561 From
.Space
= UDI29KPC
;
563 To
= (UDIUInt32
*)pc
;
566 err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
);
568 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
569 err
, CountDone
, pc
[0], pc
[1]);
571 udi_fetch_registers(-1);
573 printf_unfiltered("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *)®isters
[4 * PC_REGNUM
],
574 *(int *)®isters
[4 * NPC_REGNUM
]);
576 /* Now, read all the registers globally */
578 From
.Space
= UDI29KGlobalRegs
;
580 err
= UDIRead(From
, myregs
, 256, 4, &CountDone
, HostEndian
);
582 printf ("err = %d, CountDone = %d\n", err
, CountDone
);
586 for (i
= 0; i
< 256; i
+= 2)
587 printf("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i
, myregs
[i
], myregs
[i
],
588 myregs
[i
+1], myregs
[i
+1]);
595 /********************************************************** UDI_FETCH_REGISTERS
596 * Read a remote register 'regno'.
597 * If regno==-1 then read all the registers.
600 udi_fetch_registers (regno
)
608 UDIBool HostEndian
= 0;
613 fetch_register(regno
);
619 From
.Space
= UDI29KGlobalRegs
;
621 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
623 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
624 error("UDIRead() failed in udi_fetch_registers");
626 register_valid
[GR1_REGNUM
] = 1;
628 #if defined(GR64_REGNUM) /* Read gr64-127 */
630 /* Global Registers gr64-gr95 */
632 From
.Space
= UDI29KGlobalRegs
;
634 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
636 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
637 error("UDIRead() failed in udi_fetch_registers");
639 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
640 register_valid
[i
] = 1;
642 #endif /* GR64_REGNUM */
644 /* Global Registers gr96-gr127 */
646 From
.Space
= UDI29KGlobalRegs
;
648 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
650 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
651 error("UDIRead() failed in udi_fetch_registers");
653 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
654 register_valid
[i
] = 1;
656 /* Local Registers */
658 From
.Space
= UDI29KLocalRegs
;
660 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
662 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
663 error("UDIRead() failed in udi_fetch_registers");
665 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
666 register_valid
[i
] = 1;
668 /* Protected Special Registers */
670 From
.Space
= UDI29KSpecialRegs
;
672 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
674 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
675 error("UDIRead() failed in udi_fetch_registers");
677 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
678 register_valid
[i
] = 1;
680 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
681 fetch_register(NPC_REGNUM
);
682 fetch_register(PC_REGNUM
);
683 fetch_register(PC2_REGNUM
);
685 /* Unprotected Special Registers sr128-sr135 */
687 From
.Space
= UDI29KSpecialRegs
;
689 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
691 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
692 error("UDIRead() failed in udi_fetch_registers");
694 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
695 register_valid
[i
] = 1;
700 printf_unfiltered("Fetching all registers\n");
701 printf_unfiltered("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
702 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
703 read_register(PC2_REGNUM
));
706 /* There doesn't seem to be any way to get these. */
709 supply_register (FPE_REGNUM
, (char *) &val
);
710 supply_register (INTE_REGNUM
, (char *) &val
);
711 supply_register (FPS_REGNUM
, (char *) &val
);
712 supply_register (EXO_REGNUM
, (char *) &val
);
717 /********************************************************* UDI_STORE_REGISTERS
718 ** Store register regno into the target.
719 * If regno==-1 then store all the registers.
723 udi_store_registers (regno
)
731 UDIBool HostEndian
= 0;
735 store_register(regno
);
741 printf_unfiltered("Storing all registers\n");
742 printf_unfiltered("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
743 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
748 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
749 To
.Space
= UDI29KGlobalRegs
;
752 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
753 error("UDIWrite() failed in udi_store_regisetrs");
755 #if defined(GR64_REGNUM)
757 /* Global registers gr64-gr95 */
759 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
760 To
.Space
= UDI29KGlobalRegs
;
763 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
764 error("UDIWrite() failed in udi_store_regisetrs");
766 #endif /* GR64_REGNUM */
768 /* Global registers gr96-gr127 */
770 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
771 To
.Space
= UDI29KGlobalRegs
;
774 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
775 error("UDIWrite() failed in udi_store_regisetrs");
777 /* Local Registers */
779 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
780 To
.Space
= UDI29KLocalRegs
;
783 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
784 error("UDIWrite() failed in udi_store_regisetrs");
787 /* Protected Special Registers */ /* VAB through TMR */
789 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
790 To
.Space
= UDI29KSpecialRegs
;
793 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
794 error("UDIWrite() failed in udi_store_regisetrs");
796 /* PC0, PC1, PC2 possibly as shadow registers */
798 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
799 To
.Space
= UDI29KSpecialRegs
;
802 To
.Offset
= 20; /* SPC0 */
804 To
.Offset
= 10; /* PC0 */
805 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
806 error("UDIWrite() failed in udi_store_regisetrs");
808 /* PC1 via UDI29KPC */
810 From
= (UDIUInt32
*)®isters
[4 * PC_REGNUM
];
812 To
.Offset
= 0; /* PC1 */
814 if (UDIWrite (From
, To
, Count
, Size
, &CountDone
, HostEndian
))
815 error ("UDIWrite() failed in udi_store_regisetrs");
819 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
820 To
.Space
= UDI29KSpecialRegs
;
823 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
824 error("UDIWrite() failed in udi_store_regisetrs");
826 /* Unprotected Special Registers */
828 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
829 To
.Space
= UDI29KSpecialRegs
;
832 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
833 error("UDIWrite() failed in udi_store_regisetrs");
835 registers_changed ();
838 /****************************************************** UDI_PREPARE_TO_STORE */
839 /* Get ready to modify the registers array. On machines which store
840 individual registers, this doesn't need to do anything. On machines
841 which store all the registers in one fell swoop, this makes sure
842 that registers contains all the registers from the program being
846 udi_prepare_to_store ()
848 /* Do nothing, since we can store individual regs */
851 /********************************************************** TRANSLATE_ADDR */
856 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
857 /* Check for a virtual address in the kernel */
858 /* Assume physical address of ublock is in paddr_u register */
859 /* FIXME: doesn't work for user virtual addresses */
860 if (addr
>= UVADDR
) {
861 /* PADDR_U register holds the physical address of the ublock */
862 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
863 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
871 /************************************************* UDI_XFER_INFERIOR_MEMORY */
872 /* FIXME! Merge these two. */
874 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
881 memaddr
= translate_addr(memaddr
);
884 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
886 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
889 /********************************************************** UDI_FILES_INFO */
893 printf_unfiltered ("\tAttached to UDI socket to %s and running program %s.\n",
894 udi_config_id
, prog_name
);
897 /**************************************************** UDI_INSERT_BREAKPOINT */
899 udi_insert_breakpoint (addr
, contents_cache
)
901 char *contents_cache
;
906 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
907 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
910 if(cnt
>= BKPT_TABLE_SIZE
)
911 error("Too many breakpoints set");
913 bkpt_table
[cnt
].Addr
.Offset
= addr
;
914 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
915 bkpt_table
[cnt
].PassCount
= 1;
916 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
918 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
919 bkpt_table
[cnt
].PassCount
,
920 bkpt_table
[cnt
].Type
,
921 &bkpt_table
[cnt
].BreakId
);
923 if (err
== 0) return 0; /* Success */
925 bkpt_table
[cnt
].Type
= 0;
926 error("UDISetBreakpoint returned error code %d\n", err
);
929 /**************************************************** UDI_REMOVE_BREAKPOINT */
931 udi_remove_breakpoint (addr
, contents_cache
)
933 char *contents_cache
;
938 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
939 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
942 if(cnt
>= BKPT_TABLE_SIZE
)
943 error("Can't find breakpoint in table");
945 bkpt_table
[cnt
].Type
= 0;
947 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
948 if (err
== 0) return 0; /* Success */
950 error("UDIClearBreakpoint returned error code %d\n", err
);
954 udi_kill(arg
,from_tty
)
961 UDIStop does not really work as advertised. It causes the TIP to close it's
962 connection, which usually results in GDB dying with a SIGPIPE. For now, we
963 just invoke udi_close, which seems to get things right.
971 printf_unfiltered("Target has been stopped.");
979 Load a program into the target. Args are: `program {options}'. The options
980 are used to control loading of the program, and are NOT passed onto the
981 loaded code as arguments. (You need to use the `run' command to do that.)
984 -ms %d Set mem stack size to %d
985 -rs %d Set regular stack size to %d
986 -i send init info (default)
987 -noi don't send init info
988 -[tT] Load Text section
989 -[dD] Load Data section
990 -[bB] Load BSS section
991 -[lL] Load Lit section
995 download(load_arg_string
, from_tty
)
996 char *load_arg_string
;
999 #define DEFAULT_MEM_STACK_SIZE 0x6000
1000 #define DEFAULT_REG_STACK_SIZE 0x2000
1007 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1009 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1010 address_ranges
[0].Offset
= 0xffffffff;
1011 address_ranges
[0].Size
= 0;
1013 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1014 address_ranges
[1].Offset
= 0xffffffff;
1015 address_ranges
[1].Size
= 0;
1017 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1018 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1022 filename
= strtok(load_arg_string
, " \t");
1024 error ("Must specify at least a file name with the load command");
1026 filename
= tilde_expand (filename
);
1027 make_cleanup (free
, filename
);
1029 while (token
= strtok (NULL
, " \t"))
1031 if (token
[0] == '-')
1035 if (STREQ (token
, "ms"))
1036 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1037 else if (STREQ (token
, "rs"))
1038 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1041 load_text
= load_data
= load_bss
= load_lit
= 0;
1064 error ("Unknown UDI load option -%s", token
-1);
1071 pbfd
= bfd_openr (filename
, gnutarget
);
1074 perror_with_name (filename
);
1076 make_cleanup (bfd_close
, pbfd
);
1081 if (!bfd_check_format (pbfd
, bfd_object
))
1082 error ("It doesn't seem to be an object file");
1084 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1086 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1090 unsigned long section_size
, section_end
;
1091 const char *section_name
;
1093 section_name
= bfd_get_section_name (pbfd
, section
);
1094 if (STREQ (section_name
, ".text") && !load_text
)
1096 else if (STREQ (section_name
, ".data") && !load_data
)
1098 else if (STREQ (section_name
, ".bss") && !load_bss
)
1100 else if (STREQ (section_name
, ".lit") && !load_lit
)
1103 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1104 section_size
= bfd_section_size (pbfd
, section
);
1105 section_end
= To
.Offset
+ section_size
;
1107 if (section_size
== 0)
1108 /* This is needed at least in the BSS case, where the code
1109 below starts writing before it even checks the size. */
1112 printf_unfiltered("[Loading section %s at %x (%d bytes)]\n",
1117 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1119 To
.Space
= UDI29KIRAMSpace
;
1121 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1123 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1125 - address_ranges
[0].Offset
);
1129 To
.Space
= UDI29KDRAMSpace
;
1131 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1133 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1135 - address_ranges
[1].Offset
);
1138 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1144 while (section_size
> 0)
1148 Count
= min (section_size
, 1024);
1150 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1153 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1156 (UDISizeT
)1, /* Size */
1157 &Count
, /* CountDone */
1158 (UDIBool
)0); /* HostEndian */
1160 error ("UDIWrite failed, error = %d", err
);
1164 section_size
-= Count
;
1170 unsigned long zero
= 0;
1172 /* Write a zero byte at the vma */
1173 /* FIXME: Broken for sections of 1-3 bytes (we test for
1175 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1177 (UDICount
)1, /* Count */
1178 (UDISizeT
)4, /* Size */
1179 &Count
, /* CountDone */
1180 (UDIBool
)0); /* HostEndian */
1182 error ("UDIWrite failed, error = %d", err
);
1187 /* Now, duplicate it for the length of the BSS */
1188 err
= UDICopy (From
, /* From */
1190 (UDICount
)(section_size
/4 - 1), /* Count */
1191 (UDISizeT
)4, /* Size */
1192 &Count
, /* CountDone */
1193 (UDIBool
)1); /* Direction */
1199 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1201 fprintf_unfiltered (gdb_stderr
, "Error is %s\n", message
);
1203 fprintf_unfiltered (gdb_stderr
, "xerr is %d\n", xerr
);
1204 error ("UDICopy failed, error = %d", err
);
1211 entry
.Space
= UDI29KIRAMSpace
;
1212 entry
.Offset
= bfd_get_start_address (pbfd
);
1217 /* User interface to download an image into the remote target. See download()
1218 * for details on args.
1222 udi_load(args
, from_tty
)
1226 download (args
, from_tty
);
1228 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1231 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1232 ** Copy LEN bytes of data from debugger memory at MYADDR
1233 to inferior's memory at MEMADDR. Returns number of bytes written. */
1235 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1245 UDICount CountDone
= 0;
1246 UDIBool HostEndian
= 0;
1248 To
.Space
= udi_memory_space(memaddr
);
1249 From
= (UDIUInt32
*)myaddr
;
1251 while (nwritten
< len
)
1252 { Count
= len
- nwritten
;
1253 if (Count
> MAXDATA
) Count
= MAXDATA
;
1254 To
.Offset
= memaddr
+ nwritten
;
1255 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1256 { error("UDIWrite() failed in udi_write_inferrior_memory");
1260 { nwritten
+= CountDone
;
1267 /**************************************************** UDI_READ_INFERIOR_MEMORY
1268 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1269 at debugger address MYADDR. Returns number of bytes read. */
1271 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1281 UDICount CountDone
= 0;
1282 UDIBool HostEndian
= 0;
1285 From
.Space
= udi_memory_space(memaddr
);
1286 To
= (UDIUInt32
*)myaddr
;
1289 { Count
= len
- nread
;
1290 if (Count
> MAXDATA
) Count
= MAXDATA
;
1291 From
.Offset
= memaddr
+ nread
;
1292 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1293 { error("UDIRead() failed in udi_read_inferrior_memory");
1297 { nread
+= CountDone
;
1304 /********************************************************************* WARNING
1309 error ("ERROR while loading program into remote TIP: $d\n", num
);
1313 /*****************************************************************************/
1314 /* Fetch a single register indicatated by 'regno'.
1315 * Returns 0/-1 on success/failure.
1318 fetch_register (regno
)
1326 UDIBool HostEndian
= 0;
1330 if (regno
== GR1_REGNUM
)
1332 From
.Space
= UDI29KGlobalRegs
;
1335 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1337 From
.Space
= UDI29KGlobalRegs
;
1338 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1341 #if defined(GR64_REGNUM)
1343 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1345 From
.Space
= UDI29KGlobalRegs
;
1346 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1349 #endif /* GR64_REGNUM */
1351 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1353 From
.Space
= UDI29KLocalRegs
;
1354 From
.Offset
= (regno
- LR0_REGNUM
);
1356 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1359 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1360 return; /* Pretend Success */
1364 From
.Space
= UDI29KSpecialRegs
;
1365 From
.Offset
= regnum_to_srnum(regno
);
1368 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1369 error("UDIRead() failed in udi_fetch_registers");
1371 supply_register(regno
, (char *) &To
);
1374 printf_unfiltered("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1376 /*****************************************************************************/
1377 /* Store a single register indicated by 'regno'.
1378 * Returns 0/-1 on success/failure.
1381 store_register (regno
)
1390 UDIBool HostEndian
= 0;
1392 From
= read_register (regno
); /* get data value */
1395 printf_unfiltered("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1397 if (regno
== GR1_REGNUM
)
1399 To
.Space
= UDI29KGlobalRegs
;
1401 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1402 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1403 * register cache. Do this *after* calling read_register, because we want
1404 * read_register to return the value that write_register has just stuffed
1405 * into the registers array, not the value of the register fetched from
1408 registers_changed ();
1410 #if defined(GR64_REGNUM)
1411 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1413 To
.Space
= UDI29KGlobalRegs
;
1414 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1415 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1417 #endif /* GR64_REGNUM */
1418 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1420 To
.Space
= UDI29KGlobalRegs
;
1421 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1422 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1424 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1426 To
.Space
= UDI29KLocalRegs
;
1427 To
.Offset
= (regno
- LR0_REGNUM
);
1428 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1430 else if (regno
>= FPE_REGNUM
&& regno
<= EXO_REGNUM
)
1431 return 0; /* Pretend Success */
1432 else if (regno
== PC_REGNUM
)
1434 /* PC1 via UDI29KPC */
1436 To
.Space
= UDI29KPC
;
1437 To
.Offset
= 0; /* PC1 */
1438 result
= UDIWrite (&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1440 /* Writing to this loc actually changes the values of pc0 & pc1 */
1442 register_valid
[PC_REGNUM
] = 0; /* pc1 */
1443 register_valid
[NPC_REGNUM
] = 0; /* pc0 */
1445 else /* An unprotected or protected special register */
1447 To
.Space
= UDI29KSpecialRegs
;
1448 To
.Offset
= regnum_to_srnum(regno
);
1449 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1453 error("UDIWrite() failed in store_registers");
1457 /********************************************************** REGNUM_TO_SRNUM */
1459 * Convert a gdb special register number to a 29000 special register number.
1462 regnum_to_srnum(regno
)
1466 case VAB_REGNUM
: return(0);
1467 case OPS_REGNUM
: return(1);
1468 case CPS_REGNUM
: return(2);
1469 case CFG_REGNUM
: return(3);
1470 case CHA_REGNUM
: return(4);
1471 case CHD_REGNUM
: return(5);
1472 case CHC_REGNUM
: return(6);
1473 case RBP_REGNUM
: return(7);
1474 case TMC_REGNUM
: return(8);
1475 case TMR_REGNUM
: return(9);
1476 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1477 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1478 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1479 case MMU_REGNUM
: return(13);
1480 case LRU_REGNUM
: return(14);
1481 case IPC_REGNUM
: return(128);
1482 case IPA_REGNUM
: return(129);
1483 case IPB_REGNUM
: return(130);
1484 case Q_REGNUM
: return(131);
1485 case ALU_REGNUM
: return(132);
1486 case BP_REGNUM
: return(133);
1487 case FC_REGNUM
: return(134);
1488 case CR_REGNUM
: return(135);
1489 case FPE_REGNUM
: return(160);
1490 case INTE_REGNUM
: return(161);
1491 case FPS_REGNUM
: return(162);
1492 case EXO_REGNUM
:return(164);
1494 return(255); /* Failure ? */
1497 /****************************************************************************/
1499 * Determine the Target memory space qualifier based on the addr.
1500 * FIXME: Can't distinguis I_ROM/D_ROM.
1501 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1504 udi_memory_space(addr
)
1507 UDIUInt32 tstart
= IMemStart
;
1508 UDIUInt32 tend
= tstart
+ IMemSize
;
1509 UDIUInt32 dstart
= DMemStart
;
1510 UDIUInt32 dend
= tstart
+ DMemSize
;
1511 UDIUInt32 rstart
= RMemStart
;
1512 UDIUInt32 rend
= tstart
+ RMemSize
;
1514 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1515 return UDI29KIRAMSpace
;
1516 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1517 return UDI29KDRAMSpace
;
1518 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1519 /* FIXME: how do we determine between D_ROM and I_ROM */
1520 return UDI29KIROMSpace
;
1521 } else /* FIXME: what do me do now? */
1522 return UDI29KDRAMSpace
; /* Hmmm! */
1524 /*********************************************************************** STUBS
1527 void convert16() {;}
1528 void convert32() {;}
1529 GDB_FILE
* EchoFile
= 0; /* used for debugging */
1530 int QuietMode
= 0; /* used for debugging */
1532 #ifdef NO_HIF_SUPPORT
1536 return(0); /* Emulate a failure */
1540 /* Target_ops vector. Not static because there does not seem to be
1541 any portable way to do a forward declaration of a static variable.
1542 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1543 /bin/cc doesn't like "static" twice. */
1545 struct target_ops udi_ops
= {
1547 "Remote UDI connected TIP",
1548 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1550 `configuration-id AF_INET hostname port-number'\n\
1551 To connect via the network, where hostname and port-number specify the\n\
1552 host and port where you can connect via UDI.\n\
1553 configuration-id is unused.\n\
1555 `configuration-id AF_UNIX socket-name tip-program'\n\
1556 To connect using a local connection to the \"tip.exe\" program which is\n\
1557 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1558 tip program must already be started; connect to it using that socket.\n\
1559 If not, start up tip-program, which should be the name of the tip\n\
1560 program. If appropriate, the PATH environment variable is searched.\n\
1561 configuration-id is unused.\n\
1563 `configuration-id'\n\
1564 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1565 are files containing lines in the above formats. configuration-id is\n\
1566 used to pick which line of the file to use.",
1573 udi_fetch_registers
,
1574 udi_store_registers
,
1575 udi_prepare_to_store
,
1576 udi_xfer_inferior_memory
,
1578 udi_insert_breakpoint
,
1579 udi_remove_breakpoint
,
1580 0, /* termial_init */
1581 0, /* terminal_inferior */
1582 0, /* terminal_ours_for_output */
1583 0, /* terminal_ours */
1584 0, /* terminal_info */
1585 udi_kill
, /* FIXME, kill */
1587 0, /* lookup_symbol */
1588 udi_create_inferior
,
1589 udi_mourn
, /* mourn_inferior FIXME */
1591 0, /* notice_signals */
1594 1, /* has_all_memory */
1597 1, /* has_registers */
1598 1, /* has_execution */
1600 0, /* sections_end */
1601 OPS_MAGIC
, /* Always the last thing */
1605 _initialize_remote_udi ()
1607 add_target (&udi_ops
);