1 /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
2 Copyright 1990, 1992 Free Software Foundation, Inc.
3 Written by Daniel Mann. Contributed by AMD.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This is like remote.c but uses the Universal Debug Interface (UDI) to
22 talk to the target hardware (or simulator). UDI is a TCP/IP based
23 protocol; for hardware that doesn't run TCP, an interface adapter
24 daemon talks UDI on one side, and talks to the hardware (typically
25 over a serial port) on the other side.
27 - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
28 - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
29 file to gdb 3.95. I was unable to get this working on sun3os4
30 with termio, only with sgtty. Because we are only attempting to
31 use this module to debug our kernel, which is already loaded when
32 gdb is started up, I did not code up the file downloading facilities.
33 As a result this module has only the stubs to download files.
34 You should get tagged at compile time if you need to make any
36 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
37 MiniMON interface with UDI-p interface. */
50 #include "29k-share/udi/udiproc.h"
52 /* access the register store directly, without going through
53 the normal handler functions. This avoids an extra data copy. */
55 extern int stop_soon_quietly
; /* for wait_for_inferior */
56 extern struct value
*call_function_by_hand();
57 static void udi_resume();
58 static void udi_fetch_registers ();
59 static void udi_load();
60 static int fetch_register ();
61 static void udi_store_registers ();
62 static int store_register ();
63 static int regnum_to_srnum();
64 static void udi_close ();
65 static CPUSpace
udi_memory_space();
66 static int udi_write_inferior_memory();
67 static int udi_read_inferior_memory();
68 char CoffFileName
[100] = "";
72 #define TYPE_UNKNOWN 0
76 static char *processor_name
[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
77 static int processor_type
=TYPE_UNKNOWN
;
78 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
79 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
81 #define LLOG_FILE "udi.log"
82 #if defined (LOG_FILE)
86 static int timeout
= 5;
87 extern struct target_ops udi_ops
; /* Forward declaration */
89 /* Special register enumeration.
92 /******************************************************************* UDI DATA*/
93 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
94 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
95 udi_open knows that we don't have a file open when the program
97 UDISessionId udi_session_id
= -1;
99 CPUOffset IMemStart
= 0;
100 CPUSizeT IMemSize
= 0;
101 CPUOffset DMemStart
= 0;
102 CPUSizeT DMemSize
= 0;
103 CPUOffset RMemStart
= 0;
104 CPUSizeT RMemSize
= 0;
108 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
111 typedef struct bkpt_entry_str
116 unsigned int BreakId
;
118 #define BKPT_TABLE_SIZE 40
119 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
120 extern char dfe_errmsg
[]; /* error string */
122 /*********************************************************** SIGNAL SUPPORT */
123 /* Called when SIGALRM signal sent due to alarm() timeout. */
128 # define volatile /**/
131 volatile int n_alarms
;
138 printf ("udi_timer called\n");
142 #endif /* HAVE_TERMIO */
144 /* malloc'd name of the program on the remote system. */
145 static char *prog_name
= NULL
;
148 /* Number of SIGTRAPs we need to simulate. That is, the next
149 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
150 SIGTRAP without actually waiting for anything. */
152 /******************************************************* UDI_CREATE_INFERIOR */
153 /* This is called not only when we first attach, but also when the
154 user types "run" after having attached. */
156 udi_create_inferior (execfile
, args
, env
)
163 { if (prog_name
!= NULL
)
165 prog_name
= savestring (execfile
, strlen (execfile
));
168 if (prog_name
== 0 /* || exec_bfd == 0 */ )
169 error ("No exec file specified");
171 if (udi_session_id
< 0){
172 printf("UDI connection not open yet.\n");
176 inferior_pid
= 40000;
178 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
179 /* On ultra3 (NYU) we assume the kernel is already running so there is
180 * no file to download
186 init_wait_for_inferior ();
187 clear_proceed_status ();
190 /******************************************************* UDI_MOURN_INFERIOR */
194 pop_target (); /* Pop back to no-child state */
195 generic_mourn_inferior ();
198 /******************************************************************** UDI_OPEN
199 ** Open a connection to remote TIP.
200 NAME is the socket domain used for communication with the TIP,
201 then a space and the socket name or TIP-host name.
202 '<udi_udi_config_id> [progname]' for example.
205 /* XXX - need cleanups for udiconnect for various failures!!! */
207 static char *udi_config_id
;
209 udi_open (name
, from_tty
)
216 UDIMemoryRange KnownMemory
[10];
217 UDIUInt32 ChipVersions
[10];
218 UDIInt NumberOfRanges
= 10;
219 UDIInt NumberOfChips
= 10;
221 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
223 target_preopen(from_tty
);
225 /* Find the first whitespace character, it separates udi_config_id
227 if(!name
) goto erroid
;
229 *p
!= '\0' && !isspace (*p
); p
++)
233 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
235 udi_config_id
= (char*)malloc (p
- name
+ 1);
236 strncpy (udi_config_id
, name
, p
- name
);
237 udi_config_id
[p
- name
] = '\0';
239 /* Skip over the whitespace after udi_config_id */
240 for (; isspace (*p
); p
++)
243 if (prog_name
!= NULL
)
245 prog_name
= savestring (p
, strlen (p
));
247 if (UDIConnect(udi_config_id
, &udi_session_id
))
248 error("UDIConnect() failed: %s\n", dfe_errmsg
);
250 push_target (&udi_ops
);
253 #ifndef NO_SIGINTERRUPT
254 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
256 if (siginterrupt (SIGALRM
, 1) != 0)
257 error ("udi_open: siginterrupt() %s", safe_strerror(errno
));
260 /* Set up read timeout timer. */
261 if ((void (*)) signal (SIGALRM
, udi_timer
) == (void (*)) -1)
262 error ("udi_open: signal() %s", safe_strerror(errno
));
265 #if defined (LOG_FILE)
266 log_file
= fopen (LOG_FILE
, "w");
267 if (log_file
== NULL
)
268 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
271 ** Initialize target configuration structure (global)
273 if(UDIGetTargetConfig( KnownMemory
, &NumberOfRanges
,
274 ChipVersions
, &NumberOfChips
))
275 error ("UDIGetTargetConfig() failed");
276 if(NumberOfChips
> 2)
277 fprintf(stderr
,"Taret has more than one processor\n");
278 for(cnt
=0; cnt
<NumberOfRanges
; cnt
++)
279 { switch(KnownMemory
[cnt
].Space
)
281 default: fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
285 case UDI29KIROMSpace
:
286 RMemStart
= KnownMemory
[cnt
].Offset
;
287 RMemSize
= KnownMemory
[cnt
].Size
;
289 case UDI29KIRAMSpace
:
290 IMemStart
= KnownMemory
[cnt
].Offset
;
291 IMemSize
= KnownMemory
[cnt
].Size
;
293 case UDI29KDRAMSpace
:
294 DMemStart
= KnownMemory
[cnt
].Offset
;
295 DMemSize
= KnownMemory
[cnt
].Size
;
300 /* Determine the processor revision level */
301 prl
= (unsigned int)read_register(CFG_REGNUM
) >> 24;
303 { fprintf_filtered(stderr
,
304 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
305 processor_type
= TYPE_A29000
;
306 } else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
307 { fprintf_filtered(stderr
,
308 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
309 processor_type
= TYPE_A29030
;
310 } else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
311 { fprintf_filtered(stderr
,
312 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
313 processor_type
= TYPE_A29050
;
315 processor_type
= TYPE_UNKNOWN
;
316 fprintf_filtered(stderr
,"WARNING: processor type unknown.\n");
318 if(UDICreateProcess(&PId
))
319 fprintf(stderr
, "UDICreateProcess() failed\n");
321 /* Print out some stuff, letting the user now what's going on */
322 if(UDICapabilities( &TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
324 error ("UDICapabilities() failed");
326 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
327 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
328 processor_name
[processor_type
],
329 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
330 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
331 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
334 /* FIXME: can this restriction be removed? */
335 printf_filtered("Remote debugging using virtual addresses works only\n");
336 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
340 if (processor_type
!= TYPE_A29050
) {
341 fprintf_filtered(stderr
,
342 "Freeze-mode debugging can only be done on an Am29050,\n");
343 fprintf_filtered(stderr
,
344 " unless GDB is being used with a 29K simulator.\n");
349 /******************************************************************* UDI_CLOSE
350 Close the open connection to the TIP process.
351 Use this when you want to detach and do something else
354 udi_close (quitting
) /*FIXME: how is quitting used */
359 if (udi_session_id
< 0)
360 error ("Can't close udi connection: not debugging remotely.");
362 /* We should never get here if there isn't something valid in
365 if(UDIDisconnect(udi_stream, Terminate);)
366 error ("UDIDisconnect() failed in udi_close");
368 /* Do not try to close udi_session_id again, later in the program. */
372 #if defined (LOG_FILE)
373 if (ferror (log_file
))
374 printf ("Error writing log file.\n");
375 if (fclose (log_file
) != 0)
376 printf ("Error closing log file.\n");
379 printf_filtered (" Ending remote debugging\n");
382 /**************************************************************** UDI_ATACH */
383 /* Attach to a program that is already loaded and running
384 * Upon exiting the process's execution is stopped.
387 udi_attach (args
, from_tty
)
396 UDIBool HostEndian
= 0;
398 if (udi_session_id
< 0)
399 error ("UDI connection not opened yet, use the 'target udi' command.\n");
402 printf ("Attaching to remote program %s...\n", prog_name
);
406 From
.Offset
= UDI29KSpecialRegs
;
407 if(UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
408 error ("UDIRead failed in udi_attach");
409 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
411 /************************************************************* UDI_DETACH */
412 /* Terminate the open connection to the TIP process.
413 Use this when you want to detach and do something else
414 with your gdb. Leave remote process running (with no breakpoints set). */
416 udi_detach (args
,from_tty
)
420 remove_breakpoints(); /* Just in case there were any left in */
421 if(UDIDisconnect(udi_session_id
))
422 error ("UDIDisconnect() failed in udi_detach");
423 pop_target(); /* calls udi_close to do the real work */
425 printf ("Ending remote debugging\n");
429 /****************************************************************** UDI_RESUME
430 ** Tell the remote machine to resume. */
433 udi_resume (step
, sig
)
438 UDIStepType StepType
= UDIStepNatural
;
441 if (step
) /* step 1 instruction */
442 { tip_error
= tip_error
= UDIStep(Steps
, StepType
, Range
);
443 if(tip_error
)fprintf(stderr
, "UDIStep() error = %d\n", tip_error
);
444 if(tip_error
)error ("failed in udi_resume");
449 error ("UDIExecute() failed in udi_resume");
453 /******************************************************************** UDI_WAIT
454 ** Wait until the remote machine stops, then return,
455 storing status in STATUS just as `wait' would. */
465 int old_timeout
= timeout
;
466 int old_immediate_quit
= immediate_quit
;
469 WSETEXIT ((*status
), 0);
471 /* wait for message to arrive. It should be:
472 If the target stops executing, udi_wait() should return.
474 timeout
= 0; /* Wait indefinetly for a message */
475 immediate_quit
= 1; /* Helps ability to QUIT */
479 MaxTime
= UDIWaitForever
;
480 UDIWait(MaxTime
, &PId
, &StopReason
);
481 QUIT
; /* Let user quit if they want */
482 switch (StopReason
& 0xff)
487 if(UDIGetStdout(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
488 error("UDIGetStdin() failed in udi_wait");
489 while(CountDone
--)putc(sbuf
[i
++], stdout
);
493 UDIGetStderr(sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
494 while(CountDone
--)putc(sbuf
[i
++], stderr
);
499 printf("DEBUG: stdin requested ... continue\n");
500 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
508 if (StopReason
& 0xff == UDITrapped
) /* lower 8-bits == 0 */
510 if (StopReason
>> 24 == 0)
511 { printf("Am290*0 received vector number 0 (break point)\n");
512 WSETSTOP ((*status
), SIGTRAP
);
514 else if (StopReason
>> 24 == 1)
515 { printf("Am290*0 received vector 1\n");
516 WSETSTOP ((*status
), SIGBUS
);
518 else if (StopReason
>> 24 == 3
519 || StopReason
>> 24 == 4)
520 { printf("Am290*0 received vector number %d\n",
522 WSETSTOP ((*status
), SIGFPE
);
524 else if (StopReason
>> 24 == 5)
525 { printf("Am290*0 received vector number %d\n",
527 WSETSTOP ((*status
), SIGILL
);
529 else if (StopReason
>> 24 >= 6
530 && StopReason
>> 24 <= 11)
531 { printf("Am290*0 received vector number %d\n",
533 WSETSTOP ((*status
), SIGSEGV
);
535 else if (StopReason
>> 24 == 12
536 || StopReason
>> 24 == 13)
537 { printf("Am290*0 received vector number %d\n",
539 WSETSTOP ((*status
), SIGILL
);
541 else if ((StopReason
& 0xff) == 14)
542 { printf("Am290*0 received vector number %d\n",
544 WSETSTOP ((*status
), SIGALRM
);
546 else if ((StopReason
& 0xff) == 15)
547 WSETSTOP ((*status
), SIGTRAP
);
548 else if ((StopReason
>> 24) >= 16
549 && (StopReason
>> 24) <= 21)
550 { printf("Am290*0 received vector number %d\n",
552 WSETSTOP ((*status
), SIGINT
);
554 else if ((StopReason
& 0xff) == 22)
555 { printf("Am290*0 received vector number %d\n",
557 WSETSTOP ((*status
), SIGILL
);
559 else if ((StopReason
& 0xff) == 77)
560 WSETSTOP ((*status
), SIGTRAP
);
563 WSETEXIT ((*status
), 0);
565 else if ((StopReason
& 0xff) == UDIBreak
)
566 WSETSTOP ((*status
), SIGTRAP
);
567 else if ((StopReason
& 0xff) == UDINotExecuting
)
568 WSETSTOP ((*status
), SIGTERM
);
569 else if ((StopReason
& 0xff) == UDIRunning
)
570 WSETSTOP ((*status
), SIGILL
);
571 else if ((StopReason
& 0xff) == UDIStopped
)
572 WSETSTOP ((*status
), SIGTSTP
);
573 else if ((StopReason
& 0xff) == UDIWarned
)
574 WSETSTOP ((*status
), SIGLOST
);
575 else if ((StopReason
& 0xff) == UDIStepped
)
576 WSETSTOP ((*status
), SIGTRAP
);
577 else if ((StopReason
& 0xff) == UDIWaiting
)
578 WSETSTOP ((*status
), SIGSTOP
);
579 else if ((StopReason
& 0xff) == UDIHalted
)
580 WSETSTOP ((*status
), SIGKILL
);
582 WSETEXIT ((*status
), 0);
584 timeout
= old_timeout
; /* Restore original timeout value */
585 immediate_quit
= old_immediate_quit
;
589 /********************************************************** UDI_FETCH_REGISTERS
590 * Read a remote register 'regno'.
591 * If regno==-1 then read all the registers.
594 udi_fetch_registers (regno
)
602 UDIBool HostEndian
= 0;
606 fetch_register(regno
);
612 From
.Space
= UDI29KGlobalRegs
;
614 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
616 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
617 error("UDIRead() failed in udi_fetch_registers");
619 register_valid
[GR1_REGNUM
] = 1;
621 #if defined(GR64_REGNUM) /* Read gr64-127 */
623 /* Global Registers gr64-gr95 */
625 From
.Space
= UDI29KGlobalRegs
;
627 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
629 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
630 error("UDIRead() failed in udi_fetch_registers");
632 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
633 register_valid
[i
] = 1;
635 #endif /* GR64_REGNUM */
637 /* Global Registers gr96-gr127 */
639 From
.Space
= UDI29KGlobalRegs
;
641 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
643 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
644 error("UDIRead() failed in udi_fetch_registers");
646 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
647 register_valid
[i
] = 1;
649 /* Local Registers */
651 From
.Space
= UDI29KLocalRegs
;
653 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
655 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
656 error("UDIRead() failed in udi_fetch_registers");
658 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
659 register_valid
[i
] = 1;
661 /* Protected Special Registers */
663 From
.Space
= UDI29KSpecialRegs
;
665 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
667 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
668 error("UDIRead() failed in udi_fetch_registers");
670 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
671 register_valid
[i
] = 1;
673 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
674 fetch_register(NPC_REGNUM
);
675 fetch_register(PC_REGNUM
);
676 fetch_register(PC2_REGNUM
);
678 /* Unprotected Special Registers sr128-sr135 */
680 From
.Space
= UDI29KSpecialRegs
;
682 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
684 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
685 error("UDIRead() failed in udi_fetch_registers");
687 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
688 register_valid
[i
] = 1;
691 /* There doesn't seem to be any way to get these. */
694 supply_register (FPE_REGNUM
, (char *) &val
);
695 supply_register (INTE_REGNUM
, (char *) &val
);
696 supply_register (FPS_REGNUM
, (char *) &val
);
697 supply_register (EXO_REGNUM
, (char *) &val
);
702 /********************************************************* UDI_STORE_REGISTERS
703 ** Store register regno into the target.
704 * If regno==-1 then store all the registers.
708 udi_store_registers (regno
)
716 UDIBool HostEndian
= 0;
720 store_register(regno
);
726 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
727 To
.Space
= UDI29KGlobalRegs
;
730 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
731 error("UDIWrite() failed in udi_store_regisetrs");
733 #if defined(GR64_REGNUM)
735 /* Global registers gr64-gr95 */
737 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
738 To
.Space
= UDI29KGlobalRegs
;
741 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
742 error("UDIWrite() failed in udi_store_regisetrs");
744 #endif /* GR64_REGNUM */
746 /* Global registers gr96-gr127 */
748 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
749 To
.Space
= UDI29KGlobalRegs
;
752 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
753 error("UDIWrite() failed in udi_store_regisetrs");
755 /* Local Registers */
757 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
758 To
.Space
= UDI29KLocalRegs
;
761 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
762 error("UDIWrite() failed in udi_store_regisetrs");
765 /* Protected Special Registers */ /* VAB through TMR */
767 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
768 To
.Space
= UDI29KSpecialRegs
;
771 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
772 error("UDIWrite() failed in udi_store_regisetrs");
774 /* PC0, PC1, PC2 possibly as shadow registers */
776 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
777 To
.Space
= UDI29KSpecialRegs
;
780 To
.Offset
= 20; /* SPC0 */
782 To
.Offset
= 10; /* PC0 */
783 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
784 error("UDIWrite() failed in udi_store_regisetrs");
788 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
789 To
.Space
= UDI29KSpecialRegs
;
792 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
793 error("UDIWrite() failed in udi_store_regisetrs");
795 /* Unprotected Special Registers */
797 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
798 To
.Space
= UDI29KSpecialRegs
;
801 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
802 error("UDIWrite() failed in udi_store_regisetrs");
804 registers_changed ();
807 /****************************************************** UDI_PREPARE_TO_STORE */
808 /* Get ready to modify the registers array. On machines which store
809 individual registers, this doesn't need to do anything. On machines
810 which store all the registers in one fell swoop, this makes sure
811 that registers contains all the registers from the program being
815 udi_prepare_to_store ()
817 /* Do nothing, since we can store individual regs */
820 /********************************************************** TRANSLATE_ADDR */
825 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
826 /* Check for a virtual address in the kernel */
827 /* Assume physical address of ublock is in paddr_u register */
828 /* FIXME: doesn't work for user virtual addresses */
829 if (addr
>= UVADDR
) {
830 /* PADDR_U register holds the physical address of the ublock */
831 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
832 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
840 /************************************************* UDI_XFER_INFERIOR_MEMORY */
841 /* FIXME! Merge these two. */
843 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
850 memaddr
= translate_addr(memaddr
);
853 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
855 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
858 /********************************************************** UDI_FILES_INFO */
862 printf ("\tAttached to UDI socket to %s and running program %s.\n",
863 udi_config_id
, prog_name
);
866 /**************************************************** UDI_INSERT_BREAKPOINT */
868 udi_insert_breakpoint (addr
, contents_cache
)
870 char *contents_cache
;
875 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
876 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
879 if(cnt
>= BKPT_TABLE_SIZE
)
880 error("Too many breakpoints set");
882 bkpt_table
[cnt
].Addr
.Offset
= addr
;
883 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
884 bkpt_table
[cnt
].PassCount
= 1;
885 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
887 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
888 bkpt_table
[cnt
].PassCount
,
889 bkpt_table
[cnt
].Type
,
890 &bkpt_table
[cnt
].BreakId
);
892 if (err
== 0) return 0; /* Success */
894 bkpt_table
[cnt
].Type
= 0;
895 error("UDISetBreakpoint returned error code %d\n", err
);
898 /**************************************************** UDI_REMOVE_BREAKPOINT */
900 udi_remove_breakpoint (addr
, contents_cache
)
902 char *contents_cache
;
907 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
908 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
911 if(cnt
>= BKPT_TABLE_SIZE
)
912 error("Can't find breakpoint in table");
914 bkpt_table
[cnt
].Type
= 0;
916 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
917 if (err
== 0) return 0; /* Success */
919 error("UDIClearBreakpoint returned error code %d\n", err
);
922 /***************************************************************** UDI_KILL */
924 udi_kill(arg
,from_tty
)
930 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
931 /* We don't ever kill the kernel */
933 printf_filtered("Kernel not killed, but left in current state.\n");
934 printf_filtered("Use detach to leave kernel running.\n");
940 printf("Target has been stopped.");
948 /***************************************************************** UDI_LOAD */
950 * Load a program into the target.
953 udi_load(arg_string
,from_tty
)
957 #define MAX_TOKENS 25
958 #define BUFFER_SIZE 256
960 char *token
[MAX_TOKENS
];
961 char cmd_line
[BUFFER_SIZE
];
965 #if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
966 printf("The kernel had better be loaded already! Loading not done.\n");
969 error ("No program name");
970 arg_string
= tilde_expand (arg_string
);
971 sprintf(cmd_line
,"y %s %s", prog_name
, arg_string
);
976 if (cmd_line
[0] != '\0')
977 { token
[token_count
] = strtok(cmd_line
, " \t,;\n\r");
979 if (token
[token_count
] != NULL
)
981 token_count
= token_count
+ 1;
982 token
[token_count
] = strtok((char *) NULL
, " \t,;\n\r");
983 } while ((token
[token_count
] != NULL
) &&
984 (token_count
< MAX_TOKENS
));
989 make_cleanup (free
, arg_string
);
992 if(yank_cmd(token
, token_count
))
993 error("Failure when tring to load program");
995 symbol_file_add (prog_name
, from_tty
, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1000 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1001 ** Copy LEN bytes of data from debugger memory at MYADDR
1002 to inferior's memory at MEMADDR. Returns number of bytes written. */
1004 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1014 UDICount CountDone
= 0;
1015 UDIBool HostEndian
= 0;
1017 To
.Space
= udi_memory_space(memaddr
);
1018 From
= (UDIUInt32
*)myaddr
;
1020 while (nwritten
< len
)
1021 { Count
= len
- nwritten
;
1022 if (Count
> MAXDATA
) Count
= MAXDATA
;
1023 To
.Offset
= memaddr
+ nwritten
;
1024 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1025 { error("UDIWrite() failed in udi_write_inferrior_memory");
1029 { nwritten
+= CountDone
;
1036 /**************************************************** UDI_READ_INFERIOR_MEMORY
1037 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1038 at debugger address MYADDR. Returns number of bytes read. */
1040 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1050 UDICount CountDone
= 0;
1051 UDIBool HostEndian
= 0;
1053 From
.Space
= udi_memory_space(memaddr
);
1054 To
= (UDIUInt32
*)myaddr
;
1057 { Count
= len
- nread
;
1058 if (Count
> MAXDATA
) Count
= MAXDATA
;
1059 From
.Offset
= memaddr
+ nread
;
1060 if(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1061 { error("UDIWrite() failed in udi_read_inferrior_memory");
1065 { nread
+= CountDone
;
1072 /********************************************************************* WARNING
1077 error ("ERROR while loading program into remote TIP: $d\n", num
);
1081 /*****************************************************************************/
1082 /* Fetch a single register indicatated by 'regno'.
1083 * Returns 0/-1 on success/failure.
1086 fetch_register (regno
)
1094 UDIBool HostEndian
= 0;
1097 if (regno
== GR1_REGNUM
)
1099 From
.Space
= UDI29KGlobalRegs
;
1102 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1104 From
.Space
= UDI29KGlobalRegs
;
1105 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1108 #if defined(GR64_REGNUM)
1110 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1112 From
.Space
= UDI29KGlobalRegs
;
1113 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1116 #endif /* GR64_REGNUM */
1118 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1120 From
.Space
= UDI29KLocalRegs
;
1121 From
.Offset
= (regno
- LR0_REGNUM
);
1123 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1126 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1127 return 0; /* Pretend Success */
1131 From
.Space
= UDI29KSpecialRegs
;
1132 From
.Offset
= regnum_to_srnum(regno
);
1135 if (UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1136 error("UDIRead() failed in udi_fetch_registers");
1138 supply_register(regno
, (char *) &To
);
1141 /*****************************************************************************/
1142 /* Store a single register indicated by 'regno'.
1143 * Returns 0/-1 on success/failure.
1146 store_register (regno
)
1155 UDIBool HostEndian
= 0;
1157 From
= read_register (regno
); /* get data value */
1159 if (regno
== GR1_REGNUM
)
1160 { To
.Space
= UDI29KGlobalRegs
;
1162 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1163 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1164 * register cache. Do this *after* calling read_register, because we want
1165 * read_register to return the value that write_register has just stuffed
1166 * into the registers array, not the value of the register fetched from
1169 registers_changed ();
1171 #if defined(GR64_REGNUM)
1172 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1173 { To
.Space
= UDI29KGlobalRegs
;
1174 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1175 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1177 #endif /* GR64_REGNUM */
1178 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1179 { To
.Space
= UDI29KGlobalRegs
;
1180 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1181 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1183 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1184 { To
.Space
= UDI29KLocalRegs
;
1185 To
.Offset
= (regno
- LR0_REGNUM
);
1186 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1188 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1190 return 0; /* Pretend Success */
1192 else /* An unprotected or protected special register */
1193 { To
.Space
= UDI29KSpecialRegs
;
1194 To
.Offset
= regnum_to_srnum(regno
);
1195 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1200 error("UDIWrite() failed in store_registers");
1204 /********************************************************** REGNUM_TO_SRNUM */
1206 * Convert a gdb special register number to a 29000 special register number.
1209 regnum_to_srnum(regno
)
1213 case VAB_REGNUM
: return(0);
1214 case OPS_REGNUM
: return(1);
1215 case CPS_REGNUM
: return(2);
1216 case CFG_REGNUM
: return(3);
1217 case CHA_REGNUM
: return(4);
1218 case CHD_REGNUM
: return(5);
1219 case CHC_REGNUM
: return(6);
1220 case RBP_REGNUM
: return(7);
1221 case TMC_REGNUM
: return(8);
1222 case TMR_REGNUM
: return(9);
1223 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1224 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1225 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1226 case MMU_REGNUM
: return(13);
1227 case LRU_REGNUM
: return(14);
1228 case IPC_REGNUM
: return(128);
1229 case IPA_REGNUM
: return(129);
1230 case IPB_REGNUM
: return(130);
1231 case Q_REGNUM
: return(131);
1232 case ALU_REGNUM
: return(132);
1233 case BP_REGNUM
: return(133);
1234 case FC_REGNUM
: return(134);
1235 case CR_REGNUM
: return(135);
1236 case FPE_REGNUM
: return(160);
1237 case INTE_REGNUM
: return(161);
1238 case FPS_REGNUM
: return(162);
1239 case EXO_REGNUM
:return(164);
1241 return(255); /* Failure ? */
1244 /****************************************************************************/
1246 * Determine the Target memory space qualifier based on the addr.
1247 * FIXME: Can't distinguis I_ROM/D_ROM.
1248 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1251 udi_memory_space(addr
)
1254 UDIUInt32 tstart
= IMemStart
;
1255 UDIUInt32 tend
= tstart
+ IMemSize
;
1256 UDIUInt32 dstart
= DMemStart
;
1257 UDIUInt32 dend
= tstart
+ DMemSize
;
1258 UDIUInt32 rstart
= RMemStart
;
1259 UDIUInt32 rend
= tstart
+ RMemSize
;
1261 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1262 return UDI29KIRAMSpace
;
1263 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1264 return UDI29KDRAMSpace
;
1265 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1266 /* FIXME: how do we determine between D_ROM and I_ROM */
1267 return UDI29KIROMSpace
;
1268 } else /* FIXME: what do me do now? */
1269 return UDI29KDRAMSpace
; /* Hmmm! */
1271 /*********************************************************************** STUBS
1274 void convert16() {;}
1275 void convert32() {;}
1276 FILE* EchoFile
= 0; /* used for debugging */
1277 int QuietMode
= 0; /* used for debugging */
1279 /****************************************************************************/
1281 * Define the target subroutine names
1283 static struct target_ops udi_ops
= {
1284 "udi", "Remote UDI connected TIP",
1285 "Remote debug an AMD 29k using UDI socket connection to TIP process",
1286 udi_open
, udi_close
,
1287 udi_attach
, udi_detach
, udi_resume
, udi_wait
,
1288 udi_fetch_registers
, udi_store_registers
,
1289 udi_prepare_to_store
,
1290 udi_xfer_inferior_memory
,
1292 udi_insert_breakpoint
, udi_remove_breakpoint
, /* Breakpoints */
1293 0, 0, 0, 0, 0, /* Terminal handling */
1294 udi_kill
, /* FIXME, kill */
1296 0, /* lookup_symbol */
1297 udi_create_inferior
, /* create_inferior */
1298 udi_mourn
, /* mourn_inferior FIXME */
1300 process_stratum
, 0, /* next */
1301 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1302 0, 0, /* Section pointers */
1303 OPS_MAGIC
, /* Always the last thing */
1306 void _initialize_remote_udi()
1308 add_target (&udi_ops
);
1311 #ifdef NO_HIF_SUPPORT
1315 return(0); /* Emulate a failure */