/*
 * CRIS 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 "gdbstub/helpers.h"

int crisv10_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
    CPUCRISState *env = cpu_env(cs);

    if (n < 15) {
        return gdb_get_reg32(mem_buf, env->regs[n]);
    }

    if (n == 15) {
        return gdb_get_reg32(mem_buf, env->pc);
    }

    if (n < 32) {
        switch (n) {
        case 16:
            return gdb_get_reg8(mem_buf, env->pregs[n - 16]);
        case 17:
            return gdb_get_reg8(mem_buf, env->pregs[n - 16]);
        case 20:
        case 21:
            return gdb_get_reg16(mem_buf, env->pregs[n - 16]);
        default:
            if (n >= 23) {
                return gdb_get_reg32(mem_buf, env->pregs[n - 16]);
            }
            break;
        }
    }
    return 0;
}

int cris_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
    CPUCRISState *env = cpu_env(cs);
    uint8_t srs;

    srs = env->pregs[PR_SRS];
    if (n < 16) {
        return gdb_get_reg32(mem_buf, env->regs[n]);
    }

    if (n >= 21 && n < 32) {
        return gdb_get_reg32(mem_buf, env->pregs[n - 16]);
    }
    if (n >= 33 && n < 49) {
        return gdb_get_reg32(mem_buf, env->sregs[srs][n - 33]);
    }
    switch (n) {
    case 16:
        return gdb_get_reg8(mem_buf, env->pregs[0]);
    case 17:
        return gdb_get_reg8(mem_buf, env->pregs[1]);
    case 18:
        return gdb_get_reg32(mem_buf, env->pregs[2]);
    case 19:
        return gdb_get_reg8(mem_buf, srs);
    case 20:
        return gdb_get_reg16(mem_buf, env->pregs[4]);
    case 32:
        return gdb_get_reg32(mem_buf, env->pc);
    }

    return 0;
}

int cris_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    CPUCRISState *env = cpu_env(cs);
    uint32_t tmp;

    if (n > 49) {
        return 0;
    }

    tmp = ldl_p(mem_buf);

    if (n < 16) {
        env->regs[n] = tmp;
    }

    if (n >= 21 && n < 32) {
        env->pregs[n - 16] = tmp;
    }

    /* FIXME: Should support function regs be writable?  */
    switch (n) {
    case 16:
        return 1;
    case 17:
        return 1;
    case 18:
        env->pregs[PR_PID] = tmp;
        break;
    case 19:
        return 1;
    case 20:
        return 2;
    case 32:
        env->pc = tmp;
        break;
    }

    return 4;
}
