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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/*  armcopro.c -- co-processor interface:  ARM6 Instruction Emulator.
2
    Copyright (C) 1994, 2000 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 "armdefs.h"
19
#include "armos.h"
20
#include "armemu.h"
21
#include "ansidecl.h"
22
#include "iwmmxt.h"
23
 
24
/* Dummy Co-processors.  */
25
 
26
static unsigned
27
NoCoPro3R (ARMul_State * state ATTRIBUTE_UNUSED,
28
           unsigned      a     ATTRIBUTE_UNUSED,
29
           ARMword       b     ATTRIBUTE_UNUSED)
30
{
31
  return ARMul_CANT;
32
}
33
 
34
static unsigned
35
NoCoPro4R (ARMul_State * state ATTRIBUTE_UNUSED,
36
           unsigned      a     ATTRIBUTE_UNUSED,
37
           ARMword       b     ATTRIBUTE_UNUSED,
38
           ARMword       c     ATTRIBUTE_UNUSED)
39
{
40
  return ARMul_CANT;
41
}
42
 
43
static unsigned
44
NoCoPro4W (ARMul_State * state ATTRIBUTE_UNUSED,
45
           unsigned      a     ATTRIBUTE_UNUSED,
46
           ARMword       b     ATTRIBUTE_UNUSED,
47
           ARMword *     c     ATTRIBUTE_UNUSED)
48
{
49
  return ARMul_CANT;
50
}
51
 
52
/* The XScale Co-processors.  */
53
 
54
/* Coprocessor 15:  System Control.  */
55
static void     write_cp14_reg (unsigned, ARMword);
56
static ARMword  read_cp14_reg  (unsigned);
57
 
58
/* There are two sets of registers for copro 15.
59
   One set is available when opcode_2 is 0 and
60
   the other set when opcode_2 >= 1.  */
61
static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
62
static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16];
63
/* There are also a set of breakpoint registers
64
   which are accessed via CRm instead of opcode_2.  */
65
static ARMword XScale_cp15_DBR1;
66
static ARMword XScale_cp15_DBCON;
67
static ARMword XScale_cp15_IBCR0;
68
static ARMword XScale_cp15_IBCR1;
69
 
70
static unsigned
71
XScale_cp15_init (ARMul_State * state ATTRIBUTE_UNUSED)
72
{
73
  int i;
74
 
75
  for (i = 16; i--;)
76
    {
77
      XScale_cp15_opcode_2_is_0_Regs[i] = 0;
78
      XScale_cp15_opcode_2_is_not_0_Regs[i] = 0;
79
    }
80
 
81
  /* Initialise the processor ID.  */
82
  XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000;
83
 
84
  /* Initialise the cache type.  */
85
  XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA;
86
 
87
  /* Initialise the ARM Control Register.  */
88
  XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
89
}
90
 
91
/* Check an access to a register.  */
92
 
93
static unsigned
94
check_cp15_access (ARMul_State * state,
95
                   unsigned      reg,
96
                   unsigned      CRm,
97
                   unsigned      opcode_1,
98
                   unsigned      opcode_2)
99
{
100
  /* Do not allow access to these register in USER mode.  */
101
  if (state->Mode == USER26MODE || state->Mode == USER32MODE)
102
    return ARMul_CANT;
103
 
104
  /* Opcode_1should be zero.  */
105
  if (opcode_1 != 0)
106
    return ARMul_CANT;
107
 
108
  /* Different register have different access requirements.  */
109
  switch (reg)
110
    {
111
    case 0:
112
    case 1:
113
      /* CRm must be 0.  Opcode_2 can be anything.  */
114
      if (CRm != 0)
115
        return ARMul_CANT;
116
      break;
117
    case 2:
118
    case 3:
119
      /* CRm must be 0.  Opcode_2 must be zero.  */
120
      if ((CRm != 0) || (opcode_2 != 0))
121
        return ARMul_CANT;
122
      break;
123
    case 4:
124
      /* Access not allowed.  */
125
      return ARMul_CANT;
126
    case 5:
127
    case 6:
128
      /* Opcode_2 must be zero.  CRm must be 0.  */
129
      if ((CRm != 0) || (opcode_2 != 0))
130
        return ARMul_CANT;
131
      break;
132
    case 7:
133
      /* Permissable combinations:
134
           Opcode_2  CRm
135
 
136
 
137
 
138
              1       5
139
              1       6
140
              1      10
141
              4      10
142
              5       2
143
              6       5  */
144
      switch (opcode_2)
145
        {
146
        default:               return ARMul_CANT;
147
        case 6: if (CRm !=  5) return ARMul_CANT; break;
148
        case 5: if (CRm !=  2) return ARMul_CANT; break;
149
        case 4: if (CRm != 10) return ARMul_CANT; break;
150
        case 1: if ((CRm != 5) && (CRm != 6) && (CRm != 10)) return ARMul_CANT; break;
151
        case 0: if ((CRm < 5) || (CRm > 7)) return ARMul_CANT; break;
152
        }
153
      break;
154
 
155
    case 8:
156
      /* Permissable combinations:
157
           Opcode_2  CRm
158
 
159
 
160
 
161
              1       5
162
              1       6  */
163
      if (opcode_2 > 1)
164
        return ARMul_CANT;
165
      if ((CRm < 5) || (CRm > 7))
166
        return ARMul_CANT;
167
      if (opcode_2 == 1 && CRm == 7)
168
        return ARMul_CANT;
169
      break;
170
    case 9:
171
      /* Opcode_2 must be zero or one.  CRm must be 1 or 2.  */
172
      if (   ((CRm != 0) && (CRm != 1))
173
          || ((opcode_2 != 1) && (opcode_2 != 2)))
174
        return ARMul_CANT;
175
      break;
176
    case 10:
177
      /* Opcode_2 must be zero or one.  CRm must be 4 or 8.  */
178
      if (   ((CRm != 0) && (CRm != 1))
179
          || ((opcode_2 != 4) && (opcode_2 != 8)))
180
        return ARMul_CANT;
181
      break;
182
    case 11:
183
      /* Access not allowed.  */
184
      return ARMul_CANT;
185
    case 12:
186
      /* Access not allowed.  */
187
      return ARMul_CANT;
188
    case 13:
189
      /* Opcode_2 must be zero.  CRm must be 0.  */
190
      if ((CRm != 0) || (opcode_2 != 0))
191
        return ARMul_CANT;
192
      break;
193
    case 14:
194
      /* Opcode_2 must be 0.  CRm must be 0, 3, 4, 8 or 9.  */
195
      if (opcode_2 != 0)
196
        return ARMul_CANT;
197
 
198
      if ((CRm != 0) && (CRm != 3) && (CRm != 4) && (CRm != 8) && (CRm != 9))
199
        return ARMul_CANT;
200
      break;
201
    case 15:
202
      /* Opcode_2 must be zero.  CRm must be 1.  */
203
      if ((CRm != 1) || (opcode_2 != 0))
204
        return ARMul_CANT;
205
      break;
206
    default:
207
      /* Should never happen.  */
208
      return ARMul_CANT;
209
    }
210
 
211
  return ARMul_DONE;
212
}
213
 
