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