/*
 *  HPPA interrupt helper routines
 *
 *  Copyright (c) 2017 Richard Henderson
 *
 * 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 "migration/cpu.h"


static int get_psw(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field)
{
    CPUHPPAState *env = opaque;
    cpu_hppa_put_psw(env, qemu_get_be64(f));
    return 0;
}

static int put_psw(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field, JSONWriter *vmdesc)
{
    CPUHPPAState *env = opaque;
    qemu_put_be64(f, cpu_hppa_get_psw(env));
    return 0;
}

static const VMStateInfo vmstate_psw = {
    .name = "psw",
    .get = get_psw,
    .put = put_psw,
};

static int get_tlb(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field)
{
    HPPATLBEntry *ent = opaque;
    uint64_t val;

    ent->itree.start = qemu_get_be64(f);
    ent->itree.last = qemu_get_be64(f);
    ent->pa = qemu_get_be64(f);
    val = qemu_get_be64(f);

    if (val) {
        ent->t = extract64(val, 61, 1);
        ent->d = extract64(val, 60, 1);
        ent->b = extract64(val, 59, 1);
        ent->ar_type = extract64(val, 56, 3);
        ent->ar_pl1 = extract64(val, 54, 2);
        ent->ar_pl2 = extract64(val, 52, 2);
        ent->u = extract64(val, 51, 1);
        /* o = bit 50 */
        /* p = bit 49 */
        ent->access_id = extract64(val, 1, 31);
        ent->entry_valid = 1;
    }
    return 0;
}

static int put_tlb(QEMUFile *f, void *opaque, size_t size,
                   const VMStateField *field, JSONWriter *vmdesc)
{
    HPPATLBEntry *ent = opaque;
    uint64_t val = 0;

    if (ent->entry_valid) {
        val = 1;
        val = deposit64(val, 61, 1, ent->t);
        val = deposit64(val, 60, 1, ent->d);
        val = deposit64(val, 59, 1, ent->b);
        val = deposit64(val, 56, 3, ent->ar_type);
        val = deposit64(val, 54, 2, ent->ar_pl1);
        val = deposit64(val, 52, 2, ent->ar_pl2);
        val = deposit64(val, 51, 1, ent->u);
        /* o = bit 50 */
        /* p = bit 49 */
        val = deposit64(val, 1, 31, ent->access_id);
    }

    qemu_put_be64(f, ent->itree.start);
    qemu_put_be64(f, ent->itree.last);
    qemu_put_be64(f, ent->pa);
    qemu_put_be64(f, val);
    return 0;
}

static const VMStateInfo vmstate_tlb_entry = {
    .name = "tlb entry",
    .get = get_tlb,
    .put = put_tlb,
};

static int tlb_pre_load(void *opaque)
{
    CPUHPPAState *env = opaque;

    /*
     * Zap the entire tlb, on-the-side data structures and all.
     * Each tlb entry will have data re-filled by put_tlb.
     */
    memset(env->tlb, 0, sizeof(env->tlb));
    memset(&env->tlb_root, 0, sizeof(env->tlb_root));
    env->tlb_unused = NULL;
    env->tlb_partial = NULL;

    return 0;
}

static int tlb_post_load(void *opaque, int version_id)
{
    CPUHPPAState *env = opaque;
    uint32_t btlb_entries = HPPA_BTLB_ENTRIES(env);
    HPPATLBEntry **unused = &env->tlb_unused;
    HPPATLBEntry *partial = NULL;

    /*
     * Re-create the interval tree from the valid entries.
     * Truly invalid entries should have start == end == 0.
     * Otherwise it should be the in-flight tlb_partial entry.
     */
    for (uint32_t i = 0; i < ARRAY_SIZE(env->tlb); ++i) {
        HPPATLBEntry *e = &env->tlb[i];

        if (e->entry_valid) {
            interval_tree_insert(&e->itree, &env->tlb_root);
        } else if (i < btlb_entries) {
            /* btlb not in unused list */
        } else if (partial == NULL && e->itree.start < e->itree.last) {
            partial = e;
        } else {
            *unused = e;
            unused = &e->unused_next;
        }
    }
    env->tlb_partial = partial;
    *unused = NULL;

    return 0;
}

static const VMStateField vmstate_tlb_fields[] = {
    VMSTATE_ARRAY(tlb, CPUHPPAState,
                  ARRAY_SIZE(((CPUHPPAState *)0)->tlb),
                  0, vmstate_tlb_entry, HPPATLBEntry),
    VMSTATE_UINT32(tlb_last, CPUHPPAState),
    VMSTATE_END_OF_LIST()
};

static const VMStateDescription vmstate_tlb = {
    .name = "env/tlb",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = vmstate_tlb_fields,
    .pre_load = tlb_pre_load,
    .post_load = tlb_post_load,
};

static const VMStateField vmstate_env_fields[] = {
    VMSTATE_UINT64_ARRAY(gr, CPUHPPAState, 32),
    VMSTATE_UINT64_ARRAY(fr, CPUHPPAState, 32),
    VMSTATE_UINT64_ARRAY(sr, CPUHPPAState, 8),
    VMSTATE_UINT64_ARRAY(cr, CPUHPPAState, 32),
    VMSTATE_UINT64_ARRAY(cr_back, CPUHPPAState, 2),
    VMSTATE_UINT64_ARRAY(shadow, CPUHPPAState, 7),

    /* Save the architecture value of the psw, not the internally
       expanded version.  Since this architecture value does not
       exist in memory to be stored, this requires a but of hoop
       jumping.  We want OFFSET=0 so that we effectively pass ENV
       to the helper functions, and we need to fill in the name by
       hand since there's no field of that name.  */
    {
        .name = "psw",
        .version_id = 0,
        .size = sizeof(uint64_t),
        .info = &vmstate_psw,
        .flags = VMS_SINGLE,
        .offset = 0
    },

    VMSTATE_UINT64(iaoq_f, CPUHPPAState),
    VMSTATE_UINT64(iaoq_b, CPUHPPAState),
    VMSTATE_UINT64(iasq_f, CPUHPPAState),
    VMSTATE_UINT64(iasq_b, CPUHPPAState),

    VMSTATE_UINT32(fr0_shadow, CPUHPPAState),
    VMSTATE_END_OF_LIST()
};

static const VMStateDescription * const vmstate_env_subsections[] = {
    &vmstate_tlb,
    NULL
};

static const VMStateDescription vmstate_env = {
    .name = "env",
    .version_id = 3,
    .minimum_version_id = 3,
    .fields = vmstate_env_fields,
    .subsections = vmstate_env_subsections,
};

static const VMStateField vmstate_cpu_fields[] = {
    VMSTATE_CPU(),
    VMSTATE_STRUCT(env, HPPACPU, 1, vmstate_env, CPUHPPAState),
    VMSTATE_END_OF_LIST()
};

const VMStateDescription vmstate_hppa_cpu = {
    .name = "cpu",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = vmstate_cpu_fields,
};
