/*
 * Support for writing ELF notes for LoongArch architectures
 *
 * Copyright (c) 2023 Loongarch Technology
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "elf.h"
#include "sysemu/dump.h"
#include "internals.h"

/* struct user_pt_regs from arch/loongarch/include/uapi/asm/ptrace.h */
struct loongarch_user_regs {
    uint64_t gpr[32];
    uint64_t pad1[1];
    /* Special CSR registers. */
    uint64_t csr_era;
    uint64_t csr_badv;
    uint64_t pad2[10];
} QEMU_PACKED;

QEMU_BUILD_BUG_ON(sizeof(struct loongarch_user_regs) != 360);

/* struct elf_prstatus from include/uapi/linux/elfcore.h */
struct loongarch_elf_prstatus {
    char pad1[32]; /* 32 == offsetof(struct elf_prstatus, pr_pid) */
    uint32_t pr_pid;
    /*
     * 76 == offsetof(struct elf_prstatus, pr_reg) -
     * offsetof(struct elf_prstatus, pr_ppid)
     */
    char pad2[76];
    struct loongarch_user_regs pr_reg;
    uint32_t pr_fpvalid;
    char pad3[4];
} QEMU_PACKED;

QEMU_BUILD_BUG_ON(sizeof(struct loongarch_elf_prstatus) != 480);

/* struct user_fp_state from arch/loongarch/include/uapi/asm/ptrace.h */
struct loongarch_fpu_struct {
    uint64_t fpr[32];
    uint64_t fcc;
    unsigned int fcsr;
} QEMU_PACKED;

QEMU_BUILD_BUG_ON(sizeof(struct loongarch_fpu_struct) != 268);

struct loongarch_note {
    Elf64_Nhdr hdr;
    char name[8]; /* align_up(sizeof("CORE"), 4) */
    union {
        struct loongarch_elf_prstatus prstatus;
        struct loongarch_fpu_struct fpu;
    };
} QEMU_PACKED;

#define LOONGARCH_NOTE_HEADER_SIZE offsetof(struct loongarch_note, prstatus)
#define LOONGARCH_PRSTATUS_NOTE_SIZE                                          \
    (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_elf_prstatus))
#define LOONGARCH_PRFPREG_NOTE_SIZE                                           \
    (LOONGARCH_NOTE_HEADER_SIZE + sizeof(struct loongarch_fpu_struct))

static void loongarch_note_init(struct loongarch_note *note, DumpState *s,
                                const char *name, Elf64_Word namesz,
                                Elf64_Word type, Elf64_Word descsz)
{
    memset(note, 0, sizeof(*note));

    note->hdr.n_namesz = cpu_to_dump32(s, namesz);
    note->hdr.n_descsz = cpu_to_dump32(s, descsz);
    note->hdr.n_type = cpu_to_dump32(s, type);

    memcpy(note->name, name, namesz);
}

static int loongarch_write_elf64_fprpreg(WriteCoreDumpFunction f,
                                         CPULoongArchState *env, int cpuid,
                                         DumpState *s)
{
    struct loongarch_note note;
    int ret, i;

    loongarch_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.fpu));
    note.fpu.fcsr = cpu_to_dump64(s, env->fcsr0);

    for (i = 0; i < 8; i++) {
        note.fpu.fcc |= env->cf[i] << (8 * i);
    }
    note.fpu.fcc = cpu_to_dump64(s, note.fpu.fcc);

    for (i = 0; i < 32; ++i) {
        note.fpu.fpr[i] = cpu_to_dump64(s, env->fpr[i].vreg.UD[0]);
    }

    ret = f(&note, LOONGARCH_PRFPREG_NOTE_SIZE, s);
    if (ret < 0) {
        return -1;
    }

    return 0;
}

int loongarch_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
                                   int cpuid, DumpState *s)
{
    struct loongarch_note note;
    CPULoongArchState *env = &LOONGARCH_CPU(cs)->env;
    int ret, i;

    loongarch_note_init(&note, s, "CORE", 5, NT_PRSTATUS,
                        sizeof(note.prstatus));
    note.prstatus.pr_pid = cpu_to_dump32(s, cpuid);
    note.prstatus.pr_fpvalid = cpu_to_dump32(s, 1);

    for (i = 0; i < 32; ++i) {
        note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->gpr[i]);
    }
    note.prstatus.pr_reg.csr_era  = cpu_to_dump64(s, env->CSR_ERA);
    note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, env->CSR_BADV);
    ret = f(&note, LOONGARCH_PRSTATUS_NOTE_SIZE, s);
    if (ret < 0) {
        return -1;
    }

    ret = loongarch_write_elf64_fprpreg(f, env, cpuid, s);
    if (ret < 0) {
        return -1;
    }

    return ret;
}

int cpu_get_dump_info(ArchDumpInfo *info,
                      const GuestPhysBlockList *guest_phys_blocks)
{
    info->d_machine = EM_LOONGARCH;
    info->d_endian = ELFDATA2LSB;
    info->d_class = ELFCLASS64;

    return 0;
}

ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
{
    size_t note_size = 0;

    if (class == ELFCLASS64) {
        note_size = LOONGARCH_PRSTATUS_NOTE_SIZE + LOONGARCH_PRFPREG_NOTE_SIZE;
    }

    return note_size * nr_cpus;
}
