OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [arm/] [armrdi.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/*  armrdi.c -- ARMulator RDI interface:  ARM6 Instruction Emulator.
2
    Copyright (C) 1994 Advanced RISC Machines Ltd.
3
 
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.
8
 
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.
13
 
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
17
 
18
#include <string.h>
19
#include <ctype.h>
20
#include "armdefs.h"
21
#include "armemu.h"
22
#include "armos.h"
23
#include "dbg_cp.h"
24
#include "dbg_conf.h"
25
#include "dbg_rdi.h"
26
#include "dbg_hif.h"
27
#include "communicate.h"
28
 
29
/***************************************************************************\
30
*                               Declarations                                *
31
\***************************************************************************/
32
 
33
#define Watch_AnyRead (RDIWatch_ByteRead+RDIWatch_HalfRead+RDIWatch_WordRead)
34
#define Watch_AnyWrite (RDIWatch_ByteWrite+RDIWatch_HalfWrite+RDIWatch_WordWrite)
35
 
36
static unsigned FPRegsAddr;     /* last known address of FPE regs */
37
#define FPESTART 0x2000L
38
#define FPEEND   0x8000L
39
 
40
#define IGNORE(d) (d = d)
41
#ifdef RDI_VERBOSE
42
#define TracePrint(s) \
43
 if (rdi_log & 1) ARMul_DebugPrint s
44
#else
45
#define TracePrint(s)
46
#endif
47
 
48
static ARMul_State *state = NULL;
49
static unsigned BreaksSet;      /* The number of breakpoints set */
50
 
51
static int rdi_log = 0;          /* debugging  ? */
52
 
53
#define LOWEST_RDI_LEVEL 0
54
#define HIGHEST_RDI_LEVEL 1
55
static int MYrdi_level = LOWEST_RDI_LEVEL;
56
 
57
typedef struct BreakNode BreakNode;
58
typedef struct WatchNode WatchNode;
59
 
60
struct BreakNode
61
{                               /* A breakpoint list node */
62
  BreakNode *next;
63
  ARMword address;              /* The address of this breakpoint */
64
  unsigned type;                /* The type of comparison */
65
  ARMword bound;                /* The other address for a range */
66
  ARMword inst;
67
};
68
 
69
struct WatchNode
70
{                               /* A watchpoint list node */
71
  WatchNode *next;
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 */
76
};
77
 
78
BreakNode *BreakList = NULL;
79
WatchNode *WatchList = NULL;
80
 
81
void
82
ARMul_DebugPrint_i (const Dbg_HostosInterface * hostif, const char *format,
83
                    ...)
84
{
85
  va_list ap;
86
  va_start (ap, format);
87
  hostif->dbgprint (hostif->dbgarg, format, ap);
88
  va_end (ap);
89
}
90
 
91
void
92
ARMul_DebugPrint (ARMul_State * state, const char *format, ...)
93
{
94
  va_list ap;
95
  va_start (ap, format);
96
  if (!(rdi_log & 8))
97
    state->hostif->dbgprint (state->hostif->dbgarg, format, ap);
98
  va_end (ap);
99
}
100
 
101
#define CONSOLE_PRINT_MAX_LEN 128
102
 
103
void
104
ARMul_ConsolePrint (ARMul_State * state, const char *format, ...)
105
{
106
  va_list ap;
107
  int ch;
108
  char *str, buf[CONSOLE_PRINT_MAX_LEN];
109
  int i, j;
110
  ARMword junk;
111
 
112
  va_start (ap, format);
113
  vsprintf (buf, format, ap);
114
 
115
  for (i = 0; buf[i]; i++);      /* The string is i chars long */
116
 
117
  str = buf;
118
  while (i >= 32)
119
    {
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);
127
      i -= 32;
128
    }
129
 
130
  if (i > 0)
131
    {
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);
139
    }
140
 
141
  va_end (ap);
142
  return;
143
 
144
/*   str = buf; */
145
/*   while ((ch=*str++) != 0) */
146
/*     state->hostif->writec(state->hostif->hostosarg, ch); */
147
}
148
 
149
void
150
ARMul_DebugPause (ARMul_State * state)
151
{
152
  if (!(rdi_log & 8))
153
    state->hostif->dbgpause (state->hostif->dbgarg);
154
}
155
 
156
/***************************************************************************\
157
*                                 RDI_open                                  *
158
\***************************************************************************/
159
 
160
static void
161
InitFail (int exitcode, char const *which)
162
{
163
  ARMul_ConsolePrint (state, "%s interface failed to initialise. Exiting\n",
164
                      which);
165
  exit (exitcode);
166
}
167
 
