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