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. */
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
;
129 bkpt_entry_t bkpt_table
[MAX_BKPT
];
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 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
188 /* On ultra3 (NYU) we assume the kernel is already running so there is
189 * no file to download
192 if(*args
== '\0') args
= prog_name
;
196 /* We will get a task spawn event immediately. */
197 #ifdef NOTDEF /* start_remote() now does a wait without a resume
201 init_wait_for_inferior ();
202 clear_proceed_status ();
205 DEXIT("udi_create_inferior()");
207 /******************************************************* UDI_MOURN_INFERIOR */
211 DENTER("udi_mourn()");
212 pop_target (); /* Pop back to no-child state */
213 generic_mourn_inferior ();
214 DEXIT("udi_mourn()");
217 /******************************************************************** UDI_OPEN
218 ** Open a connection to remote TIP.
219 NAME is the socket domain used for communication with the TIP,
220 then a space and the socket name or TIP-host name.
221 '<udi_udi_config_id> [progname]' for example.
224 static char *udi_config_id
;
226 udi_open (name
, from_tty
)
233 UDIMemoryRange KnownMemory
[10];
234 UDIUInt32 ChipVersions
[10];
235 UDIInt NumberOfRanges
= 10;
236 UDIInt NumberOfChips
= 10;
238 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
240 DENTER("udi_open()");
242 /* Find the first whitespace character, it separates udi_config_id
244 if(!name
) goto erroid
;
246 *p
!= '\0' && !isspace (*p
); p
++)
250 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
251 udi_config_id
= (char*)malloc (p
- name
+ 1);
252 strncpy (udi_config_id
, name
, p
- name
);
253 udi_config_id
[p
- name
] = '\0';
255 /* Skip over the whitespace after udi_config_id */
256 for (; isspace (*p
); p
++)
259 if (prog_name
!= NULL
)
261 prog_name
= savestring (p
, strlen (p
));
263 if (udi_session_id
>= 0)
264 close (udi_session_id
);
266 if(UDIConnect(udi_config_id
, &udi_session_id
))
267 fprintf(stderr
, "UDIConnect() failed: %s\n", dfe_errmsg
);
268 push_target (&udi_ops
);
271 #ifndef NO_SIGINTERRUPT
272 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
274 if (siginterrupt (SIGALRM
, 1) != 0)
275 perror ("udi_open: error in siginterrupt");
278 /* Set up read timeout timer. */
279 if ((void (*)) signal (SIGALRM
, udi_timer
) == (void (*)) -1)
280 perror ("udi_open: error in signal");
283 #if defined (LOG_FILE)
284 log_file
= fopen (LOG_FILE
, "w");
285 if (log_file
== NULL
)
289 ** Initialize target configuration structure (global)
291 if(UDIGetTargetConfig( KnownMemory
, &NumberOfRanges
,
292 ChipVersions
, &NumberOfChips
))
293 error ("UDIGetTargetConfig() failed");
294 if(NumberOfChips
> 2)
295 fprintf(stderr
,"Taret has more than one processor\n");
296 for(cnt
=0; cnt
<NumberOfRanges
; cnt
++)
297 { switch(KnownMemory
[cnt
].Space
)
299 default: fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
303 case UDI29KIROMSpace
:
304 RMemStart
= KnownMemory
[cnt
].Offset
;
305 RMemSize
= KnownMemory
[cnt
].Size
;
307 case UDI29KIRAMSpace
:
308 IMemStart
= KnownMemory
[cnt
].Offset
;
309 IMemSize
= KnownMemory
[cnt
].Size
;
311 case UDI29KDRAMSpace
:
312 DMemStart
= KnownMemory
[cnt
].Offset
;
313 DMemSize
= KnownMemory
[cnt
].Size
;
318 /* Determine the processor revision level */
319 prl
= (unsigned int)read_register(CFG_REGNUM
) >> 24;
321 { fprintf_filtered(stderr
,
322 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
323 processor_type
= TYPE_A29000
;
324 } else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
325 { fprintf_filtered(stderr
,
326 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
327 processor_type
= TYPE_A29030
;
328 } else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
329 { fprintf_filtered(stderr
,
330 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
331 processor_type
= TYPE_A29050
;
333 processor_type
= TYPE_UNKNOWN
;
334 fprintf_filtered(stderr
,"WARNING: processor type unknown.\n");
336 if(UDICreateProcess(&PId
))
337 fprintf(stderr
, "UDICreateProcess() failed\n");
339 /* Print out some stuff, letting the user now what's going on */
340 if(UDICapabilities( &TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
342 error ("UDICapabilities() failed");
344 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
345 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
346 processor_name
[processor_type
],
347 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
348 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
349 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
352 /* FIXME: can this restriction be removed? */
353 printf_filtered("Remote debugging using virtual addresses works only\n");
354 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
358 if (processor_type
!= TYPE_A29050
) {
359 fprintf_filtered(stderr
,
360 "Freeze-mode debugging can only be done on an Am29050,\n");
361 fprintf_filtered(stderr
,
362 " unless GDB is being used with a 29K simulator.\n");
367 /******************************************************************* UDI_CLOSE
368 Close the open connection to the TIP process.
369 Use this when you want to detach and do something else
372 udi_close (quitting
) /*FIXME: how is quitting used */
376 DENTER("udi_close()");
378 if (udi_session_id
< 0)
379 error ("Can't close udi connection: not debugging remotely.");
381 /* We should never get here if there isn't something valid in
384 if(UDIDisconnect(udi_stream, Terminate);)
385 error ("UDIDisconnect() failed in udi_close");
387 /* Do not try to close udi_session_id again, later in the program. */
390 #if defined (LOG_FILE)
391 if (ferror (log_file
))
392 printf ("Error writing log file.\n");
393 if (fclose (log_file
) != 0)
394 printf ("Error closing log file.\n");
397 printf ("Ending remote debugging\n");
399 DEXIT("udi_close()");
402 /**************************************************************** UDI_ATACH */
403 /* Attach to a program that is already loaded and running
404 * Upon exiting the process's execution is stopped.
407 udi_attach (args
, from_tty
)
416 UDIBool HostEndian
= 0;
417 DENTER("udi_attach()");
419 if (udi_session_id
< 0)
420 printf ("UDI connection not opened yet, use the 'target udi' command.\n");
423 printf ("Attaching to remote program %s...\n", prog_name
);
425 mark_breakpoints_out ();
428 From
.Offset
= UDI29KSpecialRegs
;
429 if(UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
430 error ("UDIRead failed in udi_attach");
431 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
433 DEXIT("udi_attach()");
435 /************************************************************* UDI_DETACH */
436 /* Terminate the open connection to the TIP process.
437 Use this when you want to detach and do something else
438 with your gdb. Leave remote process running (with no breakpoints set). */
440 udi_detach (args
,from_tty
)
444 DENTER("udi_dettach()");
445 remove_breakpoints(); /* Just in case there were any left in */
446 if(UDIDisconnect(udi_session_id
))
447 error ("UDIDisconnect() failed in udi_detach");
448 pop_target(); /* calls udi_close to do the real work */
450 printf ("Ending remote debugging\n");
451 DEXIT("udi_dettach()");
455 /****************************************************************** UDI_RESUME
456 ** Tell the remote machine to resume. */
459 udi_resume (step
, sig
)
464 UDIStepType StepType
= UDIStepNatural
;
466 DENTER("udi_resume()");
467 if (step
) /* step 1 instruction */
468 { tip_error
= tip_error
= UDIStep(Steps
, StepType
, Range
);
469 if(tip_error
)fprintf(stderr
, "UDIStep() error = %d\n", tip_error
);
470 if(tip_error
)error ("failed in udi_resume");
475 error ("UDIExecute() failed in udi_resume");
478 DEXIT("udi_resume()");
481 /******************************************************************** UDI_WAIT
482 ** Wait until the remote machine stops, then return,
483 storing status in STATUS just as `wait' would. */
493 int old_timeout
= timeout
;
494 int old_immediate_quit
= immediate_quit
;
497 DENTER("udi_wait()");
498 WSETEXIT ((*status
), 0);
500 /* wait for message to arrive. It should be:
501 If the target stops executing, udi_wait() should return.
503 timeout
= 0; /* Wait indefinetly for a message */
504 immediate_quit
= 1; /* Helps ability to QUIT */
508 MaxTime
= UDIWaitForever
;
509 UDIWait(MaxTime
, &PId
, &StopReason
);
510 QUIT
; /* Let user quit if they want */
511 switch (StopReason
& 0xff)
516 if(UDIGetStdout(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
517 error("UDIGetStdin() failed in udi_wait");
518 while(CountDone
--)putc(sbuf
[i
++], stdout
);
522 UDIGetStderr(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
523 while(CountDone
--)putc(sbuf
[i
++], stderr
);
528 printf("DEBUG: stdin requested ... continue\n");
529 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
537 if (StopReason
& 0xff == UDITrapped
) /* lower 8-bits == 0 */
539 if (StopReason
>> 24 == 0)
540 { printf("Am290*0 received vector number 0 (break point)\n");
541 WSETSTOP ((*status
), SIGTRAP
);
543 else if (StopReason
>> 24 == 1)
544 { printf("Am290*0 received vector 1\n");
545 WSETSTOP ((*status
), SIGBUS
);
547 else if (StopReason
>> 24 == 3
548 || StopReason
>> 24 == 4)
549 { printf("Am290*0 received vector number %d\n",
551 WSETSTOP ((*status
), SIGFPE
);
553 else if (StopReason
>> 24 == 5)
554 { printf("Am290*0 received vector number %d\n",
556 WSETSTOP ((*status
), SIGILL
);
558 else if (StopReason
>> 24 >= 6
559 && StopReason
>> 24 <= 11)
560 { printf("Am290*0 received vector number %d\n",
562 WSETSTOP ((*status
), SIGSEGV
);
564 else if (StopReason
>> 24 == 12
565 || StopReason
>> 24 == 13)
566 { printf("Am290*0 received vector number %d\n",
568 WSETSTOP ((*status
), SIGILL
);
570 else if ((StopReason
& 0xff) == 14)
571 { printf("Am290*0 received vector number %d\n",
573 WSETSTOP ((*status
), SIGALRM
);
575 else if ((StopReason
& 0xff) == 15)
576 WSETSTOP ((*status
), SIGTRAP
);
577 else if ((StopReason
>> 24) >= 16
578 && (StopReason
>> 24) <= 21)
579 { printf("Am290*0 received vector number %d\n",
581 WSETSTOP ((*status
), SIGINT
);
583 else if ((StopReason
& 0xff) == 22)
584 { printf("Am290*0 received vector number %d\n",
586 WSETSTOP ((*status
), SIGILL
);
588 else if ((StopReason
& 0xff) == 77)
589 WSETSTOP ((*status
), SIGTRAP
);
592 WSETEXIT ((*status
), 0);
594 else if ((StopReason
& 0xff) == UDIBreak
)
595 WSETSTOP ((*status
), SIGTRAP
);
596 else if ((StopReason
& 0xff) == UDINotExecuting
)
597 WSETSTOP ((*status
), SIGTERM
);
598 else if ((StopReason
& 0xff) == UDIRunning
)
599 WSETSTOP ((*status
), SIGILL
);
600 else if ((StopReason
& 0xff) == UDIStopped
)
601 WSETSTOP ((*status
), SIGTSTP
);
602 else if ((StopReason
& 0xff) == UDIWarned
)
603 WSETSTOP ((*status
), SIGLOST
);
604 else if ((StopReason
& 0xff) == UDIStepped
)
605 WSETSTOP ((*status
), SIGTRAP
);
606 else if ((StopReason
& 0xff) == UDIWaiting
)
607 WSETSTOP ((*status
), SIGSTOP
);
608 else if ((StopReason
& 0xff) == UDIHalted
)
609 WSETSTOP ((*status
), SIGKILL
);
611 WSETEXIT ((*status
), 0);
613 timeout
= old_timeout
; /* Restore original timeout value */
614 immediate_quit
= old_immediate_quit
;
619 /********************************************************** UDI_FETCH_REGISTERS
620 * Read a remote register 'regno'.
621 * If regno==-1 then read all the registers.
624 udi_fetch_registers (regno
)
632 UDIBool HostEndian
= 0;
636 fetch_register(regno
);
639 DENTER("udi_fetch_registers()");
642 From
.Space
= UDI29KGlobalRegs
;
644 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
646 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
647 error("UDIRead() failed in udi_fetch_registers");
648 else register_valid
[4 * GR1_REGNUM
] = 1;
650 #if defined(GR64_REGNUM) /* Read gr64-127 */
651 /* Global Registers gr64-gr95 */
652 From
.Space
= UDI29KGlobalRegs
;
654 To
= ®isters
[4 * GR64_REGNUM
];
656 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
657 error("UDIRead() failed in udi_fetch_registers");
658 else for(i
= 4 * GR64_REGNUM
; i
< 4*GR64_REGNUM
+ 32; i
++)
659 #endif /* GR64_REGNUM */
661 /* Global Registers gr96-gr127 */
662 From
.Space
= UDI29KGlobalRegs
;
664 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
666 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
667 error("UDIRead() failed in udi_fetch_registers");
668 else for(i
= 4 * GR96_REGNUM
; i
< 4*GR96_REGNUM
+ 32; i
++)
669 register_valid
[i
] = 1;
671 /* Local Registers */
672 From
.Space
= UDI29KLocalRegs
;
674 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
676 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
677 error("UDIRead() failed in udi_fetch_registers");
678 else for(i
= 4 * LR0_REGNUM
; i
< 4*LR0_REGNUM
+ 128; i
++)
679 register_valid
[i
] = 1;
681 /* Protected Special Registers */
682 From
.Space
= UDI29KSpecialRegs
;
684 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
686 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
687 error("UDIRead() failed in udi_fetch_registers");
688 else for(i
= 4 * SR_REGNUM(0); i
< 4*SR_REGNUM(0) + 15; i
++)
689 register_valid
[i
] = 1;
691 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
692 fetch_register(NPC_REGNUM
);
693 fetch_register(PC_REGNUM
);
694 fetch_register(PC2_REGNUM
);
697 /* Unprotected Special Registers sr128-sr135*/
698 if (USE_SHADOW_PC
) /* Let regno_to_srnum() handle the register number */
699 { From
.Space
= UDI29KSpecialRegs
;
701 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
703 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
704 error("UDIRead() failed in udi_fetch_registers");
705 else for(i
= 4 * SR_REGNUM(128); i
< 4*SR_REGNUM(128) + 135-128+1; i
++)
706 register_valid
[i
] = 1;
709 /* There doesn't seem to be any way to get these. */
712 supply_register (FPE_REGNUM
, (char *) &val
);
713 supply_register (INT_REGNUM
, (char *) &val
);
714 supply_register (FPS_REGNUM
, (char *) &val
);
715 supply_register (EXO_REGNUM
, (char *) &val
);
718 DEXIT("udi_fetch_registerS()");
722 /********************************************************* UDI_STORE_REGISTERS
723 ** Store register regno into the target.
724 * If regno==-1 then store all the registers.
728 udi_store_registers (regno
)
736 UDIBool HostEndian
= 0;
740 store_register(regno
);
744 DENTER("udi_store_registers()");
747 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
748 To
.Space
= UDI29KGlobalRegs
;
751 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
752 error("UDIWrite() failed in udi_store_regisetrs");
754 #if defined(GR64_REGNUM)
755 /* Global registers gr64-gr95 */
756 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
757 To
.Space
= UDI29KGlobalRegs
;
760 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
761 error("UDIWrite() failed in udi_store_regisetrs");
762 #endif /* GR64_REGNUM */
764 /* Global registers gr96-gr127 */
765 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
766 To
.Space
= UDI29KGlobalRegs
;
769 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
770 error("UDIWrite() failed in udi_store_regisetrs");
772 /* Local Registers */
773 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
774 To
.Space
= UDI29KLocalRegs
;
777 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
778 error("UDIWrite() failed in udi_store_regisetrs");
781 /* Protected Special Registers */ /* VAB through TMR */
782 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
783 To
.Space
= UDI29KSpecialRegs
;
786 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
787 error("UDIWrite() failed in udi_store_regisetrs");
789 /* PC0, PC1, PC2 possibly as shadow registers */
790 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
791 To
.Space
= UDI29KSpecialRegs
;
794 To
.Offset
= 20; /* SPC0 */
796 To
.Offset
= 10; /* PC0 */
797 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
798 error("UDIWrite() failed in udi_store_regisetrs");
801 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
802 To
.Space
= UDI29KSpecialRegs
;
805 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
806 error("UDIWrite() failed in udi_store_regisetrs");
808 /* Unprotected Special Registers */
809 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
810 To
.Space
= UDI29KSpecialRegs
;
813 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
814 error("UDIWrite() failed in udi_store_regisetrs");
816 registers_changed ();
817 DEXIT("udi_store_registers() failed in udi_store_regisetrs");
820 /****************************************************** UDI_PREPARE_TO_STORE */
821 /* Get ready to modify the registers array. On machines which store
822 individual registers, this doesn't need to do anything. On machines
823 which store all the registers in one fell swoop, this makes sure
824 that registers contains all the registers from the program being
828 udi_prepare_to_store ()
830 /* Do nothing, since we can store individual regs */
833 /********************************************************** TRANSLATE_ADDR */
838 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
839 /* Check for a virtual address in the kernel */
840 /* Assume physical address of ublock is in paddr_u register */
841 /* FIXME: doesn't work for user virtual addresses */
842 if (addr
>= UVADDR
) {
843 /* PADDR_U register holds the physical address of the ublock */
844 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
845 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
853 /************************************************* UDI_XFER_INFERIOR_MEMORY */
854 /* FIXME! Merge these two. */
856 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
863 memaddr
= translate_addr(memaddr
);
866 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
868 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
871 /********************************************************** UDI_FILES_INFO */
875 printf ("\tAttached to UDI socket to %s and running program %s.\n",
876 udi_config_id
, prog_name
);
879 /**************************************************** UDI_INSERT_BREAKPOINT */
881 udi_insert_breakpoint (addr
, contents_cache
)
883 char *contents_cache
;
886 DENTER("udi_insert_breakpoint()");
888 while( cnt
< MAX_BKPT
) /* find BKPT slot in table */
889 if( !(bkpt_table
[cnt
].Type
) )
893 { error("Too many breakpoints set");
894 DEXIT("udi_insert_breakpoint() failure");
895 return 1; /* Failure */
897 bkpt_table
[cnt
].Addr
.Offset
= addr
;
898 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
899 bkpt_table
[cnt
].PassCount
= 1;
900 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
902 if( UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
903 bkpt_table
[cnt
].PassCount
,
904 bkpt_table
[cnt
].Type
,
905 &bkpt_table
[cnt
].BreakId
) )
906 { error("UDISetBreakpoint() failed in udi_insert_breakpoint");
907 bkpt_table
[cnt
].Type
= 0;
908 DEXIT("udi_insert_breakpoint() failure");
909 return 1; /* Failure */
911 { DEXIT("udi_insert_breakpoint() success");
912 return 0; /* Success */
916 /**************************************************** UDI_REMOVE_BREAKPOINT */
918 udi_remove_breakpoint (addr
, contents_cache
)
920 char *contents_cache
;
923 DENTER("udi_remove_breakpoint()");
925 while( cnt
< MAX_BKPT
) /* find BKPT slot in table */
926 if(bkpt_table
[cnt
].Addr
.Offset
= addr
) break;
929 { error("Can't find breakpoint in table");
930 DEXIT("udi_remove_breakpoint() failure");
931 return 1; /* Failure */
933 bkpt_table
[cnt
].Type
= 0;
935 if ( !UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
)) {
936 DEXIT("udi_remove_breakpoint()");
937 return 0; /* Success */
939 DEXIT("udi_remove_breakpoint()");
940 error("UDIClearBreakpoint() failed in udi_remove_breakpoint");
941 return 1; /* Failure */
946 /***************************************************************** UDI_KILL */
948 udi_kill(arg
,from_tty
)
954 DENTER("udi_kill()");
955 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
956 /* We don't ever kill the kernel */
958 printf("Kernel not killed, but left in current state.\n");
959 printf("Use detach to leave kernel running.\n");
964 printf("Target has been stopped.");
973 /***************************************************************** UDI_LOAD */
975 * Load a program into the target.
978 udi_load(arg_string
,from_tty
)
982 #define MAX_TOKENS 25
983 #define BUFFER_SIZE 256
985 char *token
[MAX_TOKENS
];
986 char cmd_line
[BUFFER_SIZE
];
990 #if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
991 printf("The kernel had better be loaded already! Loading not done.\n");
994 error ("The load command takes a file name");
995 arg_string
= tilde_expand (arg_string
);
996 sprintf(cmd_line
,"y %s %s", prog_name
, arg_string
);
1001 if (cmd_line
[0] != '\0')
1002 { token
[token_count
] = strtok(cmd_line
, " \t,;\n\r");
1004 if (token
[token_count
] != NULL
)
1006 token_count
= token_count
+ 1;
1007 token
[token_count
] = strtok((char *) NULL
, " \t,;\n\r");
1008 } while ((token
[token_count
] != NULL
) &&
1009 (token_count
< MAX_TOKENS
));
1014 make_cleanup (free
, arg_string
);
1017 if(yank_cmd(token
, token_count
))
1018 error("Failure when tring to load program");
1020 symbol_file_add (arg_string
, from_tty
, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1025 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1026 ** Copy LEN bytes of data from debugger memory at MYADDR
1027 to inferior's memory at MEMADDR. Returns number of bytes written. */
1029 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1039 UDICount CountDone
= 0;
1040 UDIBool HostEndian
= 0;
1043 /* DENTER("udi_write_inferior_memory()"); */
1044 To
.Space
= udi_memory_space(memaddr
);
1045 From
= (UDIUInt32
*)myaddr
;
1047 while (nwritten
< len
)
1048 { Count
= len
- nwritten
;
1049 if (Count
> MAXDATA
) Count
= MAXDATA
;
1050 To
.Offset
= memaddr
+ nwritten
;
1051 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1052 { error("UDIWrite() failed in udi_write_inferrior_memory");
1056 { nwritten
+= CountDone
;
1060 /* DEXIT("udi_write_inferior_memory()"); */
1064 /**************************************************** UDI_READ_INFERIOR_MEMORY
1065 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1066 at debugger address MYADDR. Returns number of bytes read. */
1068 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1078 UDICount CountDone
= 0;
1079 UDIBool HostEndian
= 0;
1082 /* DENTER("udi_read_inferior_memory()"); */
1083 From
.Space
= udi_memory_space(memaddr
);
1084 To
= (UDIUInt32
*)myaddr
;
1087 { Count
= len
- nread
;
1088 if (Count
> MAXDATA
) Count
= MAXDATA
;
1089 From
.Offset
= memaddr
+ nread
;
1090 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1091 { error("UDIWrite() failed in udi_read_inferrior_memory");
1095 { nread
+= CountDone
;
1102 /********************************************************************* WARNING
1107 error ("ERROR while loading program into remote TIP: $d\n", num
);
1111 /*****************************************************************************/
1112 /* Fetch a single register indicatated by 'regno'.
1113 * Returns 0/-1 on success/failure.
1116 fetch_register (regno
)
1124 UDIBool HostEndian
= 0;
1127 DENTER("udi_fetch_register()");
1129 if (regno
== GR1_REGNUM
)
1130 { From
.Space
= UDI29KGlobalRegs
;
1132 result
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
);
1134 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1135 { From
.Space
= UDI29KGlobalRegs
;
1136 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1137 result
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
);
1139 #if defined(GR64_REGNUM)
1140 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1141 { From
.Space
= UDI29KGlobalRegs
;
1142 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1143 result
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
);
1145 #endif /* GR64_REGNUM */
1146 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1147 { From
.Space
= UDI29KLocalRegs
;
1148 From
.Offset
= (regno
- LR0_REGNUM
);
1149 result
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
);
1151 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1153 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1154 return 0; /* Pretend Success */
1157 { From
.Space
= UDI29KSpecialRegs
;
1158 From
.Offset
= regnum_to_srnum(regno
);
1159 result
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
);
1161 DEXIT("udi_fetch_register()");
1164 error("UDIRead() failed in udi_fetch_registers");
1166 supply_register(regno
, (char *) &To
);
1169 /*****************************************************************************/
1170 /* Store a single register indicated by 'regno'.
1171 * Returns 0/-1 on success/failure.
1174 store_register (regno
)
1183 UDIBool HostEndian
= 0;
1185 DENTER("store_register()");
1186 From
= read_register (regno
); /* get data value */
1188 if (regno
== GR1_REGNUM
)
1189 { To
.Space
= UDI29KGlobalRegs
;
1191 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1192 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1193 * register cache. Do this *after* calling read_register, because we want
1194 * read_register to return the value that write_register has just stuffed
1195 * into the registers array, not the value of the register fetched from
1198 registers_changed ();
1200 #if defined(GR64_REGNUM)
1201 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1202 { To
.Space
= UDI29KGlobalRegs
;
1203 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1204 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1206 #endif /* GR64_REGNUM */
1207 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1208 { To
.Space
= UDI29KGlobalRegs
;
1209 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1210 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1212 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1213 { To
.Space
= UDI29KLocalRegs
;
1214 To
.Offset
= (regno
- LR0_REGNUM
);
1215 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1217 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1219 return 0; /* Pretend Success */
1221 else /* An unprotected or protected special register */
1222 { To
.Space
= UDI29KSpecialRegs
;
1223 To
.Offset
= regnum_to_srnum(regno
);
1224 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1227 DEXIT("store_register()");
1230 error("UDIWrite() failed in store_registers");
1234 /********************************************************** REGNUM_TO_SRNUM */
1236 * Convert a gdb special register number to a 29000 special register number.
1239 regnum_to_srnum(regno
)
1243 case VAB_REGNUM
: return(0);
1244 case OPS_REGNUM
: return(1);
1245 case CPS_REGNUM
: return(2);
1246 case CFG_REGNUM
: return(3);
1247 case CHA_REGNUM
: return(4);
1248 case CHD_REGNUM
: return(5);
1249 case CHC_REGNUM
: return(6);
1250 case RBP_REGNUM
: return(7);
1251 case TMC_REGNUM
: return(8);
1252 case TMR_REGNUM
: return(9);
1253 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1254 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1255 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1256 case MMU_REGNUM
: return(13);
1257 case LRU_REGNUM
: return(14);
1258 case IPC_REGNUM
: return(128);
1259 case IPA_REGNUM
: return(129);
1260 case IPB_REGNUM
: return(130);
1261 case Q_REGNUM
: return(131);
1262 case ALU_REGNUM
: return(132);
1263 case BP_REGNUM
: return(133);
1264 case FC_REGNUM
: return(134);
1265 case CR_REGNUM
: return(135);
1266 case FPE_REGNUM
: return(160);
1267 case INT_REGNUM
: return(161);
1268 case FPS_REGNUM
: return(162);
1269 case EXO_REGNUM
:return(164);
1271 return(255); /* Failure ? */
1274 /****************************************************************************/
1276 * Determine the Target memory space qualifier based on the addr.
1277 * FIXME: Can't distinguis I_ROM/D_ROM.
1278 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1281 udi_memory_space(addr
)
1284 UDIUInt32 tstart
= IMemStart
;
1285 UDIUInt32 tend
= tstart
+ IMemSize
;
1286 UDIUInt32 dstart
= DMemStart
;
1287 UDIUInt32 dend
= tstart
+ DMemSize
;
1288 UDIUInt32 rstart
= RMemStart
;
1289 UDIUInt32 rend
= tstart
+ RMemSize
;
1291 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1292 return UDI29KIRAMSpace
;
1293 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1294 return UDI29KDRAMSpace
;
1295 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1296 /* FIXME: how do we determine between D_ROM and I_ROM */
1297 return UDI29KIROMSpace
;
1298 } else /* FIXME: what do me do now? */
1299 return UDI29KDRAMSpace
; /* Hmmm! */
1301 /*********************************************************************** STUBS
1304 void convert16() {;}
1305 void convert32() {;}
1306 FILE* EchoFile
= 0; /* used for debugging */
1307 int QuietMode
= 0; /* used for debugging */
1309 /****************************************************************************/
1311 * Define the target subroutine names
1313 static struct target_ops udi_ops
= {
1314 "udi", "Remote UDI connected TIP",
1315 "Remote debug an Am290*0 using socket connection to TIP process ",
1316 udi_open
, udi_close
,
1317 udi_attach
, udi_detach
, udi_resume
, udi_wait
,
1318 udi_fetch_registers
, udi_store_registers
,
1319 udi_prepare_to_store
, 0, 0, /* conv_to, conv_from */
1320 udi_xfer_inferior_memory
,
1322 udi_insert_breakpoint
, udi_remove_breakpoint
, /* Breakpoints */
1323 0, 0, 0, 0, 0, /* Terminal handling */
1324 udi_kill
, /* FIXME, kill */
1326 0, /* lookup_symbol */
1327 udi_create_inferior
, /* create_inferior */
1328 udi_mourn
, /* mourn_inferior FIXME */
1329 process_stratum
, 0, /* next */
1330 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1331 0, 0, /* Section pointers */
1332 OPS_MAGIC
, /* Always the last thing */
1335 void _initialize_remote_udi()
1337 add_target (&udi_ops
);
1340 #ifdef NO_HIF_SUPPORT
1344 return(0); /* Emulate a failure */