Revision ea2b542a

b/hw/sh7750.c
360 360
    case SH7750_PTEL_A7:
361 361
	s->cpu->ptel = mem_value;
362 362
	return;
363
    case SH7750_PTEA_A7:
364
	s->cpu->ptea = mem_value & 0x0000000f;
365
	return;
363 366
    case SH7750_TTB_A7:
364 367
	s->cpu->ttb = mem_value;
365 368
	return;
b/target-sh4/cpu.h
163 163
#define MMUCR    0x1F000010
164 164
#define MMUCR_AT (1<<0)
165 165
#define MMUCR_SV (1<<8)
166
#define MMUCR_URC_BITS (6)
167
#define MMUCR_URC_OFFSET (10)
168
#define MMUCR_URC_SIZE (1 << MMUCR_URC_BITS)
169
#define MMUCR_URC_MASK (((MMUCR_URC_SIZE) - 1) << MMUCR_URC_OFFSET)
170
static inline int cpu_mmucr_urc (uint32_t mmucr)
171
{
172
    return ((mmucr & MMUCR_URC_MASK) >> MMUCR_URC_OFFSET);
173
}
174

  
175
/* PTEH : Page Translation Entry High register */
176
#define PTEH_ASID_BITS (8)
177
#define PTEH_ASID_SIZE (1 << PTEH_ASID_BITS)
178
#define PTEH_ASID_MASK (PTEH_ASID_SIZE - 1)
179
#define cpu_pteh_asid(pteh) ((pteh) & PTEH_ASID_MASK)
180
#define PTEH_VPN_BITS (22)
181
#define PTEH_VPN_OFFSET (10)
182
#define PTEH_VPN_SIZE (1 << PTEH_VPN_BITS)
183
#define PTEH_VPN_MASK (((PTEH_VPN_SIZE) - 1) << PTEH_VPN_OFFSET)
184
static inline int cpu_pteh_vpn (uint32_t pteh)
185
{
186
    return ((pteh & PTEH_VPN_MASK) >> PTEH_VPN_OFFSET);
187
}
188

  
189
/* PTEL : Page Translation Entry Low register */
190
#define PTEL_V        (1 << 8)
191
#define cpu_ptel_v(ptel) (((ptel) & PTEL_V) >> 8)
192
#define PTEL_C        (1 << 3)
193
#define cpu_ptel_c(ptel) (((ptel) & PTEL_C) >> 3)
194
#define PTEL_D        (1 << 2)
195
#define cpu_ptel_d(ptel) (((ptel) & PTEL_D) >> 2)
196
#define PTEL_SH       (1 << 1)
197
#define cpu_ptel_sh(ptel)(((ptel) & PTEL_SH) >> 1)
198
#define PTEL_WT       (1 << 0)
199
#define cpu_ptel_wt(ptel) ((ptel) & PTEL_WT)
200

  
201
#define PTEL_SZ_HIGH_OFFSET  (7)
202
#define PTEL_SZ_HIGH  (1 << PTEL_SZ_HIGH_OFFSET)
203
#define PTEL_SZ_LOW_OFFSET   (4)
204
#define PTEL_SZ_LOW   (1 << PTEL_SZ_LOW_OFFSET)
205
static inline int cpu_ptel_sz (uint32_t ptel)
206
{
207
    int sz;
208
    sz = (ptel & PTEL_SZ_HIGH) >> PTEL_SZ_HIGH_OFFSET;
209
    sz <<= 1;
210
    sz |= (ptel & PTEL_SZ_LOW) >> PTEL_SZ_LOW_OFFSET;
211
    return sz;
212
}
213

  
214
#define PTEL_PPN_BITS (19)
215
#define PTEL_PPN_OFFSET (10)
216
#define PTEL_PPN_SIZE (1 << PTEL_PPN_BITS)
217
#define PTEL_PPN_MASK (((PTEL_PPN_SIZE) - 1) << PTEL_PPN_OFFSET)
218
static inline int cpu_ptel_ppn (uint32_t ptel)
219
{
220
    return ((ptel & PTEL_PPN_MASK) >> PTEL_PPN_OFFSET);
221
}
222

  
223
#define PTEL_PR_BITS   (2)
224
#define PTEL_PR_OFFSET (5)
225
#define PTEL_PR_SIZE (1 << PTEL_PR_BITS)
226
#define PTEL_PR_MASK (((PTEL_PR_SIZE) - 1) << PTEL_PR_OFFSET)
227
static inline int cpu_ptel_pr (uint32_t ptel)
228
{
229
    return ((ptel & PTEL_PR_MASK) >> PTEL_PR_OFFSET);
230
}
231

  
232
/* PTEA : Page Translation Entry Assistance register */
233
#define PTEA_SA_BITS (3)
234
#define PTEA_SA_SIZE (1 << PTEA_SA_BITS)
235
#define PTEA_SA_MASK (PTEA_SA_SIZE - 1)
236
#define cpu_ptea_sa(ptea) ((ptea) & PTEA_SA_MASK)
237
#define PTEA_TC        (1 << 3)
238
#define cpu_ptea_tc(ptea) (((ptea) & PTEA_TC) >> 3)
166 239

  
167 240
#endif				/* _CPU_SH4_H */
b/target-sh4/exec.h
64 64

  
65 65
int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
66 66
			     int mmu_idx, int is_softmmu);
67
void cpu_load_tlb(CPUState * env);
67 68

  
68 69
int find_itlb_entry(CPUState * env, target_ulong address,
69 70
		    int use_asid, int update);