214
/* Store a value into one of coprocessor 15's registers.  */
215
 
216
static void
217
write_cp15_reg (ARMul_State * state,
218
                unsigned reg,
219
                unsigned opcode_2,
220
                unsigned CRm,
221
                ARMword  value)
222
{
223
  if (opcode_2)
224
    {
225
      switch (reg)
226
        {
227
        case 0: /* Cache Type.  */
228
          /* Writes are not allowed.  */
229
          return;
230
 
231
        case 1: /* Auxillary Control.  */
232
          /* Only BITS (5, 4) and BITS (1, 0) can be written.  */
233
          value &= 0x33;
234
          break;
235
 
236
        default:
237
          return;
238
        }
239
 
240
      XScale_cp15_opcode_2_is_not_0_Regs [reg] = value;
241
    }
242
  else
243
    {
244
      switch (reg)
245
        {
246
        case 0: /* ID.  */
247
          /* Writes are not allowed.  */
248
          return;
249
 
250
        case 1: /* ARM Control.  */
251
          /* Only BITS (13, 11), BITS (9, 7) and BITS (2, 0) can be written.
252
             BITS (31, 14) and BIT (10) write as zero, BITS (6, 3) write as one.  */
253
          value &= 0x00003b87;
254
          value |= 0x00000078;
255
 
256
          /* Change the endianness if necessary.  */
257
          if ((value & ARMul_CP15_R1_ENDIAN) !=
258
              (XScale_cp15_opcode_2_is_0_Regs [reg] & ARMul_CP15_R1_ENDIAN))
259
            {
260
              state->bigendSig = value & ARMul_CP15_R1_ENDIAN;
261
              /* Force ARMulator to notice these now.  */
262
              state->Emulate = CHANGEMODE;
263
            }
264
          break;
265
 
266
        case 2: /* Translation Table Base.  */
267
          /* Only BITS (31, 14) can be written.  */
268
          value &= 0xffffc000;
269
          break;
270
 
271
        case 3: /* Domain Access Control.  */
272
          /* All bits writable.  */
273
          break;
274
 
275
        case 5: /* Fault Status Register.  */
276
          /* BITS (10, 9) and BITS (7, 0) can be written.  */
277
          value &= 0x000006ff;
278
          break;
279
 
280
        case 6: /* Fault Address Register.  */
281
          /* All bits writable.  */
282
          break;
283
 
284
        case 7: /* Cache Functions.  */
285
        case 8: /* TLB Operations.  */
286
        case 10: /* TLB Lock Down.  */
287
          /* Ignore writes.  */
288
          return;
289
 
290
        case 9: /* Data Cache Lock.  */
291
          /* Only BIT (0) can be written.  */
292
          value &= 0x1;
293
          break;
294
 
295
        case 13: /* Process ID.  */
296
          /* Only BITS (31, 25) are writable.  */
297
          value &= 0xfe000000;
298
          break;
299
 
300
        case 14: /* DBR0, DBR1, DBCON, IBCR0, IBCR1 */
301
          /* All bits can be written.  Which register is accessed is
302
             dependent upon CRm.  */
303
          switch (CRm)
304
            {
305
            case 0: /* DBR0 */
306
              break;
307
            case 3: /* DBR1 */
308
              XScale_cp15_DBR1 = value;
309
              break;
310
            case 4: /* DBCON */
311
              XScale_cp15_DBCON = value;
312
              break;
313
            case 8: /* IBCR0 */
314
              XScale_cp15_IBCR0 = value;
315
              break;
316
            case 9: /* IBCR1 */
317
              XScale_cp15_IBCR1 = value;
318
              break;
319
            default:
320
              return;
321
            }
322
          break;
323
 
324
        case 15: /* Coprpcessor Access Register.  */
325
          /* Access is only valid if CRm == 1.  */
326
          if (CRm != 1)
327
            return;
328
 
329
          /* Only BITS (13, 0) may be written.  */
330
          value &= 0x00003fff;
331
          break;
332
 
333
        default:
334
          return;
335
        }
336
 
337
      XScale_cp15_opcode_2_is_0_Regs [reg] = value;
338
    }
339
 
340
  return;
341
}
342
 
343
/* Return the value in a cp15 register.  */
344
 
