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