Revision b4ab4b4e target-mips/helper.c

b/target-mips/helper.c
77 77
                                int *prot, target_ulong address,
78 78
                                int rw, int access_type)
79 79
{
80
    /* User mode can only access useg */
80
    /* User mode can only access useg/xuseg */
81 81
    int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
82
#ifdef TARGET_MIPS64
83
    int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0;
84
    int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0;
85
    int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0;
86
#endif
82 87
    int ret = TLBRET_MATCH;
83 88

  
84 89
#if 0
......
87 92
                user_mode, env->hflags);
88 93
    }
89 94
#endif
95

  
96
#ifdef TARGET_MIPS64
97
    if (user_mode && address > 0x3FFFFFFFFFFFFFFFULL)
98
        return TLBRET_BADADDR;
99
#else
90 100
    if (user_mode && address > 0x7FFFFFFFUL)
91 101
        return TLBRET_BADADDR;
92
    if (address < (int32_t)0x80000000UL) {
93
        if (!(env->CP0_Status & (1 << CP0St_ERL))) {
102
#endif
103

  
104
    if (address <= (int32_t)0x7FFFFFFFUL) {
105
        /* useg */
106
        if (!(env->CP0_Status & (1 << CP0St_ERL) && user_mode)) {
94 107
#ifdef MIPS_USES_R4K_TLB
95 108
            ret = map_address(env, physical, prot, address, rw, access_type);
96 109
#else
......
101 114
            *physical = address;
102 115
            *prot = PAGE_READ | PAGE_WRITE;
103 116
        }
117
#ifdef TARGET_MIPS64
118
/*
119
   XXX: Assuming :
120
   - PABITS = 36 (correct for MIPS64R1)
121
   - SEGBITS = 40
122
*/
123
    } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
124
        /* xuseg */
125
	if (UX && address < 0x000000FFFFFFFFFFULL) {
126
            ret = map_address(env, physical, prot, address, rw, access_type);
127
	} else {
128
	    ret = TLBRET_BADADDR;
129
        }
130
    } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
131
        /* xsseg */
132
	if (SX && address < 0x400000FFFFFFFFFFULL) {
133
            ret = map_address(env, physical, prot, address, rw, access_type);
134
	} else {
135
	    ret = TLBRET_BADADDR;
136
        }
137
    } else if (address < 0xBFFFFFFFFFFFFFFFULL) {
138
        /* xkphys */
139
        /* XXX: check supervisor mode */
140
        if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
141
	{
142
            *physical = address & 0X000000FFFFFFFFFFULL;
143
            *prot = PAGE_READ | PAGE_WRITE;
144
	} else {
145
	    ret = TLBRET_BADADDR;
146
	}
147
    } else if (address < 0xFFFFFFFF7FFFFFFFULL) {
148
        /* xkseg */
149
        /* XXX: check supervisor mode */
150
	if (KX && address < 0xC00000FF7FFFFFFFULL) {
151
            ret = map_address(env, physical, prot, address, rw, access_type);
152
	} else {
153
	    ret = TLBRET_BADADDR;
154
	}
155
#endif
104 156
    } else if (address < (int32_t)0xA0000000UL) {
105 157
        /* kseg0 */
106 158
        /* XXX: check supervisor mode */
......
116 168
#ifdef MIPS_USES_R4K_TLB
117 169
        ret = map_address(env, physical, prot, address, rw, access_type);
118 170
#else
119
        *physical = address;
171
        *physical = address & 0xFFFFFFFF;
120 172
        *prot = PAGE_READ | PAGE_WRITE;
121 173
#endif
122 174
    } else {
......
126 178
#ifdef MIPS_USES_R4K_TLB
127 179
        ret = map_address(env, physical, prot, address, rw, access_type);
128 180
#else
129
        *physical = address;
181
        *physical = address & 0xFFFFFFFF;
130 182
        *prot = PAGE_READ | PAGE_WRITE;
131 183
#endif
132 184
    }

Also available in: Unified diff