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