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