/*
 * PowerPC gdb server stub
 *
 * Copyright (c) 2003-2005 Fabrice Bellard
 * Copyright (c) 2013 SUSE LINUX Products GmbH
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/gdbstub.h"
#include "gdbstub/helpers.h"
#include "internal.h"

static int ppc_gdb_register_len_apple(int n)
{
    switch (n) {
    case 0 ... 31:
        /* gprs */
        return 8;
    case 32 ... 63:
        /* fprs */
        return 8;
    case 64 ... 95:
        return 16;
    case 64 + 32: /* nip */
    case 65 + 32: /* msr */
    case 67 + 32: /* lr */
    case 68 + 32: /* ctr */
    case 70 + 32: /* fpscr */
        return 8;
    case 66 + 32: /* cr */
    case 69 + 32: /* xer */
        return 4;
    default:
        return 0;
    }
}

static int ppc_gdb_register_len(int n)
{
    switch (n) {
    case 0 ... 31:
        /* gprs */
        return sizeof(target_ulong);
    case 66:
        /* cr */
    case 69:
        /* xer */
        return 4;
    case 64:
        /* nip */
    case 65:
        /* msr */
    case 67:
        /* lr */
    case 68:
        /* ctr */
        return sizeof(target_ulong);
    default:
        return 0;
    }
}

/*
 * We need to present the registers to gdb in the "current" memory
 * ordering.  For user-only mode we get this for free;
 * TARGET_BIG_ENDIAN is set to the proper ordering for the
 * binary, and cannot be changed.  For system mode,
 * TARGET_BIG_ENDIAN is always set, and we must check the current
 * mode of the chip to see if we're running in little-endian.
 */
void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
{
#ifndef CONFIG_USER_ONLY
    if (!FIELD_EX64(env->msr, MSR, LE)) {
        /* do nothing */
    } else if (len == 4) {
        bswap32s((uint32_t *)mem_buf);
    } else if (len == 8) {
        bswap64s((uint64_t *)mem_buf);
    } else if (len == 16) {
        bswap128s((Int128 *)mem_buf);
    } else {
        g_assert_not_reached();
    }
#endif
}

/*
 * Old gdb always expects FP registers.  Newer (xml-aware) gdb only
 * expects whatever the target description contains.  Due to a
 * historical mishap the FP registers appear in between core integer
 * regs and PC, MSR, CR, and so forth.  We hack round this by giving
 * the FP regs zero size when talking to a newer gdb.
 */

int ppc_cpu_gdb_read_register(CPUState *cs, GByteArray *buf, int n)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    uint8_t *mem_buf;
    int r = ppc_gdb_register_len(n);

    if (!r) {
        return r;
    }

    if (n < 32) {
        /* gprs */
        gdb_get_regl(buf, env->gpr[n]);
    } else {
        switch (n) {
        case 64:
            gdb_get_regl(buf, env->nip);
            break;
        case 65:
            gdb_get_regl(buf, env->msr);
            break;
        case 66:
            {
                uint32_t cr = ppc_get_cr(env);
                gdb_get_reg32(buf, cr);
                break;
            }
        case 67:
            gdb_get_regl(buf, env->lr);
            break;
        case 68:
            gdb_get_regl(buf, env->ctr);
            break;
        case 69:
            gdb_get_reg32(buf, cpu_read_xer(env));
            break;
        }
    }
    mem_buf = buf->data + buf->len - r;
    ppc_maybe_bswap_register(env, mem_buf, r);
    return r;
}

