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