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