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 
26 static unsigned
NoCoPro3R(ARMul_State * state ATTRIBUTE_UNUSED,unsigned a ATTRIBUTE_UNUSED,ARMword b ATTRIBUTE_UNUSED)27 NoCoPro3R (ARMul_State * state ATTRIBUTE_UNUSED,
28 	   unsigned      a     ATTRIBUTE_UNUSED,
29 	   ARMword       b     ATTRIBUTE_UNUSED)
30 {
31   return ARMul_CANT;
32 }
33 
34 static unsigned
NoCoPro4R(ARMul_State * state ATTRIBUTE_UNUSED,unsigned a ATTRIBUTE_UNUSED,ARMword b ATTRIBUTE_UNUSED,ARMword c ATTRIBUTE_UNUSED)35 NoCoPro4R (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 
43 static unsigned
NoCoPro4W(ARMul_State * state ATTRIBUTE_UNUSED,unsigned a ATTRIBUTE_UNUSED,ARMword b ATTRIBUTE_UNUSED,ARMword * c ATTRIBUTE_UNUSED)44 NoCoPro4W (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.  */
55 static void     write_cp14_reg (unsigned, ARMword);
56 static 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.  */
61 static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
62 static 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.  */
65 static ARMword XScale_cp15_DBR1;
66 static ARMword XScale_cp15_DBCON;
67 static ARMword XScale_cp15_IBCR0;
68 static ARMword XScale_cp15_IBCR1;
69 
70 static unsigned
XScale_cp15_init(ARMul_State * state ATTRIBUTE_UNUSED)71 XScale_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 
93 static unsigned
check_cp15_access(ARMul_State * state,unsigned reg,unsigned CRm,unsigned opcode_1,unsigned opcode_2)94 check_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 
216 static void
write_cp15_reg(ARMul_State * state,unsigned reg,unsigned opcode_2,unsigned CRm,ARMword value)217 write_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 
345 ARMword
read_cp15_reg(unsigned reg,unsigned opcode_2,unsigned CRm)346 read_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 
374 static unsigned
XScale_cp15_LDC(ARMul_State * state,unsigned type,ARMword instr,ARMword data)375 XScale_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 
388 static unsigned
XScale_cp15_STC(ARMul_State * state,unsigned type,ARMword instr,ARMword * data)389 XScale_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 
402 static unsigned
XScale_cp15_MRC(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)403 XScale_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 
421 static unsigned
XScale_cp15_MCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)422 XScale_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 
440 static unsigned
XScale_cp15_read_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)441 XScale_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 
452 static unsigned
XScale_cp15_write_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword value)453 XScale_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 
466 void
XScale_check_memacc(ARMul_State * state,ARMword * address,int store)467 XScale_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 
532 void
XScale_set_fsr_far(ARMul_State * state,ARMword fsr,ARMword far)533 XScale_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 
544 int
XScale_debug_moe(ARMul_State * state,int moe)545 XScale_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 
573 static ARMword XScale_cp13_CR0_Regs[16];
574 static ARMword XScale_cp13_CR1_Regs[16];
575 
576 static unsigned
XScale_cp13_init(ARMul_State * state ATTRIBUTE_UNUSED)577 XScale_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 
590 static unsigned
check_cp13_access(ARMul_State * state,unsigned reg,unsigned CRm,unsigned opcode_1,unsigned opcode_2)591 check_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 
629 static void
write_cp13_reg(unsigned reg,unsigned CRm,ARMword value)630 write_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 
705 static ARMword
read_cp13_reg(unsigned reg,unsigned CRm)706 read_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 
716 static unsigned
XScale_cp13_LDC(ARMul_State * state,unsigned type,ARMword instr,ARMword data)717 XScale_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 
730 static unsigned
XScale_cp13_STC(ARMul_State * state,unsigned type,ARMword instr,ARMword * data)731 XScale_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 
744 static unsigned
XScale_cp13_MRC(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)745 XScale_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 
762 static unsigned
XScale_cp13_MCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)763 XScale_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 
780 static unsigned
XScale_cp13_read_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)781 XScale_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 
792 static unsigned
XScale_cp13_write_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword value)793 XScale_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 
807 static ARMword XScale_cp14_Regs[16];
808 
809 static unsigned
XScale_cp14_init(ARMul_State * state ATTRIBUTE_UNUSED)810 XScale_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 
820 static unsigned
check_cp14_access(ARMul_State * state,unsigned reg,unsigned CRm,unsigned opcode1,unsigned opcode2)821 check_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 
848 static void
write_cp14_reg(unsigned reg,ARMword value)849 write_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 
912 ARMword
read_cp14_reg(unsigned reg)913 read_cp14_reg (unsigned reg)
914 {
915   return XScale_cp14_Regs [reg];
916 }
917 
918 static unsigned
XScale_cp14_LDC(ARMul_State * state,unsigned type,ARMword instr,ARMword data)919 XScale_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 
932 static unsigned
XScale_cp14_STC(ARMul_State * state,unsigned type,ARMword instr,ARMword * data)933 XScale_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 
946 static unsigned
XScale_cp14_MRC(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)947 XScale_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 
966 static unsigned
XScale_cp14_MCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)967 XScale_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 
986 static unsigned
XScale_cp14_read_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)987 XScale_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 
999 static unsigned
XScale_cp14_write_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword value)1000 XScale_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 
1020 static ARMword MMUReg[8];
1021 
1022 static unsigned
MMUInit(ARMul_State * state)1023 MMUInit (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 
1033 static unsigned
MMUMRC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)1034 MMUMRC (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 
1049 static unsigned
MMUMCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)1050 MMUMCR (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 
1084 static unsigned
MMURead(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)1085 MMURead (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 
1095 static unsigned
MMUWrite(ARMul_State * state,unsigned reg,ARMword value)1096 MMUWrite (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 
1138 static ARMword ValReg[16];
1139 
1140 static unsigned
ValLDC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type,ARMword instr,ARMword data)1141 ValLDC (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 
1163 static unsigned
ValSTC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type,ARMword instr,ARMword * data)1164 ValSTC (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 
1186 static unsigned
ValMRC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)1187 ValMRC (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 
1197 static unsigned
ValMCR(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)1198 ValMCR (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 
1208 static unsigned
ValCDP(ARMul_State * state,unsigned type,ARMword instr)1209 ValCDP (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 
1238 static unsigned
DoAFIQ(ARMul_State * state)1239 DoAFIQ (ARMul_State * state)
1240 {
1241   state->NfiqSig = LOW;
1242   state->Exception++;
1243   return 0;
1244 }
1245 
1246 static unsigned
DoAIRQ(ARMul_State * state)1247 DoAIRQ (ARMul_State * state)
1248 {
1249   state->NirqSig = LOW;
1250   state->Exception++;
1251   return 0;
1252 }
1253 
1254 static unsigned
IntCDP(ARMul_State * state,unsigned type,ARMword instr)1255 IntCDP (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 
1315 unsigned
ARMul_CoProInit(ARMul_State * state)1316 ARMul_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 
1390 void
ARMul_CoProExit(ARMul_State * state)1391 ARMul_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 
1405 void
ARMul_CoProAttach(ARMul_State * state,unsigned number,ARMul_CPInits * init,ARMul_CPExits * exit,ARMul_LDCs * ldc,ARMul_STCs * stc,ARMul_MRCs * mrc,ARMul_MCRs * mcr,ARMul_CDPs * cdp,ARMul_CPReads * read,ARMul_CPWrites * write)1406 ARMul_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 
1438 void
ARMul_CoProDetach(ARMul_State * state,unsigned number)1439 ARMul_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