345
ARMword
346
read_cp15_reg (unsigned reg, unsigned opcode_2, unsigned CRm)
347
{
348
  if (opcode_2 == 0)
349
    {
350
      if (reg == 15 && CRm != 1)
351
        return 0;
352
 
353
      if (reg == 14)
354
        {
355
          switch (CRm)
356
            {
357
            case 3: return XScale_cp15_DBR1;
358
            case 4: return XScale_cp15_DBCON;
359
            case 8: return XScale_cp15_IBCR0;
360
            case 9: return XScale_cp15_IBCR1;
361
            default:
362
              break;
363
            }
364
        }
365
 
366
      return XScale_cp15_opcode_2_is_0_Regs [reg];
367
    }
368
  else
369
    return XScale_cp15_opcode_2_is_not_0_Regs [reg];
370
 
371
  return 0;
372
}
373
 
374
static unsigned
375
XScale_cp15_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
376
{
377
  unsigned reg = BITS (12, 15);
378
  unsigned result;
379
 
380
  result = check_cp15_access (state, reg, 0, 0, 0);
381
 
382
  if (result == ARMul_DONE && type == ARMul_DATA)
383
    write_cp15_reg (state, reg, 0, 0, data);
384
 
385
  return result;
386
}
387
 
388
static unsigned
389
XScale_cp15_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
390
{
391
  unsigned reg = BITS (12, 15);
392
  unsigned result;
393
 
394
  result = check_cp15_access (state, reg, 0, 0, 0);
395
 
396
  if (result == ARMul_DONE && type == ARMul_DATA)
397
    * data = read_cp15_reg (reg, 0, 0);
398
 
399
  return result;
400
}
401
 
402
static unsigned
403
XScale_cp15_MRC (ARMul_State * state,
404
                 unsigned      type ATTRIBUTE_UNUSED,
405
                 ARMword       instr,
406
                 ARMword *     value)
407
{
408
  unsigned opcode_2 = BITS (5, 7);
409
  unsigned CRm = BITS (0, 3);
410
  unsigned reg = BITS (16, 19);
411
  unsigned result;
412
 
413
  result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);
414
 
415
  if (result == ARMul_DONE)
416
    * value = read_cp15_reg (reg, opcode_2, CRm);
417
 
418
  return result;
419
}
420
 
421
static unsigned
422
XScale_cp15_MCR (ARMul_State * state,
423
                 unsigned      type ATTRIBUTE_UNUSED,
424
                 ARMword       instr,
425
                 ARMword       value)
426
{
427
  unsigned opcode_2 = BITS (5, 7);
428
  unsigned CRm = BITS (0, 3);
429
  unsigned reg = BITS (16, 19);
430
  unsigned result;
431
 
432
  result = check_cp15_access (state, reg, CRm, BITS (21, 23), opcode_2);
433
 
434
  if (result == ARMul_DONE)
435
    write_cp15_reg (state, reg, opcode_2, CRm, value);
436
 
437
  return result;
438
}
439
 
440
static unsigned
441
XScale_cp15_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,
442
                      unsigned      reg,
443
                      ARMword *     value)
444
{
445
  /* FIXME: Not sure what to do about the alternative register set
446
     here.  For now default to just accessing CRm == 0 registers.  */
447
  * value = read_cp15_reg (reg, 0, 0);
448
 
449
  return TRUE;
450
}
451
 
452
static unsigned
453
XScale_cp15_write_reg (ARMul_State * state ATTRIBUTE_UNUSED,
454
                       unsigned      reg,
455
                       ARMword       value)
456
{
457
  /* FIXME: Not sure what to do about the alternative register set
458
     here.  For now default to just accessing CRm == 0 registers.  */
459
  write_cp15_reg (state, reg, 0, 0, value);
460
 
461
  return TRUE;
462
}
463
 
464
/* Check for special XScale memory access features.  */
465
 
466
void
467
XScale_check_memacc (ARMul_State * state, ARMword * address, int store)
468
{
469
  ARMword dbcon, r0, r1;
470
  int e1, e0;
471
 
472
  if (!state->is_XScale)
473
    return;
474
 
475
  /* Check for PID-ification.
476
     XXX BTB access support will require this test failing.  */
477
  r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000);
478
  if (r0 && (* address & 0xfe000000) == 0)
479
    * address |= r0;
480
 
481
  /* Check alignment fault enable/disable.  */
482
  if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (* address & 3))
483
    {
484
      /* Set the FSR and FAR.
485
         Do not use XScale_set_fsr_far as this checks the DCSR register.  */
486
      write_cp15_reg (state, 5, 0, 0, ARMul_CP15_R5_MMU_EXCPT);
487
      write_cp15_reg (state, 6, 0, 0, * address);
488
 
489
      ARMul_Abort (state, ARMul_DataAbortV);
490
    }
491
 
492
  if (XScale_debug_moe (state, -1))
493
    return;
494
 
495
  /* Check the data breakpoint registers.  */
496
  dbcon = read_cp15_reg (14, 0, 4);
497
  r0 = read_cp15_reg (14, 0, 0);
498
  r1 = read_cp15_reg (14, 0, 3);
499
  e0 = dbcon & ARMul_CP15_DBCON_E0;
500
 
501
  if (dbcon & ARMul_CP15_DBCON_M)
502
    {
503
      /* r1 is a inverse mask.  */
504
      if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
505
          && ((* address & ~r1) == (r0 & ~r1)))
506
        {
507
          XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
508
          ARMul_OSHandleSWI (state, SWI_Breakpoint);
509
        }
510
    }
511
  else
512
    {
513
      if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1))
514
              && ((* address & ~3) == (r0 & ~3)))
515
        {
516
          XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
517
          ARMul_OSHandleSWI (state, SWI_Breakpoint);
518
        }
519
 
520
      e1 = (dbcon & ARMul_CP15_DBCON_E1) >> 2;
521
      if (e1 != 0 && ((store && e1 != 3) || (!store && e1 != 1))
522
              && ((* address & ~3) == (r1 & ~3)))
