Commit 9eff14f3 authored by Blue Swirl's avatar Blue Swirl
Browse files

cpu-exec: prepare for user and softmmu split



There is little in common with user and softmmu versions of cpu_resume_signal(),
split them.

Fix coding style for the user emulator part.

Signed-off-by: default avatarBlue Swirl <blauwirbel@gmail.com>
parent aa29141d
Loading
Loading
Loading
Loading
+172 −131
Original line number Diff line number Diff line
@@ -64,21 +64,31 @@ void cpu_loop_exit(void)
/* exit the current TB from a signal handler. The host registers are
   restored in a state compatible with the CPU emulator
 */
#if defined(CONFIG_SOFTMMU)
void cpu_resume_from_signal(CPUState *env1, void *puc)
{
    env = env1;

    /* XXX: restore cpu registers saved in host registers */

    env->exception_index = -1;
    longjmp(env->jmp_env, 1);
}

#else

void cpu_resume_from_signal(CPUState *env1, void *puc)
{
#if !defined(CONFIG_SOFTMMU)
#ifdef __linux__
    struct ucontext *uc = puc;
#elif defined(__OpenBSD__)
    struct sigcontext *uc = puc;
#endif
#endif

    env = env1;

    /* XXX: restore cpu registers saved in host registers */

#if !defined(CONFIG_SOFTMMU)
    if (puc) {
        /* XXX: use siglongjmp ? */
#ifdef __linux__
@@ -91,10 +101,10 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
        sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
#endif
    }
#endif
    env->exception_index = -1;
    longjmp(env->jmp_env, 1);
}
#endif

/* Execute the code without caching the generated code. An interpreter
   could be used if available. */
@@ -751,9 +761,11 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
#if !defined(CONFIG_SOFTMMU)

#if defined(TARGET_I386)
#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code)
#define EXCEPTION_ACTION                                        \
    raise_exception_err(env->exception_index, env->error_code)
#else
#define EXCEPTION_ACTION cpu_loop_exit()
#define EXCEPTION_ACTION                                        \
    cpu_loop_exit()
#endif

/* 'pc' is the host PC at which the exception was raised. 'address' is
@@ -767,8 +779,9 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
    TranslationBlock *tb;
    int ret;

    if (cpu_single_env)
    if (cpu_single_env) {
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
    }
#if defined(DEBUG_SIGNAL)
    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
                pc, address, is_write, *(unsigned long *)old_set);
@@ -780,10 +793,12 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,

    /* see if it is an MMU fault */
    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
    if (ret < 0)
    if (ret < 0) {
        return 0; /* not an MMU fault */
    if (ret == 0)
    }
    if (ret == 0) {
        return 1; /* the MMU fault was handled without causing real CPU fault */
    }
    /* now we have a real cpu fault */
    tb = tb_find_pc(pc);
    if (tb) {
@@ -918,18 +933,28 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 */
#ifdef linux
/* All Registers access - only for local access */
# define REG_sig(reg_name, context)		((context)->uc_mcontext.regs->reg_name)
#define REG_sig(reg_name, context)              \
    ((context)->uc_mcontext.regs->reg_name)
/* Gpr Registers access  */
#define GPR_sig(reg_num, context)              REG_sig(gpr[reg_num], context)
# define IAR_sig(context)			REG_sig(nip, context)	/* Program counter */
# define MSR_sig(context)			REG_sig(msr, context)   /* Machine State Register (Supervisor) */
# define CTR_sig(context)			REG_sig(ctr, context)   /* Count register */
# define XER_sig(context)			REG_sig(xer, context) /* User's integer exception register */
# define LR_sig(context)			REG_sig(link, context) /* Link register */
# define CR_sig(context)			REG_sig(ccr, context) /* Condition register */
/* Program counter */
#define IAR_sig(context)                       REG_sig(nip, context)
/* Machine State Register (Supervisor) */
#define MSR_sig(context)                       REG_sig(msr, context)
/* Count register */
#define CTR_sig(context)                       REG_sig(ctr, context)
/* User's integer exception register */
#define XER_sig(context)                       REG_sig(xer, context)
/* Link register */
#define LR_sig(context)                        REG_sig(link, context)
/* Condition register */
#define CR_sig(context)                        REG_sig(ccr, context)

/* Float Registers access  */
# define FLOAT_sig(reg_num, context)		(((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
# define FPSCR_sig(context)			(*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
#define FLOAT_sig(reg_num, context)                                     \
    (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num])
#define FPSCR_sig(context) \
    (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4)))