168
static void
169
RDIInit (unsigned type)
170
{
171
  if (type == 0)
172
    {                           /* cold start */
173
      state->CallDebug = state->MemReadDebug = state->MemWriteDebug = 0;
174
      BreaksSet = 0;
175
    }
176
}
177
 
178
#define UNKNOWNPROC 0
179
 
180
typedef struct
181
{
182
  char name[16];
183
  unsigned properties;
184
}
185
Processor;
186
 
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 };
197
 
198
Processor const *const processors[] =
199
{
200
  &p_arm6,                      /* default: must come first */
201
  &p_arm2,
202
  &p_arm2as,
203
  &p_arm61,
204
  &p_arm3,
205
  &p_arm60,
206
  &p_arm600,
207
  &p_arm610,
208
  &p_arm620,
209
  &p_unknown
210
};
211
 
212
typedef struct ProcessorConfig ProcessorConfig;
213
struct ProcessorConfig
214
{
215
  long id[2];
216
  ProcessorConfig const *self;
217
  long count;
218
  Processor const *const *processors;
219
};
220
 
221
ProcessorConfig const processorconfig = {
222
  {((((((long) 'x' << 8) | ' ') << 8) | 'c') << 8) | 'p',
223
   ((((((long) 'u' << 8) | 's') << 8) | ' ') << 8) | 'x'},
224
  &processorconfig,
225
  16,
226
  processors
227
};
228
 
229
static int
230
RDI_open (unsigned type, const Dbg_ConfigBlock * config,
231
          const Dbg_HostosInterface * hostif, struct Dbg_MCState *dbg_state)
232
/* Initialise everything */
233
{
234
  int virgin = (state == NULL);
235
  IGNORE (dbg_state);
236
 
237
#ifdef RDI_VERBOSE
238
  if (rdi_log & 1)
239
    {
240
      if (virgin)
241
        ARMul_DebugPrint_i (hostif, "RDI_open: type = %d\n", type);
242
      else
243
        ARMul_DebugPrint (state, "RDI_open: type = %d\n", type);
244
    }
245
#endif
246
 
247
  if (type & 1)
248
    {                           /* Warm start */
249
      ARMul_Reset (state);
250
      RDIInit (1);
251
    }
252
  else
253
    {
254
      if (virgin)
255
        {
256
          ARMul_EmulateInit ();
257
          state = ARMul_NewState ();
258
          state->hostif = hostif;
259
          {
260
            int req = config->processor;
261
            unsigned processor = processors[req]->val;
262
            ARMul_SelectProcessor (state, processor);
263
            ARMul_Reset (state);
264
            ARMul_ConsolePrint (state, "ARMulator V1.50, %s",
265
                                processors[req]->name);
266
          }
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");
275
        }
276
      ARMul_Reset (state);
277
      RDIInit (0);
278
    }
279
  if (type & 2)
280
    {                           /* Reset the comms link */
281
      /* what comms link ? */
282
    }
283
  if (virgin && (type & 1) == 0) /* Cold start */
284
    ARMul_ConsolePrint (state, ", %s endian.\n",
285
                        state->bigendSig ? "Big" : "Little");
286
 
287
  if (config->bytesex == RDISex_DontCare)
288
    return (state->bigendSig ? RDIError_BigEndian : RDIError_LittleEndian);
289
  else
290
    return (RDIError_NoError);
291
}
292
 
293
/***************************************************************************\
294
*                                RDI_close                                  *
295
\***************************************************************************/
296
 
297
static int
298
RDI_close (void)
299
{
300
  TracePrint ((state, "RDI_close\n"));
301
  ARMul_OSExit (state);
302
  ARMul_CoProExit (state);
303
  ARMul_MemoryExit (state);
304
  return (RDIError_NoError);
305
}
306
 
307
/***************************************************************************\
308
*                                 RDI_read                                  *
309
\***************************************************************************/
310
 
311
static int
312
RDI_read (ARMword source, void *dest, unsigned *nbytes)
313
{
314
  unsigned i;
315
  char *memptr = (char *) dest;
316
 
317
  TracePrint ((state, "RDI_read: source=%.8lx dest=%p nbytes=%.8x\n",
318
               source, dest, *nbytes));
319
 
320
  for (i = 0; i < *nbytes; i++)
321
    *memptr++ = (char) ARMul_ReadByte (state, source++);
322
  if (state->abortSig)
323
    {
324
      state->abortSig = LOW;
325
      return (RDIError_DataAbort);
326
    }
327
  return (RDIError_NoError);
328
}
329
 
330
/***************************************************************************\
331
*                                  RDI_write                                *
332
\***************************************************************************/
333
 