523
        {
524
          XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB);
525
          ARMul_OSHandleSWI (state, SWI_Breakpoint);
526
        }
527
    }
528
}
529
 
530
/* Set the XScale FSR and FAR registers.  */
531
 
532
void
533
XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword far)
534
{
535
  if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0)
536
    return;
537
 
538
  write_cp15_reg (state, 5, 0, 0, fsr);
539
  write_cp15_reg (state, 6, 0, 0, far);
540
}
541
 
542
/* Set the XScale debug `method of entry' if it is enabled.  */
543
 
544
int
545
XScale_debug_moe (ARMul_State * state, int moe)
546
{
547
  ARMword value;
548
 
549
  if (!state->is_XScale)
550
    return 1;
551
 
552
  value = read_cp14_reg (10);
553
  if (value & (1UL << 31))
554
    {
555
      if (moe != -1)
556
        {
557
          value &= ~0x1c;
558
          value |= moe;
559
 
560
          write_cp14_reg (10, value);
561
        }
562
      return 1;
563
    }
564
  return 0;
565
}
566
 
567
/* Coprocessor 13:  Interrupt Controller and Bus Controller.  */
568
 
569
/* There are two sets of registers for copro 13.
570
   One set (of three registers) is available when CRm is 0
571
   and the other set (of six registers) when CRm is 1.  */
572
 
573
static ARMword XScale_cp13_CR0_Regs[16];
574
static ARMword XScale_cp13_CR1_Regs[16];
575
 
576
static unsigned
577
XScale_cp13_init (ARMul_State * state ATTRIBUTE_UNUSED)
578
{
579
  int i;
580
 
581
  for (i = 16; i--;)
582
    {
583
      XScale_cp13_CR0_Regs[i] = 0;
584
      XScale_cp13_CR1_Regs[i] = 0;
585
    }
586
}
587
 
588
/* Check an access to a register.  */
589
 
590
static unsigned
591
check_cp13_access (ARMul_State * state,
592
                   unsigned      reg,
593
                   unsigned      CRm,
594
                   unsigned      opcode_1,
595
                   unsigned      opcode_2)
596
{
597
  /* Do not allow access to these registers in USER mode.  */
598
  if (state->Mode == USER26MODE || state->Mode == USER32MODE)
599
    return ARMul_CANT;
600
 
601
  /* The opcodes should be zero.  */
602
  if ((opcode_1 != 0) || (opcode_2 != 0))
603
    return ARMul_CANT;
604
 
605
  /* Do not allow access to these register if bit
606
     13 of coprocessor 15's register 15 is zero.  */
607
  if (! CP_ACCESS_ALLOWED (state, 13))
608
    return ARMul_CANT;
609
 
610
  /* Registers 0, 4 and 8 are defined when CRm == 0.
611
     Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1.
612
     For all other CRm values undefined behaviour results.  */
613
  if (CRm == 0)
614
    {
615
      if (reg == 0 || reg == 4 || reg == 8)
616
        return ARMul_DONE;
617
    }
618
  else if (CRm == 1)
619
    {
620
      if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8))
621
        return ARMul_DONE;
622
    }
623
 
624
  return ARMul_CANT;
625
}
626
 
627
/* Store a value into one of coprocessor 13's registers.  */
628
 
629
static void
630
write_cp13_reg (unsigned reg, unsigned CRm, ARMword value)
631
{
632
  switch (CRm)
633
    {
634
    case 0:
635
      switch (reg)
636
        {
637
        case 0: /* INTCTL */
638
          /* Only BITS (3:0) can be written.  */
639
          value &= 0xf;
640
          break;
641
 
642
        case 4: /* INTSRC */
643
          /* No bits may be written.  */
644
          return;
645
 
646
        case 8: /* INTSTR */
647
          /* Only BITS (1:0) can be written.  */
648
          value &= 0x3;
649
          break;
650
 
651
        default:
652
          /* Should not happen.  Ignore any writes to unimplemented registers.  */
653
          return;
654
        }
655
 
656
      XScale_cp13_CR0_Regs [reg] = value;
657
      break;
658
 
659
    case 1:
660
      switch (reg)
661
        {
662
        case 0: /* BCUCTL */
663
          /* Only BITS (30:28) and BITS (3:0) can be written.
664
             BIT(31) is write ignored.  */
665
          value &= 0x7000000f;
666
          value |= XScale_cp13_CR1_Regs[0] & (1UL << 31);
667
          break;
668
 
669
        case 1: /* BCUMOD */
670
          /* Only bit 0 is accecssible.  */
671
          value &= 1;
672
          value |= XScale_cp13_CR1_Regs[1] & ~ 1;
673
          break;
674
 
675
        case 4: /* ELOG0 */
676
        case 5: /* ELOG1 */
677
        case 6: /* ECAR0 */
678
        case 7: /* ECAR1 */
679
          /* No bits can be written.  */
680
          return;
681
 
682
        case 8: /* ECTST */
683
          /* Only BITS (7:0) can be written.  */
684
          value &= 0xff;
685
          break;
686
 
687
        default:
688
          /* Should not happen.  Ignore any writes to unimplemented registers.  */
689
          return;
690
        }
691
 
692
      XScale_cp13_CR1_Regs [reg] = value;
693
      break;
694
 
695
    default:
696
      /* Should not happen.  */
697
      break;
698
    }
699
 
700
  return;
701
}
702
 
703
/* Return the value in a cp13 register.  */
704
 
705
static ARMword
706
read_cp13_reg (unsigned reg, unsigned CRm)
707
{
708
  if (CRm == 0)
709
    return XScale_cp13_CR0_Regs [reg];
710
  else if (CRm == 1)
711
    return XScale_cp13_CR1_Regs [reg];
712
 
713
  return 0;
714
}
715
 
