1/* armcopro.c -- co-processor interface: ARM6 Instruction Emulator. 2 Copyright (C) 1994, 2000 Advanced RISC Machines Ltd. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 17 18#include "armdefs.h" 19#include "armos.h" 20#include "armemu.h" 21#include "ansidecl.h" 22#include "iwmmxt.h" 23 24/* Dummy Co-processors. */ 25 26static unsigned 27NoCoPro3R (ARMul_State * state ATTRIBUTE_UNUSED, 28 unsigned a ATTRIBUTE_UNUSED, 29 ARMword b ATTRIBUTE_UNUSED) 30{ 31 return ARMul_CANT; 32} 33 34static unsigned 35NoCoPro4R (ARMul_State * state ATTRIBUTE_UNUSED, 36 unsigned a ATTRIBUTE_UNUSED, 37 ARMword b ATTRIBUTE_UNUSED, 38 ARMword c ATTRIBUTE_UNUSED) 39{ 40 return ARMul_CANT; 41} 42 43static unsigned 44NoCoPro4W (ARMul_State * state ATTRIBUTE_UNUSED, 45 unsigned a ATTRIBUTE_UNUSED, 46 ARMword b ATTRIBUTE_UNUSED, 47 ARMword * c ATTRIBUTE_UNUSED) 48{ 49 return ARMul_CANT; 50} 51 52/* The XScale Co-processors. */ 53 54/* Coprocessor 15: System Control. */ 55static void write_cp14_reg (unsigned, ARMword); 56static ARMword read_cp14_reg (unsigned); 57 58/* There are two sets of registers for copro 15. 59 One set is available when opcode_2 is 0 and 60 the other set when opcode_2 >= 1. */ 61static ARMword XScale_cp15_opcode_2_is_0_Regs[16]; 62static ARMword XScale_cp15_opcode_2_is_not_0_Regs[16]; 63/* There are also a set of breakpoint registers 64 which are accessed via CRm instead of opcode_2. */ 65static ARMword XScale_cp15_DBR1; 66static ARMword XScale_cp15_DBCON; 67static ARMword XScale_cp15_IBCR0; 68static ARMword XScale_cp15_IBCR1; 69 70static unsigned 71XScale_cp15_init (ARMul_State * state ATTRIBUTE_UNUSED) 72{ 73 int i; 74 75 for (i = 16; i--;) 76 { 77 XScale_cp15_opcode_2_is_0_Regs[i] = 0; 78 XScale_cp15_opcode_2_is_not_0_Regs[i] = 0; 79 } 80 81 /* Initialise the processor ID. */ 82 XScale_cp15_opcode_2_is_0_Regs[0] = 0x69052000; 83 84 /* Initialise the cache type. */ 85 XScale_cp15_opcode_2_is_not_0_Regs[0] = 0x0B1AA1AA; 86 87 /* Initialise the ARM Control Register. */ 88 XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078; 89} 90 91/* Check an access to a register. */ 92 93static unsigned 94check_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 216static void 217write_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 345ARMword 346read_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 374static unsigned 375XScale_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 388static unsigned 389XScale_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 402static unsigned 403XScale_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 421static unsigned 422XScale_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 440static unsigned 441XScale_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 452static unsigned 453XScale_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 466void 467XScale_check_memacc (ARMul_State * state, ARMword * address, int store) 468{ 469 ARMword dbcon, r0, r1; 470 int e1, e0; 471 472 if (!state->is_XScale) 473 return; 474 475 /* Check for PID-ification. 476 XXX BTB access support will require this test failing. */ 477 r0 = (read_cp15_reg (13, 0, 0) & 0xfe000000); 478 if (r0 && (* address & 0xfe000000) == 0) 479 * address |= r0; 480 481 /* Check alignment fault enable/disable. */ 482 if ((read_cp15_reg (1, 0, 0) & ARMul_CP15_R1_ALIGN) && (* address & 3)) 483 { 484 /* Set the FSR and FAR. 485 Do not use XScale_set_fsr_far as this checks the DCSR register. */ 486 write_cp15_reg (state, 5, 0, 0, ARMul_CP15_R5_MMU_EXCPT); 487 write_cp15_reg (state, 6, 0, 0, * address); 488 489 ARMul_Abort (state, ARMul_DataAbortV); 490 } 491 492 if (XScale_debug_moe (state, -1)) 493 return; 494 495 /* Check the data breakpoint registers. */ 496 dbcon = read_cp15_reg (14, 0, 4); 497 r0 = read_cp15_reg (14, 0, 0); 498 r1 = read_cp15_reg (14, 0, 3); 499 e0 = dbcon & ARMul_CP15_DBCON_E0; 500 501 if (dbcon & ARMul_CP15_DBCON_M) 502 { 503 /* r1 is a inverse mask. */ 504 if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1)) 505 && ((* address & ~r1) == (r0 & ~r1))) 506 { 507 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB); 508 ARMul_OSHandleSWI (state, SWI_Breakpoint); 509 } 510 } 511 else 512 { 513 if (e0 != 0 && ((store && e0 != 3) || (!store && e0 != 1)) 514 && ((* address & ~3) == (r0 & ~3))) 515 { 516 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB); 517 ARMul_OSHandleSWI (state, SWI_Breakpoint); 518 } 519 520 e1 = (dbcon & ARMul_CP15_DBCON_E1) >> 2; 521 if (e1 != 0 && ((store && e1 != 3) || (!store && e1 != 1)) 522 && ((* address & ~3) == (r1 & ~3))) 523 { 524 XScale_debug_moe (state, ARMul_CP14_R10_MOE_DB); 525 ARMul_OSHandleSWI (state, SWI_Breakpoint); 526 } 527 } 528} 529 530/* Set the XScale FSR and FAR registers. */ 531 532void 533XScale_set_fsr_far (ARMul_State * state, ARMword fsr, ARMword far) 534{ 535 if (!state->is_XScale || (read_cp14_reg (10) & (1UL << 31)) == 0) 536 return; 537 538 write_cp15_reg (state, 5, 0, 0, fsr); 539 write_cp15_reg (state, 6, 0, 0, far); 540} 541 542/* Set the XScale debug `method of entry' if it is enabled. */ 543 544int 545XScale_debug_moe (ARMul_State * state, int moe) 546{ 547 ARMword value; 548 549 if (!state->is_XScale) 550 return 1; 551 552 value = read_cp14_reg (10); 553 if (value & (1UL << 31)) 554 { 555 if (moe != -1) 556 { 557 value &= ~0x1c; 558 value |= moe; 559 560 write_cp14_reg (10, value); 561 } 562 return 1; 563 } 564 return 0; 565} 566 567/* Coprocessor 13: Interrupt Controller and Bus Controller. */ 568 569/* There are two sets of registers for copro 13. 570 One set (of three registers) is available when CRm is 0 571 and the other set (of six registers) when CRm is 1. */ 572 573static ARMword XScale_cp13_CR0_Regs[16]; 574static ARMword XScale_cp13_CR1_Regs[16]; 575 576static unsigned 577XScale_cp13_init (ARMul_State * state ATTRIBUTE_UNUSED) 578{ 579 int i; 580 581 for (i = 16; i--;) 582 { 583 XScale_cp13_CR0_Regs[i] = 0; 584 XScale_cp13_CR1_Regs[i] = 0; 585 } 586} 587 588/* Check an access to a register. */ 589 590static unsigned 591check_cp13_access (ARMul_State * state, 592 unsigned reg, 593 unsigned CRm, 594 unsigned opcode_1, 595 unsigned opcode_2) 596{ 597 /* Do not allow access to these registers in USER mode. */ 598 if (state->Mode == USER26MODE || state->Mode == USER32MODE) 599 return ARMul_CANT; 600 601 /* The opcodes should be zero. */ 602 if ((opcode_1 != 0) || (opcode_2 != 0)) 603 return ARMul_CANT; 604 605 /* Do not allow access to these register if bit 606 13 of coprocessor 15's register 15 is zero. */ 607 if (! CP_ACCESS_ALLOWED (state, 13)) 608 return ARMul_CANT; 609 610 /* Registers 0, 4 and 8 are defined when CRm == 0. 611 Registers 0, 1, 4, 5, 6, 7, 8 are defined when CRm == 1. 612 For all other CRm values undefined behaviour results. */ 613 if (CRm == 0) 614 { 615 if (reg == 0 || reg == 4 || reg == 8) 616 return ARMul_DONE; 617 } 618 else if (CRm == 1) 619 { 620 if (reg == 0 || reg == 1 || (reg >= 4 && reg <= 8)) 621 return ARMul_DONE; 622 } 623 624 return ARMul_CANT; 625} 626 627/* Store a value into one of coprocessor 13's registers. */ 628 629static void 630write_cp13_reg (unsigned reg, unsigned CRm, ARMword value) 631{ 632 switch (CRm) 633 { 634 case 0: 635 switch (reg) 636 { 637 case 0: /* INTCTL */ 638 /* Only BITS (3:0) can be written. */ 639 value &= 0xf; 640 break; 641 642 case 4: /* INTSRC */ 643 /* No bits may be written. */ 644 return; 645 646 case 8: /* INTSTR */ 647 /* Only BITS (1:0) can be written. */ 648 value &= 0x3; 649 break; 650 651 default: 652 /* Should not happen. Ignore any writes to unimplemented registers. */ 653 return; 654 } 655 656 XScale_cp13_CR0_Regs [reg] = value; 657 break; 658 659 case 1: 660 switch (reg) 661 { 662 case 0: /* BCUCTL */ 663 /* Only BITS (30:28) and BITS (3:0) can be written. 664 BIT(31) is write ignored. */ 665 value &= 0x7000000f; 666 value |= XScale_cp13_CR1_Regs[0] & (1UL << 31); 667 break; 668 669 case 1: /* BCUMOD */ 670 /* Only bit 0 is accecssible. */ 671 value &= 1; 672 value |= XScale_cp13_CR1_Regs[1] & ~ 1; 673 break; 674 675 case 4: /* ELOG0 */ 676 case 5: /* ELOG1 */ 677 case 6: /* ECAR0 */ 678 case 7: /* ECAR1 */ 679 /* No bits can be written. */ 680 return; 681 682 case 8: /* ECTST */ 683 /* Only BITS (7:0) can be written. */ 684 value &= 0xff; 685 break; 686 687 default: 688 /* Should not happen. Ignore any writes to unimplemented registers. */ 689 return; 690 } 691 692 XScale_cp13_CR1_Regs [reg] = value; 693 break; 694 695 default: 696 /* Should not happen. */ 697 break; 698 } 699 700 return; 701} 702 703/* Return the value in a cp13 register. */ 704 705static ARMword 706read_cp13_reg (unsigned reg, unsigned CRm) 707{ 708 if (CRm == 0) 709 return XScale_cp13_CR0_Regs [reg]; 710 else if (CRm == 1) 711 return XScale_cp13_CR1_Regs [reg]; 712 713 return 0; 714} 715 716static unsigned 717XScale_cp13_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data) 718{ 719 unsigned reg = BITS (12, 15); 720 unsigned result; 721 722 result = check_cp13_access (state, reg, 0, 0, 0); 723 724 if (result == ARMul_DONE && type == ARMul_DATA) 725 write_cp13_reg (reg, 0, data); 726 727 return result; 728} 729 730static unsigned 731XScale_cp13_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data) 732{ 733 unsigned reg = BITS (12, 15); 734 unsigned result; 735 736 result = check_cp13_access (state, reg, 0, 0, 0); 737 738 if (result == ARMul_DONE && type == ARMul_DATA) 739 * data = read_cp13_reg (reg, 0); 740 741 return result; 742} 743 744static unsigned 745XScale_cp13_MRC (ARMul_State * state, 746 unsigned type ATTRIBUTE_UNUSED, 747 ARMword instr, 748 ARMword * value) 749{ 750 unsigned CRm = BITS (0, 3); 751 unsigned reg = BITS (16, 19); 752 unsigned result; 753 754 result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7)); 755 756 if (result == ARMul_DONE) 757 * value = read_cp13_reg (reg, CRm); 758 759 return result; 760} 761 762static unsigned 763XScale_cp13_MCR (ARMul_State * state, 764 unsigned type ATTRIBUTE_UNUSED, 765 ARMword instr, 766 ARMword value) 767{ 768 unsigned CRm = BITS (0, 3); 769 unsigned reg = BITS (16, 19); 770 unsigned result; 771 772 result = check_cp13_access (state, reg, CRm, BITS (21, 23), BITS (5, 7)); 773 774 if (result == ARMul_DONE) 775 write_cp13_reg (reg, CRm, value); 776 777 return result; 778} 779 780static unsigned 781XScale_cp13_read_reg (ARMul_State * state ATTRIBUTE_UNUSED, 782 unsigned reg, 783 ARMword * value) 784{ 785 /* FIXME: Not sure what to do about the alternative register set 786 here. For now default to just accessing CRm == 0 registers. */ 787 * value = read_cp13_reg (reg, 0); 788 789 return TRUE; 790} 791 792static unsigned 793XScale_cp13_write_reg (ARMul_State * state ATTRIBUTE_UNUSED, 794 unsigned reg, 795 ARMword value) 796{ 797 /* FIXME: Not sure what to do about the alternative register set 798 here. For now default to just accessing CRm == 0 registers. */ 799 write_cp13_reg (reg, 0, value); 800 801 return TRUE; 802} 803 804/* Coprocessor 14: Performance Monitoring, Clock and Power management, 805 Software Debug. */ 806 807static ARMword XScale_cp14_Regs[16]; 808 809static unsigned 810XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED) 811{ 812 int i; 813 814 for (i = 16; i--;) 815 XScale_cp14_Regs[i] = 0; 816} 817 818/* Check an access to a register. */ 819 820static unsigned 821check_cp14_access (ARMul_State * state, 822 unsigned reg, 823 unsigned CRm, 824 unsigned opcode1, 825 unsigned opcode2) 826{ 827 /* Not allowed to access these register in USER mode. */ 828 if (state->Mode == USER26MODE || state->Mode == USER32MODE) 829 return ARMul_CANT; 830 831 /* CRm should be zero. */ 832 if (CRm != 0) 833 return ARMul_CANT; 834 835 /* OPcodes should be zero. */ 836 if (opcode1 != 0 || opcode2 != 0) 837 return ARMul_CANT; 838 839 /* Accessing registers 4 or 5 has unpredicatable results. */ 840 if (reg >= 4 && reg <= 5) 841 return ARMul_CANT; 842 843 return ARMul_DONE; 844} 845 846/* Store a value into one of coprocessor 14's registers. */ 847 848static void 849write_cp14_reg (unsigned reg, ARMword value) 850{ 851 switch (reg) 852 { 853 case 0: /* PMNC */ 854 /* Only BITS (27:12), BITS (10:8) and BITS (6:0) can be written. */ 855 value &= 0x0ffff77f; 856 857 /* Reset the clock counter if necessary. */ 858 if (value & ARMul_CP14_R0_CLKRST) 859 XScale_cp14_Regs [1] = 0; 860 break; 861 862 case 4: 863 case 5: 864 /* We should not normally reach this code. The debugger interface 865 can bypass the normal checks though, so it could happen. */ 866 value = 0; 867 break; 868 869 case 6: /* CCLKCFG */ 870 /* Only BITS (3:0) can be written. */ 871 value &= 0xf; 872 break; 873 874 case 7: /* PWRMODE */ 875 /* Although BITS (1:0) can be written with non-zero values, this would 876 have the side effect of putting the processor to sleep. Thus in 877 order for the register to be read again, it would have to go into 878 ACTIVE mode, which means that any read will see these bits as zero. 879 880 Rather than trying to implement complex reset-to-zero-upon-read logic 881 we just override the write value with zero. */ 882 value = 0; 883 break; 884 885 case 10: /* DCSR */ 886 /* Only BITS (31:30), BITS (23:22), BITS (20:16) and BITS (5:0) can 887 be written. */ 888 value &= 0xc0df003f; 889 break; 890 891 case 11: /* TBREG */ 892 /* No writes are permitted. */ 893 value = 0; 894 break; 895 896 case 14: /* TXRXCTRL */ 897 /* Only BITS (31:30) can be written. */ 898 value &= 0xc0000000; 899 break; 900 901 default: 902 /* All bits can be written. */ 903 break; 904 } 905 906 XScale_cp14_Regs [reg] = value; 907} 908 909/* Return the value in a cp14 register. Not a static function since 910 it is used by the code to emulate the BKPT instruction in armemu.c. */ 911 912ARMword 913read_cp14_reg (unsigned reg) 914{ 915 return XScale_cp14_Regs [reg]; 916} 917 918static unsigned 919XScale_cp14_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data) 920{ 921 unsigned reg = BITS (12, 15); 922 unsigned result; 923 924 result = check_cp14_access (state, reg, 0, 0, 0); 925 926 if (result == ARMul_DONE && type == ARMul_DATA) 927 write_cp14_reg (reg, data); 928 929 return result; 930} 931 932static unsigned 933XScale_cp14_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data) 934{ 935 unsigned reg = BITS (12, 15); 936 unsigned result; 937 938 result = check_cp14_access (state, reg, 0, 0, 0); 939 940 if (result == ARMul_DONE && type == ARMul_DATA) 941 * data = read_cp14_reg (reg); 942 943 return result; 944} 945 946static unsigned 947XScale_cp14_MRC 948( 949 ARMul_State * state, 950 unsigned type ATTRIBUTE_UNUSED, 951 ARMword instr, 952 ARMword * value 953) 954{ 955 unsigned reg = BITS (16, 19); 956 unsigned result; 957 958 result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7)); 959 960 if (result == ARMul_DONE) 961 * value = read_cp14_reg (reg); 962 963 return result; 964} 965 966static unsigned 967XScale_cp14_MCR 968( 969 ARMul_State * state, 970 unsigned type ATTRIBUTE_UNUSED, 971 ARMword instr, 972 ARMword value 973) 974{ 975 unsigned reg = BITS (16, 19); 976 unsigned result; 977 978 result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7)); 979 980 if (result == ARMul_DONE) 981 write_cp14_reg (reg, value); 982 983 return result; 984} 985 986static unsigned 987XScale_cp14_read_reg 988( 989 ARMul_State * state ATTRIBUTE_UNUSED, 990 unsigned reg, 991 ARMword * value 992) 993{ 994 * value = read_cp14_reg (reg); 995 996 return TRUE; 997} 998 999static unsigned 1000XScale_cp14_write_reg 1001( 1002 ARMul_State * state ATTRIBUTE_UNUSED, 1003 unsigned reg, 1004 ARMword value 1005) 1006{ 1007 write_cp14_reg (reg, value); 1008 1009 return TRUE; 1010} 1011 1012/* Here's ARMulator's MMU definition. A few things to note: 1013 1) It has eight registers, but only two are defined. 1014 2) You can only access its registers with MCR and MRC. 1015 3) MMU Register 0 (ID) returns 0x41440110 1016 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4 1017 controls 32/26 bit program space, bit 5 controls 32/26 bit data space, 1018 bit 6 controls late abort timimg and bit 7 controls big/little endian. */ 1019 1020static ARMword MMUReg[8]; 1021 1022static unsigned 1023MMUInit (ARMul_State * state) 1024{ 1025 MMUReg[1] = state->prog32Sig << 4 | 1026 state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7; 1027 1028 ARMul_ConsolePrint (state, ", MMU present"); 1029 1030 return TRUE; 1031} 1032 1033static unsigned 1034MMUMRC (ARMul_State * state ATTRIBUTE_UNUSED, 1035 unsigned type ATTRIBUTE_UNUSED, 1036 ARMword instr, 1037 ARMword * value) 1038{ 1039 int reg = BITS (16, 19) & 7; 1040 1041 if (reg == 0) 1042 *value = 0x41440110; 1043 else 1044 *value = MMUReg[reg]; 1045 1046 return ARMul_DONE; 1047} 1048 1049static unsigned 1050MMUMCR (ARMul_State * state, 1051 unsigned type ATTRIBUTE_UNUSED, 1052 ARMword instr, 1053 ARMword value) 1054{ 1055 int reg = BITS (16, 19) & 7; 1056 1057 MMUReg[reg] = value; 1058 1059 if (reg == 1) 1060 { 1061 ARMword p,d,l,b; 1062 1063 p = state->prog32Sig; 1064 d = state->data32Sig; 1065 l = state->lateabtSig; 1066 b = state->bigendSig; 1067 1068 state->prog32Sig = value >> 4 & 1; 1069 state->data32Sig = value >> 5 & 1; 1070 state->lateabtSig = value >> 6 & 1; 1071 state->bigendSig = value >> 7 & 1; 1072 1073 if ( p != state->prog32Sig 1074 || d != state->data32Sig 1075 || l != state->lateabtSig 1076 || b != state->bigendSig) 1077 /* Force ARMulator to notice these now. */ 1078 state->Emulate = CHANGEMODE; 1079 } 1080 1081 return ARMul_DONE; 1082} 1083 1084static unsigned 1085MMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value) 1086{ 1087 if (reg == 0) 1088 *value = 0x41440110; 1089 else if (reg < 8) 1090 *value = MMUReg[reg]; 1091 1092 return TRUE; 1093} 1094 1095static unsigned 1096MMUWrite (ARMul_State * state, unsigned reg, ARMword value) 1097{ 1098 if (reg < 8) 1099 MMUReg[reg] = value; 1100 1101 if (reg == 1) 1102 { 1103 ARMword p,d,l,b; 1104 1105 p = state->prog32Sig; 1106 d = state->data32Sig; 1107 l = state->lateabtSig; 1108 b = state->bigendSig; 1109 1110 state->prog32Sig = value >> 4 & 1; 1111 state->data32Sig = value >> 5 & 1; 1112 state->lateabtSig = value >> 6 & 1; 1113 state->bigendSig = value >> 7 & 1; 1114 1115 if ( p != state->prog32Sig 1116 || d != state->data32Sig 1117 || l != state->lateabtSig 1118 || b != state->bigendSig) 1119 /* Force ARMulator to notice these now. */ 1120 state->Emulate = CHANGEMODE; 1121 } 1122 1123 return TRUE; 1124} 1125 1126 1127/* What follows is the Validation Suite Coprocessor. It uses two 1128 co-processor numbers (4 and 5) and has the follwing functionality. 1129 Sixteen registers. Both co-processor nuimbers can be used in an MCR 1130 and MRC to access these registers. CP 4 can LDC and STC to and from 1131 the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of 1132 cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a 1133 number of cycles (specified in a CP register), CDP 2 issues an IRQW 1134 in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5 1135 stores a 32 bit time value in a CP register (actually it's the total 1136 number of N, S, I, C and F cyles). */ 1137 1138static ARMword ValReg[16]; 1139 1140static unsigned 1141ValLDC (ARMul_State * state ATTRIBUTE_UNUSED, 1142 unsigned type, 1143 ARMword instr, 1144 ARMword data) 1145{ 1146 static unsigned words; 1147 1148 if (type != ARMul_DATA) 1149 words = 0; 1150 else 1151 { 1152 ValReg[BITS (12, 15)] = data; 1153 1154 if (BIT (22)) 1155 /* It's a long access, get two words. */ 1156 if (words++ != 4) 1157 return ARMul_INC; 1158 } 1159 1160 return ARMul_DONE; 1161} 1162 1163static unsigned 1164ValSTC (ARMul_State * state ATTRIBUTE_UNUSED, 1165 unsigned type, 1166 ARMword instr, 1167 ARMword * data) 1168{ 1169 static unsigned words; 1170 1171 if (type != ARMul_DATA) 1172 words = 0; 1173 else 1174 { 1175 * data = ValReg[BITS (12, 15)]; 1176 1177 if (BIT (22)) 1178 /* It's a long access, get two words. */ 1179 if (words++ != 4) 1180 return ARMul_INC; 1181 } 1182 1183 return ARMul_DONE; 1184} 1185 1186static unsigned 1187ValMRC (ARMul_State * state ATTRIBUTE_UNUSED, 1188 unsigned type ATTRIBUTE_UNUSED, 1189 ARMword instr, 1190 ARMword * value) 1191{ 1192 *value = ValReg[BITS (16, 19)]; 1193 1194 return ARMul_DONE; 1195} 1196 1197static unsigned 1198ValMCR (ARMul_State * state ATTRIBUTE_UNUSED, 1199 unsigned type ATTRIBUTE_UNUSED, 1200 ARMword instr, 1201 ARMword value) 1202{ 1203 ValReg[BITS (16, 19)] = value; 1204 1205 return ARMul_DONE; 1206} 1207 1208static unsigned 1209ValCDP (ARMul_State * state, unsigned type, ARMword instr) 1210{ 1211 static unsigned long finish = 0; 1212 1213 if (BITS (20, 23) != 0) 1214 return ARMul_CANT; 1215 1216 if (type == ARMul_FIRST) 1217 { 1218 ARMword howlong; 1219 1220 howlong = ValReg[BITS (0, 3)]; 1221 1222 /* First cycle of a busy wait. */ 1223 finish = ARMul_Time (state) + howlong; 1224 1225 return howlong == 0 ? ARMul_DONE : ARMul_BUSY; 1226 } 1227 else if (type == ARMul_BUSY) 1228 { 1229 if (ARMul_Time (state) >= finish) 1230 return ARMul_DONE; 1231 else 1232 return ARMul_BUSY; 1233 } 1234 1235 return ARMul_CANT; 1236} 1237 1238static unsigned 1239DoAFIQ (ARMul_State * state) 1240{ 1241 state->NfiqSig = LOW; 1242 state->Exception++; 1243 return 0; 1244} 1245 1246static unsigned 1247DoAIRQ (ARMul_State * state) 1248{ 1249 state->NirqSig = LOW; 1250 state->Exception++; 1251 return 0; 1252} 1253 1254static unsigned 1255IntCDP (ARMul_State * state, unsigned type, ARMword instr) 1256{ 1257 static unsigned long finish; 1258 ARMword howlong; 1259 1260 howlong = ValReg[BITS (0, 3)]; 1261 1262 switch ((int) BITS (20, 23)) 1263 { 1264 case 0: 1265 if (type == ARMul_FIRST) 1266 { 1267 /* First cycle of a busy wait. */ 1268 finish = ARMul_Time (state) + howlong; 1269 1270 return howlong == 0 ? ARMul_DONE : ARMul_BUSY; 1271 } 1272 else if (type == ARMul_BUSY) 1273 { 1274 if (ARMul_Time (state) >= finish) 1275 return ARMul_DONE; 1276 else 1277 return ARMul_BUSY; 1278 } 1279 return ARMul_DONE; 1280 1281 case 1: 1282 if (howlong == 0) 1283 ARMul_Abort (state, ARMul_FIQV); 1284 else 1285 ARMul_ScheduleEvent (state, howlong, DoAFIQ); 1286 return ARMul_DONE; 1287 1288 case 2: 1289 if (howlong == 0) 1290 ARMul_Abort (state, ARMul_IRQV); 1291 else 1292 ARMul_ScheduleEvent (state, howlong, DoAIRQ); 1293 return ARMul_DONE; 1294 1295 case 3: 1296 state->NfiqSig = HIGH; 1297 state->Exception--; 1298 return ARMul_DONE; 1299 1300 case 4: 1301 state->NirqSig = HIGH; 1302 state->Exception--; 1303 return ARMul_DONE; 1304 1305 case 5: 1306 ValReg[BITS (0, 3)] = ARMul_Time (state); 1307 return ARMul_DONE; 1308 } 1309 1310 return ARMul_CANT; 1311} 1312 1313/* Install co-processor instruction handlers in this routine. */ 1314 1315unsigned 1316ARMul_CoProInit (ARMul_State * state) 1317{ 1318 unsigned int i; 1319 1320 /* Initialise tham all first. */ 1321 for (i = 0; i < 16; i++) 1322 ARMul_CoProDetach (state, i); 1323 1324 /* Install CoPro Instruction handlers here. 1325 The format is: 1326 ARMul_CoProAttach (state, CP Number, Init routine, Exit routine 1327 LDC routine, STC routine, MRC routine, MCR routine, 1328 CDP routine, Read Reg routine, Write Reg routine). */ 1329 if (state->is_ep9312) 1330 { 1331 ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, 1332 DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL); 1333 ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, 1334 DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL); 1335 ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, 1336 DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL); 1337 } 1338 else 1339 { 1340 ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, 1341 ValMRC, ValMCR, ValCDP, NULL, NULL); 1342 1343 ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL, 1344 ValMRC, ValMCR, IntCDP, NULL, NULL); 1345 } 1346 1347 if (state->is_XScale) 1348 { 1349 ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL, 1350 XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC, 1351 XScale_cp13_MCR, NULL, XScale_cp13_read_reg, 1352 XScale_cp13_write_reg); 1353 1354 ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL, 1355 XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC, 1356 XScale_cp14_MCR, NULL, XScale_cp14_read_reg, 1357 XScale_cp14_write_reg); 1358 1359 ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL, 1360 NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR, 1361 NULL, XScale_cp15_read_reg, XScale_cp15_write_reg); 1362 } 1363 else 1364 { 1365 ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, 1366 MMUMRC, MMUMCR, NULL, MMURead, MMUWrite); 1367 } 1368 1369 if (state->is_iWMMXt) 1370 { 1371 ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, 1372 NULL, NULL, IwmmxtCDP, NULL, NULL); 1373 1374 ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, 1375 IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL); 1376 } 1377 1378 /* No handlers below here. */ 1379 1380 /* Call all the initialisation routines. */ 1381 for (i = 0; i < 16; i++) 1382 if (state->CPInit[i]) 1383 (state->CPInit[i]) (state); 1384 1385 return TRUE; 1386} 1387 1388/* Install co-processor finalisation routines in this routine. */ 1389 1390void 1391ARMul_CoProExit (ARMul_State * state) 1392{ 1393 register unsigned i; 1394 1395 for (i = 0; i < 16; i++) 1396 if (state->CPExit[i]) 1397 (state->CPExit[i]) (state); 1398 1399 for (i = 0; i < 16; i++) /* Detach all handlers. */ 1400 ARMul_CoProDetach (state, i); 1401} 1402 1403/* Routines to hook Co-processors into ARMulator. */ 1404 1405void 1406ARMul_CoProAttach (ARMul_State * state, 1407 unsigned number, 1408 ARMul_CPInits * init, 1409 ARMul_CPExits * exit, 1410 ARMul_LDCs * ldc, 1411 ARMul_STCs * stc, 1412 ARMul_MRCs * mrc, 1413 ARMul_MCRs * mcr, 1414 ARMul_CDPs * cdp, 1415 ARMul_CPReads * read, 1416 ARMul_CPWrites * write) 1417{ 1418 if (init != NULL) 1419 state->CPInit[number] = init; 1420 if (exit != NULL) 1421 state->CPExit[number] = exit; 1422 if (ldc != NULL) 1423 state->LDC[number] = ldc; 1424 if (stc != NULL) 1425 state->STC[number] = stc; 1426 if (mrc != NULL) 1427 state->MRC[number] = mrc; 1428 if (mcr != NULL) 1429 state->MCR[number] = mcr; 1430 if (cdp != NULL) 1431 state->CDP[number] = cdp; 1432 if (read != NULL) 1433 state->CPRead[number] = read; 1434 if (write != NULL) 1435 state->CPWrite[number] = write; 1436} 1437 1438void 1439ARMul_CoProDetach (ARMul_State * state, unsigned number) 1440{ 1441 ARMul_CoProAttach (state, number, NULL, NULL, 1442 NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, 1443 NoCoPro3R, NULL, NULL); 1444 1445 state->CPInit[number] = NULL; 1446 state->CPExit[number] = NULL; 1447 state->CPRead[number] = NULL; 1448 state->CPWrite[number] = NULL; 1449} 1450