qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: WANG Xuerui <i.qemu@xen0n.name>
To: Song Gao <gaosong@loongson.cn>, qemu-devel@nongnu.org
Cc: "Xiaojuan Yang" <yangxiaojuan@loongson.cn>,
	"Richard Henderson" <richard.henderson@linaro.org>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>
Subject: Re: [PATCH v14 02/26] target/loongarch: Add core definition
Date: Sun, 9 Jan 2022 17:25:25 +0800	[thread overview]
Message-ID: <b8f31617-f217-778c-2a34-6d780de9b83a@xen0n.name> (raw)
In-Reply-To: <20220106094200.1801206-3-gaosong@loongson.cn>


On 1/6/22 17:41, Song Gao wrote:
> This patch adds target state header, target definitions
> and initialization routines.
>
> Signed-off-by: Song Gao<gaosong@loongson.cn>
> Signed-off-by: Xiaojuan Yang<yangxiaojuan@loongson.cn>
> Reviewed-by: Richard Henderson<richard.henderson@linaro.org>
> Reviewed-by: Philippe Mathieu-Daudé<f4bug@amsat.org>
> ---
>   target/loongarch/cpu-param.h |  18 ++
>   target/loongarch/cpu.c       | 314 +++++++++++++++++++++++++++++++++++
>   target/loongarch/cpu.h       | 252 ++++++++++++++++++++++++++++
>   target/loongarch/internals.h |  21 +++
>   4 files changed, 605 insertions(+)
>   create mode 100644 target/loongarch/cpu-param.h
>   create mode 100644 target/loongarch/cpu.c
>   create mode 100644 target/loongarch/cpu.h
>   create mode 100644 target/loongarch/internals.h
>
> diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h
> new file mode 100644
> index 0000000000..9a769b67e0
> --- /dev/null
> +++ b/target/loongarch/cpu-param.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * LoongArch CPU parameters for QEMU.
> + *
> + * Copyright (c) 2021 Loongson Technology Corporation Limited
> + */
> +
> +#ifndef LOONGARCH_CPU_PARAM_H
> +#define LOONGARCH_CPU_PARAM_H
> +
> +#define TARGET_LONG_BITS 64
> +#define TARGET_PHYS_ADDR_SPACE_BITS 48
> +#define TARGET_VIRT_ADDR_SPACE_BITS 48
> +
> +#define TARGET_PAGE_BITS 14
Aren't we capable of page sizes up to 64KiB? Minimal feasible page size 
is indeed 16KiB though (due to cache aliasing, although 4KiB pages are 
supported in hardware, they don't work in practice).
> +#define NB_MMU_MODES 4
> +
> +#endif
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> new file mode 100644
> index 0000000000..76b89d1606
> --- /dev/null
> +++ b/target/loongarch/cpu.c
> @@ -0,0 +1,314 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * QEMU LoongArch CPU
> + *
> + * Copyright (c) 2021 Loongson Technology Corporation Limited
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/qemu-print.h"
> +#include "qapi/error.h"
> +#include "qemu/module.h"
> +#include "sysemu/qtest.h"
> +#include "exec/exec-all.h"
> +#include "qapi/qapi-commands-machine-target.h"
> +#include "cpu.h"
> +#include "internals.h"
> +#include "fpu/softfloat-helpers.h"
> +
> +const char * const regnames[32] = {
> +    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
> +    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
> +    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
> +    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
> +};
> +
> +const char * const fregnames[32] = {
> +    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
> +    "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
> +    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
> +    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
> +};
> +
> +static const char * const excp_names[EXCP_LAST + 1] = {
> +    [EXCP_SYSCALL] = "Syscall",
> +    [EXCP_BREAK] = "Break",
> +    [EXCP_INE] = "Instruction Non-existent",
Nit: "Instruction Non-Existent" (or is there any authoritative source 
for this spelling? the English translation of the manual?)
> +    [EXCP_FPE] = "Floating Point Exception",
> +};
> +
> +const char *loongarch_exception_name(int32_t exception)
> +{
> +    assert(excp_names[exception]);
> +    return excp_names[exception];
> +}
> +
> +void QEMU_NORETURN do_raise_exception(CPULoongArchState *env,
> +                                      uint32_t exception,
> +                                      uintptr_t pc)
> +{
> +    CPUState *cs = env_cpu(env);
> +
> +    qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n",
> +                  __func__,
> +                  exception,
> +                  loongarch_exception_name(exception));
> +    cs->exception_index = exception;
> +
> +    cpu_loop_exit_restore(cs, pc);
> +}
> +
> +static void loongarch_cpu_set_pc(CPUState *cs, vaddr value)
> +{
> +    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +    CPULoongArchState *env = &cpu->env;
> +
> +    env->pc = value;
> +}
> +
> +#ifdef CONFIG_TCG
> +static void loongarch_cpu_synchronize_from_tb(CPUState *cs,
> +                                              const TranslationBlock *tb)
> +{
> +    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +    CPULoongArchState *env = &cpu->env;
> +
> +    env->pc = tb->pc;
> +}
> +#endif /* CONFIG_TCG */
> +
> +static bool loongarch_cpu_has_work(CPUState *cs)
> +{
> +    return true;

Note: this is only applicable to CONFIG_USER_ONLY, and needs to be 
changed in the following commits adding system emulation. To better 
convey your intention it may be better to use an #ifdef guard, something 
like this:

#ifndef CONFIG_USER_ONLY
#error System emulation TODO
#else
     return true;
#endif

(I'm not sure if this is okay in QEMU coding style, so please correct me 
if this isn't the case.)

> +}
> +
> +static void loongarch_3a5000_initfn(Object *obj)
> +{
> +    LoongArchCPU *cpu = LOONGARCH_CPU(obj);
> +    CPULoongArchState *env = &cpu->env;
> +    int i;
> +
> +    for (i = 0; i < 21; i++) {
> +        env->cpucfg[i] = 0x0;
> +    }
> +
> +    env->cpucfg[0] = 0x14c010;  /* PRID */
> +
> +    uint32_t data = 0;
> +    data = FIELD_DP32(data, CPUCFG1, ARCH, 2);
> +    data = FIELD_DP32(data, CPUCFG1, PGMMU, 1);
> +    data = FIELD_DP32(data, CPUCFG1, IOCSR, 1);
> +    data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f);
> +    data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f);
> +    data = FIELD_DP32(data, CPUCFG1, UAL, 1);
> +    data = FIELD_DP32(data, CPUCFG1, RI, 1);
> +    data = FIELD_DP32(data, CPUCFG1, EP, 1);
> +    data = FIELD_DP32(data, CPUCFG1, RPLV, 1);
> +    data = FIELD_DP32(data, CPUCFG1, HP, 1);
> +    data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1);
> +    env->cpucfg[1] = data;
> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG2, FP, 1);
> +    data = FIELD_DP32(data, CPUCFG2, FP_SP, 1);
> +    data = FIELD_DP32(data, CPUCFG2, FP_DP, 1);
> +    data = FIELD_DP32(data, CPUCFG2, FP_VER, 1);
> +    data = FIELD_DP32(data, CPUCFG2, LLFTP, 1);
> +    data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1);
> +    data = FIELD_DP32(data, CPUCFG2, LSPW, 1);
Do you support the SPW extension in this series? If not you probably 
don't want to set this bit.
> +    data = FIELD_DP32(data, CPUCFG2, LAM, 1);
> +    env->cpucfg[2] = data;
> +
> +    env->cpucfg[4] = 100 * 1000 * 1000; /* Crystal frequency */
> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG5, CC_MUL, 1);
> +    data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1);
> +    env->cpucfg[5] = data;
> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L2_IUPRE, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L2_IUUNIFY, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L2_IUPRIV, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L3_IUPRE, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L3_IUUNIFY, 1);
> +    data = FIELD_DP32(data, CPUCFG16, L3_IUINCL, 1);
> +    env->cpucfg[16] = data;
> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG17, L1IU_WAYS, 0x8003);

