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