Simulate XScale BCUMOD register
[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 registers 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, 1, 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 == 1 || (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 1: /* BCUMOD */
663           /* Only bit 0 is accecssible.  */
664           value &= 1;
665           value |= XScale_cp13_CR1_Regs[1] & ~ 1;
666           break;
667
668         case 4: /* ELOG0 */
669         case 5: /* ELOG1 */
670         case 6: /* ECAR0 */
671         case 7: /* ECAR1 */
672           /* No bits can be written.  */
673           return;
674
675         case 8: /* ECTST */
676           /* Only BITS (7:0) can be written.  */
677           value &= 0xff;
678           break;
679
680         default:
681           /* Should not happen.  Ignore any writes to unimplemented registers.  */
682           return;
683         }
684
685       XScale_cp13_CR1_Regs [reg] = value;
686       break;
687
688     default:
689       /* Should not happen.  */
690       break;
691     }
692
693   return;
694 }
695
696 /* Return the value in a cp13 register.  */
697
698 static ARMword
699 read_cp13_reg (unsigned reg, unsigned CRm)
700 {
701   if (CRm == 0)
702     return XScale_cp13_CR0_Regs [reg];
703   else if (CRm == 1)
704     return XScale_cp13_CR1_Regs [reg];
705
706   return 0;
707 }
708
709 static unsigned
710 XScale_cp13_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
711 {
712   unsigned reg = BITS (12, 15);
713   unsigned result;
714
715   result = check_cp13_access (state, reg, 0, 0, 0);
716
717   if (result == ARMul_DONE && type == ARMul_DATA)
718     write_cp13_reg (reg, 0, data);
719
720   return result;
721 }
722
723 static unsigned
724 XScale_cp13_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
725 {
726   unsigned reg = BITS (12, 15);
727   unsigned result;
728
729   result = check_cp13_access (state, reg, 0, 0, 0);
730
731   if (result == ARMul_DONE && type == ARMul_DATA)
732     * data = read_cp13_reg (reg, 0);
733
734   return result;
735 }
736
737 static unsigned
738 XScale_cp13_MRC (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     * value = read_cp13_reg (reg, CRm);
751
752   return result;
753 }
754
755 static unsigned
756 XScale_cp13_MCR (ARMul_State * state,
757                  unsigned      type ATTRIBUTE_UNUSED,
758                  ARMword       instr,
759                  ARMword       value)
760 {
761   unsigned CRm = BITS (0, 3);
762   unsigned reg = BITS (16, 19);
763   unsigned result;
764
765   result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7));
766
767   if (result == ARMul_DONE)
768     write_cp13_reg (reg, CRm, value);
769
770   return result;
771 }
772
773 static unsigned
774 XScale_cp13_read_reg (ARMul_State * state ATTRIBUTE_UNUSED,
775                       unsigned      reg,
776                       ARMword *     value)
777 {
778   /* FIXME: Not sure what to do about the alternative register set
779      here.  For now default to just accessing CRm == 0 registers.  */
780   * value = read_cp13_reg (reg, 0);
781
782   return TRUE;
783 }
784
785 static unsigned
786 XScale_cp13_write_reg (ARMul_State * state ATTRIBUTE_UNUSED,
787                        unsigned      reg,
788                        ARMword       value)
789 {
790   /* FIXME: Not sure what to do about the alternative register set
791      here.  For now default to just accessing CRm == 0 registers.  */
792   write_cp13_reg (reg, 0, value);
793
794   return TRUE;
795 }
796
797 /* Coprocessor 14:  Performance Monitoring,  Clock and Power management,
798    Software Debug.  */
799
800 static ARMword XScale_cp14_Regs[16];
801
802 static unsigned
803 XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED)
804 {
805   int i;
806
807   for (i = 16; i--;)
808     XScale_cp14_Regs[i] = 0;
809 }
810
811 /* Check an access to a register.  */
812
813 static unsigned
814 check_cp14_access (ARMul_State * state,
815                    unsigned      reg,
816                    unsigned      CRm,
817                    unsigned      opcode1,
818                    unsigned      opcode2)
819 {
820   /* Not allowed to access these register in USER mode.  */
821   if (state->Mode == USER26MODE || state->Mode == USER32MODE)
822     return ARMul_CANT;
823
824   /* CRm should be zero.  */
825   if (CRm != 0)
826     return ARMul_CANT;
827
828   /* OPcodes should be zero.  */
829   if (opcode1 != 0 || opcode2 != 0)
830     return ARMul_CANT;
831
832   /* Accessing registers 4 or 5 has unpredicatable results.  */
833   if (reg >= 4 && reg <= 5)
834     return ARMul_CANT;
835
836   return ARMul_DONE;
837 }
838
839 /* Store a value into one of coprocessor 14's registers.  */
840
841 static void
842 write_cp14_reg (unsigned reg, ARMword value)
843 {
844   switch (reg)
845     {
846     case 0: /* PMNC */
847       /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written.  */
848       value &= 0x0ffff77f;
849
850       /* Reset the clock counter if necessary */
851       if (value & ARMul_CP14_R0_CLKRST)
852         XScale_cp14_Regs [1] = 0;
853       break;
854
855     case 4:
856     case 5:
857       /* We should not normally reach this code.  The debugger interface
858          can bypass the normal checks though, so it could happen.  */
859       value = 0;
860       break;
861
862     case 6: /* CCLKCFG */
863       /* Only BITS (3:0) can be written.  */
864       value &= 0xf;
865       break;
866
867     case 7: /* PWRMODE */
868       /* Although BITS (1:0) can be written with non-zero values, this would
869          have the side effect of putting the processor to sleep.  Thus in
870          order for the register to be read again, it would have to go into
871          ACTIVE mode, which means that any read will see these bits as zero.
872
873          Rather than trying to implement complex reset-to-zero-upon-read logic
874          we just override the write value with zero.  */
875       value = 0;
876       break;
877
878     case 10: /* DCSR */
879       /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can
880          be written.  */
881       value &= 0xc0df003f;
882       break;
883
884     case 11: /* TBREG */
885       /* No writes are permitted.  */
886       value = 0;
887       break;
888
889     case 14: /* TXRXCTRL */
890       /* Only BITS (31:30) can be written.  */
891       value &= 0xc0000000;
892       break;
893
894     default:
895       /* All bits can be written.  */
896       break;
897     }
898
899   XScale_cp14_Regs [reg] = value;
900 }
901
902 /* Return the value in a cp14 register.  Not a static function since
903    it is used by the code to emulate the BKPT instruction in armemu.c.  */
904
905 ARMword
906 read_cp14_reg (unsigned reg)
907 {
908   return XScale_cp14_Regs [reg];
909 }
910
911 static unsigned
912 XScale_cp14_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
913 {
914   unsigned reg = BITS (12, 15);
915   unsigned result;
916
917   result = check_cp14_access (state, reg, 0, 0, 0);
918
919   if (result == ARMul_DONE && type == ARMul_DATA)
920     write_cp14_reg (reg, data);
921
922   return result;
923 }
924
925 static unsigned
926 XScale_cp14_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
927 {
928   unsigned reg = BITS (12, 15);
929   unsigned result;
930
931   result = check_cp14_access (state, reg, 0, 0, 0);
932
933   if (result == ARMul_DONE && type == ARMul_DATA)
934     * data = read_cp14_reg (reg);
935
936   return result;
937 }
938
939 static unsigned
940 XScale_cp14_MRC
941 (
942  ARMul_State * state,
943  unsigned      type ATTRIBUTE_UNUSED,
944  ARMword       instr,
945  ARMword *     value
946 )
947 {
948   unsigned reg = BITS (16, 19);
949   unsigned result;
950
951   result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
952
953   if (result == ARMul_DONE)
954     * value = read_cp14_reg (reg);
955
956   return result;
957 }
958
959 static unsigned
960 XScale_cp14_MCR
961 (
962  ARMul_State * state,
963  unsigned      type ATTRIBUTE_UNUSED,
964  ARMword       instr,
965  ARMword       value
966 )
967 {
968   unsigned reg = BITS (16, 19);
969   unsigned result;
970
971   result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7));
972
973   if (result == ARMul_DONE)
974     write_cp14_reg (reg, value);
975
976   return result;
977 }
978
979 static unsigned
980 XScale_cp14_read_reg
981 (
982  ARMul_State * state ATTRIBUTE_UNUSED,
983  unsigned      reg,
984  ARMword *     value
985 )
986 {
987   * value = read_cp14_reg (reg);
988
989   return TRUE;
990 }
991
992 static unsigned
993 XScale_cp14_write_reg
994 (
995  ARMul_State * state ATTRIBUTE_UNUSED,
996  unsigned      reg,
997  ARMword       value
998 )
999 {
1000   write_cp14_reg (reg, value);
1001
1002   return TRUE;
1003 }
1004
1005 /* Here's ARMulator's MMU definition.  A few things to note:
1006    1) It has eight registers, but only two are defined.
1007    2) You can only access its registers with MCR and MRC.
1008    3) MMU Register 0 (ID) returns 0x41440110
1009    4) Register 1 only has 4 bits defined.  Bits 0 to 3 are unused, bit 4
1010       controls 32/26 bit program space, bit 5 controls 32/26 bit data space,
1011       bit 6 controls late abort timimg and bit 7 controls big/little endian.  */
1012
1013 static ARMword MMUReg[8];
1014
1015 static unsigned
1016 MMUInit (ARMul_State * state)
1017 {
1018   MMUReg[1] = state->prog32Sig << 4 |
1019     state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7;
1020
1021   ARMul_ConsolePrint (state, ", MMU present");
1022
1023   return TRUE;
1024 }
1025
1026 static unsigned
1027 MMUMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1028         unsigned      type ATTRIBUTE_UNUSED,
1029         ARMword       instr,
1030         ARMword *     value)
1031 {
1032   int reg = BITS (16, 19) & 7;
1033
1034   if (reg == 0)
1035     *value = 0x41440110;
1036   else
1037     *value = MMUReg[reg];
1038
1039   return ARMul_DONE;
1040 }
1041
1042 static unsigned
1043 MMUMCR (ARMul_State * state,
1044         unsigned      type ATTRIBUTE_UNUSED,
1045         ARMword       instr,
1046         ARMword       value)
1047 {
1048   int reg = BITS (16, 19) & 7;
1049
1050   MMUReg[reg] = value;
1051
1052   if (reg == 1)
1053     {
1054       ARMword p,d,l,b;
1055
1056       p = state->prog32Sig;
1057       d = state->data32Sig;
1058       l = state->lateabtSig;
1059       b = state->bigendSig;
1060
1061       state->prog32Sig  = value >> 4 & 1;
1062       state->data32Sig  = value >> 5 & 1;
1063       state->lateabtSig = value >> 6 & 1;
1064       state->bigendSig  = value >> 7 & 1;
1065
1066       if (   p != state->prog32Sig
1067           || d != state->data32Sig
1068           || l != state->lateabtSig
1069           || b != state->bigendSig)
1070         /* Force ARMulator to notice these now.  */
1071         state->Emulate = CHANGEMODE;
1072     }
1073
1074   return ARMul_DONE;
1075 }
1076
1077 static unsigned
1078 MMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value)
1079 {
1080   if (reg == 0)
1081     *value = 0x41440110;
1082   else if (reg < 8)
1083     *value = MMUReg[reg];
1084
1085   return TRUE;
1086 }
1087
1088 static unsigned
1089 MMUWrite (ARMul_State * state, unsigned reg, ARMword value)
1090 {
1091   if (reg < 8)
1092     MMUReg[reg] = value;
1093
1094   if (reg == 1)
1095     {
1096       ARMword p,d,l,b;
1097
1098       p = state->prog32Sig;
1099       d = state->data32Sig;
1100       l = state->lateabtSig;
1101       b = state->bigendSig;
1102
1103       state->prog32Sig  = value >> 4 & 1;
1104       state->data32Sig  = value >> 5 & 1;
1105       state->lateabtSig = value >> 6 & 1;
1106       state->bigendSig  = value >> 7 & 1;
1107
1108       if (   p != state->prog32Sig
1109           || d != state->data32Sig
1110           || l != state->lateabtSig
1111           || b != state->bigendSig)
1112         /* Force ARMulator to notice these now.  */     
1113         state->Emulate = CHANGEMODE;
1114     }
1115
1116   return TRUE;
1117 }
1118
1119
1120 /* What follows is the Validation Suite Coprocessor.  It uses two
1121    co-processor numbers (4 and 5) and has the follwing functionality.
1122    Sixteen registers.  Both co-processor nuimbers can be used in an MCR
1123    and MRC to access these registers.  CP 4 can LDC and STC to and from
1124    the registers.  CP 4 and CP 5 CDP 0 will busy wait for the number of
1125    cycles specified by a CP register.  CP 5 CDP 1 issues a FIQ after a
1126    number of cycles (specified in a CP register), CDP 2 issues an IRQW
1127    in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5
1128    stores a 32 bit time value in a CP register (actually it's the total
1129    number of N, S, I, C and F cyles).  */
1130
1131 static ARMword ValReg[16];
1132
1133 static unsigned
1134 ValLDC (ARMul_State * state ATTRIBUTE_UNUSED,
1135         unsigned      type,
1136         ARMword       instr,
1137         ARMword        data)
1138 {
1139   static unsigned words;
1140
1141   if (type != ARMul_DATA)
1142     words = 0;
1143   else
1144     {
1145       ValReg[BITS (12, 15)] = data;
1146
1147       if (BIT (22))
1148         /* It's a long access, get two words.  */
1149         if (words++ != 4)
1150           return ARMul_INC;
1151     }
1152
1153   return ARMul_DONE;
1154 }
1155
1156 static unsigned
1157 ValSTC (ARMul_State * state ATTRIBUTE_UNUSED,
1158         unsigned      type,
1159         ARMword       instr,
1160         ARMword *     data)
1161 {
1162   static unsigned words;
1163
1164   if (type != ARMul_DATA)
1165     words = 0;
1166   else
1167     {
1168       * data = ValReg[BITS (12, 15)];
1169
1170       if (BIT (22))
1171         /* It's a long access, get two words.  */
1172         if (words++ != 4)
1173           return ARMul_INC;
1174     }
1175
1176   return ARMul_DONE;
1177 }
1178
1179 static unsigned
1180 ValMRC (ARMul_State * state ATTRIBUTE_UNUSED,
1181         unsigned      type  ATTRIBUTE_UNUSED,
1182         ARMword       instr,
1183         ARMword *     value)
1184 {
1185   *value = ValReg[BITS (16, 19)];
1186
1187   return ARMul_DONE;
1188 }
1189
1190 static unsigned
1191 ValMCR (ARMul_State * state ATTRIBUTE_UNUSED,
1192         unsigned      type  ATTRIBUTE_UNUSED,
1193         ARMword       instr,
1194         ARMword       value)
1195 {
1196   ValReg[BITS (16, 19)] = value;
1197
1198   return ARMul_DONE;
1199 }
1200
1201 static unsigned
1202 ValCDP (ARMul_State * state, unsigned type, ARMword instr)
1203 {
1204   static unsigned long finish = 0;
1205
1206   if (BITS (20, 23) != 0)
1207     return ARMul_CANT;
1208
1209   if (type == ARMul_FIRST)
1210     {
1211       ARMword howlong;
1212
1213       howlong = ValReg[BITS (0, 3)];
1214
1215       /* First cycle of a busy wait.  */
1216       finish = ARMul_Time (state) + howlong;
1217
1218       return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1219     }
1220   else if (type == ARMul_BUSY)
1221     {
1222       if (ARMul_Time (state) >= finish)
1223         return ARMul_DONE;
1224       else
1225         return ARMul_BUSY;
1226     }
1227
1228   return ARMul_CANT;
1229 }
1230
1231 static unsigned
1232 DoAFIQ (ARMul_State * state)
1233 {
1234   state->NfiqSig = LOW;
1235   state->Exception++;
1236   return 0;
1237 }
1238
1239 static unsigned
1240 DoAIRQ (ARMul_State * state)
1241 {
1242   state->NirqSig = LOW;
1243   state->Exception++;
1244   return 0;
1245 }
1246
1247 static unsigned
1248 IntCDP (ARMul_State * state, unsigned type, ARMword instr)
1249 {
1250   static unsigned long finish;
1251   ARMword howlong;
1252
1253   howlong = ValReg[BITS (0, 3)];
1254
1255   switch ((int) BITS (20, 23))
1256     {
1257     case 0:
1258       if (type == ARMul_FIRST)
1259         {
1260           /* First cycle of a busy wait.  */
1261           finish = ARMul_Time (state) + howlong;
1262
1263           return howlong == 0 ? ARMul_DONE : ARMul_BUSY;
1264         }
1265       else if (type == ARMul_BUSY)
1266         {
1267           if (ARMul_Time (state) >= finish)
1268             return ARMul_DONE;
1269           else
1270             return ARMul_BUSY;
1271         }
1272       return ARMul_DONE;
1273
1274     case 1:
1275       if (howlong == 0)
1276         ARMul_Abort (state, ARMul_FIQV);
1277       else
1278         ARMul_ScheduleEvent (state, howlong, DoAFIQ);
1279       return ARMul_DONE;
1280
1281     case 2:
1282       if (howlong == 0)
1283         ARMul_Abort (state, ARMul_IRQV);
1284       else
1285         ARMul_ScheduleEvent (state, howlong, DoAIRQ);
1286       return ARMul_DONE;
1287
1288     case 3:
1289       state->NfiqSig = HIGH;
1290       state->Exception--;
1291       return ARMul_DONE;
1292
1293     case 4:
1294       state->NirqSig = HIGH;
1295       state->Exception--;
1296       return ARMul_DONE;
1297
1298     case 5:
1299       ValReg[BITS (0, 3)] = ARMul_Time (state);
1300       return ARMul_DONE;
1301     }
1302
1303   return ARMul_CANT;
1304 }
1305
1306 /* Install co-processor instruction handlers in this routine.  */
1307
1308 unsigned
1309 ARMul_CoProInit (ARMul_State * state)
1310 {
1311   unsigned int i;
1312
1313   /* Initialise tham all first.  */
1314   for (i = 0; i < 16; i++)
1315     ARMul_CoProDetach (state, i);
1316
1317   /* Install CoPro Instruction handlers here.
1318      The format is:
1319      ARMul_CoProAttach (state, CP Number,
1320                         Init routine, Exit routine
1321                         LDC routine, STC routine,
1322                         MRC routine, MCR routine,
1323                         CDP routine,
1324                         Read Reg routine, Write Reg routine).  */
1325   ARMul_CoProAttach (state, 4, NULL, NULL,
1326                      ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL);
1327
1328   ARMul_CoProAttach (state, 5, NULL, NULL,
1329                      NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL);
1330
1331   ARMul_CoProAttach (state, 15, MMUInit, NULL,
1332                      NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite);
1333
1334   ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL,
1335                      XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC,
1336                      XScale_cp13_MCR, NULL, XScale_cp13_read_reg,
1337                      XScale_cp13_write_reg);
1338
1339   ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL,
1340                      XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC,
1341                      XScale_cp14_MCR, NULL, XScale_cp14_read_reg,
1342                      XScale_cp14_write_reg);
1343
1344   ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL,
1345                      NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR,
1346                      NULL, XScale_cp15_read_reg, XScale_cp15_write_reg);
1347
1348   /* No handlers below here.  */
1349
1350   /* Call all the initialisation routines.  */
1351   for (i = 0; i < 16; i++)
1352     if (state->CPInit[i])
1353       (state->CPInit[i]) (state);
1354
1355   return TRUE;
1356 }
1357
1358 /* Install co-processor finalisation routines in this routine.  */
1359
1360 void
1361 ARMul_CoProExit (ARMul_State * state)
1362 {
1363   register unsigned i;
1364
1365   for (i = 0; i < 16; i++)
1366     if (state->CPExit[i])
1367       (state->CPExit[i]) (state);
1368
1369   for (i = 0; i < 16; i++)      /* Detach all handlers.  */
1370     ARMul_CoProDetach (state, i);
1371 }
1372
1373 /* Routines to hook Co-processors into ARMulator.  */
1374
1375 void
1376 ARMul_CoProAttach (ARMul_State *    state,
1377                    unsigned         number,
1378                    ARMul_CPInits *  init,
1379                    ARMul_CPExits *  exit,
1380                    ARMul_LDCs *     ldc,
1381                    ARMul_STCs *     stc,
1382                    ARMul_MRCs *     mrc,
1383                    ARMul_MCRs *     mcr,
1384                    ARMul_CDPs *     cdp,
1385                    ARMul_CPReads *  read,
1386                    ARMul_CPWrites * write)
1387 {
1388   if (init != NULL)
1389     state->CPInit[number] = init;
1390   if (exit != NULL)
1391     state->CPExit[number] = exit;
1392   if (ldc != NULL)
1393     state->LDC[number] = ldc;
1394   if (stc != NULL)
1395     state->STC[number] = stc;
1396   if (mrc != NULL)
1397     state->MRC[number] = mrc;
1398   if (mcr != NULL)
1399     state->MCR[number] = mcr;
1400   if (cdp != NULL)
1401     state->CDP[number] = cdp;
1402   if (read != NULL)
1403     state->CPRead[number] = read;
1404   if (write != NULL)
1405     state->CPWrite[number] = write;
1406 }
1407
1408 void
1409 ARMul_CoProDetach (ARMul_State * state, unsigned number)
1410 {
1411   ARMul_CoProAttach (state, number, NULL, NULL,
1412                      NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R,
1413                      NoCoPro3R, NULL, NULL);
1414
1415   state->CPInit[number] = NULL;
1416   state->CPExit[number] = NULL;
1417   state->CPRead[number] = NULL;
1418   state->CPWrite[number] = NULL;
1419 }