......
81 82
void helper_subv_T0_T1(void);
82 83
void helper_rotcl(uint32_t * addr);
83 84
void helper_rotcr(uint32_t * addr);
85
void helper_ldtlb(void);
84 86

  
85 87
void do_interrupt(CPUState * env);
86 88

  
b/target-sh4/helper.c
193 193

  
194 194
    switch (itlbnb) {
195 195
    case 0:
196
	and_mask = 0x7f;
196
	and_mask = 0x1f;
197 197
	break;
198 198
    case 1:
199 199
	and_mask = 0xe7;
......
208 208
	break;
209 209
    }
210 210

  
211
    env->mmucr &= (and_mask << 24);
211
    env->mmucr &= (and_mask << 24) | 0x00ffffff;
212 212
    env->mmucr |= (or_mask << 24);
213 213
}
214 214

  
......
216 216
{
217 217
    if ((env->mmucr & 0xe0000000) == 0xe0000000)
218 218
	return 0;
219
    if ((env->mmucr & 0x98000000) == 0x08000000)
219
    if ((env->mmucr & 0x98000000) == 0x18000000)
220 220
	return 1;
221 221
    if ((env->mmucr & 0x54000000) == 0x04000000)
222 222
	return 2;
......
264 264
	start = (entries[i].vpn << 10) & ~(entries[i].size - 1);
265 265
	end = start + entries[i].size - 1;
266 266
	if (address >= start && address <= end) {	/* Match */
267
	    if (match != -1)
267
	    if (match != MMU_DTLB_MISS)
268 268
		return MMU_DTLB_MULTIPLE;	/* Multiple match */
269 269
	    match = i;
270 270
	}
......
290 290
	    n = itlb_replacement(env);
291 291
	    env->itlb[n] = env->utlb[e];
292 292
	    e = n;
293
	}
294
    }
293
	} else if (e == MMU_DTLB_MISS)
294
	    e = MMU_ITLB_MISS;
295
    } else if (e == MMU_DTLB_MISS)
296
	e = MMU_ITLB_MISS;
295 297
    if (e >= 0)
296 298
	update_itlb_use(env, e);
297 299
    return e;
......
418 420
    target_ulong physical, page_offset, page_size;
419 421
    int prot, ret, access_type;
420 422

  
423
    switch (rw) {
424
    case 0:
425
        rw = PAGE_READ;
426
        break;
427
    case 1:
428
        rw = PAGE_WRITE;
429
        break;
430
    case 2: /* READ_ACCESS_TYPE == 2 defined in softmmu_template.h */
431
        rw = PAGE_READ;
432
        break;
433
    default:
434
        /* fatal error */
435
        assert(0);
436
    }
437

  
421 438
    /* XXXXX */
422 439
#if 0
423 440
    fprintf(stderr, "%s pc %08x ad %08x rw %d mmu_idx %d smmu %d\n",
......
479 496
    return physical;
480 497
}
481 498

  
499
void cpu_load_tlb(CPUState * env)
500
{
501
    int n = cpu_mmucr_urc(env->mmucr);
502
    tlb_t * entry = &env->utlb[n];
503

  
504
    /* Take values into cpu status from registers. */
505
    entry->asid = (uint8_t)cpu_pteh_asid(env->pteh);
506
    entry->vpn  = cpu_pteh_vpn(env->pteh);
507
    entry->v    = (uint8_t)cpu_ptel_v(env->ptel);
508
    entry->ppn  = cpu_ptel_ppn(env->ptel);
509
    entry->sz   = (uint8_t)cpu_ptel_sz(env->ptel);
510
    switch (entry->sz) {
511
    case 0: /* 00 */
512
        entry->size = 1024; /* 1K */
513
        break;
514
    case 1: /* 01 */
515
        entry->size = 1024 * 4; /* 4K */
516
        break;
517
    case 2: /* 10 */
518
        entry->size = 1024 * 64; /* 64K */
519
        break;
520
    case 3: /* 11 */
521
        entry->size = 1024 * 1024; /* 1M */
522
        break;
523
    default:
524
        assert(0);
525
        break;
526
    }
527
    entry->sh   = (uint8_t)cpu_ptel_sh(env->ptel);
528
    entry->c    = (uint8_t)cpu_ptel_c(env->ptel);
529
    entry->pr   = (uint8_t)cpu_ptel_pr(env->ptel);
530
    entry->d    = (uint8_t)cpu_ptel_d(env->ptel);
531
    entry->wt   = (uint8_t)cpu_ptel_wt(env->ptel);
532
    entry->sa   = (uint8_t)cpu_ptea_sa(env->ptea);
533
    entry->tc   = (uint8_t)cpu_ptea_tc(env->ptea);
534
}
535

  
482 536
#endif
b/target-sh4/op.c
185 185
    RETURN();
186 186
}
187 187

  
188
void OPPROTO op_ldtlb(void)
189
{
190
    helper_ldtlb();
191
    RETURN();
192
}
193

  
188 194
void OPPROTO op_sets(void)
189 195
{
190 196
    env->sr |= SR_S;
b/target-sh4/op_helper.c
76 76

  
77 77
#endif
78 78

  
79
void helper_ldtlb(void)
80
{
81
#ifdef CONFIG_USER_ONLY
82
    /* XXXXX */
83
    assert(0);
84
#else
85
    cpu_load_tlb(env);
86
#endif
87
}
88

  
79 89
void helper_addc_T0_T1(void)
80 90
{
81 91
    uint32_t tmp0, tmp1;
b/target-sh4/translate.c
256 256
	gen_op_clrt();
257 257
	return;
258 258
    case 0x0038:		/* ldtlb */
259
#if defined(CONFIG_USER_ONLY)
259 260
	assert(0);		/* XXXXX */
261
#else
262
	gen_op_ldtlb();
263
#endif
260 264
	return;
261 265
    case 0x002b:		/* rte */
262 266
	CHECK_NOT_DELAY_SLOT gen_op_rte();

Also available in: Unified diff