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