/*
 *  Emulation of Linux signals
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"

struct target_sigcontext {
    abi_ulong sc_pc;
    abi_ulong sc_ps;
    abi_ulong sc_lbeg;
    abi_ulong sc_lend;
    abi_ulong sc_lcount;
    abi_ulong sc_sar;
    abi_ulong sc_acclo;
    abi_ulong sc_acchi;
    abi_ulong sc_a[16];
    abi_ulong sc_xtregs;
};

struct target_ucontext {
    abi_ulong tuc_flags;
    abi_ulong tuc_link;
    target_stack_t tuc_stack;
    struct target_sigcontext tuc_mcontext;
    target_sigset_t tuc_sigmask;
};

struct target_rt_sigframe {
    target_siginfo_t info;
    struct target_ucontext uc;
    /* TODO: xtregs */
    uint8_t retcode[6];
    abi_ulong window[4];
};

static abi_ulong get_sigframe(struct target_sigaction *sa,
                              CPUXtensaState *env,
                              unsigned long framesize)
{
    abi_ulong sp;

    sp = target_sigsp(get_sp_from_cpustate(env), sa);

    return (sp - framesize) & -16;
}

static int flush_window_regs(CPUXtensaState *env)
{
    uint32_t wb = env->sregs[WINDOW_BASE];
    uint32_t ws = xtensa_replicate_windowstart(env) >> (wb + 1);
    unsigned d = ctz32(ws) + 1;
    unsigned i;
    int ret = 0;

    for (i = d; i < env->config->nareg / 4; i += d) {
        uint32_t ssp, osp;
        unsigned j;

        ws >>= d;
        xtensa_rotate_window(env, d);

        if (ws & 0x1) {
            ssp = env->regs[5];
            d = 1;
        } else if (ws & 0x2) {
            ssp = env->regs[9];
            ret |= get_user_ual(osp, env->regs[1] - 12);
            osp -= 32;
            d = 2;
        } else if (ws & 0x4) {
            ssp = env->regs[13];
            ret |= get_user_ual(osp, env->regs[1] - 12);
            osp -= 48;
            d = 3;
        } else {
            g_assert_not_reached();
        }

        for (j = 0; j < 4; ++j) {
            ret |= put_user_ual(env->regs[j], ssp - 16 + j * 4);
        }
        for (j = 4; j < d * 4; ++j) {
            ret |= put_user_ual(env->regs[j], osp - 16 + j * 4);
        }
    }
    xtensa_rotate_window(env, d);
    g_assert(env->sregs[WINDOW_BASE] == wb);
    return ret == 0;
}

static int setup_sigcontext(struct target_rt_sigframe *frame,
                            CPUXtensaState *env)
{
    struct target_sigcontext *sc = &frame->uc.tuc_mcontext;
    int i;

    __put_user(env->pc, &sc->sc_pc);
    __put_user(env->sregs[PS], &sc->sc_ps);
    __put_user(env->sregs[LBEG], &sc->sc_lbeg);
    __put_user(env->sregs[LEND], &sc->sc_lend);
    __put_user(env->sregs[LCOUNT], &sc->sc_lcount);
    if (!flush_window_regs(env)) {
        return 0;
    }
    for (i = 0; i < 16; ++i) {
        __put_user(env->regs[i], sc->sc_a + i);
    }
    __put_user(0, &sc->sc_xtregs);
    /* TODO: xtregs */
    return 1;
}

static void install_sigtramp(uint8_t *tramp)
{
#if TARGET_BIG_ENDIAN
    /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
    __put_user(0x22, &tramp[0]);
    __put_user(0x0a, &tramp[1]);
    __put_user(TARGET_NR_rt_sigreturn, &tramp[2]);
    /* Generate instruction:  SYSCALL */
    __put_user(0x00, &tramp[3]);
    __put_user(0x05, &tramp[4]);
    __put_user(0x00, &tramp[5]);
#else
    /* Generate instruction:  MOVI a2, __NR_rt_sigreturn */
    __put_user(0x22, &tramp[0]);
    __put_user(0xa0, &tramp[1]);
    __put_user(TARGET_NR_rt_sigreturn, &tramp[2]);
    /* Generate instruction:  SYSCALL */
    __put_user(0x00, &tramp[3]);
    __put_user(0x50, &tramp[4]);
    __put_user(0x00, &tramp[5]);
#endif
}

