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