716
static unsigned
717
XScale_cp13_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
718
{
719
  unsigned reg = BITS (12, 15);
720
  unsigned result;
721
 
722
  result = check_cp13_access (state, reg, 0, 0, 0);
723
 
724
  if (result == ARMul_DONE && type == ARMul_DATA)
725
    write_cp13_reg (reg, 0, data);
726
 
727
  return result;
728
}
729
 
730
static unsigned
731
XScale_cp13_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
732
{
733
  unsigned reg = BITS (12, 15);
734
  unsigned result;
735
 
736
  result = check_cp13_access (state, reg, 0, 0, 0);
737
 
738
  if (result == ARMul_DONE && type == ARMul_DATA)
739
    * data = read_cp13_reg (reg, 0);
740
 
741
  return result;
742
}
743
 
744
static unsigned
745
XScale_cp13_MRC (ARMul_State * state,
746
                 unsigned      type ATTRIBUTE_UNUSED,
747
                 ARMword       instr,
748
                 ARMword *     value)
749
{
750
  unsigned CRm = BITS (0, 3);
751
  unsigned reg = BITS (16, 19);
752
  unsigned result;
753
 
754
  result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
755
 
756
  if (result == ARMul_DONE)
757
    * value = read_cp13_reg (reg, CRm);
758
 
759
  return result;
760
}
761
 
762
static unsigned
763
XScale_cp13_MCR (ARMul_State * state,
764
                 unsigned      type ATTRIBUTE_UNUSED,
765
                 ARMword       instr,
766
                 ARMword       value)
767
{
768
  unsigned CRm = BITS (0, 3);
769
  unsigned reg = BITS (16, 19);
770
  unsigned result;
771
 
772
  result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
773
 
774
  if (result == ARMul_DONE)
775
    write_cp13_reg (reg, CRm, value);
776
 
777
  return result;
778
}
779
 
780
static unsigned
781
XScale_cp13_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,
782
                      unsigned      reg,
783
                      ARMword *     value)
784
{
785
  /* FIXME: Not sure what to do about the alternative register set
786
     here.  For now default to just accessing CRm == 0 registers.  */
787
  * value = read_cp13_reg (reg, 0);
788
 
789
  return TRUE;
790
}
791
 
792
static unsigned
793
XScale_cp13_write_reg (ARMul_State * state ATTRIBUTE_UNUSED,
794
                       unsigned      reg,
795
                       ARMword       value)
796
{
797
  /* FIXME: Not sure what to do about the alternative register set
798
     here.  For now default to just accessing CRm == 0 registers.  */
799
  write_cp13_reg (reg, 0, value);
800
 
801
  return TRUE;
802
}
803
 
804
/* Coprocessor 14:  Performance Monitoring,  Clock and Power management,
805
   Software Debug.  */
806
 
807
static ARMword XScale_cp14_Regs[16];
808
 
809
static unsigned
810
XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED)
811
{
812
  int i;
813
 
814
  for (i = 16; i--;)
815
    XScale_cp14_Regs[i] = 0;
816
}
817
 
818
/* Check an access to a register.  */
819
 
820
static unsigned
821
check_cp14_access (ARMul_State * state,
822
                   unsigned      reg,
823
                   unsigned      CRm,
824
                   unsigned      opcode1,
825
                   unsigned      opcode2)
826
{
827
  /* Not allowed to access these register in USER mode.  */
828
  if (state->Mode == USER26MODE || state->Mode == USER32MODE)
829
    return ARMul_CANT;
830
 
831
  /* CRm should be zero.  */
832
  if (CRm != 0)
833
    return ARMul_CANT;
834
 
835
  /* OPcodes should be zero.  */
836
  if (opcode1 != 0 || opcode2 != 0)
837
    return ARMul_CANT;
838
 
839
  /* Accessing registers 4 or 5 has unpredicatable results.  */
840
  if (reg >= 4 && reg <= 5)
841
    return ARMul_CANT;
842
 
843
  return ARMul_DONE;
844
}
845
 
846
/* Store a value into one of coprocessor 14's registers.  */
847
 
848
static void
849
write_cp14_reg (unsigned reg, ARMword value)
850
{
851
  switch (reg)
852
    {
853
    case 0: /* PMNC */
854
      /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written.  */
855
      value &= 0x0ffff77f;
856
 
857
      /* Reset the clock counter if necessary.  */
858
      if (value & ARMul_CP14_R0_CLKRST)
859
        XScale_cp14_Regs [1] = 0;
860
      break;
861
 
862
    case 4:
863
    case 5:
864
      /* We should not normally reach this code.  The debugger interface
865
         can bypass the normal checks though, so it could happen.  */
866
      value = 0;
867
      break;
868
 
869
    case 6: /* CCLKCFG */
870
      /* Only BITS (3:0) can be written.  */
871
      value &= 0xf;
872
      break;
873
 
874
    case 7: /* PWRMODE */
875
      /* Although BITS (1:0) can be written with non-zero values, this would
876
         have the side effect of putting the processor to sleep.  Thus in
877
         order for the register to be read again, it would have to go into
878
         ACTIVE mode, which means that any read will see these bits as zero.
879
 
880
         Rather than trying to implement complex reset-to-zero-upon-read logic
881
         we just override the write value with zero.  */
882
      value = 0;
883
      break;
884
 
885
    case 10: /* DCSR */
886
      /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can
887
         be written.  */
888
      value &= 0xc0df003f;
889
      break;
890
 
891
    case 11: /* TBREG */
892
      /* No writes are permitted.  */
893
      value = 0;
894
      break;
895
 
896
    case 14: /* TXRXCTRL */
897
      /* Only BITS (31:30) can be written.  */
898
      value &= 0xc0000000;
899
      break;
900
 
901
    default:
902
      /* All bits can be written.  */
903
      break;
904
    }
905
 
906
  XScale_cp14_Regs [reg] = value;
907
}
908
 