334
static int
335
RDI_write (const void *source, ARMword dest, unsigned *nbytes)
336
{
337
  unsigned i;
338
  char *memptr = (char *) source;
339
 
340
  TracePrint ((state, "RDI_write: source=%p dest=%.8lx nbytes=%.8x\n",
341
               source, dest, *nbytes));
342
 
343
  for (i = 0; i < *nbytes; i++)
344
    ARMul_WriteByte (state, (ARMword) dest++, (ARMword) * memptr++);
345
 
346
  if (state->abortSig)
347
    {
348
      state->abortSig = LOW;
349
      return (RDIError_DataAbort);
350
    }
351
  return (RDIError_NoError);
352
}
353
 
354
/***************************************************************************\
355
*                                RDI_CPUread                                *
356
\***************************************************************************/
357
 
358
static int
359
RDI_CPUread (unsigned mode, unsigned long mask, ARMword buffer[])
360
{
361
  unsigned i, upto;
362
 
363
  if (mode == RDIMode_Curr)
364
    mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS);
365
 
366
  for (upto = 0, i = 0; i < 15; i++)
367
    if (mask & (1L << i))
368
      {
369
        buffer[upto++] = ARMul_GetReg (state, mode, i);
370
      }
371
 
372
  if (mask & RDIReg_R15)
373
    {
374
      buffer[upto++] = ARMul_GetR15 (state);
375
    }
376
 
377
  if (mask & RDIReg_PC)
378
    {
379
      buffer[upto++] = ARMul_GetPC (state);
380
    }
381
 
382
  if (mask & RDIReg_CPSR)
383
    buffer[upto++] = ARMul_GetCPSR (state);
384
 
385
  if (mask & RDIReg_SPSR)
386
    buffer[upto++] = ARMul_GetSPSR (state, mode);
387
 
388
  TracePrint ((state, "RDI_CPUread: mode=%.8x mask=%.8lx", mode, mask));
389
#ifdef RDI_VERBOSE
390
  if (rdi_log & 1)
391
    {
392
      for (upto = 0, i = 0; i <= 20; i++)
393
        if (mask & (1L << i))
394
          {
395
            ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ',
396
                              buffer[upto]);
397
            upto++;
398
          }
399
      ARMul_DebugPrint (state, "\n");
400
    }
401
#endif
402
 
403
  return (RDIError_NoError);
404
}
405
 
406
/***************************************************************************\
407
*                               RDI_CPUwrite                                *
408
\***************************************************************************/
409
 
410
static int
411
RDI_CPUwrite (unsigned mode, unsigned long mask, ARMword const buffer[])
412
{
413
  int i, upto;
414
 
415
 
416
  TracePrint ((state, "RDI_CPUwrite: mode=%.8x mask=%.8lx", mode, mask));
417
#ifdef RDI_VERBOSE
418
  if (rdi_log & 1)
419
    {
420
      for (upto = 0, i = 0; i <= 20; i++)
421
        if (mask & (1L << i))
422
          {
423
            ARMul_DebugPrint (state, "%c%.8lx", upto % 4 == 0 ? '\n' : ' ',
424
                              buffer[upto]);
425
            upto++;
426
          }
427
      ARMul_DebugPrint (state, "\n");
428
    }
429
#endif
430
 
431
  if (mode == RDIMode_Curr)
432
    mode = (unsigned) (ARMul_GetCPSR (state) & MODEBITS);
433
 
434
  for (upto = 0, i = 0; i < 15; i++)
435
    if (mask & (1L << i))
436
      ARMul_SetReg (state, mode, i, buffer[upto++]);
437
 
438
  if (mask & RDIReg_R15)
439
    ARMul_SetR15 (state, buffer[upto++]);
440
 
441
  if (mask & RDIReg_PC)
442
    {
443
 
444
      ARMul_SetPC (state, buffer[upto++]);
445
    }
446
  if (mask & RDIReg_CPSR)
447
    ARMul_SetCPSR (state, buffer[upto++]);
448
 
449
  if (mask & RDIReg_SPSR)
450
    ARMul_SetSPSR (state, mode, buffer[upto++]);
451
 
452
  return (RDIError_NoError);
453
}
454
 
455
/***************************************************************************\
456
*                                RDI_CPread                                 *
457
\***************************************************************************/
458
 