void setup_rt_frame(int sig, struct target_sigaction *ka,
                    target_siginfo_t *info,
                    target_sigset_t *set, CPUXtensaState *env)
{
    abi_ulong frame_addr;
    struct target_rt_sigframe *frame;
    uint32_t ra;
    bool abi_call0;
    unsigned base;
    int i;

    frame_addr = get_sigframe(ka, env, sizeof(*frame));
    trace_user_setup_rt_frame(env, frame_addr);

    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
        goto give_sigsegv;
    }

    if (ka->sa_flags & SA_SIGINFO) {
        tswap_siginfo(&frame->info, info);
    }

    __put_user(0, &frame->uc.tuc_flags);
    __put_user(0, &frame->uc.tuc_link);
    target_save_altstack(&frame->uc.tuc_stack, env);
    if (!setup_sigcontext(frame, env)) {
        unlock_user_struct(frame, frame_addr, 0);
        goto give_sigsegv;
    }
    for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
        __put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
    }

    if (ka->sa_flags & TARGET_SA_RESTORER) {
        ra = ka->sa_restorer;
    } else {
        /* Not used, but retain for ABI compatibility. */
        install_sigtramp(frame->retcode);
        ra = default_rt_sigreturn;
    }
    memset(env->regs, 0, sizeof(env->regs));
    env->pc = ka->_sa_handler;
    env->regs[1] = frame_addr;
    env->sregs[WINDOW_BASE] = 0;
    env->sregs[WINDOW_START] = 1;

    abi_call0 = (env->sregs[PS] & PS_WOE) == 0;
    env->sregs[PS] = PS_UM | (3 << PS_RING_SHIFT);

    if (abi_call0) {
        base = 0;
        env->regs[base] = ra;
    } else {
        env->sregs[PS] |= PS_WOE | (1 << PS_CALLINC_SHIFT);
        base = 4;
        env->regs[base] = (ra & 0x3fffffff) | 0x40000000;
    }
    env->regs[base + 2] = sig;
    env->regs[base + 3] = frame_addr + offsetof(struct target_rt_sigframe,
                                                info);
    env->regs[base + 4] = frame_addr + offsetof(struct target_rt_sigframe, uc);
    unlock_user_struct(frame, frame_addr, 1);
    return;

give_sigsegv:
    force_sigsegv(sig);
    return;
}

static void restore_sigcontext(CPUXtensaState *env,
                               struct target_rt_sigframe *frame)
{
    struct target_sigcontext *sc = &frame->uc.tuc_mcontext;
    uint32_t ps;
    int i;

    __get_user(env->pc, &sc->sc_pc);
    __get_user(ps, &sc->sc_ps);
    __get_user(env->sregs[LBEG], &sc->sc_lbeg);
    __get_user(env->sregs[LEND], &sc->sc_lend);
    __get_user(env->sregs[LCOUNT], &sc->sc_lcount);

    env->sregs[WINDOW_BASE] = 0;
    env->sregs[WINDOW_START] = 1;
    env->sregs[PS] = deposit32(env->sregs[PS],
                               PS_CALLINC_SHIFT,
                               PS_CALLINC_LEN,
                               extract32(ps, PS_CALLINC_SHIFT,
                                         PS_CALLINC_LEN));
    for (i = 0; i < 16; ++i) {
        __get_user(env->regs[i], sc->sc_a + i);
    }
    /* TODO: xtregs */
}

long do_rt_sigreturn(CPUXtensaState *env)
{
    abi_ulong frame_addr = env->regs[1];
    struct target_rt_sigframe *frame;
    sigset_t set;

    trace_user_do_rt_sigreturn(env, frame_addr);
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
        goto badframe;
    }
    target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
    set_sigmask(&set);

    restore_sigcontext(env, frame);
    target_restore_altstack(&frame->uc.tuc_stack, env);

    unlock_user_struct(frame, frame_addr, 0);
    return -QEMU_ESIGRETURN;

badframe:
    unlock_user_struct(frame, frame_addr, 0);
    force_sig(TARGET_SIGSEGV);
    return -QEMU_ESIGRETURN;
}

void setup_sigtramp(abi_ulong sigtramp_page)
{
    uint8_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6, 0);
    assert(tramp != NULL);

    default_rt_sigreturn = sigtramp_page;
    install_sigtramp(tramp);
    unlock_user(tramp, sigtramp_page, 6);
}
