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