/*
 * 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 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 "qemu-common.h"
#include "cpu.h"
#include "exec/gdbstub.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 32 ... 63:
        /* fprs */
        if (gdb_has_xml) {
            return 0;
        }
        return 8;
    case 66:
        /* cr */
    case 69:
        /* xer */
        return 4;
    case 64:
        /* nip */
    case 65:
        /* msr */
    case 67:
        /* lr */
    case 68:
        /* ctr */
        return sizeof(target_ulong);
    case 70:
        /* fpscr */
        if (gdb_has_xml) {
            return 0;
        }
        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_WORDS_BIGENDIAN is set to
   the proper ordering for the binary, and cannot be changed.
   For system mode, TARGET_WORDS_BIGENDIAN 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 (!msr_le) {
        /* do nothing */
    } else if (len == 4) {
        bswap32s((uint32_t *)mem_buf);
    } else if (len == 8) {
        bswap64s((uint64_t *)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, 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;
    }

    if (n < 32) {
        /* gprs */
        gdb_get_regl(mem_buf, env->gpr[n]);
    } else if (n < 64) {
        /* fprs */
        stfq_p(mem_buf, env->fpr[n-32]);
    } else {
        switch (n) {
        case 64:
            gdb_get_regl(mem_buf, env->nip);
            break;
        case 65:
            gdb_get_regl(mem_buf, env->msr);
            break;
        case 66:
            {
                uint32_t cr = 0;
                int i;
                for (i = 0; i < 8; i++) {
                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
                }
                gdb_get_reg32(mem_buf, cr);
                break;
            }
        case 67:
            gdb_get_regl(mem_buf, env->lr);
            break;
        case 68:
            gdb_get_regl(mem_buf, env->ctr);
            break;
        case 69:
            gdb_get_reg32(mem_buf, env->xer);
            break;
        case 70:
            gdb_get_reg32(mem_buf, env->fpscr);
            break;
        }
    }
    ppc_maybe_bswap_register(env, mem_buf, r);
    return r;
}

int ppc_cpu_gdb_read_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;
    }

    if (n < 32) {
        /* gprs */
        gdb_get_reg64(mem_buf, env->gpr[n]);
    } else if (n < 64) {
        /* fprs */
        stfq_p(mem_buf, env->fpr[n-32]);
    } else if (n < 96) {
        /* Altivec */
        stq_p(mem_buf, n - 64);
        stq_p(mem_buf + 8, 0);
    } else {
        switch (n) {
        case 64 + 32:
            gdb_get_reg64(mem_buf, env->nip);
            break;
        case 65 + 32:
            gdb_get_reg64(mem_buf, env->msr);
            break;
        case 66 + 32:
            {
                uint32_t cr = 0;
                int i;
                for (i = 0; i < 8; i++) {
                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
                }
                gdb_get_reg32(mem_buf, cr);
                break;
            }
        case 67 + 32:
            gdb_get_reg64(mem_buf, env->lr);
            break;
        case 68 + 32:
            gdb_get_reg64(mem_buf, env->ctr);
            break;
        case 69 + 32:
            gdb_get_reg32(mem_buf, env->xer);
            break;
        case 70 + 32:
            gdb_get_reg64(mem_buf, env->fpscr);
            break;
        }
    }
    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 */
        env->fpr[n-32] = ldfq_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);
                int i;
                for (i = 0; i < 8; i++) {
                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
                }
                break;
            }
        case 67:
            env->lr = ldtul_p(mem_buf);
            break;
        case 68:
            env->ctr = ldtul_p(mem_buf);
            break;
        case 69:
            env->xer = ldl_p(mem_buf);
            break;
        case 70:
            /* fpscr */
            store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
            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 */
        env->fpr[n-32] = ldfq_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);
                int i;
                for (i = 0; i < 8; i++) {
                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
                }
                break;
            }
        case 67 + 32:
            env->lr = ldq_p(mem_buf);
            break;
        case 68 + 32:
            env->ctr = ldq_p(mem_buf);
            break;
        case 69 + 32:
            env->xer = ldl_p(mem_buf);
            break;
        case 70 + 32:
            /* fpscr */
            store_fpscr(env, ldq_p(mem_buf), 0xffffffff);
            break;
        }
    }
    return r;
}
