Revision e034e2c3

b/target-mips/cpu.h
102 102

  
103 103
    uint32_t nb_tlb;
104 104
    uint32_t tlb_in_use;
105
    uint32_t SEGBITS;
106
    target_ulong SEGMask;
105 107
    int (*map_address) (CPUMIPSState *env, target_ulong *physical, int *prot, target_ulong address, int rw, int access_type);
106 108
    void (*do_tlbwi) (void);
107 109
    void (*do_tlbwr) (void);
b/target-mips/helper.c
77 77
        target_ulong tag = address & ~mask;
78 78
        target_ulong VPN = tlb->VPN & ~mask;
79 79
#ifdef TARGET_MIPS64
80
        tag &= 0xC00000FFFFFFFFFFULL;
80
        tag &= env->SEGMask;
81 81
#endif
82 82

  
83 83
        /* Check ASID, virtual page number & size */
......
140 140
/*
141 141
   XXX: Assuming :
142 142
   - PABITS = 36 (correct for MIPS64R1)
143
   - SEGBITS = 40
144 143
*/
145 144
    } else if (address < 0x3FFFFFFFFFFFFFFFULL) {
146 145
        /* xuseg */
147
	if (UX && address < 0x000000FFFFFFFFFFULL) {
146
	if (UX && address < (0x3FFFFFFFFFFFFFFFULL & env->SEGMask)) {
148 147
            ret = env->map_address(env, physical, prot, address, rw, access_type);
149 148
	} else {
150 149
	    ret = TLBRET_BADADDR;
151 150
        }
152 151
    } else if (address < 0x7FFFFFFFFFFFFFFFULL) {
153 152
        /* xsseg */
154
	if (SX && address < 0x400000FFFFFFFFFFULL) {
153
	if (SX && address < (0x7FFFFFFFFFFFFFFFULL & env->SEGMask)) {
155 154
            ret = env->map_address(env, physical, prot, address, rw, access_type);
156 155
	} else {
157 156
	    ret = TLBRET_BADADDR;
......
159 158
    } else if (address < 0xBFFFFFFFFFFFFFFFULL) {
160 159
        /* xkphys */
161 160
        /* XXX: check supervisor mode */
162
        if (KX && (address & 0x03FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
161
        if (KX && (address & 0x07FFFFFFFFFFFFFFULL) < 0X0000000FFFFFFFFFULL)
163 162
	{
164
            *physical = address & 0X000000FFFFFFFFFFULL;
163
            *physical = address & 0X0000000FFFFFFFFFULL;
165 164
            *prot = PAGE_READ | PAGE_WRITE;
166 165
	} else {
167 166
	    ret = TLBRET_BADADDR;
......
169 168
    } else if (address < 0xFFFFFFFF7FFFFFFFULL) {
170 169
        /* xkseg */
171 170
        /* XXX: check supervisor mode */
172
	if (KX && address < 0xC00000FF7FFFFFFFULL) {
171
	if (KX && address < (0xFFFFFFFF7FFFFFFFULL & env->SEGMask)) {
173 172
            ret = env->map_address(env, physical, prot, address, rw, access_type);
174 173
	} else {
175 174
	    ret = TLBRET_BADADDR;
......
303 302
        env->CP0_EntryHi =
304 303
            (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
305 304
#ifdef TARGET_MIPS64
306
        env->CP0_EntryHi &= 0xc00000ffffffffffULL;
307
        env->CP0_XContext = (env->CP0_XContext & 0xfffffffe00000000ULL) |
308
                            ((address >> 31) & 0x0000000180000000ULL) |
309
                            ((address >> 9) & 0x000000007ffffff0ULL);
305
        env->CP0_EntryHi &= env->SEGMask;
306
        env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
307
                            ((address & 0xC00000000000ULL) >> (env->SEGBITS - 9)) |
308
                            ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
310 309
#endif
311 310
        env->exception_index = exception;
312 311
        env->error_code = error_code;
......
555 554
    if (tlb->V0) {
556 555
        addr = tlb->VPN & ~mask;
557 556
#ifdef TARGET_MIPS64
558
        if (addr >= 0xC00000FF80000000ULL) {
557
        if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
559 558
            addr |= 0x3FFFFF0000000000ULL;
560 559
        }
561 560
#endif
......
568 567
    if (tlb->V1) {
569 568
        addr = (tlb->VPN & ~mask) | ((mask >> 1) + 1);
570 569
#ifdef TARGET_MIPS64
571
        if (addr >= 0xC00000FF80000000ULL) {
570
        if (addr >= (0xFFFFFFFF80000000ULL & env->SEGMask)) {
572 571
            addr |= 0x3FFFFF0000000000ULL;
573 572
        }
574 573
#endif
b/target-mips/op.c
1328 1328
    /* 1k pages not implemented */
1329 1329
    val = T0 & ((TARGET_PAGE_MASK << 1) | 0xFF);
1330 1330
#ifdef TARGET_MIPS64
1331
    val = T0 & 0xC00000FFFFFFFFFFULL;
1331
    val &= env->SEGMask;
1332 1332
#endif
1333 1333
    old = env->CP0_EntryHi;
1334 1334
    env->CP0_EntryHi = val;
......
1526 1526
#ifdef TARGET_MIPS64
1527 1527
void op_mtc0_xcontext (void)
1528 1528
{
1529
    env->CP0_XContext = (env->CP0_XContext & 0x1ffffffffULL) | (T0 & ~0x1ffffffffULL);
1529
    target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
1530
    env->CP0_XContext = (env->CP0_XContext & mask) | (T0 & ~mask);
1530 1531
    RETURN();
1531 1532
}
1532 1533

  
b/target-mips/op_helper.c
374 374
    tlb = &env->mmu.r4k.tlb[idx];
375 375
    tlb->VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);
376 376
#ifdef TARGET_MIPS64
377
    tlb->VPN &= 0xC00000FFFFFFFFFFULL;
377
    tlb->VPN &= env->SEGMask;
378 378
#endif
379 379
    tlb->ASID = env->CP0_EntryHi & 0xFF;
380 380
    tlb->PageMask = env->CP0_PageMask;
b/target-mips/translate_init.c
71 71
    int32_t CCRes;
72 72
    int32_t Status_rw_bitmask;
73 73
    int32_t CP1_fcr0;
74
    int32_t SEGBITS;
74 75
};
75 76

  
76 77
/*****************************************************************************/
......
87 88
        .SYNCI_Step = 32,
88 89
        .CCRes = 2,
89 90
        .Status_rw_bitmask = 0x3278FF17,
91
        .SEGBITS = 32,
90 92
    },
91 93
    {
92 94
        .name = "4KEcR1",
......
98 100
        .SYNCI_Step = 32,
99 101
        .CCRes = 2,
100 102
        .Status_rw_bitmask = 0x3278FF17,
103
        .SEGBITS = 32,
101 104
    },
102 105
    {
103 106
        .name = "4KEc",
......
109 112
        .SYNCI_Step = 32,
110 113
        .CCRes = 2,
111 114
        .Status_rw_bitmask = 0x3278FF17,
115
        .SEGBITS = 32,
112 116
    },
113 117
    {
114 118
        .name = "24Kc",
......
120 124
        .SYNCI_Step = 32,
121 125
        .CCRes = 2,
122 126
        .Status_rw_bitmask = 0x3278FF17,
127
        .SEGBITS = 32,
123 128
    },
124 129
    {
125 130
        .name = "24Kf",
......
133 138
        .Status_rw_bitmask = 0x3678FF17,
134 139
        .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
135 140
                    (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
141
        .SEGBITS = 32,
136 142
    },
137 143
#ifdef TARGET_MIPS64
138 144
    {
......
147 153
        .Status_rw_bitmask = 0x3678FFFF,
148 154
	/* The R4000 has a full 64bit FPU doesn't use the fcr0 bits. */
149 155
        .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
156
        .SEGBITS = 40,
150 157
    },
151 158
    {
152 159
        .name = "5Kc",
......
161 168
        .SYNCI_Step = 32,
162 169
        .CCRes = 2,
163 170
        .Status_rw_bitmask = 0x32F8FFFF,
171
        .SEGBITS = 42,
164 172
    },
165 173
    {
166 174
        .name = "5Kf",
......
178 186
	/* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
179 187
        .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
180 188
                    (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
189
        .SEGBITS = 42,
181 190
    },
182 191
    {
183 192
        .name = "20Kc",
......
198 207
        .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
199 208
                    (1 << FCR0_D) | (1 << FCR0_S) |
200 209
                    (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
210
        .SEGBITS = 40,
201 211
    },
202 212
#endif
203 213
};
......
274 284
    env->CCRes = def->CCRes;
275 285
    env->Status_rw_bitmask = def->Status_rw_bitmask;
276 286
    env->fcr0 = def->CP1_fcr0;
287
#ifdef TARGET_MIPS64
288
    env->SEGBITS = def->SEGBITS;
289
    env->SEGMask = (3ULL << 62) | ((1ULL << def->SEGBITS) - 1);
290
#endif
277 291
#ifdef CONFIG_USER_ONLY
278 292
    if (env->CP0_Config1 & (1 << CP0C1_FP))
279 293
        env->hflags |= MIPS_HFLAG_FPU;

Also available in: Unified diff