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