/* Exception Registers access */
#define DAR_sig(context)                       REG_sig(dar, context)
#define DSISR_sig(context)                     REG_sig(dsisr, context)
@@ -954,25 +979,38 @@ int cpu_signal_handler(int host_signum, void *pinfo,
#include <sys/ucontext.h>
typedef struct ucontext SIGCONTEXT;
/* All Registers access - only for local access */
# define REG_sig(reg_name, context)		((context)->uc_mcontext->ss.reg_name)
# define FLOATREG_sig(reg_name, context)	((context)->uc_mcontext->fs.reg_name)
# define EXCEPREG_sig(reg_name, context)	((context)->uc_mcontext->es.reg_name)
# define VECREG_sig(reg_name, context)		((context)->uc_mcontext->vs.reg_name)
#define REG_sig(reg_name, context)              \
    ((context)->uc_mcontext->ss.reg_name)
#define FLOATREG_sig(reg_name, context)         \
    ((context)->uc_mcontext->fs.reg_name)
#define EXCEPREG_sig(reg_name, context)         \
    ((context)->uc_mcontext->es.reg_name)
#define VECREG_sig(reg_name, context)           \
    ((context)->uc_mcontext->vs.reg_name)
/* Gpr Registers access */
#define GPR_sig(reg_num, context)              REG_sig(r##reg_num, context)
# define IAR_sig(context)			REG_sig(srr0, context)	/* Program counter */
# define MSR_sig(context)			REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
/* Program counter */
#define IAR_sig(context)                       REG_sig(srr0, context)
/* Machine State Register (Supervisor) */
#define MSR_sig(context)                       REG_sig(srr1, context)
#define CTR_sig(context)                       REG_sig(ctr, context)
# define XER_sig(context)			REG_sig(xer, context) /* Link register */
# define LR_sig(context)			REG_sig(lr, context)  /* User's integer exception register */
# define CR_sig(context)			REG_sig(cr, context)  /* Condition register */
/* Link register */
#define XER_sig(context)                       REG_sig(xer, context)
/* User's integer exception register */
#define LR_sig(context)                        REG_sig(lr, context)
/* Condition register */
#define CR_sig(context)                        REG_sig(cr, context)
/* Float Registers access */
# define FLOAT_sig(reg_num, context)		FLOATREG_sig(fpregs[reg_num], context)
# define FPSCR_sig(context)			((double)FLOATREG_sig(fpscr, context))
#define FLOAT_sig(reg_num, context)             \
    FLOATREG_sig(fpregs[reg_num], context)
#define FPSCR_sig(context)                      \
    ((double)FLOATREG_sig(fpscr, context))
/* Exception Registers access */
# define DAR_sig(context)			EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
/* Fault registers for coredump */
#define DAR_sig(context)                       EXCEPREG_sig(dar, context)
#define DSISR_sig(context)                     EXCEPREG_sig(dsisr, context)
# define TRAP_sig(context)			EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
/* number of powerpc exception taken */
#define TRAP_sig(context)                      EXCEPREG_sig(exception, context)
#endif /* __APPLE__ */

int cpu_signal_handler(int host_signum, void *pinfo,
@@ -991,11 +1029,13 @@ int cpu_signal_handler(int host_signum, void *pinfo,
    is_write = 0;
#if 0
    /* ppc 4xx case */
    if (DSISR_sig(uc) & 0x00800000)
    if (DSISR_sig(uc) & 0x00800000) {
        is_write = 1;
    }
#else
    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) {
        is_write = 1;
    }
#endif
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                             is_write, &uc->uc_sigmask, puc);
@@ -1014,17 +1054,17 @@ int cpu_signal_handler(int host_signum, void *pinfo,

    /* XXX: need kernel patch to get write flag faster */
    switch (insn >> 26) {
    case 0x0d: // stw
    case 0x0e: // stb
    case 0x0f: // stq_u
    case 0x24: // stf
    case 0x25: // stg
    case 0x26: // sts
    case 0x27: // stt
    case 0x2c: // stl
    case 0x2d: // stq
    case 0x2e: // stl_c
    case 0x2f: // stq_c
    case 0x0d: /* stw */
    case 0x0e: /* stb */
    case 0x0f: /* stq_u */
    case 0x24: /* stf */
    case 0x25: /* stg */
    case 0x26: /* sts */
    case 0x27: /* stt */
    case 0x2c: /* stl */
    case 0x2d: /* stq */
    case 0x2e: /* stl_c */
    case 0x2f: /* stq_c */
        is_write = 1;
    }

@@ -1061,25 +1101,25 @@ int cpu_signal_handler(int host_signum, void *pinfo,
    insn = *(uint32_t *)pc;
    if ((insn >> 30) == 3) {
        switch ((insn >> 19) & 0x3f) {
      case 0x05: // stb
      case 0x15: // stba
      case 0x06: // sth
      case 0x16: // stha
      case 0x04: // st
      case 0x14: // sta
      case 0x07: // std
      case 0x17: // stda
      case 0x0e: // stx
      case 0x1e: // stxa
      case 0x24: // stf
      case 0x34: // stfa
      case 0x27: // stdf
      case 0x37: // stdfa
      case 0x26: // stqf
      case 0x36: // stqfa
      case 0x25: // stfsr
      case 0x3c: // casa
      case 0x3e: // casxa
        case 0x05: /* stb */
        case 0x15: /* stba */
        case 0x06: /* sth */
        case 0x16: /* stha */
        case 0x04: /* st */
        case 0x14: /* sta */
        case 0x07: /* std */
        case 0x17: /* stda */
        case 0x0e: /* stx */
        case 0x1e: /* stxa */
        case 0x24: /* stf */
        case 0x34: /* stfa */
        case 0x27: /* stdf */
        case 0x37: /* stdfa */
        case 0x26: /* stqf */
        case 0x36: /* stqfa */
        case 0x25: /* stfsr */
        case 0x3c: /* casa */
        case 0x3e: /* casxa */
            is_write = 1;
            break;
        }
@@ -1149,9 +1189,10 @@ int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
    case SIGSEGV:
    case SIGBUS:
    case SIGTRAP:
	  if (info->si_code && (info->si_segvflags & __ISR_VALID))
        if (info->si_code && (info->si_segvflags & __ISR_VALID)) {
            /* ISR.W (write-access) is bit 33:  */
            is_write = (info->si_isr >> 33) & 1;
        }
        break;

    default: