Message ID | 20230808015506.1705140-12-c@jia.je (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add la32 & va32 mode for loongarch64-softmmu | expand |
On 2023/8/8 09:54, Jiajie Chen wrote: > Add la132 as a loongarch32 cpu type and allow virt machine to be used > with la132 instead of la464. > > Refactor common init logic out as loongarch_cpu_initfn_common. > > Signed-off-by: Jiajie Chen <c@jia.je> > --- > hw/loongarch/virt.c | 5 ---- > target/loongarch/cpu.c | 54 ++++++++++++++++++++++++++++++++---------- > 2 files changed, 41 insertions(+), 18 deletions(-) > > diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c > index e19b042ce8..af15bf5aaa 100644 > --- a/hw/loongarch/virt.c > +++ b/hw/loongarch/virt.c > @@ -798,11 +798,6 @@ static void loongarch_init(MachineState *machine) > cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); > } > > - if (!strstr(cpu_model, "la464")) { > - error_report("LoongArch/TCG needs cpu type la464"); > - exit(1); > - } > - > if (ram_size < 1 * GiB) { > error_report("ram_size must be greater than 1G."); > exit(1); > diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c > index 13d4fccbd3..341176817e 100644 > --- a/target/loongarch/cpu.c > +++ b/target/loongarch/cpu.c > @@ -356,30 +356,18 @@ static bool loongarch_cpu_has_work(CPUState *cs) > #endif > } > > -static void loongarch_la464_initfn(Object *obj) > +static void loongarch_cpu_initfn_common(CPULoongArchState *env) > { > - LoongArchCPU *cpu = LOONGARCH_CPU(obj); > - CPULoongArchState *env = &cpu->env; > int i; > > for (i = 0; i < 21; i++) { > env->cpucfg[i] = 0x0; > } > > - cpu->dtb_compatible = "loongarch,Loongson-3A5000"; > - 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); Sorry, this line should not be removed. > data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1); > env->cpucfg[1] = data; > > @@ -439,6 +427,45 @@ static void loongarch_la464_initfn(Object *obj) > env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); > } > > +static void loongarch_la464_initfn(Object *obj) > +{ > + LoongArchCPU *cpu = LOONGARCH_CPU(obj); > + CPULoongArchState *env = &cpu->env; > + > + loongarch_cpu_initfn_common(env); > + > + cpu->dtb_compatible = "loongarch,Loongson-3A5000"; > + env->cpucfg[0] = 0x14c010; /* PRID */ > + > + uint32_t data = env->cpucfg[1]; > + data = FIELD_DP32(data, CPUCFG1, ARCH, 2); /* LA64 */ > + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f); /* 48 bits */ > + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f); /* 48 bits */ > + data = FIELD_DP32(data, CPUCFG1, RI, 1); > + data = FIELD_DP32(data, CPUCFG1, EP, 1); > + data = FIELD_DP32(data, CPUCFG1, RPLV, 1); > + env->cpucfg[1] = data; > +} > + > +static void loongarch_la132_initfn(Object *obj) > +{ > + LoongArchCPU *cpu = LOONGARCH_CPU(obj); > + CPULoongArchState *env = &cpu->env; > + > + loongarch_cpu_initfn_common(env); > + > + cpu->dtb_compatible = "loongarch,Loongson-1C103"; > + > + uint32_t data = env->cpucfg[1]; > + data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */ > + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */ > + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */ > + data = FIELD_DP32(data, CPUCFG1, RI, 0); > + data = FIELD_DP32(data, CPUCFG1, EP, 0); > + data = FIELD_DP32(data, CPUCFG1, RPLV, 0); > + env->cpucfg[1] = data; > +} > + > static void loongarch_cpu_list_entry(gpointer data, gpointer user_data) > { > const char *typename = object_class_get_name(OBJECT_CLASS(data)); > @@ -784,5 +811,6 @@ static const TypeInfo loongarch32_cpu_type_infos[] = { > .class_size = sizeof(LoongArchCPUClass), > .class_init = loongarch32_cpu_class_init, > }, > + DEFINE_LOONGARCH32_CPU_TYPE("la132", loongarch_la132_initfn), > }; > DEFINE_TYPES(loongarch32_cpu_type_infos)
On 8/7/23 18:54, Jiajie Chen wrote: > +static void loongarch_la464_initfn(Object *obj) > +{ > + LoongArchCPU *cpu = LOONGARCH_CPU(obj); > + CPULoongArchState *env = &cpu->env; > + > + loongarch_cpu_initfn_common(env); > + > + cpu->dtb_compatible = "loongarch,Loongson-3A5000"; > + env->cpucfg[0] = 0x14c010; /* PRID */ > + > + uint32_t data = env->cpucfg[1]; > + data = FIELD_DP32(data, CPUCFG1, ARCH, 2); /* LA64 */ > + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f); /* 48 bits */ > + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f); /* 48 bits */ > + data = FIELD_DP32(data, CPUCFG1, RI, 1); > + data = FIELD_DP32(data, CPUCFG1, EP, 1); > + data = FIELD_DP32(data, CPUCFG1, RPLV, 1); > + env->cpucfg[1] = data; > +} > + > +static void loongarch_la132_initfn(Object *obj) > +{ > + LoongArchCPU *cpu = LOONGARCH_CPU(obj); > + CPULoongArchState *env = &cpu->env; > + > + loongarch_cpu_initfn_common(env); > + > + cpu->dtb_compatible = "loongarch,Loongson-1C103"; > + > + uint32_t data = env->cpucfg[1]; > + data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */ > + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */ > + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */ > + data = FIELD_DP32(data, CPUCFG1, RI, 0); > + data = FIELD_DP32(data, CPUCFG1, EP, 0); > + data = FIELD_DP32(data, CPUCFG1, RPLV, 0); > + env->cpucfg[1] = data; > +} The use of the loongarch_cpu_initfn_common function is not going to scale. Compare the set of *_initfn in target/arm/tcg/cpu32.c In general, you want to copy data in bulk from the processor manual, so that the reviewer can simply read through the table and see that the code is correct, without having to check between multiple functions to see that the combination is correct. For our existing la464, that table is Table 54 in the 3A5000 manual. Is there a public specification for the la132? I could not find one in https://www.loongson.cn/EN/product/, but perhaps that's just the english view. r~
On 2023/8/9 03:26, Richard Henderson wrote: > On 8/7/23 18:54, Jiajie Chen wrote: >> +static void loongarch_la464_initfn(Object *obj) >> +{ >> + LoongArchCPU *cpu = LOONGARCH_CPU(obj); >> + CPULoongArchState *env = &cpu->env; >> + >> + loongarch_cpu_initfn_common(env); >> + >> + cpu->dtb_compatible = "loongarch,Loongson-3A5000"; >> + env->cpucfg[0] = 0x14c010; /* PRID */ >> + >> + uint32_t data = env->cpucfg[1]; >> + data = FIELD_DP32(data, CPUCFG1, ARCH, 2); /* LA64 */ >> + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f); /* 48 bits */ >> + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f); /* 48 bits */ >> + data = FIELD_DP32(data, CPUCFG1, RI, 1); >> + data = FIELD_DP32(data, CPUCFG1, EP, 1); >> + data = FIELD_DP32(data, CPUCFG1, RPLV, 1); >> + env->cpucfg[1] = data; >> +} >> + >> +static void loongarch_la132_initfn(Object *obj) >> +{ >> + LoongArchCPU *cpu = LOONGARCH_CPU(obj); >> + CPULoongArchState *env = &cpu->env; >> + >> + loongarch_cpu_initfn_common(env); >> + >> + cpu->dtb_compatible = "loongarch,Loongson-1C103"; >> + >> + uint32_t data = env->cpucfg[1]; >> + data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */ >> + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */ >> + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */ >> + data = FIELD_DP32(data, CPUCFG1, RI, 0); >> + data = FIELD_DP32(data, CPUCFG1, EP, 0); >> + data = FIELD_DP32(data, CPUCFG1, RPLV, 0); >> + env->cpucfg[1] = data; >> +} > > The use of the loongarch_cpu_initfn_common function is not going to > scale. > Compare the set of *_initfn in target/arm/tcg/cpu32.c > > In general, you want to copy data in bulk from the processor manual, > so that the reviewer can simply read through the table and see that > the code is correct, without having to check between multiple > functions to see that the combination is correct. > > For our existing la464, that table is Table 54 in the 3A5000 manual. > > Is there a public specification for the la132? I could not find one > in https://www.loongson.cn/EN/product/, but perhaps that's just the > english view. There seems no, even from the chinese view. > > > r~
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index e19b042ce8..af15bf5aaa 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -798,11 +798,6 @@ static void loongarch_init(MachineState *machine) cpu_model = LOONGARCH_CPU_TYPE_NAME("la464"); } - if (!strstr(cpu_model, "la464")) { - error_report("LoongArch/TCG needs cpu type la464"); - exit(1); - } - if (ram_size < 1 * GiB) { error_report("ram_size must be greater than 1G."); exit(1); diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 13d4fccbd3..341176817e 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -356,30 +356,18 @@ static bool loongarch_cpu_has_work(CPUState *cs) #endif } -static void loongarch_la464_initfn(Object *obj) +static void loongarch_cpu_initfn_common(CPULoongArchState *env) { - LoongArchCPU *cpu = LOONGARCH_CPU(obj); - CPULoongArchState *env = &cpu->env; int i; for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } - cpu->dtb_compatible = "loongarch,Loongson-3A5000"; - 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; @@ -439,6 +427,45 @@ static void loongarch_la464_initfn(Object *obj) env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); } +static void loongarch_la464_initfn(Object *obj) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + CPULoongArchState *env = &cpu->env; + + loongarch_cpu_initfn_common(env); + + cpu->dtb_compatible = "loongarch,Loongson-3A5000"; + env->cpucfg[0] = 0x14c010; /* PRID */ + + uint32_t data = env->cpucfg[1]; + data = FIELD_DP32(data, CPUCFG1, ARCH, 2); /* LA64 */ + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f); /* 48 bits */ + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f); /* 48 bits */ + data = FIELD_DP32(data, CPUCFG1, RI, 1); + data = FIELD_DP32(data, CPUCFG1, EP, 1); + data = FIELD_DP32(data, CPUCFG1, RPLV, 1); + env->cpucfg[1] = data; +} + +static void loongarch_la132_initfn(Object *obj) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + CPULoongArchState *env = &cpu->env; + + loongarch_cpu_initfn_common(env); + + cpu->dtb_compatible = "loongarch,Loongson-1C103"; + + uint32_t data = env->cpucfg[1]; + data = FIELD_DP32(data, CPUCFG1, ARCH, 1); /* LA32 */ + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x1f); /* 32 bits */ + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x1f); /* 32 bits */ + data = FIELD_DP32(data, CPUCFG1, RI, 0); + data = FIELD_DP32(data, CPUCFG1, EP, 0); + data = FIELD_DP32(data, CPUCFG1, RPLV, 0); + env->cpucfg[1] = data; +} + static void loongarch_cpu_list_entry(gpointer data, gpointer user_data) { const char *typename = object_class_get_name(OBJECT_CLASS(data)); @@ -784,5 +811,6 @@ static const TypeInfo loongarch32_cpu_type_infos[] = { .class_size = sizeof(LoongArchCPUClass), .class_init = loongarch32_cpu_class_init, }, + DEFINE_LOONGARCH32_CPU_TYPE("la132", loongarch_la132_initfn), }; DEFINE_TYPES(loongarch32_cpu_type_infos)
Add la132 as a loongarch32 cpu type and allow virt machine to be used with la132 instead of la464. Refactor common init logic out as loongarch_cpu_initfn_common. Signed-off-by: Jiajie Chen <c@jia.je> --- hw/loongarch/virt.c | 5 ---- target/loongarch/cpu.c | 54 ++++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 18 deletions(-)