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
;
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
);
135 /* while ((ch=*str++) != 0) */
136 /* state->hostif->writec(state->hostif->hostosarg, ch); */
139 void ARMul_DebugPause(ARMul_State
*state
)
142 state
->hostif
->dbgpause(state
->hostif
->dbgarg
);
145 /***************************************************************************\
147 \***************************************************************************/
149 static void InitFail(int exitcode
, char const *which
) {
150 ARMul_ConsolePrint(state
, "%s interface failed to initialise. Exiting\n",
155 static void RDIInit(unsigned type
)
156 {if (type
== 0) { /* cold start */
157 state
->CallDebug
= state
->MemReadDebug
= state
->MemWriteDebug
= 0 ;
162 #define UNKNOWNPROC 0
164 typedef struct { char name
[16]; unsigned val
; } Processor
;
166 Processor
const p_arm2
= {"ARM2", ARM2
};
167 Processor
const p_arm2as
= {"ARM2AS", ARM2as
};
168 Processor
const p_arm61
= {"ARM61", ARM61
};
169 Processor
const p_arm3
= {"ARM3", ARM3
};
170 Processor
const p_arm6
= {"ARM6", ARM6
};
171 Processor
const p_arm60
= {"ARM60", ARM60
};
172 Processor
const p_arm600
= {"ARM600", ARM600
};
173 Processor
const p_arm610
= {"ARM610", ARM610
};
174 Processor
const p_arm620
= {"ARM620", ARM620
};
175 Processor
const p_unknown
= {"", UNKNOWNPROC
};
177 Processor
const *const processors
[] = {
178 &p_arm6
, /* default: must come first */
190 typedef struct ProcessorConfig ProcessorConfig
;
191 struct ProcessorConfig
{
193 ProcessorConfig
const *self
;
195 Processor
const * const *processors
;
198 ProcessorConfig
const processorconfig
= {
199 { ((((((long)'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
200 ((((((long)'u' << 8) | 's') << 8) | ' ') << 8) | 'x'
207 static int RDI_open(unsigned type
, const Dbg_ConfigBlock
*config
,
208 const Dbg_HostosInterface
*hostif
,
209 struct Dbg_MCState
*dbg_state
)
210 /* Initialise everything */
211 {int virgin
= (state
== NULL
);
217 ARMul_DebugPrint_i(hostif
, "RDI_open: type = %d\n",type
) ;
219 ARMul_DebugPrint(state
, "RDI_open: type = %d\n",type
) ;
223 if (type
& 1) { /* Warm start */
230 state
= ARMul_NewState();
231 state
->hostif
= hostif
;
232 { int req
= config
->processor
;
233 unsigned processor
= processors
[req
]->val
;
234 ARMul_SelectProcessor(state
, processor
);
236 ARMul_ConsolePrint(state
, "ARMulator V1.50, %s", processors
[req
]->name
);
238 if (ARMul_MemoryInit(state
,config
->memorysize
) == FALSE
)
239 InitFail(1, "Memory");
240 if (config
->bytesex
!= RDISex_DontCare
)
241 state
->bigendSig
= config
->bytesex
;
242 if (ARMul_CoProInit(state
) == FALSE
)
243 InitFail(2, "Co-Processor");
244 if (ARMul_OSInit(state
) == FALSE
)
245 InitFail(3, "Operating System");
250 if (type
& 2) { /* Reset the comms link */
251 /* what comms link ? */
253 if (virgin
&& (type
& 1) == 0) /* Cold start */
254 ARMul_ConsolePrint(state
, ", %s endian.\n",
255 state
->bigendSig
? "Big" : "Little");
257 if (config
->bytesex
== RDISex_DontCare
)
258 return(state
->bigendSig
? RDIError_BigEndian
: RDIError_LittleEndian
);
260 return(RDIError_NoError
) ;
263 /***************************************************************************\
265 \***************************************************************************/
267 static int RDI_close(void)
269 TracePrint((state
, "RDI_close\n"));
270 ARMul_OSExit(state
) ;
271 ARMul_CoProExit(state
) ;
272 ARMul_MemoryExit(state
) ;
273 return(RDIError_NoError
) ;
276 /***************************************************************************\
278 \***************************************************************************/
280 static int RDI_read(ARMword source
, void *dest
, unsigned *nbytes
)
282 char *memptr
= (char *)dest
;
284 TracePrint((state
, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
285 source
, dest
, *nbytes
));
287 for (i
=0 ; i
< *nbytes
; i
++)
288 *memptr
++ = (char)ARMul_ReadByte(state
,source
++) ;
289 if (state
->abortSig
) {
290 state
->abortSig
= LOW
;
291 return(RDIError_DataAbort
) ;
293 return(RDIError_NoError
) ;
296 /***************************************************************************\
298 \***************************************************************************/
300 static int RDI_write(const void *source
, ARMword dest
, unsigned *nbytes
)
302 char *memptr
= (char *)source
;
304 TracePrint((state
, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
305 source
, dest
, *nbytes
));
307 for (i
=0 ; i
< *nbytes
; i
++)
308 ARMul_WriteByte(state
,(ARMword
)dest
++,(ARMword
)*memptr
++) ;
310 if (state
->abortSig
) {
311 state
->abortSig
= LOW
;
312 return(RDIError_DataAbort
) ;
314 return(RDIError_NoError
) ;
317 /***************************************************************************\
319 \***************************************************************************/
321 static int RDI_CPUread(unsigned mode
, unsigned long mask
, ARMword buffer
[])
324 if (mode
== RDIMode_Curr
)
325 mode
= (unsigned)(ARMul_GetCPSR(state
) & MODEBITS
) ;
327 for (upto
= 0, i
= 0 ; i
< 15 ; i
++)
328 if (mask
& (1L << i
)){
329 buffer
[upto
++] = ARMul_GetReg(state
,mode
,i
) ;
332 if (mask
& RDIReg_R15
) {
333 buffer
[upto
++] = ARMul_GetR15(state
) ;
336 if (mask
& RDIReg_PC
) {
337 buffer
[upto
++] = ARMul_GetPC(state
) ;
340 if (mask
& RDIReg_CPSR
)
341 buffer
[upto
++] = ARMul_GetCPSR(state
) ;
343 if (mask
& RDIReg_SPSR
)
344 buffer
[upto
++] = ARMul_GetSPSR(state
,mode
) ;
346 TracePrint((state
, "RDI_CPUread: mode=%.8x mask=%.8lx", mode
, mask
));
349 for (upto
= 0, i
= 0 ; i
<= 20 ; i
++)
350 if (mask
& (1L << i
)) {
351 ARMul_DebugPrint(state
, "%c%.8lx",upto
%4==0?'\n':' ',buffer
[upto
]) ;
354 ARMul_DebugPrint(state
, "\n") ;
358 return(RDIError_NoError
) ;
361 /***************************************************************************\
363 \***************************************************************************/
365 static int RDI_CPUwrite(unsigned mode
, unsigned long mask
, ARMword
const buffer
[])
369 TracePrint((state
, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode
, mask
));
372 for (upto
= 0, i
= 0 ; i
<= 20 ; i
++)
373 if (mask
& (1L << i
)) {
374 ARMul_DebugPrint(state
, "%c%.8lx",upto
%4==0?'\n':' ',buffer
[upto
]) ;
377 ARMul_DebugPrint(state
, "\n") ;
381 if (mode
== RDIMode_Curr
)
382 mode
= (unsigned)(ARMul_GetCPSR(state
) & MODEBITS
) ;
384 for (upto
= 0, i
= 0 ; i
< 15 ; i
++)
385 if (mask
& (1L << i
))
386 ARMul_SetReg(state
,mode
,i
,buffer
[upto
++]) ;
388 if (mask
& RDIReg_R15
)
389 ARMul_SetR15(state
,buffer
[upto
++]) ;
391 if (mask
& RDIReg_PC
) {
393 ARMul_SetPC(state
,buffer
[upto
++]) ;
395 if (mask
& RDIReg_CPSR
)
396 ARMul_SetCPSR(state
,buffer
[upto
++]) ;
398 if (mask
& RDIReg_SPSR
)
399 ARMul_SetSPSR(state
,mode
,buffer
[upto
++]) ;
401 return(RDIError_NoError
) ;
404 /***************************************************************************\
406 \***************************************************************************/
408 static int RDI_CPread(unsigned CPnum
, unsigned long mask
, ARMword buffer
[])
409 {ARMword fpregsaddr
, word
[4] ;
414 if (CPnum
!= 1 && CPnum
!= 2) {
415 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
417 return(RDIError_UnknownCoPro
) ;
418 for (upto
= 0, r
= 0 ; r
< rmap
[-1] ; r
++)
419 if (mask
& (1L << r
)) {
420 (void)state
->CPRead
[CPnum
](state
, r
, &buffer
[upto
]);
423 TracePrint((state
, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum
, mask
));
427 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
428 if (mask
& (1L << r
)) {
430 ARMul_DebugPrint(state
, "%c%2d", (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
431 while (--words
>= 0) {
432 ARMul_DebugPrint(state
, " %.8lx", buffer
[upto
++]);
436 ARMul_DebugPrint(state
, "\n") ;
439 return RDIError_NoError
;
443 return RDIError_UnknownCoPro
;
446 if (FPRegsAddr
== 0) {
447 fpregsaddr
= ARMul_ReadWord(state
, 4L) ;
448 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
449 return RDIError_UnknownCoPro
;
450 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8 ; /* address in __fp_decode - 4 */
451 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
452 return RDIError_UnknownCoPro
;
453 fpregsaddr
= ARMul_ReadWord(state
, fpregsaddr
) ; /* pointer to fp registers */
454 FPRegsAddr
= fpregsaddr
;
457 fpregsaddr
= FPRegsAddr
;
459 if (fpregsaddr
== 0) return RDIError_UnknownCoPro
;
460 for (upto
= 0, r
= 0 ; r
< 8 ; r
++)
461 if (mask
& (1L << r
)) {
462 for (w
= 0 ; w
< 4 ; w
++)
463 word
[w
] = ARMul_ReadWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + (ARMword
)w
* 4) ;
464 switch ((int)(word
[3] >> 29)) {
468 case 6 : /* its unpacked, convert to extended */
469 buffer
[upto
++] = 2 ; /* mark as extended */
470 buffer
[upto
++] = (word
[3] & 0x7fff) | (word
[0] & 0x80000000) ; /* exp and sign */
471 buffer
[upto
++] = word
[1] ; /* mantissa 1 */
472 buffer
[upto
++] = word
[2] ; /* mantissa 2 */
474 case 1 : /* packed single */
475 buffer
[upto
++] = 0 ; /* mark as single */
476 buffer
[upto
++] = word
[0] ; /* sign, exp and mantissa */
477 buffer
[upto
++] = word
[1] ; /* padding */
478 buffer
[upto
++] = word
[2] ; /* padding */
480 case 3 : /* packed double */
481 buffer
[upto
++] = 1 ; /* mark as double */
482 buffer
[upto
++] = word
[0] ; /* sign, exp and mantissa1 */
483 buffer
[upto
++] = word
[1] ; /* mantissa 2 */
484 buffer
[upto
++] = word
[2] ; /* padding */
486 case 5 : /* packed extended */
487 buffer
[upto
++] = 2 ; /* mark as extended */
488 buffer
[upto
++] = word
[0] ; /* sign and exp */
489 buffer
[upto
++] = word
[1] ; /* mantissa 1 */
490 buffer
[upto
++] = word
[2] ; /* mantissa 2 */
492 case 7 : /* packed decimal */
493 buffer
[upto
++] = 3 ; /* mark as packed decimal */
494 buffer
[upto
++] = word
[0] ; /* sign, exp and mantissa1 */
495 buffer
[upto
++] = word
[1] ; /* mantissa 2 */
496 buffer
[upto
++] = word
[2] ; /* mantissa 3 */
500 if (mask
& (1L << r
))
501 buffer
[upto
++] = ARMul_ReadWord(state
,fpregsaddr
+ 128) ; /* fpsr */
502 if (mask
& (1L << (r
+1) ))
503 buffer
[upto
++] = 0 ; /* fpcr */
505 TracePrint((state
, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum
, mask
));
508 for (upto
= 0, r
= 0 ; r
< 9 ; r
++)
509 if (mask
& (1L << r
)) {
511 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
512 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
513 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
515 ARMul_DebugPrint(state
, "%08lx\n",buffer
[upto
++]) ;
517 ARMul_DebugPrint(state
, "\n") ;
520 return(RDIError_NoError
) ;
524 /***************************************************************************\
526 \***************************************************************************/
528 static int RDI_CPwrite(unsigned CPnum
, unsigned long mask
, ARMword
const buffer
[])
533 if (CPnum
!= 1 && CPnum
!= 2) {
534 unsigned char const *rmap
= state
->CPRegWords
[CPnum
];
536 return(RDIError_UnknownCoPro
) ;
537 TracePrint((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
541 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
542 if (mask
& (1L << r
)) {
544 ARMul_DebugPrint(state
, "%c%2d", (w
>= 4 ? (w
= 0, '\n') : ' '), r
);
545 while (--words
>= 0) {
546 ARMul_DebugPrint(state
, " %.8lx", buffer
[upto
++]);
550 ARMul_DebugPrint(state
, "\n") ;
553 for (upto
= 0, r
= 0; r
< rmap
[-1]; r
++)
554 if (mask
& (1L << r
)) {
555 (void)state
->CPWrite
[CPnum
](state
, r
, &buffer
[upto
]);
558 return RDIError_NoError
;
562 return RDIError_UnknownCoPro
;
565 TracePrint((state
, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum
, mask
));
568 for (upto
= 0, r
= 0 ; r
< 9 ; r
++)
569 if (mask
& (1L << r
)) {
571 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
572 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
573 ARMul_DebugPrint(state
, "%08lx ",buffer
[upto
++]) ;
575 ARMul_DebugPrint(state
, "%08lx\n",buffer
[upto
++]) ;
577 ARMul_DebugPrint(state
, "\n") ;
581 if (FPRegsAddr
== 0) {
582 fpregsaddr
= ARMul_ReadWord(state
, 4L) ;
583 if ((fpregsaddr
& 0xff800000) != 0xea000000) /* Must be a forward branch */
584 return RDIError_UnknownCoPro
;
585 fpregsaddr
= ((fpregsaddr
& 0xffffff) << 2) + 8 ; /* address in __fp_decode - 4 */
586 if ((fpregsaddr
< FPESTART
) || (fpregsaddr
>= FPEEND
))
587 return RDIError_UnknownCoPro
;
588 fpregsaddr
= ARMul_ReadWord(state
, fpregsaddr
) ; /* pointer to fp registers */
589 FPRegsAddr
= fpregsaddr
;
592 fpregsaddr
= FPRegsAddr
;
594 if (fpregsaddr
== 0) return RDIError_UnknownCoPro
;
595 for (upto
= 0, r
= 0 ; r
< 8 ; r
++)
596 if (mask
& (1L << r
)) {
597 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16,buffer
[upto
+1]) ;
598 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + 4,buffer
[upto
+2]) ;
599 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + 8,buffer
[upto
+3]) ;
600 ARMul_WriteWord(state
,fpregsaddr
+ (ARMword
)r
* 16 + 12,(buffer
[upto
] * 2 + 1) << 29) ; /* mark type */
603 if (mask
& (1L << r
))
604 ARMul_WriteWord(state
,fpregsaddr
+ 128,buffer
[upto
++]) ; /* fpsr */
605 return(RDIError_NoError
) ;
609 static void deletebreaknode(BreakNode
**prevp
) {
610 BreakNode
*p
= *prevp
;
612 ARMul_WriteWord(state
, p
->address
, p
->inst
);
618 static int removebreak(ARMword address
, unsigned type
)
619 { BreakNode
*p
, **prevp
= &BreakList
;
620 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
621 if (p
->address
== address
&& p
->type
== type
) {
622 deletebreaknode(prevp
);
628 /* This routine installs a breakpoint into the breakpoint table */
630 static BreakNode
*installbreak(ARMword address
, unsigned type
, ARMword bound
)
631 { BreakNode
*p
= (BreakNode
*)malloc(sizeof(BreakNode
));
634 p
->address
= address
;
637 p
->inst
= ARMul_ReadWord(state
, address
);
638 ARMul_WriteWord(state
, address
, 0xee000000L
);
642 /***************************************************************************\
644 \***************************************************************************/
646 static int RDI_setbreak(ARMword address
, unsigned type
, ARMword bound
,
649 TracePrint((state
, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
650 address
, type
, bound
));
652 removebreak(address
, type
);
653 p
= installbreak(address
, type
, bound
);
656 *handle
= (PointHandle
)p
;
657 TracePrint((state
, " returns %.8lx\n", *handle
));
658 return RDIError_NoError
;
661 /***************************************************************************\
663 \***************************************************************************/
665 static int RDI_clearbreak(PointHandle handle
)
666 { TracePrint((state
, "RDI_clearbreak: address=%.8lx\n", handle
));
667 { BreakNode
*p
, **prevp
= &BreakList
;
668 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
669 if (p
== (BreakNode
*)handle
) break;
670 if (p
== NULL
) return RDIError_NoSuchPoint
;
671 deletebreaknode(prevp
);
672 return RDIError_NoError
;
676 /***************************************************************************\
677 * Internal functions for breakpoint table manipulation *
678 \***************************************************************************/
680 static void deletewatchnode(WatchNode
**prevp
)
681 { WatchNode
*p
= *prevp
;
682 if (p
->datatype
& Watch_AnyRead
) state
->MemReadDebug
--;
683 if (p
->datatype
& Watch_AnyWrite
) state
->MemWriteDebug
--;
688 int removewatch(ARMword address
, unsigned type
)
689 { WatchNode
*p
, **prevp
= &WatchList
;
690 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
691 if (p
->address
== address
&& p
->type
== type
) { /* found a match */
692 deletewatchnode(prevp
);
695 return FALSE
; /* never found a match */
698 static WatchNode
*installwatch(ARMword address
, unsigned type
, unsigned datatype
,
700 { WatchNode
*p
= (WatchNode
*)malloc(sizeof(WatchNode
));
703 p
->address
= address
;
705 p
->datatype
= datatype
;
710 /***************************************************************************\
712 \***************************************************************************/
714 static int RDI_setwatch(ARMword address
, unsigned type
, unsigned datatype
,
715 ARMword bound
, PointHandle
*handle
)
717 TracePrint((state
, "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
718 address
, type
, datatype
, bound
));
720 if (!state
->CanWatch
) return RDIError_UnimplementedMessage
;
722 removewatch(address
, type
);
723 p
= installwatch(address
, type
, datatype
, bound
);
724 if (datatype
& Watch_AnyRead
) state
->MemReadDebug
++;
725 if (datatype
& Watch_AnyWrite
) state
->MemWriteDebug
++;
726 *handle
= (PointHandle
)p
;
727 TracePrint((state
, " returns %.8lx\n", *handle
));
728 return RDIError_NoError
;
731 /***************************************************************************\
733 \***************************************************************************/
735 static int RDI_clearwatch(PointHandle handle
)
736 { TracePrint((state
, "RDI_clearwatch: address=%.8lx\n", handle
));
737 { WatchNode
*p
, **prevp
= &WatchList
;
738 for (; (p
= *prevp
) != NULL
; prevp
= &p
->next
)
739 if (p
== (WatchNode
*)handle
) break;
740 if (p
== NULL
) return RDIError_NoSuchPoint
;
741 deletewatchnode(prevp
);
742 return RDIError_NoError
;
746 /***************************************************************************\
748 \***************************************************************************/
750 static int RDI_execute(PointHandle
*handle
)
752 TracePrint((state
, "RDI_execute\n"));
755 state
->Debug
= TRUE
;
757 state
->EndCondition
= RDIError_NoError
;
758 state
->StopHandle
= 0;
762 *handle
= state
->StopHandle
;
763 state
->Reg
[15] -= 8 ; /* undo the pipeline */
766 state
->Debug
= FALSE
;
768 return(state
->EndCondition
) ;
771 /***************************************************************************\
773 \***************************************************************************/
775 static int RDI_step(unsigned ninstr
, PointHandle
*handle
)
778 TracePrint((state
, "RDI_step\n"));
779 if (ninstr
!= 1) return RDIError_UnimplementedMessage
;
782 state
->Debug
= TRUE
;
784 state
->EndCondition
= RDIError_NoError
;
785 state
->StopHandle
= 0;
786 ARMul_DoInstr(state
) ;
787 *handle
= state
->StopHandle
;
788 state
->Reg
[15] -= 8 ; /* undo the pipeline */
791 state
->Debug
= FALSE
;
793 return(state
->EndCondition
) ;
796 /***************************************************************************\
798 \***************************************************************************/
800 static int RDI_info(unsigned type
, ARMword
*arg1
, ARMword
*arg2
)
804 TracePrint((state
, "RDI_Info_Target\n"));
805 /* Emulator, speed 10**5 IPS */
806 *arg1
= 5 | HIGHEST_RDI_LEVEL
<< 5 | LOWEST_RDI_LEVEL
<< 8;
808 return RDIError_NoError
;
811 { ARMword n
= RDIPointCapability_Comparison
| RDIPointCapability_Range
|
812 RDIPointCapability_Mask
| RDIPointCapability_Status
;
813 TracePrint((state
, "RDI_Info_Points\n"));
814 if (state
->CanWatch
) n
|= (Watch_AnyRead
+Watch_AnyWrite
) << 2;
816 return RDIError_NoError
;
820 TracePrint((state
, "RDI_Info_Step\n"));
821 *arg1
= RDIStep_Single
;
822 return RDIError_NoError
;
825 TracePrint((state
, "RDI_Info_MMU\n"));
827 return RDIError_NoError
;
830 TracePrint((state
, "RDISignal_Stop\n"));
832 state
->EndCondition
= RDIError_UserInterrupt
;
833 return RDIError_NoError
;
835 case RDIVector_Catch
:
836 TracePrint((state
, "RDIVector_Catch %.8lx\n", *arg1
));
837 state
->VectorCatch
= (unsigned)*arg1
;
838 return RDIError_NoError
;
841 TracePrint((state
, "RDI_Set_Cmdline %s\n", (char *)arg1
));
842 state
->CommandLine
= (char *)malloc((unsigned)strlen((char *)arg1
)+1) ;
843 (void)strcpy(state
->CommandLine
,(char *)arg1
) ;
844 return RDIError_NoError
;
847 TracePrint((state
, "RDI_Info_Cycles\n"));
849 arg1
[1] = state
->NumInstrs
;
851 arg1
[3] = state
->NumScycles
;
853 arg1
[5] = state
->NumNcycles
;
855 arg1
[7] = state
->NumIcycles
;
857 arg1
[9] = state
->NumCcycles
;
859 arg1
[11] = state
->NumFcycles
;
860 return RDIError_NoError
;
863 *arg1
= ARMul_OSLastErrorP(state
);
864 TracePrint((state
, "RDI_ErrorP returns %ld\n", *arg1
));
865 return RDIError_NoError
;
867 case RDIInfo_DescribeCoPro
:
868 { int cpnum
= *(int *)arg1
;
869 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*)arg2
;
871 unsigned char const *map
= state
->CPRegWords
[cpnum
];
872 if (map
== NULL
) return RDIError_UnknownCoPro
;
873 for (i
= 0; i
< cpd
->entries
; i
++) {
874 unsigned r
, w
= cpd
->regdesc
[i
].nbytes
/ sizeof(ARMword
);
875 for (r
= cpd
->regdesc
[i
].rmin
; r
<= cpd
->regdesc
[i
].rmax
; r
++)
876 if (map
[r
] != w
) return RDIError_BadCoProState
;
878 return RDIError_NoError
;
881 case RDIInfo_RequestCoProDesc
:
882 { int cpnum
= *(int *)arg1
;
883 struct Dbg_CoProDesc
*cpd
= (struct Dbg_CoProDesc
*)arg2
;
884 int i
= -1, lastw
= -1, r
;
885 unsigned char const *map
;
886 if ((unsigned)cpnum
>= 16) return RDIError_UnknownCoPro
;
887 map
= state
->CPRegWords
[cpnum
];
888 if (map
== NULL
) return RDIError_UnknownCoPro
;
889 for (r
= 0; r
< map
[-1]; r
++) {
892 cpd
->regdesc
[i
].rmax
= r
;
894 if (++i
>= cpd
->entries
) return RDIError_BufferFull
;
895 cpd
->regdesc
[i
].rmax
= cpd
->regdesc
[i
].rmin
= r
;
896 cpd
->regdesc
[i
].nbytes
= words
* sizeof(ARMword
);
897 cpd
->regdesc
[i
].access
= Dbg_Access_Readable
+Dbg_Access_Writable
;
901 return RDIError_NoError
;
905 *arg1
= (ARMword
)rdi_log
;
906 return RDIError_NoError
;
909 rdi_log
= (int)*arg1
;
910 return RDIError_NoError
;
913 return RDIError_NoError
;
915 case RDIPointStatus_Watch
:
916 { WatchNode
*p
, *handle
= (WatchNode
*)*arg1
;
917 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
921 return RDIError_NoError
;
923 return RDIError_NoSuchPoint
;
926 case RDIPointStatus_Break
:
927 { BreakNode
*p
, *handle
= (BreakNode
*)*arg1
;
928 for (p
= BreakList
; p
!= NULL
; p
= p
->next
)
932 return RDIError_NoError
;
934 return RDIError_NoSuchPoint
;
937 case RDISet_RDILevel
:
938 if (*arg1
< LOWEST_RDI_LEVEL
|| *arg1
> HIGHEST_RDI_LEVEL
)
939 return RDIError_IncompatibleRDILevels
;
941 return RDIError_NoError
;
944 return RDIError_UnimplementedMessage
;
949 /***************************************************************************\
950 * The emulator calls this routine at the beginning of every cycle when the *
951 * CallDebug flag is set. The second parameter passed is the address of the *
952 * currently executing instruction (i.e Program Counter - 8), the third *
953 * parameter is the instruction being executed. *
954 \***************************************************************************/
956 ARMword
ARMul_Debug(ARMul_State
*state
, ARMword pc
, ARMword instr
)
959 if (state
->EndCondition
== RDIError_UserInterrupt
) {
960 TracePrint((state
, "User interrupt at %.8lx\n", pc
));
962 state
->Emulate
= STOP
;
964 BreakNode
*p
= BreakList
;
965 for (; p
!= NULL
; p
= p
->next
) {
967 case RDIPoint_EQ
: if (pc
== p
->address
) break; continue;
968 case RDIPoint_GT
: if (pc
> p
->address
) break; continue;
969 case RDIPoint_GE
: if (pc
>= p
->address
) break; continue;
970 case RDIPoint_LT
: if (pc
< p
->address
) break; continue;
971 case RDIPoint_LE
: if (pc
<= p
->address
) break; continue;
972 case RDIPoint_IN
: if (p
->address
<= pc
&& pc
< p
->address
+p
->bound
) break;
974 case RDIPoint_OUT
:if (p
->address
> pc
|| pc
>= p
->address
+p
->bound
) break;
976 case RDIPoint_MASK
:if ((pc
& p
->bound
) == p
->address
) break; continue;
979 TracePrint((state
, "Breakpoint reached at %.8lx\n", pc
));
980 state
->EndCondition
= RDIError_BreakpointReached
;
981 state
->Emulate
= STOP
;
982 state
->StopHandle
= (ARMword
)p
;
989 void ARMul_CheckWatch(ARMul_State
*state
, ARMword addr
, int access
)
991 for (p
= WatchList
; p
!= NULL
; p
= p
->next
)
992 if (p
->datatype
& access
) {
994 case RDIPoint_EQ
: if (addr
== p
->address
) break; continue;
995 case RDIPoint_GT
: if (addr
> p
->address
) break; continue;
996 case RDIPoint_GE
: if (addr
>= p
->address
) break; continue;
997 case RDIPoint_LT
: if (addr
< p
->address
) break; continue;
998 case RDIPoint_LE
: if (addr
<= p
->address
) break; continue;
999 case RDIPoint_IN
: if (p
->address
<= addr
&& addr
< p
->address
+p
->bound
) break;
1001 case RDIPoint_OUT
:if (p
->address
> addr
|| addr
>= p
->address
+p
->bound
) break;
1003 case RDIPoint_MASK
:if ((addr
& p
->bound
) == p
->address
) break; continue;
1006 TracePrint((state
, "Watchpoint at %.8lx accessed\n", addr
));
1007 state
->EndCondition
= RDIError_WatchpointAccessed
;
1008 state
->Emulate
= STOP
;
1009 state
->StopHandle
= (ARMword
)p
;
1014 static RDI_NameList
const *RDI_cpunames() {
1015 return (RDI_NameList
const *)&processorconfig
.count
;
1018 const struct RDIProcVec armul_rdi
= {
1038 0, /*loadconfigdata*/