1 /* Remote debugging interface for Am290*0 running MiniMON monitor, 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 expects MiniMON to be running on the Am29000
23 - Originally written by Daniel Mann at AMD for gdb 3.91.6.
25 file to gdb 3.95. I was unable to get this working on sun3os4
26 with termio, only with sgtty. Because we are only attempting to
27 use this module to debug our kernel, which is already loaded when
28 gdb is started up, I did not code up the file downloading facilities.
29 As a result this module has only the stubs to download files.
30 You should get tagged at compile time if you need to make any
32 *- Daniel Mann at AMD took the 3.95 adaptions above and replaced
33 MiniMON interface with UDI-p interface. */
46 #include "29k-share/udi/udiproc.h"
48 /* access the register store directly, without going through
49 the normal handler functions. This avoids an extra data copy
52 /* #define DEBUG 1 /* */
54 # define DENTER(NAME) (printf("Entering %s\n",NAME), fflush(stdout))
55 # define DEXIT(NAME) (printf("Exiting %s\n",NAME), fflush(stdout))
62 extern int stop_soon_quietly; /* for wait_for_inferior */
63 extern struct value *call_function_by_hand();
64 static void udi_resume();
65 static void udi_fetch_registers ();
66 static void udi_load();
67 static int fetch_register ();
68 static void udi_store_registers ();
69 static int store_register ();
70 static int regnum_to_srnum();
71 static void udi_close ();
72 static CPUSpace udi_memory_space();
73 static int udi_write_inferior_memory();
74 static int udi_read_inferior_memory();
75 char CoffFileName[100] = "";
79 #define TYPE_UNKNOWN 0
83 static char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
84 static int processor_type=TYPE_UNKNOWN;
85 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
86 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
88 #define LLOG_FILE "udi.log"
89 #if defined (LOG_FILE)
93 static int timeout = 5;
94 extern struct target_ops udi_ops; /* Forward declaration */
96 /* Special register enumeration.
99 /******************************************************************* UDI DATA*/
100 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
101 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
102 udi_open knows that we don't have a file open when the program
104 UDISessionId udi_session_id = -1;
106 CPUOffset IMemStart = 0;
107 CPUSizeT IMemSize = 0;
108 CPUOffset DMemStart = 0;
109 CPUSizeT DMemSize = 0;
110 CPUOffset RMemStart = 0;
111 CPUSizeT RMemSize = 0;
115 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
118 typedef struct bkpt_entry_str
123 unsigned int BreakId;
125 #define BKPT_TABLE_SIZE 40
126 static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
127 extern char dfe_errmsg[]; /* error string */
129 /*********************************************************** SIGNAL SUPPORT */
130 /* Called when SIGALRM signal sent due to alarm() timeout. */
135 # define volatile /**/
138 volatile int n_alarms;
145 printf ("udi_timer called\n");
149 #endif /* HAVE_TERMIO */
151 /* malloc'd name of the program on the remote system. */
152 static char *prog_name = NULL;
155 /* Number of SIGTRAPs we need to simulate. That is, the next
156 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
157 SIGTRAP without actually waiting for anything. */
159 /******************************************************* UDI_CREATE_INFERIOR */
160 /* This is called not only when we first attach, but also when the
161 user types "run" after having attached. */
163 udi_create_inferior (execfile, args, env)
168 DENTER("udi_create_inferior()");
171 { if (prog_name != NULL)
173 prog_name = savestring (execfile, strlen (execfile));
176 if (prog_name == 0 /* || exec_bfd == 0 */ )
177 error ("No exec file specified");
179 if (udi_session_id < 0){
180 printf("UDI connection not open yet.\n");
184 inferior_pid = 40000;
186 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
187 /* On ultra3 (NYU) we assume the kernel is already running so there is
188 * no file to download
191 if(*args == '\0') args = prog_name;
195 /* We will get a task spawn event immediately. */
196 #ifdef NOTDEF /* start_remote() now does a wait without a resume
200 init_wait_for_inferior ();
201 clear_proceed_status ();
204 DEXIT("udi_create_inferior()");
206 /******************************************************* UDI_MOURN_INFERIOR */
210 DENTER("udi_mourn()");
211 pop_target (); /* Pop back to no-child state */
212 generic_mourn_inferior ();
213 DEXIT("udi_mourn()");
216 /******************************************************************** UDI_OPEN
217 ** Open a connection to remote TIP.
218 NAME is the socket domain used for communication with the TIP,
219 then a space and the socket name or TIP-host name.
220 '<udi_udi_config_id> [progname]' for example.
223 /* XXX - need cleanups for udiconnect for various failures!!! */
225 static char *udi_config_id;
227 udi_open (name, from_tty)
234 UDIMemoryRange KnownMemory[10];
235 UDIUInt32 ChipVersions[10];
236 UDIInt NumberOfRanges = 10;
237 UDIInt NumberOfChips = 10;
239 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
241 DENTER("udi_open()");
243 target_preopen(from_tty);
245 /* Find the first whitespace character, it separates udi_config_id
247 if(!name) goto erroid;
249 *p != '\0' && !isspace (*p); p++)
253 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
255 udi_config_id = (char*)malloc (p - name + 1);
256 strncpy (udi_config_id, name, p - name);
257 udi_config_id[p - name] = '\0';
259 /* Skip over the whitespace after udi_config_id */
260 for (; isspace (*p); p++)
263 if (prog_name != NULL)
265 prog_name = savestring (p, strlen (p));
267 if (UDIConnect(udi_config_id, &udi_session_id))
268 error("UDIConnect() failed: %s\n", dfe_errmsg);
270 push_target (&udi_ops);
273 #ifndef NO_SIGINTERRUPT
274 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
276 if (siginterrupt (SIGALRM, 1) != 0)
277 error ("udi_open: siginterrupt() %s", safe_strerror(errno));
280 /* Set up read timeout timer. */
281 if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
282 error ("udi_open: signal() %s", safe_strerror(errno));
285 #if defined (LOG_FILE)
286 log_file = fopen (LOG_FILE, "w");
287 if (log_file == NULL)
288 error ("udi_open: fopen(%s) %s", LOG_FILE, safe_strerror(errno));
291 ** Initialize target configuration structure (global)
293 if(UDIGetTargetConfig( KnownMemory, &NumberOfRanges,
294 ChipVersions, &NumberOfChips))
295 error ("UDIGetTargetConfig() failed");
296 if(NumberOfChips > 2)
297 fprintf(stderr,"Taret has more than one processor\n");
298 for(cnt=0; cnt<NumberOfRanges; cnt++)
299 { switch(KnownMemory[cnt].Space)
301 default: fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
305 case UDI29KIROMSpace:
306 RMemStart = KnownMemory[cnt].Offset;
307 RMemSize = KnownMemory[cnt].Size;
309 case UDI29KIRAMSpace:
310 IMemStart = KnownMemory[cnt].Offset;
311 IMemSize = KnownMemory[cnt].Size;
313 case UDI29KDRAMSpace:
314 DMemStart = KnownMemory[cnt].Offset;
315 DMemSize = KnownMemory[cnt].Size;
320 /* Determine the processor revision level */
321 prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
323 { fprintf_filtered(stderr,
324 "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
325 processor_type = TYPE_A29000;
326 } else if ((prl&0xe0) == 0x40) /* 29030 = 0x4* */
327 { fprintf_filtered(stderr,
328 "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
329 processor_type = TYPE_A29030;
330 } else if ((prl&0xe0) == 0x20) /* 29050 = 0x2* */
331 { fprintf_filtered(stderr,
332 "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
333 processor_type = TYPE_A29050;
335 processor_type = TYPE_UNKNOWN;
336 fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
338 if(UDICreateProcess(&PId))
339 fprintf(stderr, "UDICreateProcess() failed\n");
341 /* Print out some stuff, letting the user now what's going on */
342 if(UDICapabilities( &TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
344 error ("UDICapabilities() failed");
346 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
347 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
348 processor_name[processor_type],
349 (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
350 (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
351 (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
354 /* FIXME: can this restriction be removed? */
355 printf_filtered("Remote debugging using virtual addresses works only\n");
356 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
360 if (processor_type != TYPE_A29050) {
361 fprintf_filtered(stderr,
362 "Freeze-mode debugging can only be done on an Am29050,\n");
363 fprintf_filtered(stderr,
364 " unless GDB is being used with a 29K simulator.\n");
369 /******************************************************************* UDI_CLOSE
370 Close the open connection to the TIP process.
371 Use this when you want to detach and do something else
374 udi_close (quitting) /*FIXME: how is quitting used */
378 DENTER("udi_close()");
380 if (udi_session_id < 0)
381 error ("Can't close udi connection: not debugging remotely.");
383 /* We should never get here if there isn't something valid in
386 if(UDIDisconnect(udi_stream, Terminate);)
387 error ("UDIDisconnect() failed in udi_close");
389 /* Do not try to close udi_session_id again, later in the program. */
393 #if defined (LOG_FILE)
394 if (ferror (log_file))
395 printf ("Error writing log file.\n");
396 if (fclose (log_file) != 0)
397 printf ("Error closing log file.\n");
400 printf_filtered (" Ending remote debugging\n");
402 DEXIT("udi_close()");
405 /**************************************************************** UDI_ATACH */
406 /* Attach to a program that is already loaded and running
407 * Upon exiting the process's execution is stopped.
410 udi_attach (args, from_tty)
419 UDIBool HostEndian = 0;
420 DENTER("udi_attach()");
422 if (udi_session_id < 0)
423 printf ("UDI connection not opened yet, use the 'target udi' command.\n");
426 printf ("Attaching to remote program %s...\n", prog_name);
428 mark_breakpoints_out ();
431 From.Offset = UDI29KSpecialRegs;
432 if(UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
433 error ("UDIRead failed in udi_attach");
434 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
436 DEXIT("udi_attach()");
438 /************************************************************* UDI_DETACH */
439 /* Terminate the open connection to the TIP process.
440 Use this when you want to detach and do something else
441 with your gdb. Leave remote process running (with no breakpoints set). */
443 udi_detach (args,from_tty)
447 DENTER("udi_dettach()");
448 remove_breakpoints(); /* Just in case there were any left in */
449 if(UDIDisconnect(udi_session_id))
450 error ("UDIDisconnect() failed in udi_detach");
451 pop_target(); /* calls udi_close to do the real work */
453 printf ("Ending remote debugging\n");
454 DEXIT("udi_dettach()");
458 /****************************************************************** UDI_RESUME
459 ** Tell the remote machine to resume. */
462 udi_resume (step, sig)
467 UDIStepType StepType = UDIStepNatural;
469 DENTER("udi_resume()");
470 if (step) /* step 1 instruction */
471 { tip_error = tip_error = UDIStep(Steps, StepType, Range);
472 if(tip_error)fprintf(stderr, "UDIStep() error = %d\n", tip_error);
473 if(tip_error)error ("failed in udi_resume");
478 error ("UDIExecute() failed in udi_resume");
481 DEXIT("udi_resume()");
484 /******************************************************************** UDI_WAIT
485 ** Wait until the remote machine stops, then return,
486 storing status in STATUS just as `wait' would. */
496 int old_timeout = timeout;
497 int old_immediate_quit = immediate_quit;
500 DENTER("udi_wait()");
501 WSETEXIT ((*status), 0);
503 /* wait for message to arrive. It should be:
504 If the target stops executing, udi_wait() should return.
506 timeout = 0; /* Wait indefinetly for a message */
507 immediate_quit = 1; /* Helps ability to QUIT */
511 MaxTime = UDIWaitForever;
512 UDIWait(MaxTime, &PId, &StopReason);
513 QUIT; /* Let user quit if they want */
514 switch (StopReason & 0xff)
519 if(UDIGetStdout(sbuf, (UDISizeT)SBUF_MAX, &CountDone))
520 error("UDIGetStdin() failed in udi_wait");
521 while(CountDone--)putc(sbuf[i++], stdout);
525 UDIGetStderr(sbuf, (UDISizeT)SBUF_MAX, &CountDone);
526 while(CountDone--)putc(sbuf[i++], stderr);
531 printf("DEBUG: stdin requested ... continue\n");
532 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
540 if (StopReason & 0xff == UDITrapped ) /* lower 8-bits == 0 */
542 if (StopReason >> 24 == 0)
543 { printf("Am290*0 received vector number 0 (break point)\n");
544 WSETSTOP ((*status), SIGTRAP);
546 else if (StopReason >> 24 == 1)
547 { printf("Am290*0 received vector 1\n");
548 WSETSTOP ((*status), SIGBUS);
550 else if (StopReason >> 24 == 3
551 || StopReason >> 24 == 4)
552 { printf("Am290*0 received vector number %d\n",
554 WSETSTOP ((*status), SIGFPE);
556 else if (StopReason >> 24 == 5)
557 { printf("Am290*0 received vector number %d\n",
559 WSETSTOP ((*status), SIGILL);
561 else if (StopReason >> 24 >= 6
562 && StopReason >> 24 <= 11)
563 { printf("Am290*0 received vector number %d\n",
565 WSETSTOP ((*status), SIGSEGV);
567 else if (StopReason >> 24 == 12
568 || StopReason >> 24 == 13)
569 { printf("Am290*0 received vector number %d\n",
571 WSETSTOP ((*status), SIGILL);
573 else if ((StopReason & 0xff) == 14)
574 { printf("Am290*0 received vector number %d\n",
576 WSETSTOP ((*status), SIGALRM);
578 else if ((StopReason & 0xff) == 15)
579 WSETSTOP ((*status), SIGTRAP);
580 else if ((StopReason >> 24) >= 16
581 && (StopReason >> 24) <= 21)
582 { printf("Am290*0 received vector number %d\n",
584 WSETSTOP ((*status), SIGINT);
586 else if ((StopReason & 0xff) == 22)
587 { printf("Am290*0 received vector number %d\n",
589 WSETSTOP ((*status), SIGILL);
591 else if ((StopReason & 0xff) == 77)
592 WSETSTOP ((*status), SIGTRAP);
595 WSETEXIT ((*status), 0);
597 else if ((StopReason & 0xff) == UDIBreak)
598 WSETSTOP ((*status), SIGTRAP);
599 else if ((StopReason & 0xff) == UDINotExecuting)
600 WSETSTOP ((*status), SIGTERM);
601 else if ((StopReason & 0xff) == UDIRunning)
602 WSETSTOP ((*status), SIGILL);
603 else if ((StopReason & 0xff) == UDIStopped)
604 WSETSTOP ((*status), SIGTSTP);
605 else if ((StopReason & 0xff) == UDIWarned)
606 WSETSTOP ((*status), SIGLOST);
607 else if ((StopReason & 0xff) == UDIStepped)
608 WSETSTOP ((*status), SIGTRAP);
609 else if ((StopReason & 0xff) == UDIWaiting)
610 WSETSTOP ((*status), SIGSTOP);
611 else if ((StopReason & 0xff) == UDIHalted)
612 WSETSTOP ((*status), SIGKILL);
614 WSETEXIT ((*status), 0);
616 timeout = old_timeout; /* Restore original timeout value */
617 immediate_quit = old_immediate_quit;
622 /********************************************************** UDI_FETCH_REGISTERS
623 * Read a remote register 'regno'.
624 * If regno==-1 then read all the registers.
627 udi_fetch_registers (regno)
635 UDIBool HostEndian = 0;
639 fetch_register(regno);
645 From.Space = UDI29KGlobalRegs;
647 To = (UDIUInt32 *)®isters[4 * GR1_REGNUM];
649 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
650 error("UDIRead() failed in udi_fetch_registers");
652 register_valid[GR1_REGNUM] = 1;
654 #if defined(GR64_REGNUM) /* Read gr64-127 */
656 /* Global Registers gr64-gr95 */
658 From.Space = UDI29KGlobalRegs;
660 To = (UDIUInt32 *)®isters[4 * GR64_REGNUM];
662 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
663 error("UDIRead() failed in udi_fetch_registers");
665 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
666 register_valid[i] = 1;
668 #endif /* GR64_REGNUM */
670 /* Global Registers gr96-gr127 */
672 From.Space = UDI29KGlobalRegs;
674 To = (UDIUInt32 *)®isters[4 * GR96_REGNUM];
676 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
677 error("UDIRead() failed in udi_fetch_registers");
679 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
680 register_valid[i] = 1;
682 /* Local Registers */
684 From.Space = UDI29KLocalRegs;
686 To = (UDIUInt32 *)®isters[4 * LR0_REGNUM];
688 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
689 error("UDIRead() failed in udi_fetch_registers");
691 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
692 register_valid[i] = 1;
694 /* Protected Special Registers */
696 From.Space = UDI29KSpecialRegs;
698 To = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)];
700 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
701 error("UDIRead() failed in udi_fetch_registers");
703 for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
704 register_valid[i] = 1;
706 if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */
707 fetch_register(NPC_REGNUM);
708 fetch_register(PC_REGNUM);
709 fetch_register(PC2_REGNUM);
711 /* Unprotected Special Registers sr128-sr135 */
713 From.Space = UDI29KSpecialRegs;
715 To = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)];
717 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
718 error("UDIRead() failed in udi_fetch_registers");
720 for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
721 register_valid[i] = 1;
724 /* There doesn't seem to be any way to get these. */
727 supply_register (FPE_REGNUM, (char *) &val);
728 supply_register (INTE_REGNUM, (char *) &val);
729 supply_register (FPS_REGNUM, (char *) &val);
730 supply_register (EXO_REGNUM, (char *) &val);
735 /********************************************************* UDI_STORE_REGISTERS
736 ** Store register regno into the target.
737 * If regno==-1 then store all the registers.
741 udi_store_registers (regno)
749 UDIBool HostEndian = 0;
753 store_register(regno);
759 From = (UDIUInt32 *)®isters[4 * GR1_REGNUM];
760 To.Space = UDI29KGlobalRegs;
763 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
764 error("UDIWrite() failed in udi_store_regisetrs");
766 #if defined(GR64_REGNUM)
768 /* Global registers gr64-gr95 */
770 From = (UDIUInt32 *)®isters[4 * GR64_REGNUM];
771 To.Space = UDI29KGlobalRegs;
774 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
775 error("UDIWrite() failed in udi_store_regisetrs");
777 #endif /* GR64_REGNUM */
779 /* Global registers gr96-gr127 */
781 From = (UDIUInt32 *)®isters[4 * GR96_REGNUM];
782 To.Space = UDI29KGlobalRegs;
785 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
786 error("UDIWrite() failed in udi_store_regisetrs");
788 /* Local Registers */
790 From = (UDIUInt32 *)®isters[4 * LR0_REGNUM];
791 To.Space = UDI29KLocalRegs;
794 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
795 error("UDIWrite() failed in udi_store_regisetrs");
798 /* Protected Special Registers */ /* VAB through TMR */
800 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)];
801 To.Space = UDI29KSpecialRegs;
804 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
805 error("UDIWrite() failed in udi_store_regisetrs");
807 /* PC0, PC1, PC2 possibly as shadow registers */
809 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(10)];
810 To.Space = UDI29KSpecialRegs;
813 To.Offset = 20; /* SPC0 */
815 To.Offset = 10; /* PC0 */
816 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
817 error("UDIWrite() failed in udi_store_regisetrs");
821 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(13)];
822 To.Space = UDI29KSpecialRegs;
825 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
826 error("UDIWrite() failed in udi_store_regisetrs");
828 /* Unprotected Special Registers */
830 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)];
831 To.Space = UDI29KSpecialRegs;
834 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
835 error("UDIWrite() failed in udi_store_regisetrs");
837 registers_changed ();
840 /****************************************************** UDI_PREPARE_TO_STORE */
841 /* Get ready to modify the registers array. On machines which store
842 individual registers, this doesn't need to do anything. On machines
843 which store all the registers in one fell swoop, this makes sure
844 that registers contains all the registers from the program being
848 udi_prepare_to_store ()
850 /* Do nothing, since we can store individual regs */
853 /********************************************************** TRANSLATE_ADDR */
858 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
859 /* Check for a virtual address in the kernel */
860 /* Assume physical address of ublock is in paddr_u register */
861 /* FIXME: doesn't work for user virtual addresses */
862 if (addr >= UVADDR) {
863 /* PADDR_U register holds the physical address of the ublock */
864 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
865 return(i + addr - (CORE_ADDR)UVADDR);
873 /************************************************* UDI_XFER_INFERIOR_MEMORY */
874 /* FIXME! Merge these two. */
876 udi_xfer_inferior_memory (memaddr, myaddr, len, write)
883 memaddr = translate_addr(memaddr);
886 return udi_write_inferior_memory (memaddr, myaddr, len);
888 return udi_read_inferior_memory (memaddr, myaddr, len);
891 /********************************************************** UDI_FILES_INFO */
895 printf ("\tAttached to UDI socket to %s and running program %s.\n",
896 udi_config_id, prog_name);
899 /**************************************************** UDI_INSERT_BREAKPOINT */
901 udi_insert_breakpoint (addr, contents_cache)
903 char *contents_cache;
908 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
909 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
912 if(cnt >= BKPT_TABLE_SIZE)
913 error("Too many breakpoints set");
915 bkpt_table[cnt].Addr.Offset = addr;
916 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
917 bkpt_table[cnt].PassCount = 1;
918 bkpt_table[cnt].Type = UDIBreakFlagExecute;
920 err = UDISetBreakpoint(bkpt_table[cnt].Addr,
921 bkpt_table[cnt].PassCount,
922 bkpt_table[cnt].Type,
923 &bkpt_table[cnt].BreakId);
925 if (err == 0) return 0; /* Success */
927 bkpt_table[cnt].Type = 0;
928 error("UDISetBreakpoint returned error code %d\n", err);
931 /**************************************************** UDI_REMOVE_BREAKPOINT */
933 udi_remove_breakpoint (addr, contents_cache)
935 char *contents_cache;
940 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
941 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
944 if(cnt >= BKPT_TABLE_SIZE)
945 error("Can't find breakpoint in table");
947 bkpt_table[cnt].Type = 0;
949 err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
950 if (err == 0) return 0; /* Success */
952 error("UDIClearBreakpoint returned error code %d\n", err);
955 /***************************************************************** UDI_KILL */
957 udi_kill(arg,from_tty)
963 DENTER("udi_kill()");
964 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
965 /* We don't ever kill the kernel */
967 printf_filtered("Kernel not killed, but left in current state.\n");
968 printf_filtered("Use detach to leave kernel running.\n");
974 printf("Target has been stopped.");
983 /***************************************************************** UDI_LOAD */
985 * Load a program into the target.
988 udi_load(arg_string,from_tty)
992 #define MAX_TOKENS 25
993 #define BUFFER_SIZE 256
995 char *token[MAX_TOKENS];
996 char cmd_line[BUFFER_SIZE];
1000 #if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
1001 printf("The kernel had better be loaded already! Loading not done.\n");
1003 if (arg_string == 0)
1004 error ("The load command takes a file name");
1005 arg_string = tilde_expand (arg_string);
1006 sprintf(cmd_line,"y %s %s", prog_name, arg_string);
1009 token[0] = cmd_line;
1011 if (cmd_line[0] != '\0')
1012 { token[token_count] = strtok(cmd_line, " \t,;\n\r");
1014 if (token[token_count] != NULL)
1016 token_count = token_count + 1;
1017 token[token_count] = strtok((char *) NULL, " \t,;\n\r");
1018 } while ((token[token_count] != NULL) &&
1019 (token_count < MAX_TOKENS));
1024 make_cleanup (free, arg_string);
1027 if(yank_cmd(token, token_count))
1028 error("Failure when tring to load program");
1030 symbol_file_add (arg_string, from_tty, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1035 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1036 ** Copy LEN bytes of data from debugger memory at MYADDR
1037 to inferior's memory at MEMADDR. Returns number of bytes written. */
1039 udi_write_inferior_memory (memaddr, myaddr, len)
1049 UDICount CountDone = 0;
1050 UDIBool HostEndian = 0;
1053 /* DENTER("udi_write_inferior_memory()"); */
1054 To.Space = udi_memory_space(memaddr);
1055 From = (UDIUInt32*)myaddr;
1057 while (nwritten < len)
1058 { Count = len - nwritten;
1059 if (Count > MAXDATA) Count = MAXDATA;
1060 To.Offset = memaddr + nwritten;
1061 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
1062 { error("UDIWrite() failed in udi_write_inferrior_memory");
1066 { nwritten += CountDone;
1070 /* DEXIT("udi_write_inferior_memory()"); */
1074 /**************************************************** UDI_READ_INFERIOR_MEMORY
1075 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1076 at debugger address MYADDR. Returns number of bytes read. */
1078 udi_read_inferior_memory(memaddr, myaddr, len)
1088 UDICount CountDone = 0;
1089 UDIBool HostEndian = 0;
1092 /* DENTER("udi_read_inferior_memory()"); */
1093 From.Space = udi_memory_space(memaddr);
1094 To = (UDIUInt32*)myaddr;
1097 { Count = len - nread;
1098 if (Count > MAXDATA) Count = MAXDATA;
1099 From.Offset = memaddr + nread;
1100 if(UDIRead(From, To, Count, Size, &CountDone, HostEndian))
1101 { error("UDIWrite() failed in udi_read_inferrior_memory");
1105 { nread += CountDone;
1112 /********************************************************************* WARNING
1117 error ("ERROR while loading program into remote TIP: $d\n", num);
1121 /*****************************************************************************/
1122 /* Fetch a single register indicatated by 'regno'.
1123 * Returns 0/-1 on success/failure.
1126 fetch_register (regno)
1134 UDIBool HostEndian = 0;
1137 if (regno == GR1_REGNUM)
1139 From.Space = UDI29KGlobalRegs;
1142 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1144 From.Space = UDI29KGlobalRegs;
1145 From.Offset = (regno - GR96_REGNUM) + 96;;
1148 #if defined(GR64_REGNUM)
1150 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1152 From.Space = UDI29KGlobalRegs;
1153 From.Offset = (regno - GR64_REGNUM) + 64;
1156 #endif /* GR64_REGNUM */
1158 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1160 From.Space = UDI29KLocalRegs;
1161 From.Offset = (regno - LR0_REGNUM);
1163 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1166 supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
1167 return 0; /* Pretend Success */
1171 From.Space = UDI29KSpecialRegs;
1172 From.Offset = regnum_to_srnum(regno);
1175 if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
1176 error("UDIRead() failed in udi_fetch_registers");
1178 supply_register(regno, (char *) &To);
1181 /*****************************************************************************/
1182 /* Store a single register indicated by 'regno'.
1183 * Returns 0/-1 on success/failure.
1186 store_register (regno)
1195 UDIBool HostEndian = 0;
1197 DENTER("store_register()");
1198 From = read_register (regno); /* get data value */
1200 if (regno == GR1_REGNUM)
1201 { To.Space = UDI29KGlobalRegs;
1203 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1204 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1205 * register cache. Do this *after* calling read_register, because we want
1206 * read_register to return the value that write_register has just stuffed
1207 * into the registers array, not the value of the register fetched from
1210 registers_changed ();
1212 #if defined(GR64_REGNUM)
1213 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1214 { To.Space = UDI29KGlobalRegs;
1215 To.Offset = (regno - GR64_REGNUM) + 64;
1216 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1218 #endif /* GR64_REGNUM */
1219 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1220 { To.Space = UDI29KGlobalRegs;
1221 To.Offset = (regno - GR96_REGNUM) + 96;
1222 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1224 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1225 { To.Space = UDI29KLocalRegs;
1226 To.Offset = (regno - LR0_REGNUM);
1227 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1229 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1231 return 0; /* Pretend Success */
1233 else /* An unprotected or protected special register */
1234 { To.Space = UDI29KSpecialRegs;
1235 To.Offset = regnum_to_srnum(regno);
1236 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1239 DEXIT("store_register()");
1242 error("UDIWrite() failed in store_registers");
1246 /********************************************************** REGNUM_TO_SRNUM */
1248 * Convert a gdb special register number to a 29000 special register number.
1251 regnum_to_srnum(regno)
1255 case VAB_REGNUM: return(0);
1256 case OPS_REGNUM: return(1);
1257 case CPS_REGNUM: return(2);
1258 case CFG_REGNUM: return(3);
1259 case CHA_REGNUM: return(4);
1260 case CHD_REGNUM: return(5);
1261 case CHC_REGNUM: return(6);
1262 case RBP_REGNUM: return(7);
1263 case TMC_REGNUM: return(8);
1264 case TMR_REGNUM: return(9);
1265 case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
1266 case PC_REGNUM: return(USE_SHADOW_PC ? (21) : (11));
1267 case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
1268 case MMU_REGNUM: return(13);
1269 case LRU_REGNUM: return(14);
1270 case IPC_REGNUM: return(128);
1271 case IPA_REGNUM: return(129);
1272 case IPB_REGNUM: return(130);
1273 case Q_REGNUM: return(131);
1274 case ALU_REGNUM: return(132);
1275 case BP_REGNUM: return(133);
1276 case FC_REGNUM: return(134);
1277 case CR_REGNUM: return(135);
1278 case FPE_REGNUM: return(160);
1279 case INTE_REGNUM: return(161);
1280 case FPS_REGNUM: return(162);
1281 case EXO_REGNUM:return(164);
1283 return(255); /* Failure ? */
1286 /****************************************************************************/
1288 * Determine the Target memory space qualifier based on the addr.
1289 * FIXME: Can't distinguis I_ROM/D_ROM.
1290 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1293 udi_memory_space(addr)
1296 UDIUInt32 tstart = IMemStart;
1297 UDIUInt32 tend = tstart + IMemSize;
1298 UDIUInt32 dstart = DMemStart;
1299 UDIUInt32 dend = tstart + DMemSize;
1300 UDIUInt32 rstart = RMemStart;
1301 UDIUInt32 rend = tstart + RMemSize;
1303 if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) {
1304 return UDI29KIRAMSpace;
1305 } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) {
1306 return UDI29KDRAMSpace;
1307 } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
1308 /* FIXME: how do we determine between D_ROM and I_ROM */
1309 return UDI29KIROMSpace;
1310 } else /* FIXME: what do me do now? */
1311 return UDI29KDRAMSpace; /* Hmmm! */
1313 /*********************************************************************** STUBS
1316 void convert16() {;}
1317 void convert32() {;}
1318 FILE* EchoFile = 0; /* used for debugging */
1319 int QuietMode = 0; /* used for debugging */
1321 /****************************************************************************/
1323 * Define the target subroutine names
1325 static struct target_ops udi_ops = {
1326 "udi", "Remote UDI connected TIP",
1327 "Remote debug an Am290*0 using socket connection to TIP process ",
1328 udi_open, udi_close,
1329 udi_attach, udi_detach, udi_resume, udi_wait,
1330 udi_fetch_registers, udi_store_registers,
1331 udi_prepare_to_store, 0, 0, /* conv_to, conv_from */
1332 udi_xfer_inferior_memory,
1334 udi_insert_breakpoint, udi_remove_breakpoint, /* Breakpoints */
1335 0, 0, 0, 0, 0, /* Terminal handling */
1336 udi_kill, /* FIXME, kill */
1338 0, /* lookup_symbol */
1339 udi_create_inferior, /* create_inferior */
1340 udi_mourn, /* mourn_inferior FIXME */
1341 process_stratum, 0, /* next */
1342 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1343 0, 0, /* Section pointers */
1344 OPS_MAGIC, /* Always the last thing */
1347 void _initialize_remote_udi()
1349 add_target (&udi_ops);
1352 #ifdef NO_HIF_SUPPORT
1356 return(0); /* Emulate a failure */