int ppc_cpu_gdb_read_register_apple(CPUState *cs, GByteArray *buf, int n)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    uint8_t *mem_buf;
    int r = ppc_gdb_register_len_apple(n);

    if (!r) {
        return r;
    }

    if (n < 32) {
        /* gprs */
        gdb_get_reg64(buf, env->gpr[n]);
    } else if (n < 64) {
        /* fprs */
        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n - 32));
    } else if (n < 96) {
        /* Altivec */
        gdb_get_reg64(buf, n - 64);
        gdb_get_reg64(buf, 0);
    } else {
        switch (n) {
        case 64 + 32:
            gdb_get_reg64(buf, env->nip);
            break;
        case 65 + 32:
            gdb_get_reg64(buf, env->msr);
            break;
        case 66 + 32:
            {
                uint32_t cr = ppc_get_cr(env);
                gdb_get_reg32(buf, cr);
                break;
            }
        case 67 + 32:
            gdb_get_reg64(buf, env->lr);
            break;
        case 68 + 32:
            gdb_get_reg64(buf, env->ctr);
            break;
        case 69 + 32:
            gdb_get_reg32(buf, cpu_read_xer(env));
            break;
        case 70 + 32:
            gdb_get_reg64(buf, env->fpscr);
            break;
        }
    }
    mem_buf = buf->data + buf->len - r;
    ppc_maybe_bswap_register(env, mem_buf, r);
    return r;
}

int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    int r = ppc_gdb_register_len(n);

    if (!r) {
        return r;
    }
    ppc_maybe_bswap_register(env, mem_buf, r);
    if (n < 32) {
        /* gprs */
        env->gpr[n] = ldtul_p(mem_buf);
    } else if (n < 64) {
        /* fprs */
        *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
    } else {
        switch (n) {
        case 64:
            env->nip = ldtul_p(mem_buf);
            break;
        case 65:
            ppc_store_msr(env, ldtul_p(mem_buf));
            break;
        case 66:
            {
                uint32_t cr = ldl_p(mem_buf);
                ppc_set_cr(env, cr);
                break;
            }
        case 67:
            env->lr = ldtul_p(mem_buf);
            break;
        case 68:
            env->ctr = ldtul_p(mem_buf);
            break;
        case 69:
            cpu_write_xer(env, ldl_p(mem_buf));
            break;
        case 70:
            /* fpscr */
            ppc_store_fpscr(env, ldtul_p(mem_buf));
            break;
        }
    }
    return r;
}
int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    int r = ppc_gdb_register_len_apple(n);

    if (!r) {
        return r;
    }
    ppc_maybe_bswap_register(env, mem_buf, r);
    if (n < 32) {
        /* gprs */
        env->gpr[n] = ldq_p(mem_buf);
    } else if (n < 64) {
        /* fprs */
        *cpu_fpr_ptr(env, n - 32) = ldq_p(mem_buf);
    } else {
        switch (n) {
        case 64 + 32:
            env->nip = ldq_p(mem_buf);
            break;
        case 65 + 32:
            ppc_store_msr(env, ldq_p(mem_buf));
            break;
        case 66 + 32:
            {
                uint32_t cr = ldl_p(mem_buf);
                ppc_set_cr(env, cr);
                break;
            }
        case 67 + 32:
            env->lr = ldq_p(mem_buf);
            break;
        case 68 + 32:
            env->ctr = ldq_p(mem_buf);
            break;
        case 69 + 32:
            cpu_write_xer(env, ldl_p(mem_buf));
            break;
        case 70 + 32:
            /* fpscr */
            ppc_store_fpscr(env, ldq_p(mem_buf));
            break;
        }
    }
    return r;
}

