Revision 08de207b target-arm/helper.c
b/target-arm/helper.c | ||
---|---|---|
63 | 63 |
return 0; |
64 | 64 |
} |
65 | 65 |
|
66 |
static int fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) |
|
67 |
{ |
|
68 |
if (env->cp15.c13_fcse != value) { |
|
69 |
/* Unlike real hardware the qemu TLB uses virtual addresses, |
|
70 |
* not modified virtual addresses, so this causes a TLB flush. |
|
71 |
*/ |
|
72 |
tlb_flush(env, 1); |
|
73 |
env->cp15.c13_fcse = value; |
|
74 |
} |
|
75 |
return 0; |
|
76 |
} |
|
77 |
static int contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri, |
|
78 |
uint64_t value) |
|
79 |
{ |
|
80 |
if (env->cp15.c13_context != value && !arm_feature(env, ARM_FEATURE_MPU)) { |
|
81 |
/* For VMSA (when not using the LPAE long descriptor page table |
|
82 |
* format) this register includes the ASID, so do a TLB flush. |
|
83 |
* For PMSA it is purely a process ID and no action is needed. |
|
84 |
*/ |
|
85 |
tlb_flush(env, 1); |
|
86 |
} |
|
87 |
env->cp15.c13_context = value; |
|
88 |
return 0; |
|
89 |
} |
|
90 |
|
|
66 | 91 |
static const ARMCPRegInfo cp_reginfo[] = { |
67 | 92 |
/* DBGDIDR: just RAZ. In particular this means the "debug architecture |
68 | 93 |
* version" bits will read as a reserved value, which should cause |
... | ... | |
75 | 100 |
.crn = 3, .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, |
76 | 101 |
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c3), |
77 | 102 |
.resetvalue = 0, .writefn = dacr_write }, |
103 |
{ .name = "FCSEIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 0, |
|
104 |
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse), |
|
105 |
.resetvalue = 0, .writefn = fcse_write }, |
|
106 |
{ .name = "CONTEXTIDR", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 1, |
|
107 |
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.c13_fcse), |
|
108 |
.resetvalue = 0, .writefn = contextidr_write }, |
|
78 | 109 |
REGINFO_SENTINEL |
79 | 110 |
}; |
80 | 111 |
|
... | ... | |
1769 | 1800 |
break; |
1770 | 1801 |
case 12: /* Reserved. */ |
1771 | 1802 |
goto bad_reg; |
1772 |
case 13: /* Process ID. */ |
|
1773 |
switch (op2) { |
|
1774 |
case 0: |
|
1775 |
/* Unlike real hardware the qemu TLB uses virtual addresses, |
|
1776 |
not modified virtual addresses, so this causes a TLB flush. |
|
1777 |
*/ |
|
1778 |
if (env->cp15.c13_fcse != val) |
|
1779 |
tlb_flush(env, 1); |
|
1780 |
env->cp15.c13_fcse = val; |
|
1781 |
break; |
|
1782 |
case 1: |
|
1783 |
/* This changes the ASID, so do a TLB flush. */ |
|
1784 |
if (env->cp15.c13_context != val |
|
1785 |
&& !arm_feature(env, ARM_FEATURE_MPU)) |
|
1786 |
tlb_flush(env, 0); |
|
1787 |
env->cp15.c13_context = val; |
|
1788 |
break; |
|
1789 |
default: |
|
1790 |
goto bad_reg; |
|
1791 |
} |
|
1792 |
break; |
|
1793 | 1803 |
case 15: /* Implementation specific. */ |
1794 | 1804 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) { |
1795 | 1805 |
if (op2 == 0 && crm == 1) { |
... | ... | |
2071 | 2081 |
case 11: /* TCM DMA control. */ |
2072 | 2082 |
case 12: /* Reserved. */ |
2073 | 2083 |
goto bad_reg; |
2074 |
case 13: /* Process ID. */ |
|
2075 |
switch (op2) { |
|
2076 |
case 0: |
|
2077 |
return env->cp15.c13_fcse; |
|
2078 |
case 1: |
|
2079 |
return env->cp15.c13_context; |
|
2080 |
default: |
|
2081 |
goto bad_reg; |
|
2082 |
} |
|
2083 | 2084 |
case 15: /* Implementation specific. */ |
2084 | 2085 |
if (arm_feature(env, ARM_FEATURE_XSCALE)) { |
2085 | 2086 |
if (op2 == 0 && crm == 1) |
Also available in: Unified diff