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