459
static int
460
RDI_CPread (unsigned CPnum, unsigned long mask, ARMword buffer[])
461
{
462
  ARMword fpregsaddr, word[4];
463
 
464
  unsigned r, w;
465
  unsigned upto;
466
 
467
  if (CPnum != 1 && CPnum != 2)
468
    {
469
      unsigned char const *rmap = state->CPRegWords[CPnum];
470
      if (rmap == NULL)
471
        return (RDIError_UnknownCoPro);
472
      for (upto = 0, r = 0; r < rmap[-1]; r++)
473
        if (mask & (1L << r))
474
          {
475
            (void) state->CPRead[CPnum] (state, r, &buffer[upto]);
476
            upto += rmap[r];
477
          }
478
      TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx", CPnum, mask));
479
#ifdef RDI_VERBOSE
480
      if (rdi_log & 1)
481
        {
482
          w = 0;
483
          for (upto = 0, r = 0; r < rmap[-1]; r++)
484
            if (mask & (1L << r))
485
              {
486
                int words = rmap[r];
487
                ARMul_DebugPrint (state, "%c%2d",
488
                                  (w >= 4 ? (w = 0, '\n') : ' '), r);
489
                while (--words >= 0)
490
                  {
491
                    ARMul_DebugPrint (state, " %.8lx", buffer[upto++]);
492
                    w++;
493
                  }
494
              }
495
          ARMul_DebugPrint (state, "\n");
496
        }
497
#endif
498
      return RDIError_NoError;
499
    }
500
 
501
#ifdef NOFPE
502
  return RDIError_UnknownCoPro;
503
 
504
#else
505
  if (FPRegsAddr == 0)
506
    {
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;
515
    }
516
  else
517
    fpregsaddr = FPRegsAddr;
518
 
519
  if (fpregsaddr == 0)
520
    return RDIError_UnknownCoPro;
521
  for (upto = 0, r = 0; r < 8; r++)
522
    if (mask & (1L << r))
523
      {
524
        for (w = 0; w < 4; w++)
525
          word[w] =
526
            ARMul_ReadWord (state,
527
                            fpregsaddr + (ARMword) r * 16 + (ARMword) w * 4);
528
        switch ((int) (word[3] >> 29))
529
          {
530
          case 0:
531
          case 2:
532
          case 4:
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 */
538
            break;
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 */
544
            break;
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 */
550
            break;
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 */
556
            break;
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 */
562
            break;
563
          }
564
      }
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 */
569
 
570
  TracePrint ((state, "RDI_CPread: CPnum=%d mask=%.8lx\n", CPnum, mask));
571
#ifdef RDI_VERBOSE
572
  if (rdi_log & 1)
573
    {
574
      for (upto = 0, r = 0; r < 9; r++)
575
        if (mask & (1L << r))
576
          {
577
            if (r != 8)
578
              {
579
                ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
580
                ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
581
                ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
582
              }
583
            ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]);
584
          }
585
      ARMul_DebugPrint (state, "\n");
586
    }
587
#endif
588
  return (RDIError_NoError);
589
#endif /* NOFPE */
590
}
591
 
592
/***************************************************************************\
593
*                               RDI_CPwrite                                 *
594
\***************************************************************************/
595
 
596
static int
597
RDI_CPwrite (unsigned CPnum, unsigned long mask, ARMword const buffer[])
598
{
599
  unsigned r;
600
  unsigned upto;
601
  ARMword fpregsaddr;
602
 
603
  if (CPnum != 1 && CPnum != 2)
604
    {
605
      unsigned char const *rmap = state->CPRegWords[CPnum];
606
      if (rmap == NULL)
607
        return (RDIError_UnknownCoPro);
608
      TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask));
609
#ifdef RDI_VERBOSE
610
      if (rdi_log & 1)
611
        {
612
          int w = 0;
613
          for (upto = 0, r = 0; r < rmap[-1]; r++)
614
            if (mask & (1L << r))
615
              {
616
                int words = rmap[r];
617
                ARMul_DebugPrint (state, "%c%2d",
618
                                  (w >= 4 ? (w = 0, '\n') : ' '), r);
619
                while (--words >= 0)
620
                  {
621
                    ARMul_DebugPrint (state, " %.8lx", buffer[upto++]);
622
                    w++;
623
                  }
624
              }
625
          ARMul_DebugPrint (state, "\n");
626
        }
627
#endif
628
      for (upto = 0, r = 0; r < rmap[-1]; r++)
629
        if (mask & (1L << r))
630
          {
631
            (void) state->CPWrite[CPnum] (state, r, &buffer[upto]);
632
            upto += rmap[r];
633
          }
634
      return RDIError_NoError;
635
    }
636
 
637
#ifdef NOFPE
638
  return RDIError_UnknownCoPro;
639
 
640
#else
641
  TracePrint ((state, "RDI_CPwrite: CPnum=%d mask=%.8lx", CPnum, mask));
642
#ifdef RDI_VERBOSE
643
  if (rdi_log & 1)
