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 3 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, see <http://www.gnu.org/licenses/>. */
26 #include "communicate.h"
28 /***************************************************************************\
30 \***************************************************************************/
32 #define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead)
33 #define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite)
35 static unsigned FPRegsAddr
; /* last known address of FPE regs */
36 #define FPESTART 0x2000L
37 #define FPEEND 0x8000L
39 #define IGNORE(d) (d = d)
41 #define TracePrint(s) \
42 if (rdi_log & 1) ARMul_DebugPrint s
47 static ARMul_State
*state
= NULL
;
48 static unsigned BreaksSet
; /* The number of breakpoints set */
50 static int rdi_log
= 0; /* debugging ? */
52 #define LOWEST_RDI_LEVEL 0
53 #define HIGHEST_RDI_LEVEL 1
54 static int MYrdi_level
= LOWEST_RDI_LEVEL
;
56 typedef struct BreakNode BreakNode
;
57 typedef struct WatchNode WatchNode
;
60 { /* A breakpoint list node */
62 ARMword address
; /* The address of this breakpoint */
63 unsigned type
; /* The type of comparison */
64 ARMword bound
; /* The other address for a range */
69 { /* A watchpoint list node */
71 ARMword address
; /* The address of this watchpoint */
72 unsigned type
; /* The type of comparison */
73 unsigned datatype
; /* The type of access to watch for */
74 ARMword bound
; /* The other address for a range */
77 BreakNode
*BreakList
= NULL
;
78 WatchNode
*WatchList
= NULL
;
81 ARMul_DebugPrint_i (const Dbg_HostosInterface
* hostif
, const char *format
,
85 va_start (ap
, format
);
86 hostif
->dbgprint (hostif
->dbgarg
, format
, ap
);
91 ARMul_DebugPrint (ARMul_State
* state
, const char *format
, ...)
94 va_start (ap
, format
);
96 state
->hostif
->dbgprint (state
->hostif
->dbgarg
, format
, ap
);
100 #define CONSOLE_PRINT_MAX_LEN 128
103 ARMul_ConsolePrint (ARMul_State
* state
, const char *format
, ...)
107 char *str
, buf
[CONSOLE_PRINT_MAX_LEN
];
111 va_start (ap
, format
);
112 vsprintf (buf
, format
, ap
);
114 for (i
= 0; buf
[i
]; i
++); /* The string is i chars long */
119 MYwrite_char (kidmum
[1], RDP_OSOp
);
120 MYwrite_word (kidmum
[1], SWI_Write0
);
121 MYwrite_char (kidmum
[1], OS_SendString
);
122 MYwrite_char (kidmum
[1], 32); /* Send string 32bytes at a time */
123 for (j
= 0; j
< 32; j
++, str
++)
124 MYwrite_char (kidmum
[1], *str
);
125 wait_for_osreply (&junk
);
131 MYwrite_char (kidmum
[1], RDP_OSOp
);
132 MYwrite_word (kidmum
[1], SWI_Write0
);
133 MYwrite_char (kidmum
[1], OS_SendString
);
134 MYwrite_char (kidmum
[1], (unsigned char) i
); /* Send remainder of string */
135 for (j
= 0; j
< i
; j
++, str
++)
136 MYwrite_char (kidmum
[1], *str
);
137 wait_for_osreply (&junk
);
144 /* while ((ch=*str++) != 0) */
145 /* state->hostif->writec(state->hostif->hostosarg, ch); */
149 ARMul_DebugPause (ARMul_State
* state
)
152 state
->hostif
->dbgpause (state
->hostif
->dbgarg
);
155 /***************************************************************************\
157 \***************************************************************************/
160 InitFail (int exitcode
, char const *which
)
162 ARMul_ConsolePrint (state
, "%s interface failed to initialise. Exiting\n",
168 RDIInit (unsigned type
)
172 state
->CallDebug
= state
->MemReadDebug
= state
->MemWriteDebug
= 0;
177 #define UNKNOWNPROC 0
186 Processor
const p_arm2
= { "ARM2", ARM_Fix26_Prop
};
187 Processor
const p_arm2as
= { "ARM2AS", ARM_Fix26_Prop
};
188 Processor
const p_arm61
= { "ARM61", ARM_Fix26_Prop
};
189 Processor
const p_arm3
= { "ARM3", ARM_Fix26_Prop
};
190 Processor
const p_arm6
= { "ARM6", ARM_Lock_Prop
};
191 Processor
const p_arm60
= { "ARM60", ARM_Lock_Prop
};
192 Processor
const p_arm600
= { "ARM600", ARM_Lock_Prop
};
193 Processor
const p_arm610
= { "ARM610", ARM_Lock_Prop
};
194 Processor
const p_arm620
= { "ARM620", ARM_Lock_Prop
};
195 Processor
const p_unknown
= { "", 0 };
197 Processor
const *const processors
[] =
199 &p_arm6
, /* default: must come first */
211 typedef struct ProcessorConfig ProcessorConfig
;
212 struct ProcessorConfig
215 ProcessorConfig
const *self
;
217 Processor
const *const *processors
;
220 ProcessorConfig
const processorconfig
= {
221 {((((((long) 'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
222 ((((((long) 'u' << 8) | 's') << 8) | ' ') << 8) | 'x'},
229 RDI_open (unsigned type
, const Dbg_ConfigBlock
* config
,
230 const Dbg_HostosInterface
* hostif
, struct Dbg_MCState
*dbg_state
)
231 /* Initialise everything */
233 int virgin
= (state
== NULL
);
240 ARMul_DebugPrint_i (hostif
, "RDI_open: type = %d\n", type
);
242 ARMul_DebugPrint (state
, "RDI_open: type = %d\n", type
);
255 ARMul_EmulateInit ();
256 state
= ARMul_NewState ();
257 state
->hostif
= hostif
;
259 int req
= config
->processor
;
260 unsigned processor
= processors
[req
]->val
;
261 ARMul_SelectProcessor (state
, processor
);
263 ARMul_ConsolePrint (state
, "ARMulator V1.50, %s",
264 processors
[req
]->name
);
266 if (ARMul_MemoryInit (state
, config
->memorysize
) == FALSE
)
267 InitFail (1, "Memory");
268 if (config
->bytesex
!= RDISex_DontCare
)
269 state
->bigendSig
= config
->bytesex
;
270 if (ARMul_CoProInit (state
) == FALSE
)
271 InitFail (2, "Co-Processor");
272 if (ARMul_OSInit (state
) == FALSE
)
273 InitFail (3, "Operating System");
279 { /* Reset the comms link */
280 /* what comms link ? */
282 if (virgin
&& (type
& 1) == 0) /* Cold start */
283 ARMul_ConsolePrint (state
, ", %s endian.\n",
284 state
->bigendSig
? "Big" : "Little");
286 if (config
->bytesex
== RDISex_DontCare
)
287 return (state
->bigendSig
? RDIError_BigEndian
: RDIError_LittleEndian
);
289 return (RDIError_NoError
);
292 /***************************************************************************\
294 \***************************************************************************/
299 TracePrint ((state
, "RDI_close\n"));
300 ARMul_OSExit (state
);
301 ARMul_CoProExit (state
);
302 ARMul_MemoryExit (state
);
303 return (RDIError_NoError
);
306 /***************************************************************************\
308 \***************************************************************************/
311 RDI_read (ARMword source
, void *dest
, unsigned *nbytes
)
314 char *memptr
= (char *) dest
;
316 TracePrint ((state
, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
317 source
, dest
, *nbytes
));
319 for (i
= 0; i
< *nbytes
; i
++)
320 *memptr
++ = (char) ARMul_ReadByte (state
, source
++);
323 state
->abortSig
= LOW
;
324 return (RDIError_DataAbort
);
326 return (RDIError_NoError
);
329 /***************************************************************************\
331 \***************************************************************************/
334 RDI_write (const void *source
, ARMword dest
, unsigned *nbytes
)
337 char *memptr
= (char *) source
;
339 TracePrint ((state
, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
340 source
, dest
, *nbytes
));
342 for (i
= 0; i
< *nbytes
; i
++)
343 ARMul_WriteByte (state
, (ARMword
) dest
++, (ARMword
) * memptr
++);
347 state
->abortSig
= LOW
;
348 return (RDIError_DataAbort
);
350 return (RDIError_NoError
);
353 /***************************************************************************\
355 \***************************************************************************/
358 RDI_CPUread (unsigned mode
, unsigned long mask
, ARMword buffer
[])
362 if (mode
== RDIMode_Curr
)
363 mode
= (unsigned) (ARMul_GetCPSR (state
) & MODEBITS
);
365 for (upto
= 0, i
= 0; i
< 15; i
++)
366 if (mask
& (1L << i
))
368 buffer
[upto
++] = ARMul_GetReg (state
, mode
, i
);
371 if (mask
& RDIReg_R15
)
373 buffer
[upto
++] = ARMul_GetR15 (state
);
376 if (mask
& RDIReg_PC
)
378 buffer
[upto
++] = ARMul_GetPC (state
);
381 if (mask
& RDIReg_CPSR
)
382 buffer
[upto
++] = ARMul_GetCPSR (state
);
384 if (mask
& RDIReg_SPSR
)
385 buffer
[upto
++] = ARMul_GetSPSR (state
, mode
);
387 TracePrint ((state
, "RDI_CPUread: mode=%.8x mask=%.8lx", mode
, mask
));
391 for (upto
= 0, i
= 0; i
<= 20; i
++)
392 if (mask
& (1L << i
))
394 ARMul_DebugPrint (state
, "%c%.8lx", upto
% 4 == 0 ? '\n' : ' ',
398 ARMul_DebugPrint (state
, "\n");
402 return (RDIError_NoError
);
405 /***************************************************************************\
407 \***************************************************************************/
410 RDI_CPUwrite (unsigned mode
, unsigned long mask
, ARMword
const buffer
[])
415 TracePrint ((state
, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode
, mask
));
419 for (upto
= 0, i
= 0; i
<= 20; i
++)
420 if (mask
& (1L << i
))
422 ARMul_DebugPrint (state
, "%c%.8lx", upto
% 4 == 0 ? '\n' : ' ',
426 ARMul_DebugPrint (state
, "\n");
430 if (mode
== RDIMode_Curr
)
431 mode
= (unsigned) (ARMul_GetCPSR (state
) & MODEBITS
);
433 for (upto
= 0, i
= 0; i
< 15; i
++)
434 if (mask
& (1L << i
))
435 ARMul_SetReg (state
, mode
, i
, buffer
[upto
++]);
437 if (mask
& RDIReg_R15
)
438 ARMul_SetR15 (state
, buffer
[upto
++]);
440 if (mask
& RDIReg_PC
)
443 ARMul_SetPC (state
, buffer
[upto
++]);
445 if (mask
& RDIReg_CPSR
)
446 ARMul_SetCPSR (state
, buffer
[upto
++]);
448 if (mask
& RDIReg_SPSR
)
449 ARMul_SetSPSR (state
, mode
, buffer
[upto
++]);
451 return (RDIError_NoError
);
454 /***************************************************************************\
456 \***************************************************************************/
459 RDI_CPread (unsigned CPnum
, unsigned long mask
, ARMword buffer
[])
461 ARMword fpregsaddr
, word
[4];
466 if (CPnum
!= 1 && CPnum
!= 2)
468 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
470 return (RDIError_UnknownCoPro
);
471 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
472 if (mask
& (1L << r
))
474 (void) state
->CPRead
[CPnum
] (state
, r
, &buffer
[upto
]);
477 TracePrint ((state
, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum
, mask
));
482 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
483 if (mask
& (1L << r
))
486 ARMul_DebugPrint (state
, "%c%2d",
487 (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
490 ARMul_DebugPrint (state
, " %.8lx", buffer
[upto
++]);
494 ARMul_DebugPrint (state
, "\n");
497 return RDIError_NoError
;
501 return RDIError_UnknownCoPro
;
506 fpregsaddr
= ARMul_ReadWord (state
, 4L);
507 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
508 return RDIError_UnknownCoPro
;
509 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */
510 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
511 return RDIError_UnknownCoPro
;
512 fpregsaddr
= ARMul_ReadWord (state
, fpregsaddr
); /* pointer to fp registers */
513 FPRegsAddr
= fpregsaddr
;
516 fpregsaddr
= FPRegsAddr
;
519 return RDIError_UnknownCoPro
;
520 for (upto
= 0, r
= 0; r
< 8; r
++)
521 if (mask
& (1L << r
))
523 for (w
= 0; w
< 4; w
++)
525 ARMul_ReadWord (state
,
526 fpregsaddr
+ (ARMword
) r
* 16 + (ARMword
) w
* 4);
527 switch ((int) (word
[3] >> 29))
532 case 6: /* its unpacked, convert to extended */
533 buffer
[upto
++] = 2; /* mark as extended */
534 buffer
[upto
++] = (word
[3] & 0x7fff) | (word
[0] & 0x80000000); /* exp and sign */
535 buffer
[upto
++] = word
[1]; /* mantissa 1 */
536 buffer
[upto
++] = word
[2]; /* mantissa 2 */
538 case 1: /* packed single */
539 buffer
[upto
++] = 0; /* mark as single */
540 buffer
[upto
++] = word
[0]; /* sign, exp and mantissa */
541 buffer
[upto
++] = word
[1]; /* padding */
542 buffer
[upto
++] = word
[2]; /* padding */
544 case 3: /* packed double */
545 buffer
[upto
++] = 1; /* mark as double */
546 buffer
[upto
++] = word
[0]; /* sign, exp and mantissa1 */
547 buffer
[upto
++] = word
[1]; /* mantissa 2 */
548 buffer
[upto
++] = word
[2]; /* padding */
550 case 5: /* packed extended */
551 buffer
[upto
++] = 2; /* mark as extended */
552 buffer
[upto
++] = word
[0]; /* sign and exp */
553 buffer
[upto
++] = word
[1]; /* mantissa 1 */
554 buffer
[upto
++] = word
[2]; /* mantissa 2 */
556 case 7: /* packed decimal */
557 buffer
[upto
++] = 3; /* mark as packed decimal */
558 buffer
[upto
++] = word
[0]; /* sign, exp and mantissa1 */
559 buffer
[upto
++] = word
[1]; /* mantissa 2 */
560 buffer
[upto
++] = word
[2]; /* mantissa 3 */
564 if (mask
& (1L << r
))
565 buffer
[upto
++] = ARMul_ReadWord (state
, fpregsaddr
+ 128); /* fpsr */
566 if (mask
& (1L << (r
+ 1)))
567 buffer
[upto
++] = 0; /* fpcr */
569 TracePrint ((state
, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum
, mask
));
573 for (upto
= 0, r
= 0; r
< 9; r
++)
574 if (mask
& (1L << r
))
578 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
579 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
580 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
582 ARMul_DebugPrint (state
, "%08lx\n", buffer
[upto
++]);
584 ARMul_DebugPrint (state
, "\n");
587 return (RDIError_NoError
);
591 /***************************************************************************\
593 \***************************************************************************/
596 RDI_CPwrite (unsigned CPnum
, unsigned long mask
, ARMword
const buffer
[])
602 if (CPnum
!= 1 && CPnum
!= 2)
604 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
606 return (RDIError_UnknownCoPro
);
607 TracePrint ((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
612 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
613 if (mask
& (1L << r
))
616 ARMul_DebugPrint (state
, "%c%2d",
617 (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
620 ARMul_DebugPrint (state
, " %.8lx", buffer
[upto
++]);
624 ARMul_DebugPrint (state
, "\n");
627 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
628 if (mask
& (1L << r
))
630 (void) state
->CPWrite
[CPnum
] (state
, r
, &buffer
[upto
]);
633 return RDIError_NoError
;
637 return RDIError_UnknownCoPro
;
640 TracePrint ((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
644 for (upto
= 0, r
= 0; r
< 9; r
++)
645 if (mask
& (1L << r
))
649 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
650 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
651 ARMul_DebugPrint (state
, "%08lx ", buffer
[upto
++]);
653 ARMul_DebugPrint (state
, "%08lx\n", buffer
[upto
++]);
655 ARMul_DebugPrint (state
, "\n");
661 fpregsaddr
= ARMul_ReadWord (state
, 4L);
662 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
663 return RDIError_UnknownCoPro
;
664 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8; /* address in __fp_decode - 4 */
665 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
666 return RDIError_UnknownCoPro
;
667 fpregsaddr
= ARMul_ReadWord (state
, fpregsaddr
); /* pointer to fp registers */
668 FPRegsAddr
= fpregsaddr
;
671 fpregsaddr
= FPRegsAddr
;
674 return RDIError_UnknownCoPro
;
675 for (upto
= 0, r
= 0; r
< 8; r
++)
676 if (mask
& (1L << r
))
678 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16,
680 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16 + 4,
682 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16 + 8,
684 ARMul_WriteWord (state
, fpregsaddr
+ (ARMword
) r
* 16 + 12,
685 (buffer
[upto
] * 2 + 1) << 29); /* mark type */
688 if (mask
& (1L << r
))
689 ARMul_WriteWord (state
, fpregsaddr
+ 128, buffer
[upto
++]); /* fpsr */
690 return (RDIError_NoError
);
695 deletebreaknode (BreakNode
** prevp
)
697 BreakNode
*p
= *prevp
;
699 ARMul_WriteWord (state
, p
->address
, p
->inst
);
706 removebreak (ARMword address
, unsigned type
)
708 BreakNode
*p
, **prevp
= &BreakList
;
709 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
710 if (p
->address
== address
&& p
->type
== type
)
712 deletebreaknode (prevp
);
718 /* This routine installs a breakpoint into the breakpoint table */
721 installbreak (ARMword address
, unsigned type
, ARMword bound
)
723 BreakNode
*p
= (BreakNode
*) malloc (sizeof (BreakNode
));
726 p
->address
= address
;
729 p
->inst
= ARMul_ReadWord (state
, address
);
730 ARMul_WriteWord (state
, address
, 0xee000000L
);
734 /***************************************************************************\
736 \***************************************************************************/
739 RDI_setbreak (ARMword address
, unsigned type
, ARMword bound
,
740 PointHandle
* handle
)
743 TracePrint ((state
, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
744 address
, type
, bound
));
746 removebreak (address
, type
);
747 p
= installbreak (address
, type
, bound
);
750 *handle
= (PointHandle
) p
;
751 TracePrint ((state
, " returns %.8lx\n", *handle
));
752 return RDIError_NoError
;
755 /***************************************************************************\
757 \***************************************************************************/
760 RDI_clearbreak (PointHandle handle
)
762 TracePrint ((state
, "RDI_clearbreak: address=%.8lx\n", handle
));
764 BreakNode
*p
, **prevp
= &BreakList
;
765 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
766 if (p
== (BreakNode
*) handle
)
769 return RDIError_NoSuchPoint
;
770 deletebreaknode (prevp
);
771 return RDIError_NoError
;
775 /***************************************************************************\
776 * Internal functions for breakpoint table manipulation *
777 \***************************************************************************/
780 deletewatchnode (WatchNode
** prevp
)
782 WatchNode
*p
= *prevp
;
783 if (p
->datatype
& Watch_AnyRead
)
784 state
->MemReadDebug
--;
785 if (p
->datatype
& Watch_AnyWrite
)
786 state
->MemWriteDebug
--;
792 removewatch (ARMword address
, unsigned type
)
794 WatchNode
*p
, **prevp
= &WatchList
;
795 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
796 if (p
->address
== address
&& p
->type
== type
)
797 { /* found a match */
798 deletewatchnode (prevp
);
801 return FALSE
; /* never found a match */
805 installwatch (ARMword address
, unsigned type
, unsigned datatype
,
808 WatchNode
*p
= (WatchNode
*) malloc (sizeof (WatchNode
));
811 p
->address
= address
;
813 p
->datatype
= datatype
;
818 /***************************************************************************\
820 \***************************************************************************/
823 RDI_setwatch (ARMword address
, unsigned type
, unsigned datatype
,
824 ARMword bound
, PointHandle
* handle
)
829 "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
830 address
, type
, datatype
, bound
));
832 if (!state
->CanWatch
)
833 return RDIError_UnimplementedMessage
;
835 removewatch (address
, type
);
836 p
= installwatch (address
, type
, datatype
, bound
);
837 if (datatype
& Watch_AnyRead
)
838 state
->MemReadDebug
++;
839 if (datatype
& Watch_AnyWrite
)
840 state
->MemWriteDebug
++;
841 *handle
= (PointHandle
) p
;
842 TracePrint ((state
, " returns %.8lx\n", *handle
));
843 return RDIError_NoError
;
846 /***************************************************************************\
848 \***************************************************************************/
851 RDI_clearwatch (PointHandle handle
)
853 TracePrint ((state
, "RDI_clearwatch: address=%.8lx\n", handle
));
855 WatchNode
*p
, **prevp
= &WatchList
;
856 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
857 if (p
== (WatchNode
*) handle
)
860 return RDIError_NoSuchPoint
;
861 deletewatchnode (prevp
);
862 return RDIError_NoError
;
866 /***************************************************************************\
868 \***************************************************************************/
871 RDI_execute (PointHandle
* handle
)
873 TracePrint ((state
, "RDI_execute\n"));
879 state
->EndCondition
= RDIError_NoError
;
880 state
->StopHandle
= 0;
882 ARMul_DoProg (state
);
884 *handle
= state
->StopHandle
;
885 state
->Reg
[15] -= 8; /* undo the pipeline */
889 state
->Debug
= FALSE
;
891 return (state
->EndCondition
);
894 /***************************************************************************\
896 \***************************************************************************/
899 RDI_step (unsigned ninstr
, PointHandle
* handle
)
902 TracePrint ((state
, "RDI_step\n"));
904 return RDIError_UnimplementedMessage
;
910 state
->EndCondition
= RDIError_NoError
;
911 state
->StopHandle
= 0;
912 ARMul_DoInstr (state
);
913 *handle
= state
->StopHandle
;
914 state
->Reg
[15] -= 8; /* undo the pipeline */
918 state
->Debug
= FALSE
;
920 return (state
->EndCondition
);
923 /***************************************************************************\
925 \***************************************************************************/
928 RDI_info (unsigned type
, ARMword
* arg1
, ARMword
* arg2
)
933 TracePrint ((state
, "RDI_Info_Target\n"));
934 /* Emulator, speed 10**5 IPS */
935 *arg1
= 5 | HIGHEST_RDI_LEVEL
<< 5 | LOWEST_RDI_LEVEL
<< 8;
937 return RDIError_NoError
;
941 ARMword n
= RDIPointCapability_Comparison
| RDIPointCapability_Range
|
942 RDIPointCapability_Mask
| RDIPointCapability_Status
;
943 TracePrint ((state
, "RDI_Info_Points\n"));
945 n
|= (Watch_AnyRead
+ Watch_AnyWrite
) << 2;
947 return RDIError_NoError
;
951 TracePrint ((state
, "RDI_Info_Step\n"));
952 *arg1
= RDIStep_Single
;
953 return RDIError_NoError
;
956 TracePrint ((state
, "RDI_Info_MMU\n"));
958 return RDIError_NoError
;
961 TracePrint ((state
, "RDISignal_Stop\n"));
963 state
->EndCondition
= RDIError_UserInterrupt
;
964 return RDIError_NoError
;
966 case RDIVector_Catch
:
967 TracePrint ((state
, "RDIVector_Catch %.8lx\n", *arg1
));
968 state
->VectorCatch
= (unsigned) *arg1
;
969 return RDIError_NoError
;
972 TracePrint ((state
, "RDI_Set_Cmdline %s\n", (char *) arg1
));
974 (char *) malloc ((unsigned) strlen ((char *) arg1
) + 1);
975 (void) strcpy (state
->CommandLine
, (char *) arg1
);
976 return RDIError_NoError
;
979 TracePrint ((state
, "RDI_Info_Cycles\n"));
981 arg1
[1] = state
->NumInstrs
;
983 arg1
[3] = state
->NumScycles
;
985 arg1
[5] = state
->NumNcycles
;
987 arg1
[7] = state
->NumIcycles
;
989 arg1
[9] = state
->NumCcycles
;
991 arg1
[11] = state
->NumFcycles
;
992 return RDIError_NoError
;
995 *arg1
= ARMul_OSLastErrorP (state
);
996 TracePrint ((state
, "RDI_ErrorP returns %ld\n", *arg1
));
997 return RDIError_NoError
;
999 case RDIInfo_DescribeCoPro
:
1001 int cpnum
= *(int *) arg1
;
1002 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*) arg2
;
1004 unsigned char const *map
= state
->CPRegWords
[cpnum
];
1006 return RDIError_UnknownCoPro
;
1007 for (i
= 0; i
< cpd
->entries
; i
++)
1009 unsigned r
, w
= cpd
->regdesc
[i
].nbytes
/ sizeof (ARMword
);
1010 for (r
= cpd
->regdesc
[i
].rmin
; r
<= cpd
->regdesc
[i
].rmax
; r
++)
1012 return RDIError_BadCoProState
;
1014 return RDIError_NoError
;
1017 case RDIInfo_RequestCoProDesc
:
1019 int cpnum
= *(int *) arg1
;
1020 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*) arg2
;
1021 int i
= -1, lastw
= -1, r
;
1022 unsigned char const *map
;
1023 if ((unsigned) cpnum
>= 16)
1024 return RDIError_UnknownCoPro
;
1025 map
= state
->CPRegWords
[cpnum
];
1027 return RDIError_UnknownCoPro
;
1028 for (r
= 0; r
< map
[-1]; r
++)
1032 cpd
->regdesc
[i
].rmax
= r
;
1035 if (++i
>= cpd
->entries
)
1036 return RDIError_BufferFull
;
1037 cpd
->regdesc
[i
].rmax
= cpd
->regdesc
[i
].rmin
= r
;
1038 cpd
->regdesc
[i
].nbytes
= words
* sizeof (ARMword
);
1039 cpd
->regdesc
[i
].access
=
1040 Dbg_Access_Readable
+ Dbg_Access_Writable
;
1043 cpd
->entries
= i
+ 1;
1044 return RDIError_NoError
;
1048 *arg1
= (ARMword
) rdi_log
;
1049 return RDIError_NoError
;
1051 case RDIInfo_SetLog
:
1052 rdi_log
= (int) *arg1
;
1053 return RDIError_NoError
;
1056 return RDIError_NoError
;
1058 case RDIPointStatus_Watch
:
1060 WatchNode
*p
, *handle
= (WatchNode
*) * arg1
;
1061 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
1066 return RDIError_NoError
;
1068 return RDIError_NoSuchPoint
;
1071 case RDIPointStatus_Break
:
1073 BreakNode
*p
, *handle
= (BreakNode
*) * arg1
;
1074 for (p
= BreakList
; p
!= NULL
; p
= p
->next
)
1079 return RDIError_NoError
;
1081 return RDIError_NoSuchPoint
;
1084 case RDISet_RDILevel
:
1085 if (*arg1
< LOWEST_RDI_LEVEL
|| *arg1
> HIGHEST_RDI_LEVEL
)
1086 return RDIError_IncompatibleRDILevels
;
1087 MYrdi_level
= *arg1
;
1088 return RDIError_NoError
;
1091 return RDIError_UnimplementedMessage
;
1096 /***************************************************************************\
1097 * The emulator calls this routine at the beginning of every cycle when the *
1098 * CallDebug flag is set. The second parameter passed is the address of the *
1099 * currently executing instruction (i.e Program Counter - 8), the third *
1100 * parameter is the instruction being executed. *
1101 \***************************************************************************/
1104 ARMul_Debug (ARMul_State
* state
, ARMword pc
, ARMword instr
)
1107 if (state
->EndCondition
== RDIError_UserInterrupt
)
1109 TracePrint ((state
, "User interrupt at %.8lx\n", pc
));
1111 state
->Emulate
= STOP
;
1115 BreakNode
*p
= BreakList
;
1116 for (; p
!= NULL
; p
= p
->next
)
1121 if (pc
== p
->address
)
1125 if (pc
> p
->address
)
1129 if (pc
>= p
->address
)
1133 if (pc
< p
->address
)
1137 if (pc
<= p
->address
)
1141 if (p
->address
<= pc
&& pc
< p
->address
+ p
->bound
)
1145 if (p
->address
> pc
|| pc
>= p
->address
+ p
->bound
)
1149 if ((pc
& p
->bound
) == p
->address
)
1154 TracePrint ((state
, "Breakpoint reached at %.8lx\n", pc
));
1155 state
->EndCondition
= RDIError_BreakpointReached
;
1156 state
->Emulate
= STOP
;
1157 state
->StopHandle
= (ARMword
) p
;
1165 ARMul_CheckWatch (ARMul_State
* state
, ARMword addr
, int access
)
1168 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
1169 if (p
->datatype
& access
)
1174 if (addr
== p
->address
)
1178 if (addr
> p
->address
)
1182 if (addr
>= p
->address
)
1186 if (addr
< p
->address
)
1190 if (addr
<= p
->address
)
1194 if (p
->address
<= addr
&& addr
< p
->address
+ p
->bound
)
1198 if (p
->address
> addr
|| addr
>= p
->address
+ p
->bound
)
1202 if ((addr
& p
->bound
) == p
->address
)
1207 TracePrint ((state
, "Watchpoint at %.8lx accessed\n", addr
));
1208 state
->EndCondition
= RDIError_WatchpointAccessed
;
1209 state
->Emulate
= STOP
;
1210 state
->StopHandle
= (ARMword
) p
;
1215 static RDI_NameList
const *
1218 return (RDI_NameList
const *) &processorconfig
.count
;
1221 const struct RDIProcVec armul_rdi
= {
1241 0, /*loadconfigdata */
1242 0, /*selectconfig */