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., 675 Mass Ave, Cambridge, MA 02139, 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
;
60 struct BreakNode
{ /* 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 */
68 struct WatchNode
{ /* A watchpoint list node */
70 ARMword address
; /* The address of this watchpoint */
71 unsigned type
; /* The type of comparison */
72 unsigned datatype
; /* The type of access to watch for */
73 ARMword bound
; /* The other address for a range */
76 BreakNode
*BreakList
= NULL
;
77 WatchNode
*WatchList
= NULL
;
79 void ARMul_DebugPrint_i(const Dbg_HostosInterface
*hostif
, const char *format
, ...)
82 hostif
->dbgprint(hostif
->dbgarg
, format
, ap
);
86 void ARMul_DebugPrint(ARMul_State
*state
, const char *format
, ...)
90 state
->hostif
->dbgprint(state
->hostif
->dbgarg
, format
, ap
);
94 #define CONSOLE_PRINT_MAX_LEN 128
96 void ARMul_ConsolePrint(ARMul_State
*state
, const char *format
, ...)
100 char *str
, buf
[CONSOLE_PRINT_MAX_LEN
];
104 va_start(ap
, format
);
105 vsprintf(buf
, format
, ap
);
107 for (i
= 0; buf
[i
] ;i
++); /* The string is i chars long */
111 MYwrite_char(kidmum
[1], RDP_OSOp
);
112 MYwrite_word(kidmum
[1], SWI_Write0
);
113 MYwrite_char(kidmum
[1], OS_SendString
);
114 MYwrite_char(kidmum
[1], 32); /* Send string 32bytes at a time */
115 for (j
= 0; j
< 32; j
++, str
++)
116 MYwrite_char(kidmum
[1], *str
);
117 wait_for_osreply(&junk
);
122 MYwrite_char(kidmum
[1], RDP_OSOp
);
123 MYwrite_word(kidmum
[1], SWI_Write0
);
124 MYwrite_char(kidmum
[1], OS_SendString
);
125 MYwrite_char(kidmum
[1], (unsigned char) i
); /* Send remainder of string */
126 for (j
= 0; j
< i
; j
++, str
++)
127 MYwrite_char(kidmum
[1], *str
);
128 wait_for_osreply(&junk
);
133 /* while ((ch=*str++) != 0) */
134 /* state->hostif->writec(state->hostif->hostosarg, ch); */
137 void ARMul_DebugPause(ARMul_State
*state
)
140 state
->hostif
->dbgpause(state
->hostif
->dbgarg
);
143 /***************************************************************************\
145 \***************************************************************************/
147 static void InitFail(int exitcode
, char const *which
) {
148 ARMul_ConsolePrint(state
, "%s interface failed to initialise. Exiting\n",
153 static void RDIInit(unsigned type
)
154 {if (type
== 0) { /* cold start */
155 state
->CallDebug
= state
->MemReadDebug
= state
->MemWriteDebug
= 0 ;
160 #define UNKNOWNPROC 0
162 typedef struct { char name
[16]; unsigned val
; } Processor
;
164 Processor
const p_arm2
= {"ARM2", ARM2
};
165 Processor
const p_arm2as
= {"ARM2AS", ARM2as
};
166 Processor
const p_arm61
= {"ARM61", ARM61
};
167 Processor
const p_arm3
= {"ARM3", ARM3
};
168 Processor
const p_arm6
= {"ARM6", ARM6
};
169 Processor
const p_arm60
= {"ARM60", ARM60
};
170 Processor
const p_arm600
= {"ARM600", ARM600
};
171 Processor
const p_arm610
= {"ARM610", ARM610
};
172 Processor
const p_arm620
= {"ARM620", ARM620
};
173 Processor
const p_unknown
= {"", UNKNOWNPROC
};
175 Processor
const *const processors
[] = {
176 &p_arm6
, /* default: must come first */
188 typedef struct ProcessorConfig ProcessorConfig
;
189 struct ProcessorConfig
{
191 ProcessorConfig
const *self
;
193 Processor
const * const *processors
;
196 ProcessorConfig
const processorconfig
= {
197 { ((((((long)'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
198 ((((((long)'u' << 8) | 's') << 8) | ' ') << 8) | 'x'
205 static int RDI_open(unsigned type
, const Dbg_ConfigBlock
*config
,
206 const Dbg_HostosInterface
*hostif
,
207 struct Dbg_MCState
*dbg_state
)
208 /* Initialise everything */
209 {int virgin
= (state
== NULL
);
215 ARMul_DebugPrint_i(hostif
, "RDI_open: type = %d\n",type
) ;
217 ARMul_DebugPrint(state
, "RDI_open: type = %d\n",type
) ;
221 if (type
& 1) { /* Warm start */
228 state
= ARMul_NewState();
229 state
->hostif
= hostif
;
230 { int req
= config
->processor
;
231 unsigned processor
= processors
[req
]->val
;
232 ARMul_SelectProcessor(state
, processor
);
234 ARMul_ConsolePrint(state
, "ARMulator V1.50, %s", processors
[req
]->name
);
236 if (ARMul_MemoryInit(state
,config
->memorysize
) == FALSE
)
237 InitFail(1, "Memory");
238 if (config
->bytesex
!= RDISex_DontCare
)
239 state
->bigendSig
= config
->bytesex
;
240 if (ARMul_CoProInit(state
) == FALSE
)
241 InitFail(2, "Co-Processor");
242 if (ARMul_OSInit(state
) == FALSE
)
243 InitFail(3, "Operating System");
248 if (type
& 2) { /* Reset the comms link */
249 /* what comms link ? */
251 if (virgin
&& (type
& 1) == 0) /* Cold start */
252 ARMul_ConsolePrint(state
, ", %s endian.\n",
253 state
->bigendSig
? "Big" : "Little");
255 if (config
->bytesex
== RDISex_DontCare
)
256 return(state
->bigendSig
? RDIError_BigEndian
: RDIError_LittleEndian
);
258 return(RDIError_NoError
) ;
261 /***************************************************************************\
263 \***************************************************************************/
265 static int RDI_close(void)
267 TracePrint((state
, "RDI_close\n"));
268 ARMul_OSExit(state
) ;
269 ARMul_CoProExit(state
) ;
270 ARMul_MemoryExit(state
) ;
271 return(RDIError_NoError
) ;
274 /***************************************************************************\
276 \***************************************************************************/
278 static int RDI_read(ARMword source
, void *dest
, unsigned *nbytes
)
280 char *memptr
= (char *)dest
;
282 TracePrint((state
, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
283 source
, dest
, *nbytes
));
285 for (i
=0 ; i
< *nbytes
; i
++)
286 *memptr
++ = (char)ARMul_ReadByte(state
,source
++) ;
287 if (state
->abortSig
) {
288 state
->abortSig
= LOW
;
289 return(RDIError_DataAbort
) ;
291 return(RDIError_NoError
) ;
294 /***************************************************************************\
296 \***************************************************************************/
298 static int RDI_write(const void *source
, ARMword dest
, unsigned *nbytes
)
300 char *memptr
= (char *)source
;
302 TracePrint((state
, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
303 source
, dest
, *nbytes
));
305 for (i
=0 ; i
< *nbytes
; i
++)
306 ARMul_WriteByte(state
,(ARMword
)dest
++,(ARMword
)*memptr
++) ;
308 if (state
->abortSig
) {
309 state
->abortSig
= LOW
;
310 return(RDIError_DataAbort
) ;
312 return(RDIError_NoError
) ;
315 /***************************************************************************\
317 \***************************************************************************/
319 static int RDI_CPUread(unsigned mode
, unsigned long mask
, ARMword buffer
[])
322 if (mode
== RDIMode_Curr
)
323 mode
= (unsigned)(ARMul_GetCPSR(state
) & MODEBITS
) ;
325 for (upto
= 0, i
= 0 ; i
< 15 ; i
++)
326 if (mask
& (1L << i
)){
327 buffer
[upto
++] = ARMul_GetReg(state
,mode
,i
) ;
330 if (mask
& RDIReg_R15
) {
331 buffer
[upto
++] = ARMul_GetR15(state
) ;
334 if (mask
& RDIReg_PC
) {
335 buffer
[upto
++] = ARMul_GetPC(state
) ;
338 if (mask
& RDIReg_CPSR
)
339 buffer
[upto
++] = ARMul_GetCPSR(state
) ;
341 if (mask
& RDIReg_SPSR
)
342 buffer
[upto
++] = ARMul_GetSPSR(state
,mode
) ;
344 TracePrint((state
, "RDI_CPUread: mode=%.8x mask=%.8lx", mode
, mask
));
347 for (upto
= 0, i
= 0 ; i
<= 20 ; i
++)
348 if (mask
& (1L << i
)) {
349 ARMul_DebugPrint(state
, "%c%.8lx",upto
%4==0?'\n':' ',buffer
[upto
]) ;
352 ARMul_DebugPrint(state
, "\n") ;
356 return(RDIError_NoError
) ;
359 /***************************************************************************\
361 \***************************************************************************/
363 static int RDI_CPUwrite(unsigned mode
, unsigned long mask
, ARMword
const buffer
[])
367 TracePrint((state
, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode
, mask
));
370 for (upto
= 0, i
= 0 ; i
<= 20 ; i
++)
371 if (mask
& (1L << i
)) {
372 ARMul_DebugPrint(state
, "%c%.8lx",upto
%4==0?'\n':' ',buffer
[upto
]) ;
375 ARMul_DebugPrint(state
, "\n") ;
379 if (mode
== RDIMode_Curr
)
380 mode
= (unsigned)(ARMul_GetCPSR(state
) & MODEBITS
) ;
382 for (upto
= 0, i
= 0 ; i
< 15 ; i
++)
383 if (mask
& (1L << i
))
384 ARMul_SetReg(state
,mode
,i
,buffer
[upto
++]) ;
386 if (mask
& RDIReg_R15
)
387 ARMul_SetR15(state
,buffer
[upto
++]) ;
389 if (mask
& RDIReg_PC
) {
391 ARMul_SetPC(state
,buffer
[upto
++]) ;
393 if (mask
& RDIReg_CPSR
)
394 ARMul_SetCPSR(state
,buffer
[upto
++]) ;
396 if (mask
& RDIReg_SPSR
)
397 ARMul_SetSPSR(state
,mode
,buffer
[upto
++]) ;
399 return(RDIError_NoError
) ;
402 /***************************************************************************\
404 \***************************************************************************/
406 static int RDI_CPread(unsigned CPnum
, unsigned long mask
, ARMword buffer
[])
407 {ARMword fpregsaddr
, word
[4] ;
412 if (CPnum
!= 1 && CPnum
!= 2) {
413 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
415 return(RDIError_UnknownCoPro
) ;
416 for (upto
= 0, r
= 0 ; r
< rmap
[-1] ; r
++)
417 if (mask
& (1L << r
)) {
418 (void)state
->CPRead
[CPnum
](state
, r
, &buffer
[upto
]);
421 TracePrint((state
, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum
, mask
));
425 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
426 if (mask
& (1L << r
)) {
428 ARMul_DebugPrint(state
, "%c%2d", (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
429 while (--words
>= 0) {
430 ARMul_DebugPrint(state
, " %.8lx", buffer
[upto
++]);
434 ARMul_DebugPrint(state
, "\n") ;
437 return RDIError_NoError
;
441 return RDIError_UnknownCoPro
;
444 if (FPRegsAddr
== 0) {
445 fpregsaddr
= ARMul_ReadWord(state
, 4L) ;
446 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
447 return RDIError_UnknownCoPro
;
448 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8 ; /* address in __fp_decode - 4 */
449 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
450 return RDIError_UnknownCoPro
;
451 fpregsaddr
= ARMul_ReadWord(state
, fpregsaddr
) ; /* pointer to fp registers */
452 FPRegsAddr
= fpregsaddr
;
455 fpregsaddr
= FPRegsAddr
;
457 if (fpregsaddr
== 0) return RDIError_UnknownCoPro
;
458 for (upto
= 0, r
= 0 ; r
< 8 ; r
++)
459 if (mask
& (1L << r
)) {
460 for (w
= 0 ; w
< 4 ; w
++)
461 word
[w
] = ARMul_ReadWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + (ARMword
)w
* 4) ;
462 switch ((int)(word
[3] >> 29)) {
466 case 6 : /* its unpacked, convert to extended */
467 buffer
[upto
++] = 2 ; /* mark as extended */
468 buffer
[upto
++] = (word
[3] & 0x7fff) | (word
[0] & 0x80000000) ; /* exp and sign */
469 buffer
[upto
++] = word
[1] ; /* mantissa 1 */
470 buffer
[upto
++] = word
[2] ; /* mantissa 2 */
472 case 1 : /* packed single */
473 buffer
[upto
++] = 0 ; /* mark as single */
474 buffer
[upto
++] = word
[0] ; /* sign, exp and mantissa */
475 buffer
[upto
++] = word
[1] ; /* padding */
476 buffer
[upto
++] = word
[2] ; /* padding */
478 case 3 : /* packed double */
479 buffer
[upto
++] = 1 ; /* mark as double */
480 buffer
[upto
++] = word
[0] ; /* sign, exp and mantissa1 */
481 buffer
[upto
++] = word
[1] ; /* mantissa 2 */
482 buffer
[upto
++] = word
[2] ; /* padding */
484 case 5 : /* packed extended */
485 buffer
[upto
++] = 2 ; /* mark as extended */
486 buffer
[upto
++] = word
[0] ; /* sign and exp */
487 buffer
[upto
++] = word
[1] ; /* mantissa 1 */
488 buffer
[upto
++] = word
[2] ; /* mantissa 2 */
490 case 7 : /* packed decimal */
491 buffer
[upto
++] = 3 ; /* mark as packed decimal */
492 buffer
[upto
++] = word
[0] ; /* sign, exp and mantissa1 */
493 buffer
[upto
++] = word
[1] ; /* mantissa 2 */
494 buffer
[upto
++] = word
[2] ; /* mantissa 3 */
498 if (mask
& (1L << r
))
499 buffer
[upto
++] = ARMul_ReadWord(state
,fpregsaddr
+ 128) ; /* fpsr */
500 if (mask
& (1L << (r
+1) ))
501 buffer
[upto
++] = 0 ; /* fpcr */
503 TracePrint((state
, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum
, mask
));
506 for (upto
= 0, r
= 0 ; r
< 9 ; r
++)
507 if (mask
& (1L << r
)) {
509 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
510 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
511 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
513 ARMul_DebugPrint(state
, "%08lx\n",buffer
[upto
++]) ;
515 ARMul_DebugPrint(state
, "\n") ;
518 return(RDIError_NoError
) ;
522 /***************************************************************************\
524 \***************************************************************************/
526 static int RDI_CPwrite(unsigned CPnum
, unsigned long mask
, ARMword
const buffer
[])
531 if (CPnum
!= 1 && CPnum
!= 2) {
532 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
534 return(RDIError_UnknownCoPro
) ;
535 TracePrint((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
539 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
540 if (mask
& (1L << r
)) {
542 ARMul_DebugPrint(state
, "%c%2d", (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
543 while (--words
>= 0) {
544 ARMul_DebugPrint(state
, " %.8lx", buffer
[upto
++]);
548 ARMul_DebugPrint(state
, "\n") ;
551 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
552 if (mask
& (1L << r
)) {
553 (void)state
->CPWrite
[CPnum
](state
, r
, &buffer
[upto
]);
556 return RDIError_NoError
;
560 return RDIError_UnknownCoPro
;
563 TracePrint((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
566 for (upto
= 0, r
= 0 ; r
< 9 ; r
++)
567 if (mask
& (1L << r
)) {
569 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
570 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
571 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
573 ARMul_DebugPrint(state
, "%08lx\n",buffer
[upto
++]) ;
575 ARMul_DebugPrint(state
, "\n") ;
579 if (FPRegsAddr
== 0) {
580 fpregsaddr
= ARMul_ReadWord(state
, 4L) ;
581 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
582 return RDIError_UnknownCoPro
;
583 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8 ; /* address in __fp_decode - 4 */
584 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
585 return RDIError_UnknownCoPro
;
586 fpregsaddr
= ARMul_ReadWord(state
, fpregsaddr
) ; /* pointer to fp registers */
587 FPRegsAddr
= fpregsaddr
;
590 fpregsaddr
= FPRegsAddr
;
592 if (fpregsaddr
== 0) return RDIError_UnknownCoPro
;
593 for (upto
= 0, r
= 0 ; r
< 8 ; r
++)
594 if (mask
& (1L << r
)) {
595 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16,buffer
[upto
+1]) ;
596 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + 4,buffer
[upto
+2]) ;
597 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + 8,buffer
[upto
+3]) ;
598 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + 12,(buffer
[upto
] * 2 + 1) << 29) ; /* mark type */
601 if (mask
& (1L << r
))
602 ARMul_WriteWord(state
,fpregsaddr
+ 128,buffer
[upto
++]) ; /* fpsr */
603 return(RDIError_NoError
) ;
607 static void deletebreaknode(BreakNode
**prevp
) {
608 BreakNode
*p
= *prevp
;
610 ARMul_WriteWord(state
, p
->address
, p
->inst
);
616 static int removebreak(ARMword address
, unsigned type
)
617 { BreakNode
*p
, **prevp
= &BreakList
;
618 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
619 if (p
->address
== address
&& p
->type
== type
) {
620 deletebreaknode(prevp
);
626 /* This routine installs a breakpoint into the breakpoint table */
628 static BreakNode
*installbreak(ARMword address
, unsigned type
, ARMword bound
)
629 { BreakNode
*p
= (BreakNode
*)malloc(sizeof(BreakNode
));
632 p
->address
= address
;
635 p
->inst
= ARMul_ReadWord(state
, address
);
636 ARMul_WriteWord(state
, address
, 0xee000000L
);
640 /***************************************************************************\
642 \***************************************************************************/
644 static int RDI_setbreak(ARMword address
, unsigned type
, ARMword bound
,
647 TracePrint((state
, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
648 address
, type
, bound
));
650 removebreak(address
, type
);
651 p
= installbreak(address
, type
, bound
);
654 *handle
= (PointHandle
)p
;
655 TracePrint((state
, " returns %.8lx\n", *handle
));
656 return RDIError_NoError
;
659 /***************************************************************************\
661 \***************************************************************************/
663 static int RDI_clearbreak(PointHandle handle
)
664 { TracePrint((state
, "RDI_clearbreak: address=%.8lx\n", handle
));
665 { BreakNode
*p
, **prevp
= &BreakList
;
666 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
667 if (p
== (BreakNode
*)handle
) break;
668 if (p
== NULL
) return RDIError_NoSuchPoint
;
669 deletebreaknode(prevp
);
670 return RDIError_NoError
;
674 /***************************************************************************\
675 * Internal functions for breakpoint table manipulation *
676 \***************************************************************************/
678 static void deletewatchnode(WatchNode
**prevp
)
679 { WatchNode
*p
= *prevp
;
680 if (p
->datatype
& Watch_AnyRead
) state
->MemReadDebug
--;
681 if (p
->datatype
& Watch_AnyWrite
) state
->MemWriteDebug
--;
686 int removewatch(ARMword address
, unsigned type
)
687 { WatchNode
*p
, **prevp
= &WatchList
;
688 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
689 if (p
->address
== address
&& p
->type
== type
) { /* found a match */
690 deletewatchnode(prevp
);
693 return FALSE
; /* never found a match */
696 static WatchNode
*installwatch(ARMword address
, unsigned type
, unsigned datatype
,
698 { WatchNode
*p
= (WatchNode
*)malloc(sizeof(WatchNode
));
701 p
->address
= address
;
703 p
->datatype
= datatype
;
708 /***************************************************************************\
710 \***************************************************************************/
712 static int RDI_setwatch(ARMword address
, unsigned type
, unsigned datatype
,
713 ARMword bound
, PointHandle
*handle
)
715 TracePrint((state
, "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
716 address
, type
, datatype
, bound
));
718 if (!state
->CanWatch
) return RDIError_UnimplementedMessage
;
720 removewatch(address
, type
);
721 p
= installwatch(address
, type
, datatype
, bound
);
722 if (datatype
& Watch_AnyRead
) state
->MemReadDebug
++;
723 if (datatype
& Watch_AnyWrite
) state
->MemWriteDebug
++;
724 *handle
= (PointHandle
)p
;
725 TracePrint((state
, " returns %.8lx\n", *handle
));
726 return RDIError_NoError
;
729 /***************************************************************************\
731 \***************************************************************************/
733 static int RDI_clearwatch(PointHandle handle
)
734 { TracePrint((state
, "RDI_clearwatch: address=%.8lx\n", handle
));
735 { WatchNode
*p
, **prevp
= &WatchList
;
736 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
737 if (p
== (WatchNode
*)handle
) break;
738 if (p
== NULL
) return RDIError_NoSuchPoint
;
739 deletewatchnode(prevp
);
740 return RDIError_NoError
;
744 /***************************************************************************\
746 \***************************************************************************/
748 static int RDI_execute(PointHandle
*handle
)
750 TracePrint((state
, "RDI_execute\n"));
753 state
->Debug
= TRUE
;
755 state
->EndCondition
= RDIError_NoError
;
756 state
->StopHandle
= 0;
760 *handle
= state
->StopHandle
;
761 state
->Reg
[15] -= 8 ; /* undo the pipeline */
764 state
->Debug
= FALSE
;
766 return(state
->EndCondition
) ;
769 /***************************************************************************\
771 \***************************************************************************/
773 static int RDI_step(unsigned ninstr
, PointHandle
*handle
)
776 TracePrint((state
, "RDI_step\n"));
777 if (ninstr
!= 1) return RDIError_UnimplementedMessage
;
780 state
->Debug
= TRUE
;
782 state
->EndCondition
= RDIError_NoError
;
783 state
->StopHandle
= 0;
784 ARMul_DoInstr(state
) ;
785 *handle
= state
->StopHandle
;
786 state
->Reg
[15] -= 8 ; /* undo the pipeline */
789 state
->Debug
= FALSE
;
791 return(state
->EndCondition
) ;
794 /***************************************************************************\
796 \***************************************************************************/
798 static int RDI_info(unsigned type
, ARMword
*arg1
, ARMword
*arg2
)
802 TracePrint((state
, "RDI_Info_Target\n"));
803 /* Emulator, speed 10**5 IPS */
804 *arg1
= 5 | HIGHEST_RDI_LEVEL
<< 5 | LOWEST_RDI_LEVEL
<< 8;
806 return RDIError_NoError
;
809 { ARMword n
= RDIPointCapability_Comparison
| RDIPointCapability_Range
|
810 RDIPointCapability_Mask
| RDIPointCapability_Status
;
811 TracePrint((state
, "RDI_Info_Points\n"));
812 if (state
->CanWatch
) n
|= (Watch_AnyRead
+Watch_AnyWrite
) << 2;
814 return RDIError_NoError
;
818 TracePrint((state
, "RDI_Info_Step\n"));
819 *arg1
= RDIStep_Single
;
820 return RDIError_NoError
;
823 TracePrint((state
, "RDI_Info_MMU\n"));
825 return RDIError_NoError
;
828 TracePrint((state
, "RDISignal_Stop\n"));
830 state
->EndCondition
= RDIError_UserInterrupt
;
831 return RDIError_NoError
;
833 case RDIVector_Catch
:
834 TracePrint((state
, "RDIVector_Catch %.8lx\n", *arg1
));
835 state
->VectorCatch
= (unsigned)*arg1
;
836 return RDIError_NoError
;
839 TracePrint((state
, "RDI_Set_Cmdline %s\n", (char *)arg1
));
840 state
->CommandLine
= (char *)malloc((unsigned)strlen((char *)arg1
)+1) ;
841 (void)strcpy(state
->CommandLine
,(char *)arg1
) ;
842 return RDIError_NoError
;
845 TracePrint((state
, "RDI_Info_Cycles\n"));
847 arg1
[1] = state
->NumInstrs
;
849 arg1
[3] = state
->NumScycles
;
851 arg1
[5] = state
->NumNcycles
;
853 arg1
[7] = state
->NumIcycles
;
855 arg1
[9] = state
->NumCcycles
;
857 arg1
[11] = state
->NumFcycles
;
858 return RDIError_NoError
;
861 *arg1
= ARMul_OSLastErrorP(state
);
862 TracePrint((state
, "RDI_ErrorP returns %ld\n", *arg1
));
863 return RDIError_NoError
;
865 case RDIInfo_DescribeCoPro
:
866 { int cpnum
= *(int *)arg1
;
867 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*)arg2
;
869 unsigned char const *map
= state
->CPRegWords
[cpnum
];
870 if (map
== NULL
) return RDIError_UnknownCoPro
;
871 for (i
= 0; i
< cpd
->entries
; i
++) {
872 unsigned r
, w
= cpd
->regdesc
[i
].nbytes
/ sizeof(ARMword
);
873 for (r
= cpd
->regdesc
[i
].rmin
; r
<= cpd
->regdesc
[i
].rmax
; r
++)
874 if (map
[r
] != w
) return RDIError_BadCoProState
;
876 return RDIError_NoError
;
879 case RDIInfo_RequestCoProDesc
:
880 { int cpnum
= *(int *)arg1
;
881 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*)arg2
;
882 int i
= -1, lastw
= -1, r
;
883 unsigned char const *map
;
884 if ((unsigned)cpnum
>= 16) return RDIError_UnknownCoPro
;
885 map
= state
->CPRegWords
[cpnum
];
886 if (map
== NULL
) return RDIError_UnknownCoPro
;
887 for (r
= 0; r
< map
[-1]; r
++) {
890 cpd
->regdesc
[i
].rmax
= r
;
892 if (++i
>= cpd
->entries
) return RDIError_BufferFull
;
893 cpd
->regdesc
[i
].rmax
= cpd
->regdesc
[i
].rmin
= r
;
894 cpd
->regdesc
[i
].nbytes
= words
* sizeof(ARMword
);
895 cpd
->regdesc
[i
].access
= Dbg_Access_Readable
+Dbg_Access_Writable
;
899 return RDIError_NoError
;
903 *arg1
= (ARMword
)rdi_log
;
904 return RDIError_NoError
;
907 rdi_log
= (int)*arg1
;
908 return RDIError_NoError
;
911 return RDIError_NoError
;
913 case RDIPointStatus_Watch
:
914 { WatchNode
*p
, *handle
= (WatchNode
*)*arg1
;
915 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
919 return RDIError_NoError
;
921 return RDIError_NoSuchPoint
;
924 case RDIPointStatus_Break
:
925 { BreakNode
*p
, *handle
= (BreakNode
*)*arg1
;
926 for (p
= BreakList
; p
!= NULL
; p
= p
->next
)
930 return RDIError_NoError
;
932 return RDIError_NoSuchPoint
;
935 case RDISet_RDILevel
:
936 if (*arg1
< LOWEST_RDI_LEVEL
|| *arg1
> HIGHEST_RDI_LEVEL
)
937 return RDIError_IncompatibleRDILevels
;
939 return RDIError_NoError
;
942 return RDIError_UnimplementedMessage
;
947 /***************************************************************************\
948 * The emulator calls this routine at the beginning of every cycle when the *
949 * CallDebug flag is set. The second parameter passed is the address of the *
950 * currently executing instruction (i.e Program Counter - 8), the third *
951 * parameter is the instruction being executed. *
952 \***************************************************************************/
954 ARMword
ARMul_Debug(ARMul_State
*state
, ARMword pc
, ARMword instr
)
957 if (state
->EndCondition
== RDIError_UserInterrupt
) {
958 TracePrint((state
, "User interrupt at %.8lx\n", pc
));
960 state
->Emulate
= STOP
;
962 BreakNode
*p
= BreakList
;
963 for (; p
!= NULL
; p
= p
->next
) {
965 case RDIPoint_EQ
: if (pc
== p
->address
) break; continue;
966 case RDIPoint_GT
: if (pc
> p
->address
) break; continue;
967 case RDIPoint_GE
: if (pc
>= p
->address
) break; continue;
968 case RDIPoint_LT
: if (pc
< p
->address
) break; continue;
969 case RDIPoint_LE
: if (pc
<= p
->address
) break; continue;
970 case RDIPoint_IN
: if (p
->address
<= pc
&& pc
< p
->address
+p
->bound
) break;
972 case RDIPoint_OUT
:if (p
->address
> pc
|| pc
>= p
->address
+p
->bound
) break;
974 case RDIPoint_MASK
:if ((pc
& p
->bound
) == p
->address
) break; continue;
977 TracePrint((state
, "Breakpoint reached at %.8lx\n", pc
));
978 state
->EndCondition
= RDIError_BreakpointReached
;
979 state
->Emulate
= STOP
;
980 state
->StopHandle
= (ARMword
)p
;
987 void ARMul_CheckWatch(ARMul_State
*state
, ARMword addr
, int access
)
989 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
990 if (p
->datatype
& access
) {
992 case RDIPoint_EQ
: if (addr
== p
->address
) break; continue;
993 case RDIPoint_GT
: if (addr
> p
->address
) break; continue;
994 case RDIPoint_GE
: if (addr
>= p
->address
) break; continue;
995 case RDIPoint_LT
: if (addr
< p
->address
) break; continue;
996 case RDIPoint_LE
: if (addr
<= p
->address
) break; continue;
997 case RDIPoint_IN
: if (p
->address
<= addr
&& addr
< p
->address
+p
->bound
) break;
999 case RDIPoint_OUT
:if (p
->address
> addr
|| addr
>= p
->address
+p
->bound
) break;
1001 case RDIPoint_MASK
:if ((addr
& p
->bound
) == p
->address
) break; continue;
1004 TracePrint((state
, "Watchpoint at %.8lx accessed\n", addr
));
1005 state
->EndCondition
= RDIError_WatchpointAccessed
;
1006 state
->Emulate
= STOP
;
1007 state
->StopHandle
= (ARMword
)p
;
1012 static RDI_NameList
const *RDI_cpunames() {
1013 return (RDI_NameList
const *)&processorconfig
.count
;
1016 const struct RDIProcVec armul_rdi
= {
1036 0, /*loadconfigdata*/