1 /* armrdi.c -- ARMulator RDI interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 #include "communicate.h"
29 /***************************************************************************\
31 \***************************************************************************/
33 #define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead)
34 #define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite)
36 static unsigned FPRegsAddr
; /* last known address of FPE regs */
37 #define FPESTART 0x2000L
38 #define FPEEND 0x8000L
40 #define IGNORE(d) (d = d)
42 #define TracePrint(s) \
43 if (rdi_log & 1) ARMul_DebugPrint s
48 static ARMul_State
*state
= NULL
;
49 static unsigned BreaksSet
; /* The number of breakpoints set */
51 static int rdi_log
= 0; /* debugging ? */
53 #define LOWEST_RDI_LEVEL 0
54 #define HIGHEST_RDI_LEVEL 1
55 static int MYrdi_level
= LOWEST_RDI_LEVEL
;
57 typedef struct BreakNode BreakNode
;
58 typedef struct WatchNode WatchNode
;
61 { /* A breakpoint list node */
63 ARMword address
; /* The address of this breakpoint */
64 unsigned type
; /* The type of comparison */
65 ARMword bound
; /* The other address for a range */
70 { /* A watchpoint list node */
72 ARMword address
; /* The address of this watchpoint */
73 unsigned type
; /* The type of comparison */
74 unsigned datatype
; /* The type of access to watch for */
75 ARMword bound
; /* The other address for a range */
78 BreakNode
*BreakList
= NULL
;
79 WatchNode
*WatchList
= NULL
;
82 ARMul_DebugPrint_i (const Dbg_HostosInterface
* hostif
, const char *format
,
86 va_start (ap
, format
);
87 hostif
->dbgprint (hostif
->dbgarg
, format
, ap
);
92 ARMul_DebugPrint (ARMul_State
* state
, const char *format
, ...)
95 va_start (ap
, format
);
97 state
->hostif
->dbgprint (state
->hostif
->dbgarg
, format
, ap
);
101 #define CONSOLE_PRINT_MAX_LEN 128
104 ARMul_ConsolePrint (ARMul_State
* state
, const char *format
, ...)
108 char *str
, buf
[CONSOLE_PRINT_MAX_LEN
];
112 va_start (ap
, format
);
113 vsprintf (buf
, format
, ap
);
115 for (i
= 0; buf
[i
]; i
++); /* The string is i chars long */
120 MYwrite_char (kidmum
[1], RDP_OSOp
);
121 MYwrite_word (kidmum
[1], SWI_Write0
);
122 MYwrite_char (kidmum
[1], OS_SendString
);
123 MYwrite_char (kidmum
[1], 32); /* Send string 32bytes at a time */
124 for (j
= 0; j
< 32; j
++, str
++)
125 MYwrite_char (kidmum
[1], *str
);
126 wait_for_osreply (&junk
);
132 MYwrite_char (kidmum
[1], RDP_OSOp
);
133 MYwrite_word (kidmum
[1], SWI_Write0
);
134 MYwrite_char (kidmum
[1], OS_SendString
);
135 MYwrite_char (kidmum
[1], (unsigned char) i
); /* Send remainder of string */
136 for (j
= 0; j
< i
; j
++, str
++)
137 MYwrite_char (kidmum
[1], *str
);
138 wait_for_osreply (&junk
);
145 /* while ((ch=*str++) != 0) */
146 /* state->hostif->writec(state->hostif->hostosarg, ch); */
150 ARMul_DebugPause (ARMul_State
* state
)
153 state
->hostif
->dbgpause (state
->hostif
->dbgarg
);
156 /***************************************************************************\
158 \***************************************************************************/
161 InitFail (int exitcode
, char const *which
)
163 ARMul_ConsolePrint (state
, "%s interface failed to initialise. Exiting\n",
169 RDIInit (unsigned type
)
173 state
->CallDebug
= state
->MemReadDebug
= state
->MemWriteDebug
= 0;
178 #define UNKNOWNPROC 0
187 Processor
const p_arm2
= { "ARM2", ARM_Fix26_Prop
};
188 Processor
const p_arm2as
= { "ARM2AS", ARM_Fix26_Prop
};
189 Processor
const p_arm61
= { "ARM61", ARM_Fix26_Prop
};
190 Processor
const p_arm3
= { "ARM3", ARM_Fix26_Prop
};
191 Processor
const p_arm6
= { "ARM6", ARM_Lock_Prop
};
192 Processor
const p_arm60
= { "ARM60", ARM_Lock_Prop
};
193 Processor
const p_arm600
= { "ARM600", ARM_Lock_Prop
};
194 Processor
const p_arm610
= { "ARM610", ARM_Lock_Prop
};
195 Processor
const p_arm620
= { "ARM620", ARM_Lock_Prop
};
196 Processor
const p_unknown
= { "", 0 };
198 Processor
const *const processors
[] =
200 &p_arm6
, /* default: must come first */
212 typedef struct ProcessorConfig ProcessorConfig
;
213 struct ProcessorConfig
216 ProcessorConfig
const *self
;
218 Processor
const *const *processors
;
221 ProcessorConfig
const processorconfig
= {
222 {((((((long) 'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
223 ((((((long) 'u' << 8) | 's') << 8) | ' ') << 8) | 'x'},
230 RDI_open (unsigned type
, const Dbg_ConfigBlock
* config
,
231 const Dbg_HostosInterface
* hostif
, struct Dbg_MCState
*dbg_state
)
232 /* Initialise everything */
234 int virgin
= (state
== NULL
);
241 ARMul_DebugPrint_i (hostif
, "RDI_open: type = %d\n", type
);
243 ARMul_DebugPrint (state
, "RDI_open: type = %d\n", type
);
256 ARMul_EmulateInit ();
257 state
= ARMul_NewState ();
258 state
->hostif
= hostif
;
260 int req
= config
->processor
;
261 unsigned processor
= processors
[req
]->val
;
262 ARMul_SelectProcessor (state
, processor
);
264 ARMul_ConsolePrint (state
, "ARMulator V1.50, %s",
265 processors
[req
]->name
);
267 if (ARMul_MemoryInit (state
, config
->memorysize
) == FALSE
)
268 InitFail (1, "Memory");
269 if (config
->bytesex
!= RDISex_DontCare
)
270 state
->bigendSig
= config
->bytesex
;
271 if (ARMul_CoProInit (state
) == FALSE
)
272 InitFail (2, "Co-Processor");
273 if (ARMul_OSInit (state
) == FALSE
)
274 InitFail (3, "Operating System");
280 { /* Reset the comms link */
281 /* what comms link ? */
283 if (virgin
&& (type
& 1) == 0) /* Cold start */
284 ARMul_ConsolePrint (state
, ", %s endian.\n",
285 state
->bigendSig
? "Big" : "Little");
287 if (config
->bytesex
== RDISex_DontCare
)
288 return (state
->bigendSig
? RDIError_BigEndian
: RDIError_LittleEndian
);
290 return (RDIError_NoError
);
293 /***************************************************************************\
295 \***************************************************************************/
300 TracePrint ((state
, "RDI_close\n"));
301 ARMul_OSExit (state
);
302 ARMul_CoProExit (state
);
303 ARMul_MemoryExit (state
);
304 return (RDIError_NoError
);
307 /***************************************************************************\
309 \***************************************************************************/
312 RDI_read (ARMword source
, void *dest
, unsigned *nbytes
)
315 char *memptr
= (char *) dest
;
317 TracePrint ((state
, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
318 source
, dest
, *nbytes
));
320 for (i
= 0; i
< *nbytes
; i
++)
321 *memptr
++ = (char) ARMul_ReadByte (state
, source
++);
324 state
->abortSig
= LOW
;
325 return (RDIError_DataAbort
);
327 return (RDIError_NoError
);
330 /***************************************************************************\
332 \***************************************************************************/
335 RDI_write (const void *source
, ARMword dest
, unsigned *nbytes
)
338 char *memptr
= (char *) source
;
340 TracePrint ((state
, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
341 source
, dest
, *nbytes
));
343 for (i
= 0; i
< *nbytes
; i
++)
344 ARMul_WriteByte (state
, (ARMword
) dest
++, (ARMword
) * memptr
++);
348 state
->abortSig
= LOW
;
349 return (RDIError_DataAbort
);
351 return (RDIError_NoError
);
354 /***************************************************************************\
356 \***************************************************************************/
359 RDI_CPUread (unsigned mode
, unsigned long mask
, ARMword buffer
[])
363 if (mode
== RDIMode_Curr
)
364 mode
= (unsigned) (ARMul_GetCPSR (state
) & MODEBITS
);
366 for (upto
= 0, i
= 0; i
< 15; i
++)
367 if (mask
& (1L << i
))
369 buffer
[upto
++] = ARMul_GetReg (state
, mode
, i
);
372 if (mask
& RDIReg_R15
)
374 buffer
[upto
++] = ARMul_GetR15 (state
);
377 if (mask
& RDIReg_PC
)
379 buffer
[upto
++] = ARMul_GetPC (state
);
382 if (mask
& RDIReg_CPSR
)
383 buffer
[upto
++] = ARMul_GetCPSR (state
);
385 if (mask
& RDIReg_SPSR
)
386 buffer
[upto
++] = ARMul_GetSPSR (state
, mode
);
388 TracePrint ((state
, "RDI_CPUread: mode=%.8x mask=%.8lx", mode
, mask
));
392 for (upto
= 0, i
= 0; i
<= 20; i
++)
393 if (mask
& (1L << i
))
395 ARMul_DebugPrint (state
, "%c%.8lx", upto
% 4 == 0 ? '\n' : ' ',
399 ARMul_DebugPrint (state
, "\n");
403 return (RDIError_NoError
);
406 /***************************************************************************\
408 \***************************************************************************/
411 RDI_CPUwrite (unsigned mode
, unsigned long mask
, ARMword
const buffer
[])
416 TracePrint ((state
, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode
, mask
));
420 for (upto
= 0, i
= 0; i
<= 20; i
++)
421 if (mask
& (1L << i
))
423 ARMul_DebugPrint (state
, "%c%.8lx", upto
% 4 == 0 ? '\n' : ' ',
427 ARMul_DebugPrint (state
, "\n");
431 if (mode
== RDIMode_Curr
)
432 mode
= (unsigned) (ARMul_GetCPSR (state
) & MODEBITS
);
434 for (upto
= 0, i
= 0; i
< 15; i
++)
435 if (mask
& (1L << i
))
436 ARMul_SetReg (state
, mode
, i
, buffer
[upto
++]);
438 if (mask
& RDIReg_R15
)
439 ARMul_SetR15 (state
, buffer
[upto
++]);
441 if (mask
& RDIReg_PC
)
444 ARMul_SetPC (state
, buffer
[upto
++]);
446 if (mask
& RDIReg_CPSR
)
447 ARMul_SetCPSR (state
, buffer
[upto
++]);
449 if (mask
& RDIReg_SPSR
)
450 ARMul_SetSPSR (state
, mode
, buffer
[upto
++]);
452 return (RDIError_NoError
);
455 /***************************************************************************\
457 \***************************************************************************/
460 RDI_CPread (unsigned CPnum
, unsigned long mask
, ARMword buffer
[])
462 ARMword fpregsaddr
, word
[4];
467 if (CPnum
!= 1 && CPnum
!= 2)
469 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
471 return (RDIError_UnknownCoPro
);
472 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
473 if (mask
& (1L << r
))
475 (void) state
->CPRead
[CPnum
] (state
, r
, &buffer
[upto
]);
478 TracePrint ((state
, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum
, mask
));
483 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
484 if (mask
& (1L << r
))
487 ARMul_DebugPrint (state
, "%c%2d",
488 (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
491 ARMul_DebugPrint (state
, " %.8lx", buffer
[upto
++]);
495 ARMul_DebugPrint (state
, "\n");
498 return RDIError_NoError
;
502 return RDIError_UnknownCoPro
;
507 fpregsaddr
= ARMul_ReadWord (state
, 4L);
508 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
509 return RDIError_UnknownCoPro
;
510 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */
511 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
512 return RDIError_UnknownCoPro
;
513 fpregsaddr
= ARMul_ReadWord (state
, fpregsaddr
); /* pointer to fp registers */
514 FPRegsAddr
= fpregsaddr
;
517 fpregsaddr
= FPRegsAddr
;
520 return RDIError_UnknownCoPro
;
521 for (upto
= 0, r
= 0; r
< 8; r
++)
522 if (mask
& (1L << r
))
524 for (w
= 0; w
< 4; w
++)
526 ARMul_ReadWord (state
,
527 fpregsaddr
+ (ARMword
) r
* 16 + (ARMword
) w
* 4);
528 switch ((int) (word
[3] >> 29))
533 case 6: /* its unpacked, convert to extended */
534 buffer
[upto
++] = 2; /* mark as extended */
535 buffer
[upto
++] = (word
[3] & 0x7fff) | (word
[0] & 0x80000000); /* exp and sign */
536 buffer
[upto
++] = word
[1]; /* mantissa 1 */
537 buffer
[upto
++] = word
[2]; /* mantissa 2 */
539 case 1: /* packed single */
540 buffer
[upto
++] = 0; /* mark as single */
541 buffer
[upto
++] = word
[0]; /* sign, exp and mantissa */
542 buffer
[upto
++] = word
[1]; /* padding */
543 buffer
[upto
++] = word
[2]; /* padding */
545 case 3: /* packed double */
546 buffer
[upto
++] = 1; /* mark as double */
547 buffer
[upto
++] = word
[0]; /* sign, exp and mantissa1 */
548 buffer
[upto
++] = word
[1]; /* mantissa 2 */
549 buffer
[upto
++] = word
[2]; /* padding */
551 case 5: /* packed extended */
552 buffer
[upto
++] = 2; /* mark as extended */
553 buffer
[upto
++] = word
[0]; /* sign and exp */
554 buffer
[upto
++] = word
[1]; /* mantissa 1 */
555 buffer
[upto
++] = word
[2]; /* mantissa 2 */
557 case 7: /* packed decimal */
558 buffer
[upto
++] = 3; /* mark as packed decimal */
559 buffer
[upto
++] = word
[0]; /* sign, exp and mantissa1 */
560 buffer
[upto
++] = word
[1]; /* mantissa 2 */
561 buffer
[upto
++] = word
[2]; /* mantissa 3 */
565 if (mask
& (1L << r
))
566 buffer
[upto
++] = ARMul_ReadWord (state
, fpregsaddr
+ 128); /* fpsr */
567 if (mask
& (1L << (r
+ 1)))
568 buffer
[upto
++] = 0; /* fpcr */
570 TracePrint ((state
, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum
, mask
));
574 for (upto
= 0, r
= 0; r
< 9; r
++)
575 if (mask
& (1L << r
))
579 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
580 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
581 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
583 ARMul_DebugPrint (state
, "%08lx\n", buffer
[upto
++]);
585 ARMul_DebugPrint (state
, "\n");
588 return (RDIError_NoError
);
592 /***************************************************************************\
594 \***************************************************************************/
597 RDI_CPwrite (unsigned CPnum
, unsigned long mask
, ARMword
const buffer
[])
603 if (CPnum
!= 1 && CPnum
!= 2)
605 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
607 return (RDIError_UnknownCoPro
);
608 TracePrint ((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
613 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
614 if (mask
& (1L << r
))
617 ARMul_DebugPrint (state
, "%c%2d",
618 (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
621 ARMul_DebugPrint (state
, " %.8lx", buffer
[upto
++]);
625 ARMul_DebugPrint (state
, "\n");
628 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
629 if (mask
& (1L << r
))
631 (void) state
->CPWrite
[CPnum
] (state
, r
, &buffer
[upto
]);
634 return RDIError_NoError
;
638 return RDIError_UnknownCoPro
;
641 TracePrint ((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
645 for (upto
= 0, r
= 0; r
< 9; r
++)
646 if (mask
& (1L << r
))
650 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
651 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
652 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
654 ARMul_DebugPrint (state
, "%08lx\n", buffer
[upto
++]);
656 ARMul_DebugPrint (state
, "\n");
662 fpregsaddr
= ARMul_ReadWord (state
, 4L);
663 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
664 return RDIError_UnknownCoPro
;
665 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */
666 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
667 return RDIError_UnknownCoPro
;
668 fpregsaddr
= ARMul_ReadWord (state
, fpregsaddr
); /* pointer to fp registers */
669 FPRegsAddr
= fpregsaddr
;
672 fpregsaddr
= FPRegsAddr
;
675 return RDIError_UnknownCoPro
;
676 for (upto
= 0, r
= 0; r
< 8; r
++)
677 if (mask
& (1L << r
))
679 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16,
681 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16 + 4,
683 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16 + 8,
685 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16 + 12,
686 (buffer
[upto
] * 2 + 1) << 29); /* mark type */
689 if (mask
& (1L << r
))
690 ARMul_WriteWord (state
, fpregsaddr
+ 128, buffer
[upto
++]); /* fpsr */
691 return (RDIError_NoError
);
696 deletebreaknode (BreakNode
** prevp
)
698 BreakNode
*p
= *prevp
;
700 ARMul_WriteWord (state
, p
->address
, p
->inst
);
707 removebreak (ARMword address
, unsigned type
)
709 BreakNode
*p
, **prevp
= &BreakList
;
710 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
711 if (p
->address
== address
&& p
->type
== type
)
713 deletebreaknode (prevp
);
719 /* This routine installs a breakpoint into the breakpoint table */
722 installbreak (ARMword address
, unsigned type
, ARMword bound
)
724 BreakNode
*p
= (BreakNode
*) malloc (sizeof (BreakNode
));
727 p
->address
= address
;
730 p
->inst
= ARMul_ReadWord (state
, address
);
731 ARMul_WriteWord (state
, address
, 0xee000000L
);
735 /***************************************************************************\
737 \***************************************************************************/
740 RDI_setbreak (ARMword address
, unsigned type
, ARMword bound
,
741 PointHandle
* handle
)
744 TracePrint ((state
, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
745 address
, type
, bound
));
747 removebreak (address
, type
);
748 p
= installbreak (address
, type
, bound
);
751 *handle
= (PointHandle
) p
;
752 TracePrint ((state
, " returns %.8lx\n", *handle
));
753 return RDIError_NoError
;
756 /***************************************************************************\
758 \***************************************************************************/
761 RDI_clearbreak (PointHandle handle
)
763 TracePrint ((state
, "RDI_clearbreak: address=%.8lx\n", handle
));
765 BreakNode
*p
, **prevp
= &BreakList
;
766 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
767 if (p
== (BreakNode
*) handle
)
770 return RDIError_NoSuchPoint
;
771 deletebreaknode (prevp
);
772 return RDIError_NoError
;
776 /***************************************************************************\
777 * Internal functions for breakpoint table manipulation *
778 \***************************************************************************/
781 deletewatchnode (WatchNode
** prevp
)
783 WatchNode
*p
= *prevp
;
784 if (p
->datatype
& Watch_AnyRead
)
785 state
->MemReadDebug
--;
786 if (p
->datatype
& Watch_AnyWrite
)
787 state
->MemWriteDebug
--;
793 removewatch (ARMword address
, unsigned type
)
795 WatchNode
*p
, **prevp
= &WatchList
;
796 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
797 if (p
->address
== address
&& p
->type
== type
)
798 { /* found a match */
799 deletewatchnode (prevp
);
802 return FALSE
; /* never found a match */
806 installwatch (ARMword address
, unsigned type
, unsigned datatype
,
809 WatchNode
*p
= (WatchNode
*) malloc (sizeof (WatchNode
));
812 p
->address
= address
;
814 p
->datatype
= datatype
;
819 /***************************************************************************\
821 \***************************************************************************/
824 RDI_setwatch (ARMword address
, unsigned type
, unsigned datatype
,
825 ARMword bound
, PointHandle
* handle
)
830 "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
831 address
, type
, datatype
, bound
));
833 if (!state
->CanWatch
)
834 return RDIError_UnimplementedMessage
;
836 removewatch (address
, type
);
837 p
= installwatch (address
, type
, datatype
, bound
);
838 if (datatype
& Watch_AnyRead
)
839 state
->MemReadDebug
++;
840 if (datatype
& Watch_AnyWrite
)
841 state
->MemWriteDebug
++;
842 *handle
= (PointHandle
) p
;
843 TracePrint ((state
, " returns %.8lx\n", *handle
));
844 return RDIError_NoError
;
847 /***************************************************************************\
849 \***************************************************************************/
852 RDI_clearwatch (PointHandle handle
)
854 TracePrint ((state
, "RDI_clearwatch: address=%.8lx\n", handle
));
856 WatchNode
*p
, **prevp
= &WatchList
;
857 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
858 if (p
== (WatchNode
*) handle
)
861 return RDIError_NoSuchPoint
;
862 deletewatchnode (prevp
);
863 return RDIError_NoError
;
867 /***************************************************************************\
869 \***************************************************************************/
872 RDI_execute (PointHandle
* handle
)
874 TracePrint ((state
, "RDI_execute\n"));
880 state
->EndCondition
= RDIError_NoError
;
881 state
->StopHandle
= 0;
883 ARMul_DoProg (state
);
885 *handle
= state
->StopHandle
;
886 state
->Reg
[15] -= 8; /* undo the pipeline */
890 state
->Debug
= FALSE
;
892 return (state
->EndCondition
);
895 /***************************************************************************\
897 \***************************************************************************/
900 RDI_step (unsigned ninstr
, PointHandle
* handle
)
903 TracePrint ((state
, "RDI_step\n"));
905 return RDIError_UnimplementedMessage
;
911 state
->EndCondition
= RDIError_NoError
;
912 state
->StopHandle
= 0;
913 ARMul_DoInstr (state
);
914 *handle
= state
->StopHandle
;
915 state
->Reg
[15] -= 8; /* undo the pipeline */
919 state
->Debug
= FALSE
;
921 return (state
->EndCondition
);
924 /***************************************************************************\
926 \***************************************************************************/
929 RDI_info (unsigned type
, ARMword
* arg1
, ARMword
* arg2
)
934 TracePrint ((state
, "RDI_Info_Target\n"));
935 /* Emulator, speed 10**5 IPS */
936 *arg1
= 5 | HIGHEST_RDI_LEVEL
<< 5 | LOWEST_RDI_LEVEL
<< 8;
938 return RDIError_NoError
;
942 ARMword n
= RDIPointCapability_Comparison
| RDIPointCapability_Range
|
943 RDIPointCapability_Mask
| RDIPointCapability_Status
;
944 TracePrint ((state
, "RDI_Info_Points\n"));
946 n
|= (Watch_AnyRead
+ Watch_AnyWrite
) << 2;
948 return RDIError_NoError
;
952 TracePrint ((state
, "RDI_Info_Step\n"));
953 *arg1
= RDIStep_Single
;
954 return RDIError_NoError
;
957 TracePrint ((state
, "RDI_Info_MMU\n"));
959 return RDIError_NoError
;
962 TracePrint ((state
, "RDISignal_Stop\n"));
964 state
->EndCondition
= RDIError_UserInterrupt
;
965 return RDIError_NoError
;
967 case RDIVector_Catch
:
968 TracePrint ((state
, "RDIVector_Catch %.8lx\n", *arg1
));
969 state
->VectorCatch
= (unsigned) *arg1
;
970 return RDIError_NoError
;
973 TracePrint ((state
, "RDI_Set_Cmdline %s\n", (char *) arg1
));
975 (char *) malloc ((unsigned) strlen ((char *) arg1
) + 1);
976 (void) strcpy (state
->CommandLine
, (char *) arg1
);
977 return RDIError_NoError
;
980 TracePrint ((state
, "RDI_Info_Cycles\n"));
982 arg1
[1] = state
->NumInstrs
;
984 arg1
[3] = state
->NumScycles
;
986 arg1
[5] = state
->NumNcycles
;
988 arg1
[7] = state
->NumIcycles
;
990 arg1
[9] = state
->NumCcycles
;
992 arg1
[11] = state
->NumFcycles
;
993 return RDIError_NoError
;
996 *arg1
= ARMul_OSLastErrorP (state
);
997 TracePrint ((state
, "RDI_ErrorP returns %ld\n", *arg1
));
998 return RDIError_NoError
;
1000 case RDIInfo_DescribeCoPro
:
1002 int cpnum
= *(int *) arg1
;
1003 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*) arg2
;
1005 unsigned char const *map
= state
->CPRegWords
[cpnum
];
1007 return RDIError_UnknownCoPro
;
1008 for (i
= 0; i
< cpd
->entries
; i
++)
1010 unsigned r
, w
= cpd
->regdesc
[i
].nbytes
/ sizeof (ARMword
);
1011 for (r
= cpd
->regdesc
[i
].rmin
; r
<= cpd
->regdesc
[i
].rmax
; r
++)
1013 return RDIError_BadCoProState
;
1015 return RDIError_NoError
;
1018 case RDIInfo_RequestCoProDesc
:
1020 int cpnum
= *(int *) arg1
;
1021 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*) arg2
;
1022 int i
= -1, lastw
= -1, r
;
1023 unsigned char const *map
;
1024 if ((unsigned) cpnum
>= 16)
1025 return RDIError_UnknownCoPro
;
1026 map
= state
->CPRegWords
[cpnum
];
1028 return RDIError_UnknownCoPro
;
1029 for (r
= 0; r
< map
[-1]; r
++)
1033 cpd
->regdesc
[i
].rmax
= r
;
1036 if (++i
>= cpd
->entries
)
1037 return RDIError_BufferFull
;
1038 cpd
->regdesc
[i
].rmax
= cpd
->regdesc
[i
].rmin
= r
;
1039 cpd
->regdesc
[i
].nbytes
= words
* sizeof (ARMword
);
1040 cpd
->regdesc
[i
].access
=
1041 Dbg_Access_Readable
+ Dbg_Access_Writable
;
1044 cpd
->entries
= i
+ 1;
1045 return RDIError_NoError
;
1049 *arg1
= (ARMword
) rdi_log
;
1050 return RDIError_NoError
;
1052 case RDIInfo_SetLog
:
1053 rdi_log
= (int) *arg1
;
1054 return RDIError_NoError
;
1057 return RDIError_NoError
;
1059 case RDIPointStatus_Watch
:
1061 WatchNode
*p
, *handle
= (WatchNode
*) * arg1
;
1062 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
1067 return RDIError_NoError
;
1069 return RDIError_NoSuchPoint
;
1072 case RDIPointStatus_Break
:
1074 BreakNode
*p
, *handle
= (BreakNode
*) * arg1
;
1075 for (p
= BreakList
; p
!= NULL
; p
= p
->next
)
1080 return RDIError_NoError
;
1082 return RDIError_NoSuchPoint
;
1085 case RDISet_RDILevel
:
1086 if (*arg1
< LOWEST_RDI_LEVEL
|| *arg1
> HIGHEST_RDI_LEVEL
)
1087 return RDIError_IncompatibleRDILevels
;
1088 MYrdi_level
= *arg1
;
1089 return RDIError_NoError
;
1092 return RDIError_UnimplementedMessage
;
1097 /***************************************************************************\
1098 * The emulator calls this routine at the beginning of every cycle when the *
1099 * CallDebug flag is set. The second parameter passed is the address of the *
1100 * currently executing instruction (i.e Program Counter - 8), the third *
1101 * parameter is the instruction being executed. *
1102 \***************************************************************************/
1105 ARMul_Debug (ARMul_State
* state
, ARMword pc
, ARMword instr
)
1108 if (state
->EndCondition
== RDIError_UserInterrupt
)
1110 TracePrint ((state
, "User interrupt at %.8lx\n", pc
));
1112 state
->Emulate
= STOP
;
1116 BreakNode
*p
= BreakList
;
1117 for (; p
!= NULL
; p
= p
->next
)
1122 if (pc
== p
->address
)
1126 if (pc
> p
->address
)
1130 if (pc
>= p
->address
)
1134 if (pc
< p
->address
)
1138 if (pc
<= p
->address
)
1142 if (p
->address
<= pc
&& pc
< p
->address
+ p
->bound
)
1146 if (p
->address
> pc
|| pc
>= p
->address
+ p
->bound
)
1150 if ((pc
& p
->bound
) == p
->address
)
1155 TracePrint ((state
, "Breakpoint reached at %.8lx\n", pc
));
1156 state
->EndCondition
= RDIError_BreakpointReached
;
1157 state
->Emulate
= STOP
;
1158 state
->StopHandle
= (ARMword
) p
;
1166 ARMul_CheckWatch (ARMul_State
* state
, ARMword addr
, int access
)
1169 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
1170 if (p
->datatype
& access
)
1175 if (addr
== p
->address
)
1179 if (addr
> p
->address
)
1183 if (addr
>= p
->address
)
1187 if (addr
< p
->address
)
1191 if (addr
<= p
->address
)
1195 if (p
->address
<= addr
&& addr
< p
->address
+ p
->bound
)
1199 if (p
->address
> addr
|| addr
>= p
->address
+ p
->bound
)
1203 if ((addr
& p
->bound
) == p
->address
)
1208 TracePrint ((state
, "Watchpoint at %.8lx accessed\n", addr
));
1209 state
->EndCondition
= RDIError_WatchpointAccessed
;
1210 state
->Emulate
= STOP
;
1211 state
->StopHandle
= (ARMword
) p
;
1216 static RDI_NameList
const *
1219 return (RDI_NameList
const *) &processorconfig
.count
;
1222 const struct RDIProcVec armul_rdi
= {
1242 0, /*loadconfigdata */
1243 0, /*selectconfig */