644
    {
645
      for (upto = 0, r = 0; r < 9; r++)
646
        if (mask & (1L << r))
647
          {
648
            if (r != 8)
649
              {
650
                ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
651
                ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
652
                ARMul_DebugPrint (state, "%08lx ", buffer[upto++]);
653
              }
654
            ARMul_DebugPrint (state, "%08lx\n", buffer[upto++]);
655
          }
656
      ARMul_DebugPrint (state, "\n");
657
    }
658
#endif
659
 
660
  if (FPRegsAddr == 0)
661
    {
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;
670
    }
671
  else
672
    fpregsaddr = FPRegsAddr;
673
 
674
  if (fpregsaddr == 0)
675
    return RDIError_UnknownCoPro;
676
  for (upto = 0, r = 0; r < 8; r++)
677
    if (mask & (1L << r))
678
      {
679
        ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16,
680
                         buffer[upto + 1]);
681
        ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 4,
682
                         buffer[upto + 2]);
683
        ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 8,
684
                         buffer[upto + 3]);
685
        ARMul_WriteWord (state, fpregsaddr + (ARMword) r * 16 + 12,
686
                         (buffer[upto] * 2 + 1) << 29); /* mark type */
687
        upto += 4;
688
      }
689
  if (mask & (1L << r))
690
    ARMul_WriteWord (state, fpregsaddr + 128, buffer[upto++]);  /* fpsr */
691
  return (RDIError_NoError);
692
#endif /* NOFPE */
693
}
694
 
695
static void
696
deletebreaknode (BreakNode ** prevp)
697
{
698
  BreakNode *p = *prevp;
699
  *prevp = p->next;
700
  ARMul_WriteWord (state, p->address, p->inst);
701
  free ((char *) p);
702
  BreaksSet--;
703
  state->CallDebug--;
704
}
705
 
706
static int
707
removebreak (ARMword address, unsigned type)
708
{
709
  BreakNode *p, **prevp = &BreakList;
710
  for (; (p = *prevp) != NULL; prevp = &p->next)
711
    if (p->address == address && p->type == type)
712
      {
713
        deletebreaknode (prevp);
714
        return TRUE;
715
      }
716
  return FALSE;
717
}
718
 
719
/* This routine installs a breakpoint into the breakpoint table */
720
 
721
static BreakNode *
722
installbreak (ARMword address, unsigned type, ARMword bound)
723
{
724
  BreakNode *p = (BreakNode *) malloc (sizeof (BreakNode));
725
  p->next = BreakList;
726
  BreakList = p;
727
  p->address = address;
728
  p->type = type;
729
  p->bound = bound;
730
  p->inst = ARMul_ReadWord (state, address);
731
  ARMul_WriteWord (state, address, 0xee000000L);
732
  return p;
733
}
734
 
735
/***************************************************************************\
736
*                               RDI_setbreak                                *
737
\***************************************************************************/
738
 
739
static int
740
RDI_setbreak (ARMword address, unsigned type, ARMword bound,
741
              PointHandle * handle)
742
{
743
  BreakNode *p;
744
  TracePrint ((state, "RDI_setbreak: address=%.8lx type=%d bound=%.8lx\n",
745
               address, type, bound));
746
 
747
  removebreak (address, type);
748
  p = installbreak (address, type, bound);
749
  BreaksSet++;
750
  state->CallDebug++;
751
  *handle = (PointHandle) p;
752
  TracePrint ((state, " returns %.8lx\n", *handle));
753
  return RDIError_NoError;
754
}
755
 
756
/***************************************************************************\
757
*                               RDI_clearbreak                              *
758
\***************************************************************************/
759
 
760
static int
761
RDI_clearbreak (PointHandle handle)
762
{
763
  TracePrint ((state, "RDI_clearbreak: address=%.8lx\n", handle));
764
  {
765
    BreakNode *p, **prevp = &BreakList;
766
    for (; (p = *prevp) != NULL; prevp = &p->next)
767
      if (p == (BreakNode *) handle)
768
        break;
769
    if (p == NULL)
770
      return RDIError_NoSuchPoint;
771
    deletebreaknode (prevp);
772
    return RDIError_NoError;
773
  }
774
}
775
 
776
/***************************************************************************\
777
*            Internal functions for breakpoint table manipulation           *
778
\***************************************************************************/
779
 
780
static void
781
deletewatchnode (WatchNode ** prevp)
782
{
783
  WatchNode *p = *prevp;
784
  if (p->datatype & Watch_AnyRead)
785
    state->MemReadDebug--;
786
  if (p->datatype & Watch_AnyWrite)
787
    state->MemWriteDebug--;
788
  *prevp = p->next;
789
  free ((char *) p);
790
}
791
 
792
int
793
removewatch (ARMword address, unsigned type)
794
{
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);
800
        return TRUE;
