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