Revision 3475187d target-sparc/helper.c

b/target-sparc/helper.c
43 43
int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
44 44
                               int is_user, int is_softmmu)
45 45
{
46
    env->mmuregs[4] = address;
47 46
    if (rw & 2)
48 47
        env->exception_index = TT_TFAULT;
49 48
    else
......
102 101
    env = saved_env;
103 102
}
104 103

  
104
#ifndef TARGET_SPARC64
105 105
static const int access_table[8][8] = {
106 106
    { 0, 0, 0, 0, 2, 0, 3, 3 },
107 107
    { 0, 0, 0, 0, 2, 0, 0, 0 },
......
268 268
        return 1;
269 269
    }
270 270
}
271
#else
272
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
273
			  int *access_index, target_ulong address, int rw,
274
			  int is_user)
275
{
276
    target_ulong mask;
277
    unsigned int i;
278

  
279
    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
280
	*physical = address & 0xffffffff;
281
	*prot = PAGE_READ | PAGE_WRITE;
282
        return 0;
283
    }
284

  
285
    for (i = 0; i < 64; i++) {
286
	if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
287
	    switch (env->dtlb_tte[i] >> 60) {
288
	    default:
289
	    case 0x4: // 8k
290
		mask = 0xffffffffffffe000ULL;
291
		break;
292
	    case 0x5: // 64k
293
		mask = 0xffffffffffff0000ULL;
294
		break;
295
	    case 0x6: // 512k
296
		mask = 0xfffffffffff80000ULL;
297
		break;
298
	    case 0x7: // 4M
299
		mask = 0xffffffffffc00000ULL;
300
		break;
301
	    }
302
	    // ctx match, vaddr match?
303
	    if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
304
		(address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
305
		// access ok?
306
		if (((env->dtlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) ||
307
		    (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
308
		    env->exception_index = TT_DFAULT;
309
		    return 1;
310
		}
311
		*physical = env->dtlb_tte[i] & 0xffffe000;
312
		*prot = PAGE_READ;
313
		if (env->dtlb_tte[i] & 0x2)
314
		    *prot |= PAGE_WRITE;
315
		return 0;
316
	    }
317
	}
318
    }
319
    env->exception_index = TT_DFAULT;
320
    return 1;
321
}
322

  
323
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
324
			  int *access_index, target_ulong address, int rw,
325
			  int is_user)
326
{
327
    target_ulong mask;
328
    unsigned int i;
329

  
330
    if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
331
	*physical = address & 0xffffffff;
332
	*prot = PAGE_READ;
333
        return 0;
334
    }
335
    for (i = 0; i < 64; i++) {
336
	if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
337
	    switch (env->itlb_tte[i] >> 60) {
338
	    default:
339
	    case 0x4: // 8k
340
		mask = 0xffffffffffffe000ULL;
341
		break;
342
	    case 0x5: // 64k
343
		mask = 0xffffffffffff0000ULL;
344
		break;
345
	    case 0x6: // 512k
346
		mask = 0xfffffffffff80000ULL;
347
		break;
348
	    case 0x7: // 4M
349
		mask = 0xffffffffffc00000ULL;
350
		break;
351
	    }
352
	    // ctx match, vaddr match?
353
	    if (env->immuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
354
		(address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
355
		// access ok?
356
		if ((env->itlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) {
357
		    env->exception_index = TT_TFAULT;
358
		    return 1;
359
		}
360
		*physical = env->itlb_tte[i] & 0xffffe000;
361
		*prot = PAGE_READ;
362
		return 0;
363
	    }
364
	}
365
    }
366
    env->exception_index = TT_TFAULT;
367
    return 1;
368
}
369

  
370
int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
371
			  int *access_index, target_ulong address, int rw,
372
			  int is_user)
373
{
374
    if (rw == 2)
375
	return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
376
    else
377
	return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
378
}
379

  
380
/* Perform address translation */
381
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
382
                              int is_user, int is_softmmu)
383
{
384
    target_ulong virt_addr;
385
    target_phys_addr_t paddr;
386
    unsigned long vaddr;
387
    int error_code = 0, prot, ret = 0, access_index;
388

  
389
    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
390
    if (error_code == 0) {
391
	virt_addr = address & TARGET_PAGE_MASK;
392
	vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
393
	ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
394
	return ret;
395
    }
396
    // XXX
397
    return 1;
398
}
399

  
400
#endif
271 401
#endif
272 402

  
273 403
void memcpy32(target_ulong *dst, const target_ulong *src)
......
292 422
    if (new_cwp == (NWINDOWS - 1))
293 423
        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
294 424
    env->regwptr = env->regbase + (new_cwp * 16);
425
    REGWPTR = env->regwptr;
295 426
}
296 427

  
297 428
void cpu_set_cwp(CPUState *env1, int new_cwp)
298 429
{
299 430
    CPUState *saved_env;
431
#ifdef reg_REGWPTR
432
    target_ulong *saved_regwptr;
433
#endif
434

  
300 435
    saved_env = env;
436
#ifdef reg_REGWPTR
437
    saved_regwptr = REGWPTR;
438
#endif
301 439
    env = env1;
302 440
    set_cwp(new_cwp);
303 441
    env = saved_env;
442
#ifdef reg_REGWPTR
443
    REGWPTR = saved_regwptr;
444
#endif
304 445
}
305 446

  
447
#ifdef TARGET_SPARC64
448
void do_interrupt(int intno)
449
{
450
#ifdef DEBUG_PCALL
451
    if (loglevel & CPU_LOG_INT) {
452
	static int count;
453
	fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
454
                count, intno,
455
                env->pc,
456
                env->npc, env->regwptr[6]);
457
	cpu_dump_state(env, logfile, fprintf, 0);
458
#if 0
459
	{
460
	    int i;
461
	    uint8_t *ptr;
462

  
463
	    fprintf(logfile, "       code=");
464
	    ptr = (uint8_t *)env->pc;
465
	    for(i = 0; i < 16; i++) {
466
		fprintf(logfile, " %02x", ldub(ptr + i));
467
	    }
468
	    fprintf(logfile, "\n");
469
	}
470
#endif
471
	count++;
472
    }
473
#endif
474
#if !defined(CONFIG_USER_ONLY) 
475
    if (env->pstate & PS_IE) {
476
        cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
477
	return;
478
    }
479
#endif
480
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
481
	((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
482
    env->tpc[env->tl] = env->pc;
483
    env->tnpc[env->tl] = env->npc;
484
    env->tt[env->tl] = intno;
485
    env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);
486
    env->tl++;
487
    env->pc = env->tbr;
488
    env->npc = env->pc + 4;
489
    env->exception_index = 0;
490
}
491
#else
306 492
void do_interrupt(int intno)
307 493
{
308 494
    int cwp;
......
448 634
    printf("MMU dump ends\n");
449 635
}
450 636
#endif
637
#endif

Also available in: Unified diff