2 - Remote debugging interface for Am290*0 running MiniMON monitor, for GDB.
3 This is like remote.c but expects MiniMON to be running on the Am29000
5 - Originally written by Daniel Mann at AMD for gdb 3.91.6.
6 - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
7 file to gdb 3.95. I was unable to get this working on sun3os4
8 with termio, only with sgtty. Because we are only attempting to
9 use this module to debug our kernel, which is already loaded when
10 gdb is started up, I did not code up the file downloading facilities.
11 As a result this module has only the stubs to download files.
12 You should get tagged at compile time if you need to make any
14 *- Daniel Mann at AMD took the 3.95 adaptions above and replaced
15 MiniMON interface with UDI-p interface.
17 Copyright (C) 1990 Free Software Foundation, Inc.
19 This file is part of GDB.
21 This program is free software; you can redistribute it and/or modify
22 it under the terms of the GNU General Public License as published by
23 the Free Software Foundation; either version 1, or (at your option)
26 This program is distributed in the hope that it will be useful,
27 but WITHOUT ANY WARRANTY; without even the implied warranty of
28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 GNU General Public License for more details.
31 You should have received a copy of the GNU General Public License
32 along with this program; see the file COPYING. If not, write to
33 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
48 #include "29k-share/udi/udiproc.h"
50 /* access the register store directly, without going through
51 the normal handler functions. This avoids an extra data copy
54 /* #define DEBUG 1 /* */
56 # define DENTER(NAME) (printf("Entering %s\n",NAME), fflush(stdout))
57 # define DEXIT(NAME) (printf("Exiting %s\n",NAME), fflush(stdout))
64 extern int stop_soon_quietly
; /* for wait_for_inferior */
65 extern struct value
*call_function_by_hand();
66 static void udi_resume();
67 static void udi_fetch_registers ();
68 static void udi_load();
69 static int fetch_register ();
70 static void udi_store_registers ();
71 static int store_register ();
72 static int regnum_to_srnum();
73 static void udi_close ();
74 static CPUSpace
udi_memory_space();
75 static int udi_write_inferior_memory();
76 static int udi_read_inferior_memory();
77 char CoffFileName
[100] = "";
81 #define TYPE_UNKNOWN 0
85 static char *processor_name
[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
86 static int processor_type
=TYPE_UNKNOWN
;
87 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
88 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
90 #define LLOG_FILE "udi.log"
91 #if defined (LOG_FILE)
95 static int timeout
= 5;
96 extern struct target_ops udi_ops
; /* Forward declaration */
98 /* Special register enumeration.
101 /******************************************************************* UDI DATA*/
102 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
103 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
104 udi_open knows that we don't have a file open when the program
106 UDISessionId udi_session_id
= -1;
108 CPUOffset IMemStart
= 0;
109 CPUSizeT IMemSize
= 0;
110 CPUOffset DMemStart
= 0;
111 CPUSizeT DMemSize
= 0;
112 CPUOffset RMemStart
= 0;
113 CPUSizeT RMemSize
= 0;
117 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
120 typedef struct bkpt_entry_str
125 unsigned int BreakId
;
127 #define BKPT_TABLE_SIZE 40
128 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
129 extern char dfe_errmsg
[]; /* error string */
131 /*********************************************************** SIGNAL SUPPORT */
132 /* Called when SIGALRM signal sent due to alarm() timeout. */
137 # define volatile /**/
140 volatile int n_alarms
;
147 printf ("udi_timer called\n");
151 #endif /* HAVE_TERMIO */
153 /* malloc'd name of the program on the remote system. */
154 static char *prog_name
= NULL
;
157 /* Number of SIGTRAPs we need to simulate. That is, the next
158 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
159 SIGTRAP without actually waiting for anything. */
161 /******************************************************* UDI_CREATE_INFERIOR */
162 /* This is called not only when we first attach, but also when the
163 user types "run" after having attached. */
165 udi_create_inferior (execfile
, args
, env
)
170 DENTER("udi_create_inferior()");
173 { if (prog_name
!= NULL
)
175 prog_name
= savestring (execfile
, strlen (execfile
));
178 if (prog_name
== 0 /* || exec_bfd == 0 */ )
179 error ("No exec file specified");
181 if (udi_session_id
< 0){
182 printf("UDI connection not open yet.\n");
186 inferior_pid
= 40000;
188 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
189 /* On ultra3 (NYU) we assume the kernel is already running so there is
190 * no file to download
193 if(*args
== '\0') args
= prog_name
;
197 /* We will get a task spawn event immediately. */
198 #ifdef NOTDEF /* start_remote() now does a wait without a resume
202 init_wait_for_inferior ();
203 clear_proceed_status ();
206 DEXIT("udi_create_inferior()");
208 /******************************************************* UDI_MOURN_INFERIOR */
212 DENTER("udi_mourn()");
213 pop_target (); /* Pop back to no-child state */
214 generic_mourn_inferior ();
215 DEXIT("udi_mourn()");
218 /******************************************************************** UDI_OPEN
219 ** Open a connection to remote TIP.
220 NAME is the socket domain used for communication with the TIP,
221 then a space and the socket name or TIP-host name.
222 '<udi_udi_config_id> [progname]' for example.
225 /* XXX - need cleanups for udiconnect for various failures!!! */
227 static char *udi_config_id
;
229 udi_open (name
, from_tty
)
236 UDIMemoryRange KnownMemory
[10];
237 UDIUInt32 ChipVersions
[10];
238 UDIInt NumberOfRanges
= 10;
239 UDIInt NumberOfChips
= 10;
241 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
243 DENTER("udi_open()");
245 target_preopen(from_tty
);
247 /* Find the first whitespace character, it separates udi_config_id
249 if(!name
) goto erroid
;
251 *p
!= '\0' && !isspace (*p
); p
++)
255 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
257 udi_config_id
= (char*)malloc (p
- name
+ 1);
258 strncpy (udi_config_id
, name
, p
- name
);
259 udi_config_id
[p
- name
] = '\0';
261 /* Skip over the whitespace after udi_config_id */
262 for (; isspace (*p
); p
++)
265 if (prog_name
!= NULL
)
267 prog_name
= savestring (p
, strlen (p
));
269 if (UDIConnect(udi_config_id
, &udi_session_id
))
270 error("UDIConnect() failed: %s\n", dfe_errmsg
);
272 push_target (&udi_ops
);
275 #ifndef NO_SIGINTERRUPT
276 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
278 if (siginterrupt (SIGALRM
, 1) != 0)
279 error ("udi_open: siginterrupt() %s", safe_strerror(errno
));
282 /* Set up read timeout timer. */
283 if ((void (*)) signal (SIGALRM
, udi_timer
) == (void (*)) -1)
284 error ("udi_open: signal() %s", safe_strerror(errno
));
287 #if defined (LOG_FILE)
288 log_file
= fopen (LOG_FILE
, "w");
289 if (log_file
== NULL
)
290 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
293 ** Initialize target configuration structure (global)
295 if(UDIGetTargetConfig( KnownMemory
, &NumberOfRanges
,
296 ChipVersions
, &NumberOfChips
))
297 error ("UDIGetTargetConfig() failed");
298 if(NumberOfChips
> 2)
299 fprintf(stderr
,"Taret has more than one processor\n");
300 for(cnt
=0; cnt
<NumberOfRanges
; cnt
++)
301 { switch(KnownMemory
[cnt
].Space
)
303 default: fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
307 case UDI29KIROMSpace
:
308 RMemStart
= KnownMemory
[cnt
].Offset
;
309 RMemSize
= KnownMemory
[cnt
].Size
;
311 case UDI29KIRAMSpace
:
312 IMemStart
= KnownMemory
[cnt
].Offset
;
313 IMemSize
= KnownMemory
[cnt
].Size
;
315 case UDI29KDRAMSpace
:
316 DMemStart
= KnownMemory
[cnt
].Offset
;
317 DMemSize
= KnownMemory
[cnt
].Size
;
322 /* Determine the processor revision level */
323 prl
= (unsigned int)read_register(CFG_REGNUM
) >> 24;
325 { fprintf_filtered(stderr
,
326 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
327 processor_type
= TYPE_A29000
;
328 } else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
329 { fprintf_filtered(stderr
,
330 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
331 processor_type
= TYPE_A29030
;
332 } else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
333 { fprintf_filtered(stderr
,
334 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
335 processor_type
= TYPE_A29050
;
337 processor_type
= TYPE_UNKNOWN
;
338 fprintf_filtered(stderr
,"WARNING: processor type unknown.\n");
340 if(UDICreateProcess(&PId
))
341 fprintf(stderr
, "UDICreateProcess() failed\n");
343 /* Print out some stuff, letting the user now what's going on */
344 if(UDICapabilities( &TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
346 error ("UDICapabilities() failed");
348 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
349 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
350 processor_name
[processor_type
],
351 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
352 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
353 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
356 /* FIXME: can this restriction be removed? */
357 printf_filtered("Remote debugging using virtual addresses works only\n");
358 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
362 if (processor_type
!= TYPE_A29050
) {
363 fprintf_filtered(stderr
,
364 "Freeze-mode debugging can only be done on an Am29050,\n");
365 fprintf_filtered(stderr
,
366 " unless GDB is being used with a 29K simulator.\n");
371 /******************************************************************* UDI_CLOSE
372 Close the open connection to the TIP process.
373 Use this when you want to detach and do something else
376 udi_close (quitting
) /*FIXME: how is quitting used */
380 DENTER("udi_close()");
382 if (udi_session_id
< 0)
383 error ("Can't close udi connection: not debugging remotely.");
385 /* We should never get here if there isn't something valid in
388 if(UDIDisconnect(udi_stream, Terminate);)
389 error ("UDIDisconnect() failed in udi_close");
391 /* Do not try to close udi_session_id again, later in the program. */
395 #if defined (LOG_FILE)
396 if (ferror (log_file
))
397 printf ("Error writing log file.\n");
398 if (fclose (log_file
) != 0)
399 printf ("Error closing log file.\n");
402 printf_filtered (" Ending remote debugging\n");
404 DEXIT("udi_close()");
407 /**************************************************************** UDI_ATACH */
408 /* Attach to a program that is already loaded and running
409 * Upon exiting the process's execution is stopped.
412 udi_attach (args
, from_tty
)
421 UDIBool HostEndian
= 0;
422 DENTER("udi_attach()");
424 if (udi_session_id
< 0)
425 printf ("UDI connection not opened yet, use the 'target udi' command.\n");
428 printf ("Attaching to remote program %s...\n", prog_name
);
430 mark_breakpoints_out ();
433 From
.Offset
= UDI29KSpecialRegs
;
434 if(UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
435 error ("UDIRead failed in udi_attach");
436 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
438 DEXIT("udi_attach()");
440 /************************************************************* UDI_DETACH */
441 /* Terminate the open connection to the TIP process.
442 Use this when you want to detach and do something else
443 with your gdb. Leave remote process running (with no breakpoints set). */
445 udi_detach (args
,from_tty
)
449 DENTER("udi_dettach()");
450 remove_breakpoints(); /* Just in case there were any left in */
451 if(UDIDisconnect(udi_session_id
))
452 error ("UDIDisconnect() failed in udi_detach");
453 pop_target(); /* calls udi_close to do the real work */
455 printf ("Ending remote debugging\n");
456 DEXIT("udi_dettach()");
460 /****************************************************************** UDI_RESUME
461 ** Tell the remote machine to resume. */
464 udi_resume (step
, sig
)
469 UDIStepType StepType
= UDIStepNatural
;
471 DENTER("udi_resume()");
472 if (step
) /* step 1 instruction */
473 { tip_error
= tip_error
= UDIStep(Steps
, StepType
, Range
);
474 if(tip_error
)fprintf(stderr
, "UDIStep() error = %d\n", tip_error
);
475 if(tip_error
)error ("failed in udi_resume");
480 error ("UDIExecute() failed in udi_resume");
483 DEXIT("udi_resume()");
486 /******************************************************************** UDI_WAIT
487 ** Wait until the remote machine stops, then return,
488 storing status in STATUS just as `wait' would. */
498 int old_timeout
= timeout
;
499 int old_immediate_quit
= immediate_quit
;
502 DENTER("udi_wait()");
503 WSETEXIT ((*status
), 0);
505 /* wait for message to arrive. It should be:
506 If the target stops executing, udi_wait() should return.
508 timeout
= 0; /* Wait indefinetly for a message */
509 immediate_quit
= 1; /* Helps ability to QUIT */
513 MaxTime
= UDIWaitForever
;
514 UDIWait(MaxTime
, &PId
, &StopReason
);
515 QUIT
; /* Let user quit if they want */
516 switch (StopReason
& 0xff)
521 if(UDIGetStdout(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
522 error("UDIGetStdin() failed in udi_wait");
523 while(CountDone
--)putc(sbuf
[i
++], stdout
);
527 UDIGetStderr(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
528 while(CountDone
--)putc(sbuf
[i
++], stderr
);
533 printf("DEBUG: stdin requested ... continue\n");
534 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
542 if (StopReason
& 0xff == UDITrapped
) /* lower 8-bits == 0 */
544 if (StopReason
>> 24 == 0)
545 { printf("Am290*0 received vector number 0 (break point)\n");
546 WSETSTOP ((*status
), SIGTRAP
);
548 else if (StopReason
>> 24 == 1)
549 { printf("Am290*0 received vector 1\n");
550 WSETSTOP ((*status
), SIGBUS
);
552 else if (StopReason
>> 24 == 3
553 || StopReason
>> 24 == 4)
554 { printf("Am290*0 received vector number %d\n",
556 WSETSTOP ((*status
), SIGFPE
);
558 else if (StopReason
>> 24 == 5)
559 { printf("Am290*0 received vector number %d\n",
561 WSETSTOP ((*status
), SIGILL
);
563 else if (StopReason
>> 24 >= 6
564 && StopReason
>> 24 <= 11)
565 { printf("Am290*0 received vector number %d\n",
567 WSETSTOP ((*status
), SIGSEGV
);
569 else if (StopReason
>> 24 == 12
570 || StopReason
>> 24 == 13)
571 { printf("Am290*0 received vector number %d\n",
573 WSETSTOP ((*status
), SIGILL
);
575 else if ((StopReason
& 0xff) == 14)
576 { printf("Am290*0 received vector number %d\n",
578 WSETSTOP ((*status
), SIGALRM
);
580 else if ((StopReason
& 0xff) == 15)
581 WSETSTOP ((*status
), SIGTRAP
);
582 else if ((StopReason
>> 24) >= 16
583 && (StopReason
>> 24) <= 21)
584 { printf("Am290*0 received vector number %d\n",
586 WSETSTOP ((*status
), SIGINT
);
588 else if ((StopReason
& 0xff) == 22)
589 { printf("Am290*0 received vector number %d\n",
591 WSETSTOP ((*status
), SIGILL
);
593 else if ((StopReason
& 0xff) == 77)
594 WSETSTOP ((*status
), SIGTRAP
);
597 WSETEXIT ((*status
), 0);
599 else if ((StopReason
& 0xff) == UDIBreak
)
600 WSETSTOP ((*status
), SIGTRAP
);
601 else if ((StopReason
& 0xff) == UDINotExecuting
)
602 WSETSTOP ((*status
), SIGTERM
);
603 else if ((StopReason
& 0xff) == UDIRunning
)
604 WSETSTOP ((*status
), SIGILL
);
605 else if ((StopReason
& 0xff) == UDIStopped
)
606 WSETSTOP ((*status
), SIGTSTP
);
607 else if ((StopReason
& 0xff) == UDIWarned
)
608 WSETSTOP ((*status
), SIGLOST
);
609 else if ((StopReason
& 0xff) == UDIStepped
)
610 WSETSTOP ((*status
), SIGTRAP
);
611 else if ((StopReason
& 0xff) == UDIWaiting
)
612 WSETSTOP ((*status
), SIGSTOP
);
613 else if ((StopReason
& 0xff) == UDIHalted
)
614 WSETSTOP ((*status
), SIGKILL
);
616 WSETEXIT ((*status
), 0);
618 timeout
= old_timeout
; /* Restore original timeout value */
619 immediate_quit
= old_immediate_quit
;
624 /********************************************************** UDI_FETCH_REGISTERS
625 * Read a remote register 'regno'.
626 * If regno==-1 then read all the registers.
629 udi_fetch_registers (regno
)
637 UDIBool HostEndian
= 0;
641 fetch_register(regno
);
647 From
.Space
= UDI29KGlobalRegs
;
649 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
651 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
652 error("UDIRead() failed in udi_fetch_registers");
654 register_valid
[GR1_REGNUM
] = 1;
656 #if defined(GR64_REGNUM) /* Read gr64-127 */
658 /* Global Registers gr64-gr95 */
660 From
.Space
= UDI29KGlobalRegs
;
662 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
664 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
665 error("UDIRead() failed in udi_fetch_registers");
667 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
668 register_valid
[i
] = 1;
670 #endif /* GR64_REGNUM */
672 /* Global Registers gr96-gr127 */
674 From
.Space
= UDI29KGlobalRegs
;
676 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
678 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
679 error("UDIRead() failed in udi_fetch_registers");
681 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
682 register_valid
[i
] = 1;
684 /* Local Registers */
686 From
.Space
= UDI29KLocalRegs
;
688 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
690 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
691 error("UDIRead() failed in udi_fetch_registers");
693 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
694 register_valid
[i
] = 1;
696 /* Protected Special Registers */
698 From
.Space
= UDI29KSpecialRegs
;
700 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
702 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
703 error("UDIRead() failed in udi_fetch_registers");
705 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
706 register_valid
[i
] = 1;
708 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
709 fetch_register(NPC_REGNUM
);
710 fetch_register(PC_REGNUM
);
711 fetch_register(PC2_REGNUM
);
713 /* Unprotected Special Registers sr128-sr135 */
715 From
.Space
= UDI29KSpecialRegs
;
717 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
719 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
720 error("UDIRead() failed in udi_fetch_registers");
722 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
723 register_valid
[i
] = 1;
726 /* There doesn't seem to be any way to get these. */
729 supply_register (FPE_REGNUM
, (char *) &val
);
730 supply_register (INTE_REGNUM
, (char *) &val
);
731 supply_register (FPS_REGNUM
, (char *) &val
);
732 supply_register (EXO_REGNUM
, (char *) &val
);
737 /********************************************************* UDI_STORE_REGISTERS
738 ** Store register regno into the target.
739 * If regno==-1 then store all the registers.
743 udi_store_registers (regno
)
751 UDIBool HostEndian
= 0;
755 store_register(regno
);
761 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
762 To
.Space
= UDI29KGlobalRegs
;
765 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
766 error("UDIWrite() failed in udi_store_regisetrs");
768 #if defined(GR64_REGNUM)
770 /* Global registers gr64-gr95 */
772 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
773 To
.Space
= UDI29KGlobalRegs
;
776 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
777 error("UDIWrite() failed in udi_store_regisetrs");
779 #endif /* GR64_REGNUM */
781 /* Global registers gr96-gr127 */
783 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
784 To
.Space
= UDI29KGlobalRegs
;
787 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
788 error("UDIWrite() failed in udi_store_regisetrs");
790 /* Local Registers */
792 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
793 To
.Space
= UDI29KLocalRegs
;
796 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
797 error("UDIWrite() failed in udi_store_regisetrs");
800 /* Protected Special Registers */ /* VAB through TMR */
802 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
803 To
.Space
= UDI29KSpecialRegs
;
806 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
807 error("UDIWrite() failed in udi_store_regisetrs");
809 /* PC0, PC1, PC2 possibly as shadow registers */
811 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
812 To
.Space
= UDI29KSpecialRegs
;
815 To
.Offset
= 20; /* SPC0 */
817 To
.Offset
= 10; /* PC0 */
818 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
819 error("UDIWrite() failed in udi_store_regisetrs");
823 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
824 To
.Space
= UDI29KSpecialRegs
;
827 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
828 error("UDIWrite() failed in udi_store_regisetrs");
830 /* Unprotected Special Registers */
832 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
833 To
.Space
= UDI29KSpecialRegs
;
836 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
837 error("UDIWrite() failed in udi_store_regisetrs");
839 registers_changed ();
842 /****************************************************** UDI_PREPARE_TO_STORE */
843 /* Get ready to modify the registers array. On machines which store
844 individual registers, this doesn't need to do anything. On machines
845 which store all the registers in one fell swoop, this makes sure
846 that registers contains all the registers from the program being
850 udi_prepare_to_store ()
852 /* Do nothing, since we can store individual regs */
855 /********************************************************** TRANSLATE_ADDR */
860 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
861 /* Check for a virtual address in the kernel */
862 /* Assume physical address of ublock is in paddr_u register */
863 /* FIXME: doesn't work for user virtual addresses */
864 if (addr
>= UVADDR
) {
865 /* PADDR_U register holds the physical address of the ublock */
866 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
867 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
875 /************************************************* UDI_XFER_INFERIOR_MEMORY */
876 /* FIXME! Merge these two. */
878 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
885 memaddr
= translate_addr(memaddr
);
888 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
890 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
893 /********************************************************** UDI_FILES_INFO */
897 printf ("\tAttached to UDI socket to %s and running program %s.\n",
898 udi_config_id
, prog_name
);
901 /**************************************************** UDI_INSERT_BREAKPOINT */
903 udi_insert_breakpoint (addr
, contents_cache
)
905 char *contents_cache
;
910 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
911 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
914 if(cnt
>= BKPT_TABLE_SIZE
)
915 error("Too many breakpoints set");
917 bkpt_table
[cnt
].Addr
.Offset
= addr
;
918 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
919 bkpt_table
[cnt
].PassCount
= 1;
920 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
922 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
923 bkpt_table
[cnt
].PassCount
,
924 bkpt_table
[cnt
].Type
,
925 &bkpt_table
[cnt
].BreakId
);
927 if (err
== 0) return 0; /* Success */
929 bkpt_table
[cnt
].Type
= 0;
930 error("UDISetBreakpoint returned error code %d\n", err
);
933 /**************************************************** UDI_REMOVE_BREAKPOINT */
935 udi_remove_breakpoint (addr
, contents_cache
)
937 char *contents_cache
;
942 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
943 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
946 if(cnt
>= BKPT_TABLE_SIZE
)
947 error("Can't find breakpoint in table");
949 bkpt_table
[cnt
].Type
= 0;
951 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
952 if (err
== 0) return 0; /* Success */
954 error("UDIClearBreakpoint returned error code %d\n", err
);
957 /***************************************************************** UDI_KILL */
959 udi_kill(arg
,from_tty
)
965 DENTER("udi_kill()");
966 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
967 /* We don't ever kill the kernel */
969 printf_filtered("Kernel not killed, but left in current state.\n");
970 printf_filtered("Use detach to leave kernel running.\n");
976 printf("Target has been stopped.");
985 /***************************************************************** UDI_LOAD */
987 * Load a program into the target.
990 udi_load(arg_string
,from_tty
)
994 #define MAX_TOKENS 25
995 #define BUFFER_SIZE 256
997 char *token
[MAX_TOKENS
];
998 char cmd_line
[BUFFER_SIZE
];
1002 #if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
1003 printf("The kernel had better be loaded already! Loading not done.\n");
1005 if (arg_string
== 0)
1006 error ("The load command takes a file name");
1007 arg_string
= tilde_expand (arg_string
);
1008 sprintf(cmd_line
,"y %s %s", prog_name
, arg_string
);
1011 token
[0] = cmd_line
;
1013 if (cmd_line
[0] != '\0')
1014 { token
[token_count
] = strtok(cmd_line
, " \t,;\n\r");
1016 if (token
[token_count
] != NULL
)
1018 token_count
= token_count
+ 1;
1019 token
[token_count
] = strtok((char *) NULL
, " \t,;\n\r");
1020 } while ((token
[token_count
] != NULL
) &&
1021 (token_count
< MAX_TOKENS
));
1026 make_cleanup (free
, arg_string
);
1029 if(yank_cmd(token
, token_count
))
1030 error("Failure when tring to load program");
1032 symbol_file_add (arg_string
, from_tty
, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1037 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1038 ** Copy LEN bytes of data from debugger memory at MYADDR
1039 to inferior's memory at MEMADDR. Returns number of bytes written. */
1041 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1051 UDICount CountDone
= 0;
1052 UDIBool HostEndian
= 0;
1055 /* DENTER("udi_write_inferior_memory()"); */
1056 To
.Space
= udi_memory_space(memaddr
);
1057 From
= (UDIUInt32
*)myaddr
;
1059 while (nwritten
< len
)
1060 { Count
= len
- nwritten
;
1061 if (Count
> MAXDATA
) Count
= MAXDATA
;
1062 To
.Offset
= memaddr
+ nwritten
;
1063 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1064 { error("UDIWrite() failed in udi_write_inferrior_memory");
1068 { nwritten
+= CountDone
;
1072 /* DEXIT("udi_write_inferior_memory()"); */
1076 /**************************************************** UDI_READ_INFERIOR_MEMORY
1077 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1078 at debugger address MYADDR. Returns number of bytes read. */
1080 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1090 UDICount CountDone
= 0;
1091 UDIBool HostEndian
= 0;
1094 /* DENTER("udi_read_inferior_memory()"); */
1095 From
.Space
= udi_memory_space(memaddr
);
1096 To
= (UDIUInt32
*)myaddr
;
1099 { Count
= len
- nread
;
1100 if (Count
> MAXDATA
) Count
= MAXDATA
;
1101 From
.Offset
= memaddr
+ nread
;
1102 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1103 { error("UDIWrite() failed in udi_read_inferrior_memory");
1107 { nread
+= CountDone
;
1114 /********************************************************************* WARNING
1119 error ("ERROR while loading program into remote TIP: $d\n", num
);
1123 /*****************************************************************************/
1124 /* Fetch a single register indicatated by 'regno'.
1125 * Returns 0/-1 on success/failure.
1128 fetch_register (regno
)
1136 UDIBool HostEndian
= 0;
1139 if (regno
== GR1_REGNUM
)
1141 From
.Space
= UDI29KGlobalRegs
;
1144 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1146 From
.Space
= UDI29KGlobalRegs
;
1147 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1150 #if defined(GR64_REGNUM)
1152 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1154 From
.Space
= UDI29KGlobalRegs
;
1155 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1158 #endif /* GR64_REGNUM */
1160 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1162 From
.Space
= UDI29KLocalRegs
;
1163 From
.Offset
= (regno
- LR0_REGNUM
);
1165 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1168 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1169 return 0; /* Pretend Success */
1173 From
.Space
= UDI29KSpecialRegs
;
1174 From
.Offset
= regnum_to_srnum(regno
);
1177 if (UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1178 error("UDIRead() failed in udi_fetch_registers");
1180 supply_register(regno
, (char *) &To
);
1183 /*****************************************************************************/
1184 /* Store a single register indicated by 'regno'.
1185 * Returns 0/-1 on success/failure.
1188 store_register (regno
)
1197 UDIBool HostEndian
= 0;
1199 DENTER("store_register()");
1200 From
= read_register (regno
); /* get data value */
1202 if (regno
== GR1_REGNUM
)
1203 { To
.Space
= UDI29KGlobalRegs
;
1205 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1206 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1207 * register cache. Do this *after* calling read_register, because we want
1208 * read_register to return the value that write_register has just stuffed
1209 * into the registers array, not the value of the register fetched from
1212 registers_changed ();
1214 #if defined(GR64_REGNUM)
1215 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1216 { To
.Space
= UDI29KGlobalRegs
;
1217 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1218 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1220 #endif /* GR64_REGNUM */
1221 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1222 { To
.Space
= UDI29KGlobalRegs
;
1223 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1224 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1226 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1227 { To
.Space
= UDI29KLocalRegs
;
1228 To
.Offset
= (regno
- LR0_REGNUM
);
1229 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1231 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1233 return 0; /* Pretend Success */
1235 else /* An unprotected or protected special register */
1236 { To
.Space
= UDI29KSpecialRegs
;
1237 To
.Offset
= regnum_to_srnum(regno
);
1238 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1241 DEXIT("store_register()");
1244 error("UDIWrite() failed in store_registers");
1248 /********************************************************** REGNUM_TO_SRNUM */
1250 * Convert a gdb special register number to a 29000 special register number.
1253 regnum_to_srnum(regno
)
1257 case VAB_REGNUM
: return(0);
1258 case OPS_REGNUM
: return(1);
1259 case CPS_REGNUM
: return(2);
1260 case CFG_REGNUM
: return(3);
1261 case CHA_REGNUM
: return(4);
1262 case CHD_REGNUM
: return(5);
1263 case CHC_REGNUM
: return(6);
1264 case RBP_REGNUM
: return(7);
1265 case TMC_REGNUM
: return(8);
1266 case TMR_REGNUM
: return(9);
1267 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1268 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1269 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1270 case MMU_REGNUM
: return(13);
1271 case LRU_REGNUM
: return(14);
1272 case IPC_REGNUM
: return(128);
1273 case IPA_REGNUM
: return(129);
1274 case IPB_REGNUM
: return(130);
1275 case Q_REGNUM
: return(131);
1276 case ALU_REGNUM
: return(132);
1277 case BP_REGNUM
: return(133);
1278 case FC_REGNUM
: return(134);
1279 case CR_REGNUM
: return(135);
1280 case FPE_REGNUM
: return(160);
1281 case INTE_REGNUM
: return(161);
1282 case FPS_REGNUM
: return(162);
1283 case EXO_REGNUM
:return(164);
1285 return(255); /* Failure ? */
1288 /****************************************************************************/
1290 * Determine the Target memory space qualifier based on the addr.
1291 * FIXME: Can't distinguis I_ROM/D_ROM.
1292 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1295 udi_memory_space(addr
)
1298 UDIUInt32 tstart
= IMemStart
;
1299 UDIUInt32 tend
= tstart
+ IMemSize
;
1300 UDIUInt32 dstart
= DMemStart
;
1301 UDIUInt32 dend
= tstart
+ DMemSize
;
1302 UDIUInt32 rstart
= RMemStart
;
1303 UDIUInt32 rend
= tstart
+ RMemSize
;
1305 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1306 return UDI29KIRAMSpace
;
1307 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1308 return UDI29KDRAMSpace
;
1309 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1310 /* FIXME: how do we determine between D_ROM and I_ROM */
1311 return UDI29KIROMSpace
;
1312 } else /* FIXME: what do me do now? */
1313 return UDI29KDRAMSpace
; /* Hmmm! */
1315 /*********************************************************************** STUBS
1318 void convert16() {;}
1319 void convert32() {;}
1320 FILE* EchoFile
= 0; /* used for debugging */
1321 int QuietMode
= 0; /* used for debugging */
1323 /****************************************************************************/
1325 * Define the target subroutine names
1327 static struct target_ops udi_ops
= {
1328 "udi", "Remote UDI connected TIP",
1329 "Remote debug an Am290*0 using socket connection to TIP process ",
1330 udi_open
, udi_close
,
1331 udi_attach
, udi_detach
, udi_resume
, udi_wait
,
1332 udi_fetch_registers
, udi_store_registers
,
1333 udi_prepare_to_store
, 0, 0, /* conv_to, conv_from */
1334 udi_xfer_inferior_memory
,
1336 udi_insert_breakpoint
, udi_remove_breakpoint
, /* Breakpoints */
1337 0, 0, 0, 0, 0, /* Terminal handling */
1338 udi_kill
, /* FIXME, kill */
1340 0, /* lookup_symbol */
1341 udi_create_inferior
, /* create_inferior */
1342 udi_mourn
, /* mourn_inferior FIXME */
1343 process_stratum
, 0, /* next */
1344 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1345 0, 0, /* Section pointers */
1346 OPS_MAGIC
, /* Always the last thing */
1349 void _initialize_remote_udi()
1351 add_target (&udi_ops
);
1354 #ifdef NO_HIF_SUPPORT
1358 return(0); /* Emulate a failure */