Revision 08de207b

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