801
      }
802
  return FALSE;                 /* never found a match */
803
}
804
 
805
static WatchNode *
806
installwatch (ARMword address, unsigned type, unsigned datatype,
807
              ARMword bound)
808
{
809
  WatchNode *p = (WatchNode *) malloc (sizeof (WatchNode));
810
  p->next = WatchList;
811
  WatchList = p;
812
  p->address = address;
813
  p->type = type;
814
  p->datatype = datatype;
815
  p->bound = bound;
816
  return p;
817
}
818
 
819
/***************************************************************************\
820
*                               RDI_setwatch                                *
821
\***************************************************************************/
822
 
823
static int
824
RDI_setwatch (ARMword address, unsigned type, unsigned datatype,
825
              ARMword bound, PointHandle * handle)
826
{
827
  WatchNode *p;
828
  TracePrint (
829
              (state,
830
               "RDI_setwatch: address=%.8lx type=%d datatype=%d bound=%.8lx",
831
               address, type, datatype, bound));
832
 
833
  if (!state->CanWatch)
834
    return RDIError_UnimplementedMessage;
835
 
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;
845
}
846
 
847
/***************************************************************************\
848
*                               RDI_clearwatch                              *
849
\***************************************************************************/
850
 
851
static int
852
RDI_clearwatch (PointHandle handle)
853
{
854
  TracePrint ((state, "RDI_clearwatch: address=%.8lx\n", handle));
855
  {
856
    WatchNode *p, **prevp = &WatchList;
857
    for (; (p = *prevp) != NULL; prevp = &p->next)
858
      if (p == (WatchNode *) handle)
859
        break;
860
    if (p == NULL)
861
      return RDIError_NoSuchPoint;
862
    deletewatchnode (prevp);
863
    return RDIError_NoError;
864
  }
865
}
866
 
867
/***************************************************************************\
868
*                               RDI_execute                                 *
869
\***************************************************************************/
870
 
871
static int
872
RDI_execute (PointHandle * handle)
873
{
874
  TracePrint ((state, "RDI_execute\n"));
875
  if (rdi_log & 4)
876
    {
877
      state->CallDebug++;
878
      state->Debug = TRUE;
879
    }
880
  state->EndCondition = RDIError_NoError;
881
  state->StopHandle = 0;
882
 
883
  ARMul_DoProg (state);
884
 
885
  *handle = state->StopHandle;
886
  state->Reg[15] -= 8;          /* undo the pipeline */
887
  if (rdi_log & 4)
888
    {
889
      state->CallDebug--;
890
      state->Debug = FALSE;
891
    }
892
  return (state->EndCondition);
893
}
894
 
895
/***************************************************************************\
896
*                                RDI_step                                   *
897
\***************************************************************************/
898
 
899
static int
900
RDI_step (unsigned ninstr, PointHandle * handle)
901
{
902
 
903
  TracePrint ((state, "RDI_step\n"));
904
  if (ninstr != 1)
905
    return RDIError_UnimplementedMessage;
906
  if (rdi_log & 4)
907
    {
908
      state->CallDebug++;
909
      state->Debug = TRUE;
910
    }
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 */
916
  if (rdi_log & 4)
917
    {
918
      state->CallDebug--;
919
      state->Debug = FALSE;
920
    }
921
  return (state->EndCondition);
922
}
923
 
924
/***************************************************************************\
925
*                               RDI_info                                    *
926
\***************************************************************************/
927
 
