Revision ee5bbe38 target-sparc/helper.c

b/target-sparc/helper.c
17 17
 * License along with this library; if not, write to the Free Software
18 18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 19
 */
20
#include "exec.h"
20
#include <stdarg.h>
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <string.h>
24
#include <inttypes.h>
25
#include <signal.h>
26
#include <assert.h>
27

  
28
#include "cpu.h"
29
#include "exec-all.h"
21 30

  
22 31
//#define DEBUG_PCALL
23 32
//#define DEBUG_MMU
......
52 61

  
53 62
#else
54 63

  
55
#define MMUSUFFIX _mmu
56
#define GETPC() (__builtin_return_address(0))
57

  
58
#define SHIFT 0
59
#include "softmmu_template.h"
60

  
61
#define SHIFT 1
62
#include "softmmu_template.h"
63

  
64
#define SHIFT 2
65
#include "softmmu_template.h"
66

  
67
#define SHIFT 3
68
#include "softmmu_template.h"
69

  
70

  
71
/* try to fill the TLB and return an exception if error. If retaddr is
72
   NULL, it means that the function was called in C code (i.e. not
73
   from generated code or from helper.c) */
74
/* XXX: fix it to restore all registers */
75
void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
76
{
77
    TranslationBlock *tb;
78
    int ret;
79
    unsigned long pc;
80
    CPUState *saved_env;
81

  
82
    /* XXX: hack to restore env in all cases, even if not called from
83
       generated code */
84
    saved_env = env;
85
    env = cpu_single_env;
86

  
87
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
88
    if (ret) {
89
        if (retaddr) {
90
            /* now we have a real cpu fault */
91
            pc = (unsigned long)retaddr;
92
            tb = tb_find_pc(pc);
93
            if (tb) {
94
                /* the PC is inside the translated code. It means that we have
95
                   a virtual CPU fault */
96
                cpu_restore_state(tb, env, pc, (void *)T2);
97
            }
98
        }
99
        cpu_loop_exit();
100
    }
101
    env = saved_env;
102
}
103

  
104 64
#ifndef TARGET_SPARC64
105 65
static const int access_table[8][8] = {
106 66
    { 0, 0, 0, 0, 2, 0, 3, 3 },
......
412 372
    dst[7] = src[7];
413 373
}
414 374

  
415
void set_cwp(int new_cwp)
416
{
417
    /* put the modified wrap registers at their proper location */
418
    if (env->cwp == (NWINDOWS - 1))
419
        memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
420
    env->cwp = new_cwp;
421
    /* put the wrap registers at their temporary location */
422
    if (new_cwp == (NWINDOWS - 1))
423
        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
424
    env->regwptr = env->regbase + (new_cwp * 16);
425
    REGWPTR = env->regwptr;
426
}
427

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

  
435
    saved_env = env;
436
#ifdef reg_REGWPTR
437
    saved_regwptr = REGWPTR;
438
#endif
439
    env = env1;
440
    set_cwp(new_cwp);
441
    env = saved_env;
442
#ifdef reg_REGWPTR
443
    REGWPTR = saved_regwptr;
444
#endif
445
}
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
492
void do_interrupt(int intno)
493
{
494
    int cwp;
495

  
496
#ifdef DEBUG_PCALL
497
    if (loglevel & CPU_LOG_INT) {
498
	static int count;
499
	fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
500
                count, intno,
501
                env->pc,
502
                env->npc, env->regwptr[6]);
503
	cpu_dump_state(env, logfile, fprintf, 0);
504
#if 0
505
	{
506
	    int i;
507
	    uint8_t *ptr;
508

  
509
	    fprintf(logfile, "       code=");
510
	    ptr = (uint8_t *)env->pc;
511
	    for(i = 0; i < 16; i++) {
512
		fprintf(logfile, " %02x", ldub(ptr + i));
513
	    }
514
	    fprintf(logfile, "\n");
515
	}
516
#endif
517
	count++;
518
    }
519
#endif
520
#if !defined(CONFIG_USER_ONLY) 
521
    if (env->psret == 0) {
522
        cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
523
	return;
524
    }
525
#endif
526
    env->psret = 0;
527
    cwp = (env->cwp - 1) & (NWINDOWS - 1); 
528
    set_cwp(cwp);
529
    env->regwptr[9] = env->pc;
530
    env->regwptr[10] = env->npc;
531
    env->psrps = env->psrs;
532
    env->psrs = 1;
533
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
534
    env->pc = env->tbr;
535
    env->npc = env->pc + 4;
536
    env->exception_index = 0;
537
}
538

  
539
target_ulong mmu_probe(target_ulong address, int mmulev)
375
#if !defined(TARGET_SPARC64)
376
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
540 377
{
541 378
    target_phys_addr_t pde_ptr;
542 379
    uint32_t pde;
......
599 436
}
600 437

  
601 438
#ifdef DEBUG_MMU
602
void dump_mmu(void)
439
void dump_mmu(CPUState *env)
603 440
{
604 441
     target_ulong va, va1, va2;
605 442
     unsigned int n, m, o;
......
611 448
    pde = ldl_phys(pde_ptr);
612 449
    printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
613 450
    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
614
	pde_ptr = mmu_probe(va, 2);
451
	pde_ptr = mmu_probe(env, va, 2);
615 452
	if (pde_ptr) {
616 453
	    pa = cpu_get_phys_page_debug(env, va);
617 454
 	    printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr);
618 455
	    for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
619
		pde_ptr = mmu_probe(va1, 1);
456
		pde_ptr = mmu_probe(env, va1, 1);
620 457
		if (pde_ptr) {
621 458
		    pa = cpu_get_phys_page_debug(env, va1);
622 459
 		    printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr);
623 460
		    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
624
			pde_ptr = mmu_probe(va2, 0);
461
			pde_ptr = mmu_probe(env, va2, 0);
625 462
			if (pde_ptr) {
626 463
			    pa = cpu_get_phys_page_debug(env, va2);
627 464
 			    printf("  VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr);

Also available in: Unified diff