/*
 * Xtensa 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"
#include "qemu/log.h"

enum {
  xtRegisterTypeArRegfile = 1,  /* Register File ar0..arXX.  */
  xtRegisterTypeSpecialReg,     /* CPU states, such as PS, Booleans, (rsr).  */
  xtRegisterTypeUserReg,        /* User defined registers (rur).  */
  xtRegisterTypeTieRegfile,     /* User define register files.  */
  xtRegisterTypeTieState,       /* TIE States (mapped on user regs).  */
  xtRegisterTypeMapped,         /* Mapped on Special Registers.  */
  xtRegisterTypeUnmapped,       /* Special case of masked registers.  */
  xtRegisterTypeWindow,         /* Live window registers (a0..a15).  */
  xtRegisterTypeVirtual,        /* PC, FP.  */
  xtRegisterTypeUnknown
};

#define XTENSA_REGISTER_FLAGS_PRIVILEGED        0x0001
#define XTENSA_REGISTER_FLAGS_READABLE          0x0002
#define XTENSA_REGISTER_FLAGS_WRITABLE          0x0004
#define XTENSA_REGISTER_FLAGS_VOLATILE          0x0008

void xtensa_count_regs(const XtensaConfig *config,
                       unsigned *n_regs, unsigned *n_core_regs)
{
    unsigned i;
    bool count_core_regs = true;

    for (i = 0; config->gdb_regmap.reg[i].targno >= 0; ++i) {
        if (config->gdb_regmap.reg[i].type != xtRegisterTypeTieState &&
            config->gdb_regmap.reg[i].type != xtRegisterTypeMapped &&
            config->gdb_regmap.reg[i].type != xtRegisterTypeUnmapped) {
            ++*n_regs;
            if (count_core_regs) {
                if ((config->gdb_regmap.reg[i].flags &
                     XTENSA_REGISTER_FLAGS_PRIVILEGED) == 0) {
                    ++*n_core_regs;
                } else {
                    count_core_regs = false;
                }
            }
        }
    }
}

int xtensa_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
    CPUXtensaState *env = cpu_env(cs);
    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
#ifdef CONFIG_USER_ONLY
    int num_regs = env->config->gdb_regmap.num_core_regs;
#else
    int num_regs = env->config->gdb_regmap.num_regs;
#endif
    unsigned i;

    if (n < 0 || n >= num_regs) {
        return 0;
    }

    switch (reg->type) {
    case xtRegisterTypeVirtual: /*pc*/
        return gdb_get_reg32(mem_buf, env->pc);

    case xtRegisterTypeArRegfile: /*ar*/
        xtensa_sync_phys_from_window(env);
        return gdb_get_reg32(mem_buf, env->phys_regs[(reg->targno & 0xff)
                                                     % env->config->nareg]);

    case xtRegisterTypeSpecialReg: /*SR*/
        return gdb_get_reg32(mem_buf, env->sregs[reg->targno & 0xff]);

    case xtRegisterTypeUserReg: /*UR*/
        return gdb_get_reg32(mem_buf, env->uregs[reg->targno & 0xff]);

    case xtRegisterTypeTieRegfile: /*f*/
        i = reg->targno & 0x0f;
        switch (reg->size) {
        case 4:
            return gdb_get_reg32(mem_buf,
                                 float32_val(env->fregs[i].f32[FP_F32_LOW]));
        case 8:
            return gdb_get_reg64(mem_buf, float64_val(env->fregs[i].f64));
        default:
            qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported size %d\n",
                          __func__, n, reg->size);
            return gdb_get_zeroes(mem_buf, reg->size);
        }

    case xtRegisterTypeWindow: /*a*/
        return gdb_get_reg32(mem_buf, env->regs[reg->targno & 0x0f]);

    default:
        qemu_log_mask(LOG_UNIMP, "%s from reg %d of unsupported type %d\n",
                      __func__, n, reg->type);
        return gdb_get_zeroes(mem_buf, reg->size);
    }
}

int xtensa_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
    CPUXtensaState *env = cpu_env(cs);
    uint32_t tmp;
    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
#ifdef CONFIG_USER_ONLY
    int num_regs = env->config->gdb_regmap.num_core_regs;
#else
    int num_regs = env->config->gdb_regmap.num_regs;
#endif

    if (n < 0 || n >= num_regs) {
        return 0;
    }

    tmp = ldl_p(mem_buf);

    switch (reg->type) {
    case xtRegisterTypeVirtual: /*pc*/
        env->pc = tmp;
        break;

    case xtRegisterTypeArRegfile: /*ar*/
        env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
        xtensa_sync_window_from_phys(env);
        break;

    case xtRegisterTypeSpecialReg: /*SR*/
        env->sregs[reg->targno & 0xff] = tmp;
        break;

    case xtRegisterTypeUserReg: /*UR*/
        env->uregs[reg->targno & 0xff] = tmp;
        break;

    case xtRegisterTypeTieRegfile: /*f*/
        switch (reg->size) {
        case 4:
            env->fregs[reg->targno & 0x0f].f32[FP_F32_LOW] = make_float32(tmp);
            return 4;
        case 8:
            env->fregs[reg->targno & 0x0f].f64 = make_float64(tmp);
            return 8;
        default:
            qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported size %d\n",
                          __func__, n, reg->size);
            return reg->size;
        }

    case xtRegisterTypeWindow: /*a*/
        env->regs[reg->targno & 0x0f] = tmp;
        break;

    default:
        qemu_log_mask(LOG_UNIMP, "%s to reg %d of unsupported type %d\n",
                      __func__, n, reg->type);
        return reg->size;
    }

    return 4;
}