909
/* Return the value in a cp14 register.  Not a static function since
910
   it is used by the code to emulate the BKPT instruction in armemu.c.  */
911
 
912
ARMword
913
read_cp14_reg (unsigned reg)
914
{
915
  return XScale_cp14_Regs [reg];
916
}
917
 
918
static unsigned
919
XScale_cp14_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
920
{
921
  unsigned reg = BITS (12, 15);
922
  unsigned result;
923
 
924
  result = check_cp14_access (state, reg, 0, 0, 0);
925
 
926
  if (result == ARMul_DONE && type == ARMul_DATA)
927
    write_cp14_reg (reg, data);
928
 
929
  return result;
930
}
931
 
932
static unsigned
933
XScale_cp14_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
934
{
935
  unsigned reg = BITS (12, 15);
936
  unsigned result;
937
 
938
  result = check_cp14_access (state, reg, 0, 0, 0);
939
 
940
  if (result == ARMul_DONE && type == ARMul_DATA)
941
    * data = read_cp14_reg (reg);
942
 
943
  return result;
944
}
945
 
946
static unsigned
947
XScale_cp14_MRC
948
(
949
 ARMul_State * state,
950
 unsigned      type ATTRIBUTE_UNUSED,
951
 ARMword       instr,
952
 ARMword *     value
953
)
954
{
955
  unsigned reg = BITS (16, 19);
956
  unsigned result;
957
 
958
  result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
959
 
960
  if (result == ARMul_DONE)
961
    * value = read_cp14_reg (reg);
962
 
963
  return result;
964
}
965
 
966
static unsigned
967
XScale_cp14_MCR
968
(
969
 ARMul_State * state,
970
 unsigned      type ATTRIBUTE_UNUSED,
971
 ARMword       instr,
972
 ARMword       value
973
)
974
{
975
  unsigned reg = BITS (16, 19);
976
  unsigned result;
977
 
978
  result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
979
 
980
  if (result == ARMul_DONE)
981
    write_cp14_reg (reg, value);
982
 
983
  return result;
984
}
985
 
986
static unsigned
987
XScale_cp14_read_reg
988
(
989
 ARMul_State * state ATTRIBUTE_UNUSED,
990
 unsigned      reg,
991
 ARMword *     value
992
)
993
{
994
  * value = read_cp14_reg (reg);
995
 
996
  return TRUE;
997
}
998
 
999
static unsigned
1000
XScale_cp14_write_reg
1001
(
1002
 ARMul_State * state ATTRIBUTE_UNUSED,
1003
 unsigned      reg,
1004
 ARMword       value
1005
)
1006
{
1007
  write_cp14_reg (reg, value);
1008
 
1009
  return TRUE;
1010
}
1011
 
1012
/* Here's ARMulator's MMU definition.  A few things to note:
1013
   1) It has eight registers, but only two are defined.
1014
   2) You can only access its registers with MCR and MRC.
1015
   3) MMU Register 0 (ID) returns 0x41440110
1016
   4) Register 1 only has 4 bits defined.  Bits 0 to 3 are unused, bit 4
1017
      controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
1018
      bit 6 controls late abort timimg and bit 7 controls big/little endian.  */
1019
 
1020
static ARMword MMUReg[8];
1021
 
1022
static unsigned
1023
MMUInit (ARMul_State * state)
1024
{
1025
  MMUReg[1] = state->prog32Sig << 4 |
1026
    state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
1027
 
1028
  ARMul_ConsolePrint (state, ", MMU present");
1029
 
1030
  return TRUE;
1031
}
1032
 
1033
static unsigned
1034
MMUMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1035
        unsigned      type ATTRIBUTE_UNUSED,
1036
        ARMword       instr,
1037
        ARMword *     value)
1038
{
1039
  int reg = BITS (16, 19) & 7;
1040
 
1041
  if (reg == 0)
1042
    *value = 0x41440110;
1043
  else
1044
    *value = MMUReg[reg];
1045
 
1046
  return ARMul_DONE;
1047
}
1048
 
1049
static unsigned
1050
MMUMCR (ARMul_State * state,
1051
        unsigned      type ATTRIBUTE_UNUSED,
1052
        ARMword       instr,
1053
        ARMword       value)
1054
{
1055
  int reg = BITS (16, 19) & 7;
1056
 
1057
  MMUReg[reg] = value;
1058
 
1059
  if (reg == 1)
1060
    {
1061
      ARMword p,d,l,b;
1062
 
1063
      p = state->prog32Sig;
1064
      d = state->data32Sig;
1065
      l = state->lateabtSig;
1066
      b = state->bigendSig;
1067
 
1068
      state->prog32Sig  = value >> 4 & 1;
1069
      state->data32Sig  = value >> 5 & 1;
1070
      state->lateabtSig = value >> 6 & 1;
1071
      state->bigendSig  = value >> 7 & 1;
1072
 
1073
      if (   p != state->prog32Sig
1074
          || d != state->data32Sig
1075
          || l != state->lateabtSig
1076
          || b != state->bigendSig)
1077
        /* Force ARMulator to notice these now.  */
1078
        state->Emulate = CHANGEMODE;
1079
    }
1080
 
1081
  return ARMul_DONE;
1082
}
1083
 
1084
static unsigned
1085
MMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value)
1086
{
1087
  if (reg == 0)
1088
    *value = 0x41440110;
1089
  else if (reg < 8)
1090
    *value = MMUReg[reg];
1091
 
1092
  return TRUE;
1093
}
1094
 