#ifndef CONFIG_USER_ONLY
void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu)
{
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
    CPUPPCState *env = &cpu->env;
    GString *xml;
    char *spr_name;
    unsigned int num_regs = 0;
    int i;

    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
        ppc_spr_t *spr = &env->spr_cb[i];

        if (!spr->name) {
            continue;
        }

        /*
         * GDB identifies registers based on the order they are
         * presented in the XML. These ids will not match QEMU's
         * representation (which follows the PowerISA).
         *
         * Store the position of the current register description so
         * we can make the correspondence later.
         */
        spr->gdb_id = num_regs;
        num_regs++;
    }

    if (pcc->gdb_spr_xml) {
        return;
    }

    xml = g_string_new("<?xml version=\"1.0\"?>");
    g_string_append(xml, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
    g_string_append(xml, "<feature name=\"org.qemu.power.spr\">");

    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
        ppc_spr_t *spr = &env->spr_cb[i];

        if (!spr->name) {
            continue;
        }

        spr_name = g_ascii_strdown(spr->name, -1);
        g_string_append_printf(xml, "<reg name=\"%s\"", spr_name);
        g_free(spr_name);

        g_string_append_printf(xml, " bitsize=\"%d\"", TARGET_LONG_BITS);
        g_string_append(xml, " group=\"spr\"/>");
    }

    g_string_append(xml, "</feature>");

    pcc->gdb_num_sprs = num_regs;
    pcc->gdb_spr_xml = g_string_free(xml, false);
}

const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name)
{
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);

    if (strcmp(xml_name, "power-spr.xml") == 0) {
        return pcc->gdb_spr_xml;
    }
    return NULL;
}
#endif

#if !defined(CONFIG_USER_ONLY)
static int gdb_find_spr_idx(CPUPPCState *env, int n)
{
    int i;

    for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
        ppc_spr_t *spr = &env->spr_cb[i];

        if (spr->name && spr->gdb_id == n) {
            return i;
        }
    }
    return -1;
}

static int gdb_get_spr_reg(CPUPPCState *env, GByteArray *buf, int n)
{
    int reg;
    int len;

    reg = gdb_find_spr_idx(env, n);
    if (reg < 0) {
        return 0;
    }

    len = TARGET_LONG_SIZE;
    gdb_get_regl(buf, env->spr[reg]);
    ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, len), len);
    return len;
}

static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
    int reg;
    int len;

    reg = gdb_find_spr_idx(env, n);
    if (reg < 0) {
        return 0;
    }

    len = TARGET_LONG_SIZE;
    ppc_maybe_bswap_register(env, mem_buf, len);
    env->spr[reg] = ldn_p(mem_buf, len);

    return len;
}
#endif

static int gdb_get_float_reg(CPUPPCState *env, GByteArray *buf, int n)
{
    uint8_t *mem_buf;
    if (n < 32) {
        gdb_get_reg64(buf, *cpu_fpr_ptr(env, n));
        mem_buf = gdb_get_reg_ptr(buf, 8);
        ppc_maybe_bswap_register(env, mem_buf, 8);
        return 8;
    }
    if (n == 32) {
        gdb_get_reg32(buf, env->fpscr);
        mem_buf = gdb_get_reg_ptr(buf, 4);
        ppc_maybe_bswap_register(env, mem_buf, 4);
        return 4;
    }
    return 0;
}

static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
    if (n < 32) {
        ppc_maybe_bswap_register(env, mem_buf, 8);
        *cpu_fpr_ptr(env, n) = ldq_p(mem_buf);
        return 8;
    }
    if (n == 32) {
        ppc_maybe_bswap_register(env, mem_buf, 4);
        ppc_store_fpscr(env, ldl_p(mem_buf));
        return 4;
    }
    return 0;
}

static int gdb_get_avr_reg(CPUPPCState *env, GByteArray *buf, int n)
{
    uint8_t *mem_buf;

    if (n < 32) {
        ppc_avr_t *avr = cpu_avr_ptr(env, n);
        gdb_get_reg128(buf, avr->VsrD(0), avr->VsrD(1));
        mem_buf = gdb_get_reg_ptr(buf, 16);
        ppc_maybe_bswap_register(env, mem_buf, 16);
        return 16;
    }
    if (n == 32) {
        gdb_get_reg32(buf, ppc_get_vscr(env));
        mem_buf = gdb_get_reg_ptr(buf, 4);
        ppc_maybe_bswap_register(env, mem_buf, 4);
        return 4;
    }
    if (n == 33) {
        gdb_get_reg32(buf, (uint32_t)env->spr[SPR_VRSAVE]);
        mem_buf = gdb_get_reg_ptr(buf, 4);
        ppc_maybe_bswap_register(env, mem_buf, 4);
        return 4;
    }
    return 0;
}

