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