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 char register_valid
[];
65 extern int stop_soon_quietly
; /* for wait_for_inferior */
66 extern struct value
*call_function_by_hand();
67 static void udi_resume();
68 static void udi_fetch_registers ();
69 static void udi_load();
70 static int fetch_register ();
71 static void udi_store_registers ();
72 static int store_register ();
73 static int regnum_to_srnum();
74 static void udi_close ();
75 static CPUSpace
udi_memory_space();
76 static int udi_write_inferior_memory();
77 static int udi_read_inferior_memory();
78 char CoffFileName
[100] = "";
82 #define TYPE_UNKNOWN 0
86 static char *processor_name
[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
87 static int processor_type
=TYPE_UNKNOWN
;
88 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
89 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
91 #define LLOG_FILE "udi.log"
92 #if defined (LOG_FILE)
96 static int timeout
= 5;
97 extern struct target_ops udi_ops
; /* Forward declaration */
99 /* Special register enumeration.
102 /******************************************************************* UDI DATA*/
103 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
104 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
105 udi_open knows that we don't have a file open when the program
107 UDISessionId udi_session_id
= -1;
109 CPUOffset IMemStart
= 0;
110 CPUSizeT IMemSize
= 0;
111 CPUOffset DMemStart
= 0;
112 CPUSizeT DMemSize
= 0;
113 CPUOffset RMemStart
= 0;
114 CPUSizeT RMemSize
= 0;
118 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
121 typedef struct bkpt_entry_str
126 unsigned int BreakId
;
128 #define BKPT_TABLE_SIZE 40
129 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
130 extern char dfe_errmsg
[]; /* error string */
132 /*********************************************************** SIGNAL SUPPORT */
133 /* Called when SIGALRM signal sent due to alarm() timeout. */
138 # define volatile /**/
141 volatile int n_alarms
;
148 printf ("udi_timer called\n");
152 #endif /* HAVE_TERMIO */
154 /* malloc'd name of the program on the remote system. */
155 static char *prog_name
= NULL
;
158 /* Number of SIGTRAPs we need to simulate. That is, the next
159 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
160 SIGTRAP without actually waiting for anything. */
162 /******************************************************* UDI_CREATE_INFERIOR */
163 /* This is called not only when we first attach, but also when the
164 user types "run" after having attached. */
166 udi_create_inferior (execfile
, args
, env
)
171 DENTER("udi_create_inferior()");
174 { if (prog_name
!= NULL
)
176 prog_name
= savestring (execfile
, strlen (execfile
));
179 if (prog_name
== 0 /* || exec_bfd == 0 */ )
180 error ("No exec file specified");
182 if (udi_session_id
< 0){
183 printf("UDI connection not open yet.\n");
187 inferior_pid
= 40000;
189 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
190 /* On ultra3 (NYU) we assume the kernel is already running so there is
191 * no file to download
194 if(*args
== '\0') args
= prog_name
;
198 /* We will get a task spawn event immediately. */
199 #ifdef NOTDEF /* start_remote() now does a wait without a resume
203 init_wait_for_inferior ();
204 clear_proceed_status ();
207 DEXIT("udi_create_inferior()");
209 /******************************************************* UDI_MOURN_INFERIOR */
213 DENTER("udi_mourn()");
214 pop_target (); /* Pop back to no-child state */
215 generic_mourn_inferior ();
216 DEXIT("udi_mourn()");
219 /******************************************************************** UDI_OPEN
220 ** Open a connection to remote TIP.
221 NAME is the socket domain used for communication with the TIP,
222 then a space and the socket name or TIP-host name.
223 '<udi_udi_config_id> [progname]' for example.
226 /* XXX - need cleanups for udiconnect for various failures!!! */
228 static char *udi_config_id
;
230 udi_open (name
, from_tty
)
237 UDIMemoryRange KnownMemory
[10];
238 UDIUInt32 ChipVersions
[10];
239 UDIInt NumberOfRanges
= 10;
240 UDIInt NumberOfChips
= 10;
242 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
244 DENTER("udi_open()");
246 target_preopen(from_tty
);
248 /* Find the first whitespace character, it separates udi_config_id
250 if(!name
) goto erroid
;
252 *p
!= '\0' && !isspace (*p
); p
++)
256 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
258 udi_config_id
= (char*)malloc (p
- name
+ 1);
259 strncpy (udi_config_id
, name
, p
- name
);
260 udi_config_id
[p
- name
] = '\0';
262 /* Skip over the whitespace after udi_config_id */
263 for (; isspace (*p
); p
++)
266 if (prog_name
!= NULL
)
268 prog_name
= savestring (p
, strlen (p
));
270 if (UDIConnect(udi_config_id
, &udi_session_id
))
271 error("UDIConnect() failed: %s\n", dfe_errmsg
);
273 push_target (&udi_ops
);
276 #ifndef NO_SIGINTERRUPT
277 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
279 if (siginterrupt (SIGALRM
, 1) != 0)
280 error ("udi_open: siginterrupt() %s", safe_strerror(errno
));
283 /* Set up read timeout timer. */
284 if ((void (*)) signal (SIGALRM
, udi_timer
) == (void (*)) -1)
285 error ("udi_open: signal() %s", safe_strerror(errno
));
288 #if defined (LOG_FILE)
289 log_file
= fopen (LOG_FILE
, "w");
290 if (log_file
== NULL
)
291 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
294 ** Initialize target configuration structure (global)
296 if(UDIGetTargetConfig( KnownMemory
, &NumberOfRanges
,
297 ChipVersions
, &NumberOfChips
))
298 error ("UDIGetTargetConfig() failed");
299 if(NumberOfChips
> 2)
300 fprintf(stderr
,"Taret has more than one processor\n");
301 for(cnt
=0; cnt
<NumberOfRanges
; cnt
++)
302 { switch(KnownMemory
[cnt
].Space
)
304 default: fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
308 case UDI29KIROMSpace
:
309 RMemStart
= KnownMemory
[cnt
].Offset
;
310 RMemSize
= KnownMemory
[cnt
].Size
;
312 case UDI29KIRAMSpace
:
313 IMemStart
= KnownMemory
[cnt
].Offset
;
314 IMemSize
= KnownMemory
[cnt
].Size
;
316 case UDI29KDRAMSpace
:
317 DMemStart
= KnownMemory
[cnt
].Offset
;
318 DMemSize
= KnownMemory
[cnt
].Size
;
323 /* Determine the processor revision level */
324 prl
= (unsigned int)read_register(CFG_REGNUM
) >> 24;
326 { fprintf_filtered(stderr
,
327 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
328 processor_type
= TYPE_A29000
;
329 } else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
330 { fprintf_filtered(stderr
,
331 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
332 processor_type
= TYPE_A29030
;
333 } else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
334 { fprintf_filtered(stderr
,
335 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
336 processor_type
= TYPE_A29050
;
338 processor_type
= TYPE_UNKNOWN
;
339 fprintf_filtered(stderr
,"WARNING: processor type unknown.\n");
341 if(UDICreateProcess(&PId
))
342 fprintf(stderr
, "UDICreateProcess() failed\n");
344 /* Print out some stuff, letting the user now what's going on */
345 if(UDICapabilities( &TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
347 error ("UDICapabilities() failed");
349 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
350 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
351 processor_name
[processor_type
],
352 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
353 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
354 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
357 /* FIXME: can this restriction be removed? */
358 printf_filtered("Remote debugging using virtual addresses works only\n");
359 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
363 if (processor_type
!= TYPE_A29050
) {
364 fprintf_filtered(stderr
,
365 "Freeze-mode debugging can only be done on an Am29050,\n");
366 fprintf_filtered(stderr
,
367 " unless GDB is being used with a 29K simulator.\n");
372 /******************************************************************* UDI_CLOSE
373 Close the open connection to the TIP process.
374 Use this when you want to detach and do something else
377 udi_close (quitting
) /*FIXME: how is quitting used */
381 DENTER("udi_close()");
383 if (udi_session_id
< 0)
384 error ("Can't close udi connection: not debugging remotely.");
386 /* We should never get here if there isn't something valid in
389 if(UDIDisconnect(udi_stream, Terminate);)
390 error ("UDIDisconnect() failed in udi_close");
392 /* Do not try to close udi_session_id again, later in the program. */
396 #if defined (LOG_FILE)
397 if (ferror (log_file
))
398 printf ("Error writing log file.\n");
399 if (fclose (log_file
) != 0)
400 printf ("Error closing log file.\n");
403 printf_filtered (" Ending remote debugging\n");
405 DEXIT("udi_close()");
408 /**************************************************************** UDI_ATACH */
409 /* Attach to a program that is already loaded and running
410 * Upon exiting the process's execution is stopped.
413 udi_attach (args
, from_tty
)
422 UDIBool HostEndian
= 0;
423 DENTER("udi_attach()");
425 if (udi_session_id
< 0)
426 printf ("UDI connection not opened yet, use the 'target udi' command.\n");
429 printf ("Attaching to remote program %s...\n", prog_name
);
431 mark_breakpoints_out ();
434 From
.Offset
= UDI29KSpecialRegs
;
435 if(UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
436 error ("UDIRead failed in udi_attach");
437 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
439 DEXIT("udi_attach()");
441 /************************************************************* UDI_DETACH */
442 /* Terminate the open connection to the TIP process.
443 Use this when you want to detach and do something else
444 with your gdb. Leave remote process running (with no breakpoints set). */
446 udi_detach (args
,from_tty
)
450 DENTER("udi_dettach()");
451 remove_breakpoints(); /* Just in case there were any left in */
452 if(UDIDisconnect(udi_session_id
))
453 error ("UDIDisconnect() failed in udi_detach");
454 pop_target(); /* calls udi_close to do the real work */
456 printf ("Ending remote debugging\n");
457 DEXIT("udi_dettach()");
461 /****************************************************************** UDI_RESUME
462 ** Tell the remote machine to resume. */
465 udi_resume (step
, sig
)
470 UDIStepType StepType
= UDIStepNatural
;
472 DENTER("udi_resume()");
473 if (step
) /* step 1 instruction */
474 { tip_error
= tip_error
= UDIStep(Steps
, StepType
, Range
);
475 if(tip_error
)fprintf(stderr
, "UDIStep() error = %d\n", tip_error
);
476 if(tip_error
)error ("failed in udi_resume");
481 error ("UDIExecute() failed in udi_resume");
484 DEXIT("udi_resume()");
487 /******************************************************************** UDI_WAIT
488 ** Wait until the remote machine stops, then return,
489 storing status in STATUS just as `wait' would. */
499 int old_timeout
= timeout
;
500 int old_immediate_quit
= immediate_quit
;
503 DENTER("udi_wait()");
504 WSETEXIT ((*status
), 0);
506 /* wait for message to arrive. It should be:
507 If the target stops executing, udi_wait() should return.
509 timeout
= 0; /* Wait indefinetly for a message */
510 immediate_quit
= 1; /* Helps ability to QUIT */
514 MaxTime
= UDIWaitForever
;
515 UDIWait(MaxTime
, &PId
, &StopReason
);
516 QUIT
; /* Let user quit if they want */
517 switch (StopReason
& 0xff)
522 if(UDIGetStdout(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
523 error("UDIGetStdin() failed in udi_wait");
524 while(CountDone
--)putc(sbuf
[i
++], stdout
);
528 UDIGetStderr(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
529 while(CountDone
--)putc(sbuf
[i
++], stderr
);
534 printf("DEBUG: stdin requested ... continue\n");
535 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
543 if (StopReason
& 0xff == UDITrapped
) /* lower 8-bits == 0 */
545 if (StopReason
>> 24 == 0)
546 { printf("Am290*0 received vector number 0 (break point)\n");
547 WSETSTOP ((*status
), SIGTRAP
);
549 else if (StopReason
>> 24 == 1)
550 { printf("Am290*0 received vector 1\n");
551 WSETSTOP ((*status
), SIGBUS
);
553 else if (StopReason
>> 24 == 3
554 || StopReason
>> 24 == 4)
555 { printf("Am290*0 received vector number %d\n",
557 WSETSTOP ((*status
), SIGFPE
);
559 else if (StopReason
>> 24 == 5)
560 { printf("Am290*0 received vector number %d\n",
562 WSETSTOP ((*status
), SIGILL
);
564 else if (StopReason
>> 24 >= 6
565 && StopReason
>> 24 <= 11)
566 { printf("Am290*0 received vector number %d\n",
568 WSETSTOP ((*status
), SIGSEGV
);
570 else if (StopReason
>> 24 == 12
571 || StopReason
>> 24 == 13)
572 { printf("Am290*0 received vector number %d\n",
574 WSETSTOP ((*status
), SIGILL
);
576 else if ((StopReason
& 0xff) == 14)
577 { printf("Am290*0 received vector number %d\n",
579 WSETSTOP ((*status
), SIGALRM
);
581 else if ((StopReason
& 0xff) == 15)
582 WSETSTOP ((*status
), SIGTRAP
);
583 else if ((StopReason
>> 24) >= 16
584 && (StopReason
>> 24) <= 21)
585 { printf("Am290*0 received vector number %d\n",
587 WSETSTOP ((*status
), SIGINT
);
589 else if ((StopReason
& 0xff) == 22)
590 { printf("Am290*0 received vector number %d\n",
592 WSETSTOP ((*status
), SIGILL
);
594 else if ((StopReason
& 0xff) == 77)
595 WSETSTOP ((*status
), SIGTRAP
);
598 WSETEXIT ((*status
), 0);
600 else if ((StopReason
& 0xff) == UDIBreak
)
601 WSETSTOP ((*status
), SIGTRAP
);
602 else if ((StopReason
& 0xff) == UDINotExecuting
)
603 WSETSTOP ((*status
), SIGTERM
);
604 else if ((StopReason
& 0xff) == UDIRunning
)
605 WSETSTOP ((*status
), SIGILL
);
606 else if ((StopReason
& 0xff) == UDIStopped
)
607 WSETSTOP ((*status
), SIGTSTP
);
608 else if ((StopReason
& 0xff) == UDIWarned
)
609 WSETSTOP ((*status
), SIGLOST
);
610 else if ((StopReason
& 0xff) == UDIStepped
)
611 WSETSTOP ((*status
), SIGTRAP
);
612 else if ((StopReason
& 0xff) == UDIWaiting
)
613 WSETSTOP ((*status
), SIGSTOP
);
614 else if ((StopReason
& 0xff) == UDIHalted
)
615 WSETSTOP ((*status
), SIGKILL
);
617 WSETEXIT ((*status
), 0);
619 timeout
= old_timeout
; /* Restore original timeout value */
620 immediate_quit
= old_immediate_quit
;
625 /********************************************************** UDI_FETCH_REGISTERS
626 * Read a remote register 'regno'.
627 * If regno==-1 then read all the registers.
630 udi_fetch_registers (regno
)
638 UDIBool HostEndian
= 0;
642 fetch_register(regno
);
648 From
.Space
= UDI29KGlobalRegs
;
650 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
652 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
653 error("UDIRead() failed in udi_fetch_registers");
655 register_valid
[GR1_REGNUM
] = 1;
657 #if defined(GR64_REGNUM) /* Read gr64-127 */
659 /* Global Registers gr64-gr95 */
661 From
.Space
= UDI29KGlobalRegs
;
663 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
665 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
666 error("UDIRead() failed in udi_fetch_registers");
668 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
669 register_valid
[i
] = 1;
671 #endif /* GR64_REGNUM */
673 /* Global Registers gr96-gr127 */
675 From
.Space
= UDI29KGlobalRegs
;
677 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
679 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
680 error("UDIRead() failed in udi_fetch_registers");
682 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
683 register_valid
[i
] = 1;
685 /* Local Registers */
687 From
.Space
= UDI29KLocalRegs
;
689 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
691 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
692 error("UDIRead() failed in udi_fetch_registers");
694 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
695 register_valid
[i
] = 1;
697 /* Protected Special Registers */
699 From
.Space
= UDI29KSpecialRegs
;
701 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
703 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
704 error("UDIRead() failed in udi_fetch_registers");
706 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
707 register_valid
[i
] = 1;
709 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
710 fetch_register(NPC_REGNUM
);
711 fetch_register(PC_REGNUM
);
712 fetch_register(PC2_REGNUM
);
714 /* Unprotected Special Registers sr128-sr135 */
716 From
.Space
= UDI29KSpecialRegs
;
718 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
720 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
721 error("UDIRead() failed in udi_fetch_registers");
723 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
724 register_valid
[i
] = 1;
727 /* There doesn't seem to be any way to get these. */
730 supply_register (FPE_REGNUM
, (char *) &val
);
731 supply_register (INTE_REGNUM
, (char *) &val
);
732 supply_register (FPS_REGNUM
, (char *) &val
);
733 supply_register (EXO_REGNUM
, (char *) &val
);
738 /********************************************************* UDI_STORE_REGISTERS
739 ** Store register regno into the target.
740 * If regno==-1 then store all the registers.
744 udi_store_registers (regno
)
752 UDIBool HostEndian
= 0;
756 store_register(regno
);
762 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
763 To
.Space
= UDI29KGlobalRegs
;
766 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
767 error("UDIWrite() failed in udi_store_regisetrs");
769 #if defined(GR64_REGNUM)
771 /* Global registers gr64-gr95 */
773 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
774 To
.Space
= UDI29KGlobalRegs
;
777 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
778 error("UDIWrite() failed in udi_store_regisetrs");
780 #endif /* GR64_REGNUM */
782 /* Global registers gr96-gr127 */
784 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
785 To
.Space
= UDI29KGlobalRegs
;
788 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
789 error("UDIWrite() failed in udi_store_regisetrs");
791 /* Local Registers */
793 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
794 To
.Space
= UDI29KLocalRegs
;
797 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
798 error("UDIWrite() failed in udi_store_regisetrs");
801 /* Protected Special Registers */ /* VAB through TMR */
803 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
804 To
.Space
= UDI29KSpecialRegs
;
807 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
808 error("UDIWrite() failed in udi_store_regisetrs");
810 /* PC0, PC1, PC2 possibly as shadow registers */
812 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
813 To
.Space
= UDI29KSpecialRegs
;
816 To
.Offset
= 20; /* SPC0 */
818 To
.Offset
= 10; /* PC0 */
819 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
820 error("UDIWrite() failed in udi_store_regisetrs");
824 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
825 To
.Space
= UDI29KSpecialRegs
;
828 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
829 error("UDIWrite() failed in udi_store_regisetrs");
831 /* Unprotected Special Registers */
833 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
834 To
.Space
= UDI29KSpecialRegs
;
837 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
838 error("UDIWrite() failed in udi_store_regisetrs");
840 registers_changed ();
843 /****************************************************** UDI_PREPARE_TO_STORE */
844 /* Get ready to modify the registers array. On machines which store
845 individual registers, this doesn't need to do anything. On machines
846 which store all the registers in one fell swoop, this makes sure
847 that registers contains all the registers from the program being
851 udi_prepare_to_store ()
853 /* Do nothing, since we can store individual regs */
856 /********************************************************** TRANSLATE_ADDR */
861 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
862 /* Check for a virtual address in the kernel */
863 /* Assume physical address of ublock is in paddr_u register */
864 /* FIXME: doesn't work for user virtual addresses */
865 if (addr
>= UVADDR
) {
866 /* PADDR_U register holds the physical address of the ublock */
867 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
868 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
876 /************************************************* UDI_XFER_INFERIOR_MEMORY */
877 /* FIXME! Merge these two. */
879 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
886 memaddr
= translate_addr(memaddr
);
889 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
891 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
894 /********************************************************** UDI_FILES_INFO */
898 printf ("\tAttached to UDI socket to %s and running program %s.\n",
899 udi_config_id
, prog_name
);
902 /**************************************************** UDI_INSERT_BREAKPOINT */
904 udi_insert_breakpoint (addr
, contents_cache
)
906 char *contents_cache
;
911 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
912 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
915 if(cnt
>= BKPT_TABLE_SIZE
)
916 error("Too many breakpoints set");
918 bkpt_table
[cnt
].Addr
.Offset
= addr
;
919 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
920 bkpt_table
[cnt
].PassCount
= 1;
921 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
923 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
924 bkpt_table
[cnt
].PassCount
,
925 bkpt_table
[cnt
].Type
,
926 &bkpt_table
[cnt
].BreakId
);
928 if (err
== 0) return 0; /* Success */
930 bkpt_table
[cnt
].Type
= 0;
931 error("UDISetBreakpoint returned error code %d\n", err
);
934 /**************************************************** UDI_REMOVE_BREAKPOINT */
936 udi_remove_breakpoint (addr
, contents_cache
)
938 char *contents_cache
;
943 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
944 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
947 if(cnt
>= BKPT_TABLE_SIZE
)
948 error("Can't find breakpoint in table");
950 bkpt_table
[cnt
].Type
= 0;
952 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
953 if (err
== 0) return 0; /* Success */
955 error("UDIClearBreakpoint returned error code %d\n", err
);
958 /***************************************************************** UDI_KILL */
960 udi_kill(arg
,from_tty
)
966 DENTER("udi_kill()");
967 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
968 /* We don't ever kill the kernel */
970 printf_filtered("Kernel not killed, but left in current state.\n");
971 printf_filtered("Use detach to leave kernel running.\n");
977 printf("Target has been stopped.");
986 /***************************************************************** UDI_LOAD */
988 * Load a program into the target.
991 udi_load(arg_string
,from_tty
)
995 #define MAX_TOKENS 25
996 #define BUFFER_SIZE 256
998 char *token
[MAX_TOKENS
];
999 char cmd_line
[BUFFER_SIZE
];
1003 #if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
1004 printf("The kernel had better be loaded already! Loading not done.\n");
1006 if (arg_string
== 0)
1007 error ("The load command takes a file name");
1008 arg_string
= tilde_expand (arg_string
);
1009 sprintf(cmd_line
,"y %s %s", prog_name
, arg_string
);
1012 token
[0] = cmd_line
;
1014 if (cmd_line
[0] != '\0')
1015 { token
[token_count
] = strtok(cmd_line
, " \t,;\n\r");
1017 if (token
[token_count
] != NULL
)
1019 token_count
= token_count
+ 1;
1020 token
[token_count
] = strtok((char *) NULL
, " \t,;\n\r");
1021 } while ((token
[token_count
] != NULL
) &&
1022 (token_count
< MAX_TOKENS
));
1027 make_cleanup (free
, arg_string
);
1030 if(yank_cmd(token
, token_count
))
1031 error("Failure when tring to load program");
1033 symbol_file_add (arg_string
, from_tty
, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1038 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1039 ** Copy LEN bytes of data from debugger memory at MYADDR
1040 to inferior's memory at MEMADDR. Returns number of bytes written. */
1042 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1052 UDICount CountDone
= 0;
1053 UDIBool HostEndian
= 0;
1056 /* DENTER("udi_write_inferior_memory()"); */
1057 To
.Space
= udi_memory_space(memaddr
);
1058 From
= (UDIUInt32
*)myaddr
;
1060 while (nwritten
< len
)
1061 { Count
= len
- nwritten
;
1062 if (Count
> MAXDATA
) Count
= MAXDATA
;
1063 To
.Offset
= memaddr
+ nwritten
;
1064 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1065 { error("UDIWrite() failed in udi_write_inferrior_memory");
1069 { nwritten
+= CountDone
;
1073 /* DEXIT("udi_write_inferior_memory()"); */
1077 /**************************************************** UDI_READ_INFERIOR_MEMORY
1078 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1079 at debugger address MYADDR. Returns number of bytes read. */
1081 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1091 UDICount CountDone
= 0;
1092 UDIBool HostEndian
= 0;
1095 /* DENTER("udi_read_inferior_memory()"); */
1096 From
.Space
= udi_memory_space(memaddr
);
1097 To
= (UDIUInt32
*)myaddr
;
1100 { Count
= len
- nread
;
1101 if (Count
> MAXDATA
) Count
= MAXDATA
;
1102 From
.Offset
= memaddr
+ nread
;
1103 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1104 { error("UDIWrite() failed in udi_read_inferrior_memory");
1108 { nread
+= CountDone
;
1115 /********************************************************************* WARNING
1120 error ("ERROR while loading program into remote TIP: $d\n", num
);
1124 /*****************************************************************************/
1125 /* Fetch a single register indicatated by 'regno'.
1126 * Returns 0/-1 on success/failure.
1129 fetch_register (regno
)
1137 UDIBool HostEndian
= 0;
1140 if (regno
== GR1_REGNUM
)
1142 From
.Space
= UDI29KGlobalRegs
;
1145 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1147 From
.Space
= UDI29KGlobalRegs
;
1148 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1151 #if defined(GR64_REGNUM)
1153 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1155 From
.Space
= UDI29KGlobalRegs
;
1156 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1159 #endif /* GR64_REGNUM */
1161 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1163 From
.Space
= UDI29KLocalRegs
;
1164 From
.Offset
= (regno
- LR0_REGNUM
);
1166 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1169 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1170 return 0; /* Pretend Success */
1174 From
.Space
= UDI29KSpecialRegs
;
1175 From
.Offset
= regnum_to_srnum(regno
);
1178 if (UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1179 error("UDIRead() failed in udi_fetch_registers");
1181 supply_register(regno
, (char *) &To
);
1184 /*****************************************************************************/
1185 /* Store a single register indicated by 'regno'.
1186 * Returns 0/-1 on success/failure.
1189 store_register (regno
)
1198 UDIBool HostEndian
= 0;
1200 DENTER("store_register()");
1201 From
= read_register (regno
); /* get data value */
1203 if (regno
== GR1_REGNUM
)
1204 { To
.Space
= UDI29KGlobalRegs
;
1206 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1207 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1208 * register cache. Do this *after* calling read_register, because we want
1209 * read_register to return the value that write_register has just stuffed
1210 * into the registers array, not the value of the register fetched from
1213 registers_changed ();
1215 #if defined(GR64_REGNUM)
1216 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1217 { To
.Space
= UDI29KGlobalRegs
;
1218 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1219 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1221 #endif /* GR64_REGNUM */
1222 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1223 { To
.Space
= UDI29KGlobalRegs
;
1224 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1225 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1227 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1228 { To
.Space
= UDI29KLocalRegs
;
1229 To
.Offset
= (regno
- LR0_REGNUM
);
1230 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1232 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1234 return 0; /* Pretend Success */
1236 else /* An unprotected or protected special register */
1237 { To
.Space
= UDI29KSpecialRegs
;
1238 To
.Offset
= regnum_to_srnum(regno
);
1239 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1242 DEXIT("store_register()");
1245 error("UDIWrite() failed in store_registers");
1249 /********************************************************** REGNUM_TO_SRNUM */
1251 * Convert a gdb special register number to a 29000 special register number.
1254 regnum_to_srnum(regno
)
1258 case VAB_REGNUM
: return(0);
1259 case OPS_REGNUM
: return(1);
1260 case CPS_REGNUM
: return(2);
1261 case CFG_REGNUM
: return(3);
1262 case CHA_REGNUM
: return(4);
1263 case CHD_REGNUM
: return(5);
1264 case CHC_REGNUM
: return(6);
1265 case RBP_REGNUM
: return(7);
1266 case TMC_REGNUM
: return(8);
1267 case TMR_REGNUM
: return(9);
1268 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1269 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1270 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1271 case MMU_REGNUM
: return(13);
1272 case LRU_REGNUM
: return(14);
1273 case IPC_REGNUM
: return(128);
1274 case IPA_REGNUM
: return(129);
1275 case IPB_REGNUM
: return(130);
1276 case Q_REGNUM
: return(131);
1277 case ALU_REGNUM
: return(132);
1278 case BP_REGNUM
: return(133);
1279 case FC_REGNUM
: return(134);
1280 case CR_REGNUM
: return(135);
1281 case FPE_REGNUM
: return(160);
1282 case INTE_REGNUM
: return(161);
1283 case FPS_REGNUM
: return(162);
1284 case EXO_REGNUM
:return(164);
1286 return(255); /* Failure ? */
1289 /****************************************************************************/
1291 * Determine the Target memory space qualifier based on the addr.
1292 * FIXME: Can't distinguis I_ROM/D_ROM.
1293 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1296 udi_memory_space(addr
)
1299 UDIUInt32 tstart
= IMemStart
;
1300 UDIUInt32 tend
= tstart
+ IMemSize
;
1301 UDIUInt32 dstart
= DMemStart
;
1302 UDIUInt32 dend
= tstart
+ DMemSize
;
1303 UDIUInt32 rstart
= RMemStart
;
1304 UDIUInt32 rend
= tstart
+ RMemSize
;
1306 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1307 return UDI29KIRAMSpace
;
1308 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1309 return UDI29KDRAMSpace
;
1310 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1311 /* FIXME: how do we determine between D_ROM and I_ROM */
1312 return UDI29KIROMSpace
;
1313 } else /* FIXME: what do me do now? */
1314 return UDI29KDRAMSpace
; /* Hmmm! */
1316 /*********************************************************************** STUBS
1319 void convert16() {;}
1320 void convert32() {;}
1321 FILE* EchoFile
= 0; /* used for debugging */
1322 int QuietMode
= 0; /* used for debugging */
1324 /****************************************************************************/
1326 * Define the target subroutine names
1328 static struct target_ops udi_ops
= {
1329 "udi", "Remote UDI connected TIP",
1330 "Remote debug an Am290*0 using socket connection to TIP process ",
1331 udi_open
, udi_close
,
1332 udi_attach
, udi_detach
, udi_resume
, udi_wait
,
1333 udi_fetch_registers
, udi_store_registers
,
1334 udi_prepare_to_store
, 0, 0, /* conv_to, conv_from */
1335 udi_xfer_inferior_memory
,
1337 udi_insert_breakpoint
, udi_remove_breakpoint
, /* Breakpoints */
1338 0, 0, 0, 0, 0, /* Terminal handling */
1339 udi_kill
, /* FIXME, kill */
1341 0, /* lookup_symbol */
1342 udi_create_inferior
, /* create_inferior */
1343 udi_mourn
, /* mourn_inferior FIXME */
1344 process_stratum
, 0, /* next */
1345 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1346 0, 0, /* Section pointers */
1347 OPS_MAGIC
, /* Always the last thing */
1350 void _initialize_remote_udi()
1352 add_target (&udi_ops
);
1355 #ifdef NO_HIF_SUPPORT
1359 return(0); /* Emulate a failure */