This seems out-of-place, according to the manual this field is Way-1 for 
the L1I cache, so you have 0x8004=32772 ways in this cache?

Same for all similar constructions below.

> +    data = FIELD_DP32(data, CPUCFG17, L1IU_SETS, 0x60);
> +    env->cpucfg[17] =  data;

Extra space after the "=" operator.

Also it seems the L1IU_SIZE field is not provided initialization value; 
same for all similar constructions below.

> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG18, L1D_WAYS, 0x8003);
> +    data = FIELD_DP32(data, CPUCFG18, L1D_SETS, 0x60);
> +    env->cpucfg[18] = data;
> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG19, L2IU_WAYS, 0x800f);
> +    data = FIELD_DP32(data, CPUCFG19, L2IU_SETS, 0x60);
> +    env->cpucfg[19] = data;
> +
> +    data = 0;
> +    data = FIELD_DP32(data, CPUCFG20, L3IU_WAYS, 0xf00f);
> +    data = FIELD_DP32(data, CPUCFG20, L3IU_SETS, 0x60);
> +    env->cpucfg[20] = data;
> +}
> +
> +static void loongarch_cpu_list_entry(gpointer data, gpointer user_data)
> +{
> +    const char *typename = object_class_get_name(OBJECT_CLASS(data));
> +
> +    qemu_printf("%s\n", typename);
> +}
> +
> +void loongarch_cpu_list(void)
> +{
> +    GSList *list;
> +    list = object_class_get_list_sorted(TYPE_LOONGARCH_CPU, false);
> +    g_slist_foreach(list, loongarch_cpu_list_entry, NULL);
> +    g_slist_free(list);
> +}
> +
> +static void loongarch_cpu_reset(DeviceState *dev)
> +{
> +    CPUState *cs = CPU(dev);
> +    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +    LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(cpu);
> +    CPULoongArchState *env = &cpu->env;
> +
> +    lacc->parent_reset(dev);
> +
> +    env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3;
> +    env->fcsr0 = 0x0;
> +
> +    cs->exception_index = EXCP_NONE;
> +}
> +
> +static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info)
> +{
> +    info->print_insn = print_insn_loongarch;
> +}
> +
> +static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp)
> +{
> +    CPUState *cs = CPU(dev);
> +    LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(dev);
> +    Error *local_err = NULL;
> +
> +    cpu_exec_realizefn(cs, &local_err);
> +    if (local_err != NULL) {
> +        error_propagate(errp, local_err);
> +        return;
> +    }
> +
> +    cpu_reset(cs);
> +    qemu_init_vcpu(cs);
> +
> +    lacc->parent_realize(dev, errp);
> +}
> +
> +static void loongarch_cpu_initfn(Object *obj)
> +{
> +    LoongArchCPU *cpu = LOONGARCH_CPU(obj);
> +
> +    cpu_set_cpustate_pointers(cpu);
> +}
> +
> +static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model)
> +{
> +    ObjectClass *oc;
> +    char *typename;
> +
> +    typename = g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model);
> +    oc = object_class_by_name(typename);
> +    g_free(typename);
> +    return oc;
> +}
> +
> +void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
> +{
> +    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
> +    CPULoongArchState *env = &cpu->env;
> +    int i;
> +
> +    qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
> +    qemu_fprintf(f, " FCSR0 0x%08x  fp_status 0x%02x\n", env->fcsr0,
> +                 get_float_exception_flags(&env->fp_status));
> +
> +    /* gpr */
> +    for (i = 0; i < 32; i++) {
> +        if ((i & 3) == 0) {
> +            qemu_fprintf(f, " GPR%02d:", i);
> +        }
> +        qemu_fprintf(f, " %s %016" PRIx64, regnames[i], env->gpr[i]);
> +        if ((i & 3) == 3) {
> +            qemu_fprintf(f, "\n");
> +        }
> +    }
> +
> +    /* fpr */
> +    if (flags & CPU_DUMP_FPU) {
> +        for (i = 0; i < 32; i++) {
> +            qemu_fprintf(f, " %s %016" PRIx64, fregnames[i], env->fpr[i]);
> +            if ((i & 3) == 3) {
> +                qemu_fprintf(f, "\n");
> +            }
> +        }
> +    }
> +}
> +
> +#ifdef CONFIG_TCG
> +#include "hw/core/tcg-cpu-ops.h"
> +
> +static struct TCGCPUOps loongarch_tcg_ops = {
> +    .initialize = loongarch_translate_init,
> +    .synchronize_from_tb = loongarch_cpu_synchronize_from_tb,
> +};
> +#endif /* CONFIG_TCG */
> +
> +static void loongarch_cpu_class_init(ObjectClass *c, void *data)
> +{
> +    LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c);
> +    CPUClass *cc = CPU_CLASS(c);
> +    DeviceClass *dc = DEVICE_CLASS(c);
> +
> +    device_class_set_parent_realize(dc, loongarch_cpu_realizefn,
> +                                    &lacc->parent_realize);
> +    device_class_set_parent_reset(dc, loongarch_cpu_reset, &lacc->parent_reset);
> +
> +    cc->class_by_name = loongarch_cpu_class_by_name;
> +    cc->has_work = loongarch_cpu_has_work;
> +    cc->dump_state = loongarch_cpu_dump_state;
> +    cc->set_pc = loongarch_cpu_set_pc;
> +    cc->disas_set_info = loongarch_cpu_disas_set_info;
> +#ifdef CONFIG_TCG
> +    cc->tcg_ops = &loongarch_tcg_ops;
> +#endif
> +}
> +
> +#define DEFINE_LOONGARCH_CPU_TYPE(model, initfn) \
> +    { \
> +        .parent = TYPE_LOONGARCH_CPU, \
> +        .instance_init = initfn, \
> +        .name = LOONGARCH_CPU_TYPE_NAME(model), \
> +    }
> +
> +static const TypeInfo loongarch_cpu_type_infos[] = {
> +    {
> +        .name = TYPE_LOONGARCH_CPU,
> +        .parent = TYPE_CPU,
> +        .instance_size = sizeof(LoongArchCPU),
> +        .instance_init = loongarch_cpu_initfn,
> +
> +        .abstract = true,
> +        .class_size = sizeof(LoongArchCPUClass),
> +        .class_init = loongarch_cpu_class_init,
> +    },
> +    DEFINE_LOONGARCH_CPU_TYPE("Loongson-3A5000", loongarch_3a5000_initfn),
> +};
> +
> +DEFINE_TYPES(loongarch_cpu_type_infos)
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> new file mode 100644
> index 0000000000..b036cdee5f
> --- /dev/null
> +++ b/target/loongarch/cpu.h
> @@ -0,0 +1,252 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * QEMU LoongArch CPU
> + *
> + * Copyright (c) 2021 Loongson Technology Corporation Limited
> + */
> +
> +#ifndef LOONGARCH_CPU_H
> +#define LOONGARCH_CPU_H
> +
> +#include "exec/cpu-defs.h"
> +#include "fpu/softfloat-types.h"
> +#include "hw/registerfields.h"
> +
> +#define TCG_GUEST_DEFAULT_MO (0)
> +
> +#define FCSR0_M1    0x1f         /* FCSR1 mask, Enables */
> +#define FCSR0_M2    0x1f1f0000   /* FCSR2 mask, Cause and Flags */
> +#define FCSR0_M3    0x300        /* FCSR3 mask, Round Mode */
> +#define FCSR0_RM    8            /* Round Mode bit num on fcsr0 */
> +
> +FIELD(FCSR0, ENABLES, 0, 5)
> +FIELD(FCSR0, RM, 8, 2)
> +FIELD(FCSR0, FLAGS, 16, 5)
> +FIELD(FCSR0, CAUSE, 24, 5)
> +
> +#define GET_FP_CAUSE(REG)      FIELD_EX32(REG, FCSR0, CAUSE)
> +#define SET_FP_CAUSE(REG, V)   FIELD_DP32(REG, FCSR0, CAUSE, V)
> +#define GET_FP_ENABLES(REG)    FIELD_EX32(REG, FCSR0, ENABLES)
> +#define SET_FP_ENABLES(REG, V) FIELD_DP32(REG, FCSR0, ENABLES, V)
> +#define GET_FP_FLAGS(REG)      FIELD_EX32(REG, FCSR0, FLAGS)
> +#define SET_FP_FLAGS(REG, V)   FIELD_DP32(REG, FCSR0, FLAGS, V)
> +#define UPDATE_FP_FLAGS(REG, V) \
> +    do { \
> +        (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \
> +    } while (0)
> +
> +#define FP_INEXACT        1
> +#define FP_UNDERFLOW      2
> +#define FP_OVERFLOW       4
> +#define FP_DIV0           8
> +#define FP_INVALID        16
> +
> +/* cpucfg[0] bits */
> +FIELD(CPUCFG0, PRID, 0, 32)
> +
> +/* cpucfg[1] bits */
> +FIELD(CPUCFG1, ARCH, 0, 2)
> +FIELD(CPUCFG1, PGMMU, 2, 1)
> +FIELD(CPUCFG1, IOCSR, 3, 1)
> +FIELD(CPUCFG1, PALEN, 4, 8)
> +FIELD(CPUCFG1, VALEN, 12, 8)
> +FIELD(CPUCFG1, UAL, 20, 1)
> +FIELD(CPUCFG1, RI, 21, 1)
> +FIELD(CPUCFG1, EP, 22, 1)
> +FIELD(CPUCFG1, RPLV, 23, 1)
> +FIELD(CPUCFG1, HP, 24, 1)
> +FIELD(CPUCFG1, IOCSR_BRD, 25, 1)
> +FIELD(CPUCFG1, MSG_INT, 26, 1)
> +
> +/* cpucfg[2] bits */
> +FIELD(CPUCFG2, FP, 0, 1)
> +FIELD(CPUCFG2, FP_SP, 1, 1)
> +FIELD(CPUCFG2, FP_DP, 2, 1)
> +FIELD(CPUCFG2, FP_VER, 3, 3)
> +FIELD(CPUCFG2, LSX, 6, 1)
> +FIELD(CPUCFG2, LASX, 7, 1)
> +FIELD(CPUCFG2, COMPLEX, 8, 1)
> +FIELD(CPUCFG2, CRYPTO, 9, 1)
> +FIELD(CPUCFG2, LVZ, 10, 1)
> +FIELD(CPUCFG2, LVZ_VER, 11, 3)
> +FIELD(CPUCFG2, LLFTP, 14, 1)
> +FIELD(CPUCFG2, LLFTP_VER, 15, 3)
> +FIELD(CPUCFG2, LBT_X86, 18, 1)
> +FIELD(CPUCFG2, LBT_ARM, 19, 1)
> +FIELD(CPUCFG2, LBT_MIPS, 20, 1)
> +FIELD(CPUCFG2, LSPW, 21, 1)
> +FIELD(CPUCFG2, LAM, 22, 1)
> +
> +/* cpucfg[3] bits */
> +FIELD(CPUCFG3, CCDMA, 0, 1)
> +FIELD(CPUCFG3, SFB, 1, 1)
> +FIELD(CPUCFG3, UCACC, 2, 1)
> +FIELD(CPUCFG3, LLEXC, 3, 1)
> +FIELD(CPUCFG3, SCDLY, 4, 1)
> +FIELD(CPUCFG3, LLDBAR, 5, 1)
> +FIELD(CPUCFG3, ITLBHMC, 6, 1)
> +FIELD(CPUCFG3, ICHMC, 7, 1)
> +FIELD(CPUCFG3, SPW_LVL, 8, 3)
> +FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
> +FIELD(CPUCFG3, RVA, 12, 1)
> +FIELD(CPUCFG3, RVAMAX, 13, 4)
> +
> +/* cpucfg[4] bits */
> +FIELD(CPUCFG4, CC_FREQ, 0, 32)
> +
> +/* cpucfg[5] bits */
> +FIELD(CPUCFG5, CC_MUL, 0, 16)
> +FIELD(CPUCFG5, CC_DIV, 16, 16)
> +
> +/* cpucfg[6] bits */
> +FIELD(CPUCFG6, PMP, 0, 1)
> +FIELD(CPUCFG6, PMVER, 1, 3)
> +FIELD(CPUCFG6, PMNUM, 4, 4)
> +FIELD(CPUCFG6, PMBITS, 8, 6)
> +FIELD(CPUCFG6, UPM, 14, 1)
> +
> +/* cpucfg[16] bits */
> +FIELD(CPUCFG16, L1_IUPRE, 0, 1)
> +FIELD(CPUCFG16, L1_IUUNIFY, 1, 1)
> +FIELD(CPUCFG16, L1_DPRE, 2, 1)
> +FIELD(CPUCFG16, L2_IUPRE, 3, 1)
> +FIELD(CPUCFG16, L2_IUUNIFY, 4, 1)
> +FIELD(CPUCFG16, L2_IUPRIV, 5, 1)
> +FIELD(CPUCFG16, L2_IUINCL, 6, 1)
> +FIELD(CPUCFG16, L2_DPRE, 7, 1)
> +FIELD(CPUCFG16, L2_DPRIV, 8, 1)
> +FIELD(CPUCFG16, L2_DINCL, 9, 1)
> +FIELD(CPUCFG16, L3_IUPRE, 10, 1)
> +FIELD(CPUCFG16, L3_IUUNIFY, 11, 1)
> +FIELD(CPUCFG16, L3_IUPRIV, 12, 1)
> +FIELD(CPUCFG16, L3_IUINCL, 13, 1)
> +FIELD(CPUCFG16, L3_DPRE, 14, 1)
> +FIELD(CPUCFG16, L3_DPRIV, 15, 1)
> +FIELD(CPUCFG16, L3_DINCL, 16, 1)
> +
> +/* cpucfg[17] bits */
> +FIELD(CPUCFG17, L1IU_WAYS, 0, 16)
> +FIELD(CPUCFG17, L1IU_SETS, 16, 8)
> +FIELD(CPUCFG17, L1IU_SIZE, 24, 7)
> +
> +/* cpucfg[18] bits */
> +FIELD(CPUCFG18, L1D_WAYS, 0, 16)
> +FIELD(CPUCFG18, L1D_SETS, 16, 8)
> +FIELD(CPUCFG18, L1D_SIZE, 24, 7)
> +
> +/* cpucfg[19] bits */
> +FIELD(CPUCFG19, L2IU_WAYS, 0, 16)
> +FIELD(CPUCFG19, L2IU_SETS, 16, 8)
> +FIELD(CPUCFG19, L2IU_SIZE, 24, 7)
> +
> +/* cpucfg[20] bits */
> +FIELD(CPUCFG20, L3IU_WAYS, 0, 16)
> +FIELD(CPUCFG20, L3IU_SETS, 16, 8)
> +FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
> +
> +extern const char * const regnames[32];
> +extern const char * const fregnames[32];
> +
> +typedef struct CPULoongArchState CPULoongArchState;
> +struct CPULoongArchState {
> +    uint64_t gpr[32];
> +    uint64_t pc;
> +
> +    uint64_t fpr[32];
> +    float_status fp_status;
> +    bool cf[8];
> +
> +    /*
> +     * fcsr0
> +     * 31:29 |28:24 |23:21 |20:16 |15:10 |9:8 |7:5 |4:0
> +     *        Cause         Flags         RM        Enables
> +     */
> +    uint32_t fcsr0;
> +    uint32_t fcsr0_mask;
With the field definition somewhere above, is this "infographic" necessary?
> +
> +    uint32_t cpucfg[21];
> +
> +    uint64_t lladdr; /* LL virtual address compared against SC */
Similarly, do we explain every field with comments *here*? I think if 
fields are named according to the manuals, people will naturally look up 
names there so there's no worry for misunderstanding.
> +    uint64_t llval;
> +
> +    uint64_t badaddr;
> +};
> +
> +/**
> + * LoongArchCPU:
> + * @env: #CPULoongArchState
> + *
> + * A LoongArch CPU.
> + */
> +struct LoongArchCPU {
> +    /*< private >*/
> +    CPUState parent_obj;
> +    /*< public >*/
> +
> +    CPUNegativeOffsetState neg;
> +    CPULoongArchState env;
> +};
> +
> +#define TYPE_LOONGARCH_CPU "loongarch-cpu"
> +
> +OBJECT_DECLARE_TYPE(LoongArchCPU, LoongArchCPUClass,
> +                    LOONGARCH_CPU)
> +
> +/**
> + * LoongArchCPUClass:
> + * @parent_realize: The parent class' realize handler.
> + * @parent_reset: The parent class' reset handler.
> + *
> + * A LoongArch CPU model.
> + */
> +struct LoongArchCPUClass {
> +    /*< private >*/
> +    CPUClass parent_class;
> +    /*< public >*/
> +
> +    DeviceRealize parent_realize;
> +    DeviceReset parent_reset;
> +};
> +
> +#define MMU_USER_IDX 3
> +
> +static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch)
> +{
> +    return MMU_USER_IDX;
> +}
> +
> +static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
> +                                        target_ulong *pc,
> +                                        target_ulong *cs_base,
> +                                        uint32_t *flags)
> +{
> +    *pc = env->pc;
> +    *cs_base = 0;
> +    *flags = cpu_mmu_index(env, false);
> +}
> +
> +void loongarch_cpu_list(void);
> +
> +#define cpu_list loongarch_cpu_list
> +
> +typedef CPULoongArchState CPUArchState;
> +typedef LoongArchCPU ArchCPU;
> +
> +#include "exec/cpu-all.h"
> +
> +/* Exceptions */
> +enum {
> +    EXCP_NONE          = -1,
> +    EXCP_SYSCALL       = 0,
> +    EXCP_BREAK,
> +    EXCP_INE,
> +    EXCP_FPE,
> +
> +    EXCP_LAST = EXCP_FPE,
> +};
> +
> +#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU
> +#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
> +#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
> +
> +#endif /* LOONGARCH_CPU_H */
> diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
> new file mode 100644
> index 0000000000..1e69e7d9d9
> --- /dev/null
> +++ b/target/loongarch/internals.h
> @@ -0,0 +1,21 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * QEMU LoongArch CPU -- internal functions and types
> + *
> + * Copyright (c) 2021 Loongson Technology Corporation Limited
> + */
> +
> +#ifndef LOONGARCH_INTERNALS_H
> +#define LOONGARCH_INTERNALS_H
> +
> +void loongarch_translate_init(void);
> +
> +void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
> +
> +void QEMU_NORETURN do_raise_exception(CPULoongArchState *env,
> +                                      uint32_t exception,
> +                                      uintptr_t pc);
> +
> +const char *loongarch_exception_name(int32_t exception);
> +
> +#endif


  reply	other threads:[~2022-01-09  9:29 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-01-06  9:41 [PATCH v14 00/26] Add LoongArch linux-user emulation support Song Gao
2022-01-06  9:41 ` [PATCH v14 01/26] target/loongarch: Add README Song Gao
2022-01-09  9:24   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 02/26] target/loongarch: Add core definition Song Gao
2022-01-09  9:25   ` WANG Xuerui [this message]
2022-01-09 18:49     ` Richard Henderson
2022-01-10 12:34       ` gaosong
2022-01-10 15:20         ` WANG Xuerui
2022-01-10 13:00     ` gaosong
2022-01-10 15:11       ` WANG Xuerui
2022-01-12  9:28     ` gaosong
2022-01-12 10:17       ` gaosong
2022-01-12 10:26         ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 03/26] target/loongarch: Add main translation routines Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 04/26] target/loongarch: Add fixed point arithmetic instruction translation Song Gao
2022-01-06  9:41 ` [PATCH v14 05/26] target/loongarch: Add fixed point shift " Song Gao
2022-01-06  9:41 ` [PATCH v14 06/26] target/loongarch: Add fixed point bit " Song Gao
2022-01-06  9:41 ` [PATCH v14 07/26] target/loongarch: Add fixed point load/store " Song Gao
2022-01-06  9:41 ` [PATCH v14 08/26] target/loongarch: Add fixed point atomic " Song Gao
2022-01-06  9:41 ` [PATCH v14 09/26] target/loongarch: Add fixed point extra " Song Gao
2022-01-06  9:41 ` [PATCH v14 10/26] target/loongarch: Add floating point arithmetic " Song Gao
2022-01-06  9:41 ` [PATCH v14 11/26] target/loongarch: Add floating point comparison " Song Gao
2022-01-06  9:41 ` [PATCH v14 12/26] target/loongarch: Add floating point conversion " Song Gao
2022-01-06  9:41 ` [PATCH v14 13/26] target/loongarch: Add floating point move " Song Gao
2022-01-06  9:41 ` [PATCH v14 14/26] target/loongarch: Add floating point load/store " Song Gao
2022-01-06  9:41 ` [PATCH v14 15/26] target/loongarch: Add branch " Song Gao
2022-01-06  9:41 ` [PATCH v14 16/26] target/loongarch: Add disassembler Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-09 18:51     ` Richard Henderson
2022-01-06  9:41 ` [PATCH v14 17/26] linux-user: Add LoongArch generic header files Song Gao
2022-01-06  9:41 ` [PATCH v14 18/26] linux-user: Add LoongArch specific structures Song Gao
2022-01-07  4:29   ` Richard Henderson
2022-01-06  9:41 ` [PATCH v14 19/26] linux-user: Add LoongArch signal support Song Gao
2022-01-07  4:58   ` Richard Henderson
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 20/26] linux-user: Add LoongArch elf support Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 21/26] linux-user: Add LoongArch syscall support Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 22/26] linux-user: Add LoongArch cpu_loop support Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 23/26] default-configs: Add loongarch linux-user support Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 24/26] target/loongarch: Add target build suport Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:41 ` [PATCH v14 25/26] target/loongarch: 'make check-tcg' support Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-06  9:42 ` [PATCH v14 26/26] scripts: add loongarch64 binfmt config Song Gao
2022-01-09  9:25   ` WANG Xuerui
2022-01-07  5:01 ` [PATCH v14 00/26] Add LoongArch linux-user emulation support Richard Henderson
2022-01-07  7:59   ` gaosong
2022-01-09  5:09     ` WANG Xuerui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b8f31617-f217-778c-2a34-6d780de9b83a@xen0n.name \
    --to=i.qemu@xen0n.name \
    --cc=f4bug@amsat.org \
    --cc=gaosong@loongson.cn \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=yangxiaojuan@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).