static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
    if (n < 32) {
        ppc_avr_t *avr = cpu_avr_ptr(env, n);
        ppc_maybe_bswap_register(env, mem_buf, 16);
        avr->VsrD(0) = ldq_p(mem_buf);
        avr->VsrD(1) = ldq_p(mem_buf + 8);
        return 16;
    }
    if (n == 32) {
        ppc_maybe_bswap_register(env, mem_buf, 4);
        ppc_store_vscr(env, ldl_p(mem_buf));
        return 4;
    }
    if (n == 33) {
        ppc_maybe_bswap_register(env, mem_buf, 4);
        env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
        return 4;
    }
    return 0;
}

static int gdb_get_spe_reg(CPUPPCState *env, GByteArray *buf, int n)
{
    if (n < 32) {
#if defined(TARGET_PPC64)
        gdb_get_reg32(buf, env->gpr[n] >> 32);
        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
#else
        gdb_get_reg32(buf, env->gprh[n]);
#endif
        return 4;
    }
    if (n == 32) {
        gdb_get_reg64(buf, env->spe_acc);
        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
        return 8;
    }
    if (n == 33) {
        gdb_get_reg32(buf, env->spe_fscr);
        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 4), 4);
        return 4;
    }
    return 0;
}

static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
    if (n < 32) {
#if defined(TARGET_PPC64)
        target_ulong lo = (uint32_t)env->gpr[n];
        target_ulong hi;

        ppc_maybe_bswap_register(env, mem_buf, 4);

        hi = (target_ulong)ldl_p(mem_buf) << 32;
        env->gpr[n] = lo | hi;
#else
        env->gprh[n] = ldl_p(mem_buf);
#endif
        return 4;
    }
    if (n == 32) {
        ppc_maybe_bswap_register(env, mem_buf, 8);
        env->spe_acc = ldq_p(mem_buf);
        return 8;
    }
    if (n == 33) {
        ppc_maybe_bswap_register(env, mem_buf, 4);
        env->spe_fscr = ldl_p(mem_buf);
        return 4;
    }
    return 0;
}

static int gdb_get_vsx_reg(CPUPPCState *env, GByteArray *buf, int n)
{
    if (n < 32) {
        gdb_get_reg64(buf, *cpu_vsrl_ptr(env, n));
        ppc_maybe_bswap_register(env, gdb_get_reg_ptr(buf, 8), 8);
        return 8;
    }
    return 0;
}

static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
{
    if (n < 32) {
        ppc_maybe_bswap_register(env, mem_buf, 8);
        *cpu_vsrl_ptr(env, n) = ldq_p(mem_buf);
        return 8;
    }
    return 0;
}

const gchar *ppc_gdb_arch_name(CPUState *cs)
{
#if defined(TARGET_PPC64)
    return "powerpc:common64";
#else
    return "powerpc:common";
#endif
}

void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *pcc)
{
    if (pcc->insns_flags & PPC_FLOAT) {
        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
                                 33, "power-fpu.xml", 0);
    }
    if (pcc->insns_flags & PPC_ALTIVEC) {
        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
                                 34, "power-altivec.xml", 0);
    }
    if (pcc->insns_flags & PPC_SPE) {
        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
                                 34, "power-spe.xml", 0);
    }
    if (pcc->insns_flags2 & PPC2_VSX) {
        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
                                 32, "power-vsx.xml", 0);
    }
#ifndef CONFIG_USER_ONLY
    gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
                             pcc->gdb_num_sprs, "power-spr.xml", 0);
#endif
}
