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