1095
static unsigned
1096
MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
1097
{
1098
  if (reg < 8)
1099
    MMUReg[reg] = value;
1100
 
1101
  if (reg == 1)
1102
    {
1103
      ARMword p,d,l,b;
1104
 
1105
      p = state->prog32Sig;
1106
      d = state->data32Sig;
1107
      l = state->lateabtSig;
1108
      b = state->bigendSig;
1109
 
1110
      state->prog32Sig  = value >> 4 & 1;
1111
      state->data32Sig  = value >> 5 & 1;
1112
      state->lateabtSig = value >> 6 & 1;
1113
      state->bigendSig  = value >> 7 & 1;
1114
 
1115
      if (   p != state->prog32Sig
1116
          || d != state->data32Sig
1117
          || l != state->lateabtSig
1118
          || b != state->bigendSig)
1119
        /* Force ARMulator to notice these now.  */
1120
        state->Emulate = CHANGEMODE;
1121
    }
1122
 
1123
  return TRUE;
1124
}
1125
 
1126
 
1127
/* What follows is the Validation Suite Coprocessor.  It uses two
1128
   co-processor numbers (4 and 5) and has the follwing functionality.
1129
   Sixteen registers.  Both co-processor nuimbers can be used in an MCR
1130
   and MRC to access these registers.  CP 4 can LDC and STC to and from
1131
   the registers.  CP 4 and CP 5 CDP 0 will busy wait for the number of
1132
   cycles specified by a CP register.  CP 5 CDP 1 issues a FIQ after a
1133
   number of cycles (specified in a CP register), CDP 2 issues an IRQW
1134
   in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
1135
   stores a 32 bit time value in a CP register (actually it's the total
1136
   number of N, S, I, C and F cyles).  */
1137
 
1138
static ARMword ValReg[16];
1139
 
1140
static unsigned
1141
ValLDC (ARMul_State * state ATTRIBUTE_UNUSED,
1142
        unsigned      type,
1143
        ARMword       instr,
1144
        ARMword        data)
1145
{
1146
  static unsigned words;
1147
 
1148
  if (type != ARMul_DATA)
1149
    words = 0;
1150
  else
1151
    {
1152
      ValReg[BITS (12, 15)] = data;
1153
 
1154
      if (BIT (22))
1155
        /* It's a long access, get two words.  */
1156
        if (words++ != 4)
1157
          return ARMul_INC;
1158
    }
1159
 
1160
  return ARMul_DONE;
1161
}
1162
 
1163
static unsigned
1164
ValSTC (ARMul_State * state ATTRIBUTE_UNUSED,
1165
        unsigned      type,
1166
        ARMword       instr,
1167
        ARMword *     data)
1168
{
1169
  static unsigned words;
1170
 
1171
  if (type != ARMul_DATA)
1172
    words = 0;
1173
  else
1174
    {
1175
      * data = ValReg[BITS (12, 15)];
1176
 
1177
      if (BIT (22))
1178
        /* It's a long access, get two words.  */
1179
        if (words++ != 4)
1180
          return ARMul_INC;
1181
    }
1182
 
1183
  return ARMul_DONE;
1184
}
1185
 
1186
static unsigned
1187
ValMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1188
        unsigned      type  ATTRIBUTE_UNUSED,
1189
        ARMword       instr,
1190
        ARMword *     value)
1191
{
1192
  *value = ValReg[BITS (16, 19)];
1193
 
1194
  return ARMul_DONE;
1195
}
1196
 
1197
static unsigned
1198
ValMCR (ARMul_State * state ATTRIBUTE_UNUSED,
1199
        unsigned      type  ATTRIBUTE_UNUSED,
1200
        ARMword       instr,
1201
        ARMword       value)
1202
{
1203
  ValReg[BITS (16, 19)] = value;
1204
 
1205
  return ARMul_DONE;
1206
}
1207
 
1208
static unsigned
1209
ValCDP (ARMul_State * state, unsigned type, ARMword instr)
1210
{
1211
  static unsigned long finish = 0;
1212
 
1213
  if (BITS (20, 23) != 0)
1214
    return ARMul_CANT;
1215
 
1216
  if (type == ARMul_FIRST)
1217
    {
1218
      ARMword howlong;
1219
 
1220
      howlong = ValReg[BITS (0, 3)];
1221
 
1222
      /* First cycle of a busy wait.  */
1223
      finish = ARMul_Time (state) + howlong;
1224
 
1225
      return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1226
    }
1227
  else if (type == ARMul_BUSY)
1228
    {
1229
      if (ARMul_Time (state) >= finish)
1230
        return ARMul_DONE;
1231
      else
1232
        return ARMul_BUSY;
1233
    }
1234
 
1235
  return ARMul_CANT;
1236
}
1237
 
1238
static unsigned
1239
DoAFIQ (ARMul_State * state)
1240
{
1241
  state->NfiqSig = LOW;
1242
  state->Exception++;
1243
  return 0;
1244
}
1245
 
1246
static unsigned
1247
DoAIRQ (ARMul_State * state)
1248
{
1249
  state->NirqSig = LOW;
1250
  state->Exception++;
1251
  return 0;
1252
}
1253
 
