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