928
static int
929
RDI_info (unsigned type, ARMword * arg1, ARMword * arg2)
930
{
931
  switch (type)
932
    {
933
    case RDIInfo_Target:
934
      TracePrint ((state, "RDI_Info_Target\n"));
935
      /* Emulator, speed 10**5 IPS */
936
      *arg1 = 5 | HIGHEST_RDI_LEVEL << 5 | LOWEST_RDI_LEVEL << 8;
937
      *arg2 = 1298224434;
938
      return RDIError_NoError;
939
 
940
    case RDIInfo_Points:
941
      {
942
        ARMword n = RDIPointCapability_Comparison | RDIPointCapability_Range |
943
          RDIPointCapability_Mask | RDIPointCapability_Status;
944
        TracePrint ((state, "RDI_Info_Points\n"));
945
        if (state->CanWatch)
946
          n |= (Watch_AnyRead + Watch_AnyWrite) << 2;
947
        *arg1 = n;
948
        return RDIError_NoError;
949
      }
950
 
951
    case RDIInfo_Step:
952
      TracePrint ((state, "RDI_Info_Step\n"));
953
      *arg1 = RDIStep_Single;
954
      return RDIError_NoError;
955
 
956
    case RDIInfo_MMU:
957
      TracePrint ((state, "RDI_Info_MMU\n"));
958
      *arg1 = 1313820229;
959
      return RDIError_NoError;
960
 
961
    case RDISignal_Stop:
962
      TracePrint ((state, "RDISignal_Stop\n"));
963
      state->CallDebug++;
964
      state->EndCondition = RDIError_UserInterrupt;
965
      return RDIError_NoError;
966
 
967
    case RDIVector_Catch:
968
      TracePrint ((state, "RDIVector_Catch %.8lx\n", *arg1));
969
      state->VectorCatch = (unsigned) *arg1;
970
      return RDIError_NoError;
971
 
972
    case RDISet_Cmdline:
973
      TracePrint ((state, "RDI_Set_Cmdline %s\n", (char *) arg1));
974
      state->CommandLine =
975
        (char *) malloc ((unsigned) strlen ((char *) arg1) + 1);
976
      (void) strcpy (state->CommandLine, (char *) arg1);
977
      return RDIError_NoError;
978
 
979
    case RDICycles:
980
      TracePrint ((state, "RDI_Info_Cycles\n"));
981
      arg1[0] = 0;
982
      arg1[1] = state->NumInstrs;
983
      arg1[2] = 0;
984
      arg1[3] = state->NumScycles;
985
      arg1[4] = 0;
986
      arg1[5] = state->NumNcycles;
987
      arg1[6] = 0;
988
      arg1[7] = state->NumIcycles;
989
      arg1[8] = 0;
990
      arg1[9] = state->NumCcycles;
991
      arg1[10] = 0;
992
      arg1[11] = state->NumFcycles;
993
      return RDIError_NoError;
994
 
995
    case RDIErrorP:
996
      *arg1 = ARMul_OSLastErrorP (state);
997
      TracePrint ((state, "RDI_ErrorP returns %ld\n", *arg1));
998
      return RDIError_NoError;
999
 
1000
    case RDIInfo_DescribeCoPro:
1001
      {
1002
        int cpnum = *(int *) arg1;
1003
        struct Dbg_CoProDesc *cpd = (struct Dbg_CoProDesc *) arg2;
1004
        int i;
1005
        unsigned char const *map = state->CPRegWords[cpnum];
1006
        if (map == NULL)
1007
          return RDIError_UnknownCoPro;
1008
        for (i = 0; i < cpd->entries; i++)
1009
          {
1010
            unsigned r, w = cpd->regdesc[i].nbytes / sizeof (ARMword);
1011
            for (r = cpd->regdesc[i].rmin; r <= cpd->regdesc[i].rmax; r++)
1012
              if (map[r] != w)
1013
                return RDIError_BadCoProState;
1014
          }
1015
        return RDIError_NoError;
1016
      }
1017
 
1018
    case RDIInfo_RequestCoProDesc:
1019
      {
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];
1027
        if (map == NULL)
1028
          return RDIError_UnknownCoPro;
1029
        for (r = 0; r < map[-1]; r++)
1030
          {
1031
            int words = map[r];
1032
            if (words == lastw)
1033
              cpd->regdesc[i].rmax = r;
1034
            else
1035
              {
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;
1042
              }
1043
          }
1044
        cpd->entries = i + 1;
1045
        return RDIError_NoError;
1046
      }
1047
 
1048
    case RDIInfo_Log:
1049
      *arg1 = (ARMword) rdi_log;
1050
      return RDIError_NoError;
1051
 
1052
    case RDIInfo_SetLog:
1053
      rdi_log = (int) *arg1;
1054
      return RDIError_NoError;
1055
 
1056
    case RDIInfo_CoPro:
1057
      return RDIError_NoError;
1058
 
1059
    case RDIPointStatus_Watch:
1060
      {
1061
        WatchNode *p, *handle = (WatchNode *) * arg1;
1062
        for (p = WatchList; p != NULL; p = p->next)
1063
          if (p == handle)
1064
            {
1065
              *arg1 = -1;
1066
              *arg2 = 1;
1067
              return RDIError_NoError;
1068
            }
1069
        return RDIError_NoSuchPoint;
1070
      }
1071
 
1072
    case RDIPointStatus_Break:
1073
      {
1074
        BreakNode *p, *handle = (BreakNode *) * arg1;
1075
        for (p = BreakList; p != NULL; p = p->next)
1076
          if (p == handle)
1077
            {
1078
              *arg1 = -1;
1079
              *arg2 = 1;
1080
              return RDIError_NoError;
1081
            }
1082
        return RDIError_NoSuchPoint;
1083
      }
1084
 
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;
1090
 
1091
    default:
1092
      return RDIError_UnimplementedMessage;
1093
 
1094
    }