1254
static unsigned
1255
IntCDP (ARMul_State * state, unsigned type, ARMword instr)
1256
{
1257
  static unsigned long finish;
1258
  ARMword howlong;
1259
 
1260
  howlong = ValReg[BITS (0, 3)];
1261
 
1262
  switch ((int) BITS (20, 23))
1263
    {
1264
    case 0:
1265
      if (type == ARMul_FIRST)
1266
        {
1267
          /* First cycle of a busy wait.  */
1268
          finish = ARMul_Time (state) + howlong;
1269
 
1270
          return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1271
        }
1272
      else if (type == ARMul_BUSY)
1273
        {
1274
          if (ARMul_Time (state) >= finish)
1275
            return ARMul_DONE;
1276
          else
1277
            return ARMul_BUSY;
1278
        }
1279
      return ARMul_DONE;
1280
 
1281
    case 1:
1282
      if (howlong == 0)
1283
        ARMul_Abort (state, ARMul_FIQV);
1284
      else
1285
        ARMul_ScheduleEvent (state, howlong, DoAFIQ);
1286
      return ARMul_DONE;
1287
 
1288
    case 2:
1289
      if (howlong == 0)
1290
        ARMul_Abort (state, ARMul_IRQV);
1291
      else
1292
        ARMul_ScheduleEvent (state, howlong, DoAIRQ);
1293
      return ARMul_DONE;
1294
 
1295
    case 3:
1296
      state->NfiqSig = HIGH;
1297
      state->Exception--;
1298
      return ARMul_DONE;
1299
 
1300
    case 4:
1301
      state->NirqSig = HIGH;
1302
      state->Exception--;
1303
      return ARMul_DONE;
1304
 
1305
    case 5:
1306
      ValReg[BITS (0, 3)] = ARMul_Time (state);
1307
      return ARMul_DONE;
1308
    }
1309
 
1310
  return ARMul_CANT;
1311
}
1312
 
1313
/* Install co-processor instruction handlers in this routine.  */
1314
 
1315
unsigned
1316
ARMul_CoProInit (ARMul_State * state)
1317
{
1318
  unsigned int i;
1319
 
1320
  /* Initialise tham all first.  */
1321
  for (i = 0; i < 16; i++)
1322
    ARMul_CoProDetach (state, i);
1323
 
1324
  /* Install CoPro Instruction handlers here.
1325
     The format is:
1326
     ARMul_CoProAttach (state, CP Number, Init routine, Exit routine
1327
                        LDC routine, STC routine, MRC routine, MCR routine,
1328
                        CDP routine, Read Reg routine, Write Reg routine).  */
1329
  if (state->is_ep9312)
1330
    {
1331
      ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4,
1332
                         DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL);
1333
      ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5,
1334
                         DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL);
1335
      ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL,
1336
                         DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL);
1337
    }
1338
  else
1339
    {
1340
      ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC,
1341
                         ValMRC, ValMCR, ValCDP, NULL, NULL);
1342
 
1343
      ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL,
1344
                         ValMRC, ValMCR, IntCDP, NULL, NULL);
1345
    }
1346
 
1347
  if (state->is_XScale)
1348
    {
1349
      ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
1350
                         XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
1351
                         XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
1352
                         XScale_cp13_write_reg);
1353
 
1354
      ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL,
1355
                         XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC,
1356
                         XScale_cp14_MCR, NULL, XScale_cp14_read_reg,
1357
                         XScale_cp14_write_reg);
1358
 
1359
      ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
1360
                         NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
1361
                         NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
1362
    }
1363
  else
1364
    {
1365
      ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL,
1366
                         MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
1367
    }
1368
 
1369
  if (state->is_iWMMXt)
1370
    {
1371
      ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC,
1372
                         NULL, NULL, IwmmxtCDP, NULL, NULL);
1373
 
1374
      ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL,
1375
                         IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL);
1376
    }
1377
 
1378
  /* No handlers below here.  */
1379
 
1380
  /* Call all the initialisation routines.  */
1381
  for (i = 0; i < 16; i++)
1382
    if (state->CPInit[i])
1383
      (state->CPInit[i]) (state);
1384
 
1385
  return TRUE;
1386
}
1387
 
1388
/* Install co-processor finalisation routines in this routine.  */
1389
 
1390
void
1391
ARMul_CoProExit (ARMul_State * state)
1392
{
1393
  register unsigned i;
1394
 
1395
  for (i = 0; i < 16; i++)
1396
    if (state->CPExit[i])
1397
      (state->CPExit[i]) (state);
1398
 
1399
  for (i = 0; i < 16; i++)       /* Detach all handlers.  */
1400
    ARMul_CoProDetach (state, i);
1401
}
1402
 
1403
/* Routines to hook Co-processors into ARMulator.  */
1404
 
1405
void
1406
ARMul_CoProAttach (ARMul_State *    state,
1407
                   unsigned         number,
1408
                   ARMul_CPInits *  init,
1409
                   ARMul_CPExits *  exit,
1410
                   ARMul_LDCs *     ldc,
1411
                   ARMul_STCs *     stc,
1412
                   ARMul_MRCs *     mrc,
1413
                   ARMul_MCRs *     mcr,
1414
                   ARMul_CDPs *     cdp,
1415
                   ARMul_CPReads *  read,
1416
                   ARMul_CPWrites * write)
1417
{
1418
  if (init != NULL)
1419
    state->CPInit[number] = init;
1420
  if (exit != NULL)
1421
    state->CPExit[number] = exit;
1422
  if (ldc != NULL)
1423
    state->LDC[number] = ldc;
1424
  if (stc != NULL)
1425
    state->STC[number] = stc;
1426
  if (mrc != NULL)
1427
    state->MRC[number] = mrc;
1428
  if (mcr != NULL)
1429
    state->MCR[number] = mcr;
1430
  if (cdp != NULL)
1431
    state->CDP[number] = cdp;
1432
  if (read != NULL)
1433
    state->CPRead[number] = read;
1434
  if (write != NULL)
1435
    state->CPWrite[number] = write;
1436
}
1437
 
1438
void
1439
ARMul_CoProDetach (ARMul_State * state, unsigned number)
1440
{
1441
  ARMul_CoProAttach (state, number, NULL, NULL,
1442
                     NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
1443
                     NoCoPro3R, NULL, NULL);
1444
 
1445
  state->CPInit[number] = NULL;
1446
  state->CPExit[number] = NULL;
1447
  state->CPRead[number] = NULL;
1448
  state->CPWrite[number] = NULL;
1449
}

powered by: WebSVN 2.1.0

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