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