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