xref: /netbsd-src/external/gpl3/gdb/dist/sim/arm/armcopro.c (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
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 
28 static unsigned
NoCoPro3R(ARMul_State * state ATTRIBUTE_UNUSED,unsigned a ATTRIBUTE_UNUSED,ARMword b ATTRIBUTE_UNUSED)29 NoCoPro3R (ARMul_State * state ATTRIBUTE_UNUSED,
30 	   unsigned      a     ATTRIBUTE_UNUSED,
31 	   ARMword       b     ATTRIBUTE_UNUSED)
32 {
33   return ARMul_CANT;
34 }
35 
36 static unsigned
NoCoPro4R(ARMul_State * state ATTRIBUTE_UNUSED,unsigned a ATTRIBUTE_UNUSED,ARMword b ATTRIBUTE_UNUSED,ARMword c ATTRIBUTE_UNUSED)37 NoCoPro4R (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 
45 static unsigned
NoCoPro4W(ARMul_State * state ATTRIBUTE_UNUSED,unsigned a ATTRIBUTE_UNUSED,ARMword b ATTRIBUTE_UNUSED,ARMword * c ATTRIBUTE_UNUSED)46 NoCoPro4W (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.  */
57 static void     write_cp14_reg (unsigned, ARMword);
58 static 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.  */
63 static ARMword XScale_cp15_opcode_2_is_0_Regs[16];
64 static 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.  */
67 static ARMword XScale_cp15_DBR1;
68 static ARMword XScale_cp15_DBCON;
69 static ARMword XScale_cp15_IBCR0;
70 static ARMword XScale_cp15_IBCR1;
71 
72 static unsigned
XScale_cp15_init(ARMul_State * state ATTRIBUTE_UNUSED)73 XScale_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 
97 static unsigned
check_cp15_access(ARMul_State * state,unsigned reg,unsigned CRm,unsigned opcode_1,unsigned opcode_2)98 check_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 
220 static void
write_cp15_reg(ARMul_State * state,unsigned reg,unsigned opcode_2,unsigned CRm,ARMword value)221 write_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 
349 ARMword
read_cp15_reg(unsigned reg,unsigned opcode_2,unsigned CRm)350 read_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 
378 static unsigned
XScale_cp15_MRC(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)379 XScale_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 
397 static unsigned
XScale_cp15_MCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)398 XScale_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 
416 static unsigned
XScale_cp15_read_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)417 XScale_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 
428 static unsigned
XScale_cp15_write_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword value)429 XScale_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 
442 void
XScale_check_memacc(ARMul_State * state,ARMword * address,int store)443 XScale_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 
508 void
XScale_set_fsr_far(ARMul_State * state,ARMword fsr,ARMword far)509 XScale_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 
520 int
XScale_debug_moe(ARMul_State * state,int moe)521 XScale_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 
549 static ARMword XScale_cp13_CR0_Regs[16];
550 static ARMword XScale_cp13_CR1_Regs[16];
551 
552 static unsigned
XScale_cp13_init(ARMul_State * state ATTRIBUTE_UNUSED)553 XScale_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 
568 static unsigned
check_cp13_access(ARMul_State * state,unsigned reg,unsigned CRm,unsigned opcode_1,unsigned opcode_2)569 check_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 
607 static void
write_cp13_reg(unsigned reg,unsigned CRm,ARMword value)608 write_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 
683 static ARMword
read_cp13_reg(unsigned reg,unsigned CRm)684 read_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 
694 static unsigned
XScale_cp13_LDC(ARMul_State * state,unsigned type,ARMword instr,ARMword data)695 XScale_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 
708 static unsigned
XScale_cp13_STC(ARMul_State * state,unsigned type,ARMword instr,ARMword * data)709 XScale_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 
722 static unsigned
XScale_cp13_MRC(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)723 XScale_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 
740 static unsigned
XScale_cp13_MCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)741 XScale_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 
758 static unsigned
XScale_cp13_read_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)759 XScale_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 
770 static unsigned
XScale_cp13_write_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword value)771 XScale_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 
785 static ARMword XScale_cp14_Regs[16];
786 
787 static unsigned
XScale_cp14_init(ARMul_State * state ATTRIBUTE_UNUSED)788 XScale_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 
800 static unsigned
check_cp14_access(ARMul_State * state,unsigned reg,unsigned CRm,unsigned opcode1,unsigned opcode2)801 check_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 
828 static void
write_cp14_reg(unsigned reg,ARMword value)829 write_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 
892 ARMword
read_cp14_reg(unsigned reg)893 read_cp14_reg (unsigned reg)
894 {
895   return XScale_cp14_Regs [reg];
896 }
897 
898 static unsigned
XScale_cp14_LDC(ARMul_State * state,unsigned type,ARMword instr,ARMword data)899 XScale_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 
912 static unsigned
XScale_cp14_STC(ARMul_State * state,unsigned type,ARMword instr,ARMword * data)913 XScale_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 
926 static unsigned
XScale_cp14_MRC(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)927 XScale_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 
946 static unsigned
XScale_cp14_MCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)947 XScale_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 
966 static unsigned
XScale_cp14_read_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)967 XScale_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 
979 static unsigned
XScale_cp14_write_reg(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword value)980 XScale_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 
1000 static ARMword MMUReg[8];
1001 
1002 static unsigned
MMUInit(ARMul_State * state)1003 MMUInit (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 
1013 static unsigned
MMUMRC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)1014 MMUMRC (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 
1029 static unsigned
MMUMCR(ARMul_State * state,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)1030 MMUMCR (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 
1064 static unsigned
MMURead(ARMul_State * state ATTRIBUTE_UNUSED,unsigned reg,ARMword * value)1065 MMURead (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 
1075 static unsigned
MMUWrite(ARMul_State * state,unsigned reg,ARMword value)1076 MMUWrite (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 
1118 static ARMword ValReg[16];
1119 
1120 static unsigned
ValLDC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type,ARMword instr,ARMword data)1121 ValLDC (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 
1143 static unsigned
ValSTC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type,ARMword instr,ARMword * data)1144 ValSTC (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 
1166 static unsigned
ValMRC(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword * value)1167 ValMRC (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 
1177 static unsigned
ValMCR(ARMul_State * state ATTRIBUTE_UNUSED,unsigned type ATTRIBUTE_UNUSED,ARMword instr,ARMword value)1178 ValMCR (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 
1188 static unsigned
ValCDP(ARMul_State * state,unsigned type,ARMword instr)1189 ValCDP (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 
1218 static unsigned
DoAFIQ(ARMul_State * state)1219 DoAFIQ (ARMul_State * state)
1220 {
1221   state->NfiqSig = LOW;
1222   state->Exception++;
1223   return 0;
1224 }
1225 
1226 static unsigned
DoAIRQ(ARMul_State * state)1227 DoAIRQ (ARMul_State * state)
1228 {
1229   state->NirqSig = LOW;
1230   state->Exception++;
1231   return 0;
1232 }
1233 
1234 static unsigned
IntCDP(ARMul_State * state,unsigned type,ARMword instr)1235 IntCDP (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 
1295 unsigned
ARMul_CoProInit(ARMul_State * state)1296 ARMul_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 
1370 void
ARMul_CoProExit(ARMul_State * state)1371 ARMul_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 
1385 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)1386 ARMul_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 
1418 void
ARMul_CoProDetach(ARMul_State * state,unsigned number)1419 ARMul_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