Revision c1713132 target-arm/helper.c
b/target-arm/helper.c | ||
---|---|---|
17 | 17 |
case ARM_CPUID_ARM926: |
18 | 18 |
set_feature(env, ARM_FEATURE_VFP); |
19 | 19 |
env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; |
20 |
env->cp15.c0_cachetype = 0x1dd20d2; |
|
20 | 21 |
break; |
21 | 22 |
case ARM_CPUID_ARM1026: |
22 | 23 |
set_feature(env, ARM_FEATURE_VFP); |
23 | 24 |
set_feature(env, ARM_FEATURE_AUXCR); |
24 | 25 |
env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; |
26 |
env->cp15.c0_cachetype = 0x1dd20d2; |
|
27 |
break; |
|
28 |
case ARM_CPUID_PXA250: |
|
29 |
case ARM_CPUID_PXA255: |
|
30 |
case ARM_CPUID_PXA260: |
|
31 |
case ARM_CPUID_PXA261: |
|
32 |
case ARM_CPUID_PXA262: |
|
33 |
set_feature(env, ARM_FEATURE_XSCALE); |
|
34 |
/* JTAG_ID is ((id << 28) | 0x09265013) */ |
|
35 |
env->cp15.c0_cachetype = 0xd172172; |
|
36 |
break; |
|
37 |
case ARM_CPUID_PXA270_A0: |
|
38 |
case ARM_CPUID_PXA270_A1: |
|
39 |
case ARM_CPUID_PXA270_B0: |
|
40 |
case ARM_CPUID_PXA270_B1: |
|
41 |
case ARM_CPUID_PXA270_C0: |
|
42 |
case ARM_CPUID_PXA270_C5: |
|
43 |
set_feature(env, ARM_FEATURE_XSCALE); |
|
44 |
/* JTAG_ID is ((id << 28) | 0x09265013) */ |
|
45 |
env->cp15.c0_cachetype = 0xd172172; |
|
25 | 46 |
break; |
26 | 47 |
default: |
27 | 48 |
cpu_abort(env, "Bad CPU ID: %x\n", id); |
... | ... | |
68 | 89 |
static const struct arm_cpu_t arm_cpu_names[] = { |
69 | 90 |
{ ARM_CPUID_ARM926, "arm926"}, |
70 | 91 |
{ ARM_CPUID_ARM1026, "arm1026"}, |
92 |
{ ARM_CPUID_PXA250, "pxa250" }, |
|
93 |
{ ARM_CPUID_PXA255, "pxa255" }, |
|
94 |
{ ARM_CPUID_PXA260, "pxa260" }, |
|
95 |
{ ARM_CPUID_PXA261, "pxa261" }, |
|
96 |
{ ARM_CPUID_PXA262, "pxa262" }, |
|
97 |
{ ARM_CPUID_PXA270, "pxa270" }, |
|
98 |
{ ARM_CPUID_PXA270_A0, "pxa270-a0" }, |
|
99 |
{ ARM_CPUID_PXA270_A1, "pxa270-a1" }, |
|
100 |
{ ARM_CPUID_PXA270_B0, "pxa270-b0" }, |
|
101 |
{ ARM_CPUID_PXA270_B1, "pxa270-b1" }, |
|
102 |
{ ARM_CPUID_PXA270_C0, "pxa270-c0" }, |
|
103 |
{ ARM_CPUID_PXA270_C5, "pxa270-c5" }, |
|
71 | 104 |
{ 0, NULL} |
72 | 105 |
}; |
73 | 106 |
|
... | ... | |
132 | 165 |
} |
133 | 166 |
|
134 | 167 |
/* These should probably raise undefined insn exceptions. */ |
168 |
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val) |
|
169 |
{ |
|
170 |
int op1 = (insn >> 8) & 0xf; |
|
171 |
cpu_abort(env, "cp%i insn %08x\n", op1, insn); |
|
172 |
return; |
|
173 |
} |
|
174 |
|
|
175 |
uint32_t helper_get_cp(CPUState *env, uint32_t insn) |
|
176 |
{ |
|
177 |
int op1 = (insn >> 8) & 0xf; |
|
178 |
cpu_abort(env, "cp%i insn %08x\n", op1, insn); |
|
179 |
return 0; |
|
180 |
} |
|
181 |
|
|
135 | 182 |
void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val) |
136 | 183 |
{ |
137 | 184 |
cpu_abort(env, "cp15 insn %08x\n", insn); |
... | ... | |
393 | 440 |
ap = (desc >> (4 + ((address >> 13) & 6))) & 3; |
394 | 441 |
break; |
395 | 442 |
case 3: /* 1k page. */ |
396 |
if (type == 1) { |
|
397 |
/* Page translation fault. */ |
|
398 |
code = 7; |
|
399 |
goto do_fault; |
|
443 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) |
|
444 |
phys_addr = (desc & 0xfffff000) | (address & 0xfff); |
|
445 |
else { |
|
446 |
if (type == 1) { |
|
447 |
/* Page translation fault. */ |
|
448 |
code = 7; |
|
449 |
goto do_fault; |
|
450 |
} |
|
451 |
phys_addr = (desc & 0xfffffc00) | (address & 0x3ff); |
|
400 | 452 |
} |
401 |
phys_addr = (desc & 0xfffffc00) | (address & 0x3ff); |
|
402 | 453 |
ap = (desc >> 4) & 3; |
403 | 454 |
break; |
404 | 455 |
default: |
... | ... | |
461 | 512 |
return phys_addr; |
462 | 513 |
} |
463 | 514 |
|
515 |
void helper_set_cp(CPUState *env, uint32_t insn, uint32_t val) |
|
516 |
{ |
|
517 |
int cp_num = (insn >> 8) & 0xf; |
|
518 |
int cp_info = (insn >> 5) & 7; |
|
519 |
int src = (insn >> 16) & 0xf; |
|
520 |
int operand = insn & 0xf; |
|
521 |
|
|
522 |
if (env->cp[cp_num].cp_write) |
|
523 |
env->cp[cp_num].cp_write(env->cp[cp_num].opaque, |
|
524 |
cp_info, src, operand, val); |
|
525 |
} |
|
526 |
|
|
527 |
uint32_t helper_get_cp(CPUState *env, uint32_t insn) |
|
528 |
{ |
|
529 |
int cp_num = (insn >> 8) & 0xf; |
|
530 |
int cp_info = (insn >> 5) & 7; |
|
531 |
int dest = (insn >> 16) & 0xf; |
|
532 |
int operand = insn & 0xf; |
|
533 |
|
|
534 |
if (env->cp[cp_num].cp_read) |
|
535 |
return env->cp[cp_num].cp_read(env->cp[cp_num].opaque, |
|
536 |
cp_info, dest, operand); |
|
537 |
return 0; |
|
538 |
} |
|
539 |
|
|
464 | 540 |
void helper_set_cp15(CPUState *env, uint32_t insn, uint32_t val) |
465 | 541 |
{ |
466 | 542 |
uint32_t op2; |
... | ... | |
472 | 548 |
case 1: /* System configuration. */ |
473 | 549 |
switch (op2) { |
474 | 550 |
case 0: |
475 |
env->cp15.c1_sys = val; |
|
551 |
if (!arm_feature(env, ARM_FEATURE_XSCALE) || (insn & 0xf) == 0) |
|
552 |
env->cp15.c1_sys = val; |
|
476 | 553 |
/* ??? Lots of these bits are not implemented. */ |
477 | 554 |
/* This may enable/disable the MMU, so do a TLB flush. */ |
478 | 555 |
tlb_flush(env, 1); |
479 | 556 |
break; |
557 |
case 1: |
|
558 |
/* XScale doesn't implement AUX CR (P-Bit) but allows |
|
559 |
* writing with zero and reading. */ |
|
560 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) |
|
561 |
break; |
|
562 |
goto bad_reg; |
|
480 | 563 |
case 2: |
481 | 564 |
env->cp15.c1_coproc = val; |
482 | 565 |
/* ??? Is this safe when called from within a TB? */ |
483 | 566 |
tb_flush(env); |
567 |
break; |
|
484 | 568 |
default: |
485 | 569 |
goto bad_reg; |
486 | 570 |
} |
... | ... | |
584 | 668 |
case 14: /* Reserved. */ |
585 | 669 |
goto bad_reg; |
586 | 670 |
case 15: /* Implementation specific. */ |
587 |
/* ??? Internal registers not implemented. */ |
|
671 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) { |
|
672 |
if (op2 == 0 && (insn & 0xf) == 1) { |
|
673 |
/* Changes cp0 to cp13 behavior, so needs a TB flush. */ |
|
674 |
tb_flush(env); |
|
675 |
env->cp15.c15_cpar = (val & 0x3fff) | 2; |
|
676 |
break; |
|
677 |
} |
|
678 |
goto bad_reg; |
|
679 |
} |
|
588 | 680 |
break; |
589 | 681 |
} |
590 | 682 |
return; |
591 | 683 |
bad_reg: |
592 | 684 |
/* ??? For debugging only. Should raise illegal instruction exception. */ |
593 |
cpu_abort(env, "Unimplemented cp15 register read\n");
|
|
685 |
cpu_abort(env, "Unimplemented cp15 register write\n");
|
|
594 | 686 |
} |
595 | 687 |
|
596 | 688 |
uint32_t helper_get_cp15(CPUState *env, uint32_t insn) |
... | ... | |
604 | 696 |
default: /* Device ID. */ |
605 | 697 |
return env->cp15.c0_cpuid; |
606 | 698 |
case 1: /* Cache Type. */ |
607 |
return 0x1dd20d2;
|
|
699 |
return env->cp15.c0_cachetype;
|
|
608 | 700 |
case 2: /* TCM status. */ |
609 | 701 |
return 0; |
610 | 702 |
} |
... | ... | |
615 | 707 |
case 1: /* Auxiliary control register. */ |
616 | 708 |
if (arm_feature(env, ARM_FEATURE_AUXCR)) |
617 | 709 |
return 1; |
710 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) |
|
711 |
return 0; |
|
618 | 712 |
goto bad_reg; |
619 | 713 |
case 2: /* Coprocessor access register. */ |
620 | 714 |
return env->cp15.c1_coproc; |
... | ... | |
649 | 743 |
} |
650 | 744 |
case 7: /* Cache control. */ |
651 | 745 |
/* ??? This is for test, clean and invaidate operations that set the |
652 |
Z flag. We can't represent N = Z = 1, so it also clears clears
|
|
746 |
Z flag. We can't represent N = Z = 1, so it also clears |
|
653 | 747 |
the N flag. Oh well. */ |
654 | 748 |
env->NZF = 0; |
655 | 749 |
return 0; |
... | ... | |
682 | 776 |
case 14: /* Reserved. */ |
683 | 777 |
goto bad_reg; |
684 | 778 |
case 15: /* Implementation specific. */ |
685 |
/* ??? Internal registers not implemented. */ |
|
779 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) { |
|
780 |
if (op2 == 0 && (insn & 0xf) == 1) |
|
781 |
return env->cp15.c15_cpar; |
|
782 |
|
|
783 |
goto bad_reg; |
|
784 |
} |
|
686 | 785 |
return 0; |
687 | 786 |
} |
688 | 787 |
bad_reg: |
... | ... | |
691 | 790 |
return 0; |
692 | 791 |
} |
693 | 792 |
|
793 |
void cpu_arm_set_cp_io(CPUARMState *env, int cpnum, |
|
794 |
ARMReadCPFunc *cp_read, ARMWriteCPFunc *cp_write, |
|
795 |
void *opaque) |
|
796 |
{ |
|
797 |
if (cpnum < 0 || cpnum > 14) { |
|
798 |
cpu_abort(env, "Bad coprocessor number: %i\n", cpnum); |
|
799 |
return; |
|
800 |
} |
|
801 |
|
|
802 |
env->cp[cpnum].cp_read = cp_read; |
|
803 |
env->cp[cpnum].cp_write = cp_write; |
|
804 |
env->cp[cpnum].opaque = opaque; |
|
805 |
} |
|
806 |
|
|
694 | 807 |
#endif |
Also available in: Unified diff