1095
}
1096
 
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
\***************************************************************************/
1103
 
1104
ARMword
1105
ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr)
1106
{
1107
 
1108
  if (state->EndCondition == RDIError_UserInterrupt)
1109
    {
1110
      TracePrint ((state, "User interrupt at %.8lx\n", pc));
1111
      state->CallDebug--;
1112
      state->Emulate = STOP;
1113
    }
1114
  else
1115
    {
1116
      BreakNode *p = BreakList;
1117
      for (; p != NULL; p = p->next)
1118
        {
1119
          switch (p->type)
1120
            {
1121
            case RDIPoint_EQ:
1122
              if (pc == p->address)
1123
                break;
1124
              continue;
1125
            case RDIPoint_GT:
1126
              if (pc > p->address)
1127
                break;
1128
              continue;
1129
            case RDIPoint_GE:
1130
              if (pc >= p->address)
1131
                break;
1132
              continue;
1133
            case RDIPoint_LT:
1134
              if (pc < p->address)
1135
                break;
1136
              continue;
1137
            case RDIPoint_LE:
1138
              if (pc <= p->address)
1139
                break;
1140
              continue;
1141
            case RDIPoint_IN:
1142
              if (p->address <= pc && pc < p->address + p->bound)
1143
                break;
1144
              continue;
1145
            case RDIPoint_OUT:
1146
              if (p->address > pc || pc >= p->address + p->bound)
1147
                break;
1148
              continue;
1149
            case RDIPoint_MASK:
1150
              if ((pc & p->bound) == p->address)
1151
                break;
1152
              continue;
1153
            }
1154
          /* found a match */
1155
          TracePrint ((state, "Breakpoint reached at %.8lx\n", pc));
1156
          state->EndCondition = RDIError_BreakpointReached;
1157
          state->Emulate = STOP;
1158
          state->StopHandle = (ARMword) p;
1159
          break;
1160
        }
1161
    }
1162
  return instr;
1163
}
1164
 
1165
void
1166
ARMul_CheckWatch (ARMul_State * state, ARMword addr, int access)
1167
{
1168
  WatchNode *p;
1169
  for (p = WatchList; p != NULL; p = p->next)
1170
    if (p->datatype & access)
1171
      {
1172
        switch (p->type)
1173
          {
1174
          case RDIPoint_EQ:
1175
            if (addr == p->address)
1176
              break;
1177
            continue;
1178
          case RDIPoint_GT:
1179
            if (addr > p->address)
1180
              break;
1181
            continue;
1182
          case RDIPoint_GE:
1183
            if (addr >= p->address)
1184
              break;
1185
            continue;
1186
          case RDIPoint_LT:
1187
            if (addr < p->address)
1188
              break;
1189
            continue;
1190
          case RDIPoint_LE:
1191
            if (addr <= p->address)
1192
              break;
1193
            continue;
1194
          case RDIPoint_IN:
1195
            if (p->address <= addr && addr < p->address + p->bound)
1196
              break;
1197
            continue;
1198
          case RDIPoint_OUT:
1199
            if (p->address > addr || addr >= p->address + p->bound)
1200
              break;
1201
            continue;
1202
          case RDIPoint_MASK:
1203
            if ((addr & p->bound) == p->address)
1204
              break;
1205
            continue;
1206
          }
1207
        /* found a match */
1208
        TracePrint ((state, "Watchpoint at %.8lx accessed\n", addr));
1209
        state->EndCondition = RDIError_WatchpointAccessed;
1210
        state->Emulate = STOP;
1211
        state->StopHandle = (ARMword) p;
1212
        return;
1213
      }
1214
}
1215
 
1216
static RDI_NameList const *
1217
RDI_cpunames ()
1218
{
1219
  return (RDI_NameList const *) &processorconfig.count;
1220
}
1221
 
1222
const struct RDIProcVec armul_rdi = {
1223
  "ARMUL",
1224
  RDI_open,
1225
  RDI_close,
1226
  RDI_read,
1227
  RDI_write,
1228
  RDI_CPUread,
1229
  RDI_CPUwrite,
1230
  RDI_CPread,
1231
  RDI_CPwrite,
1232
  RDI_setbreak,
1233
  RDI_clearbreak,
1234
  RDI_setwatch,
1235
  RDI_clearwatch,
1236
  RDI_execute,
1237
  RDI_step,
1238
  RDI_info,
1239
 
1240
  0,                             /*pointinq */
1241
  0,                             /*addconfig */
1242
  0,                             /*loadconfigdata */
1243
  0,                             /*selectconfig */
1244
  0,                             /*drivernames */
1245
 
1246
  RDI_cpunames
1247
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.