Host CPU model is basically the same with max CPU model, except Product
ID and CPU model name. With host CPU model, Product ID comes from
cpucfg0 and CPU model comes from /proc/cpuinfo.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu.c | 94 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 8b8723a343..c7f52adeb9 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -429,6 +429,97 @@ static void loongarch_max_initfn(Object *obj)
}
}
+#if defined(CONFIG_KVM)
+static int read_cpuinfo(const char *field, char *value, int len)
+{
+ FILE *f;
+ int ret = -1;
+ int field_len = strlen(field);
+ char line[512];
+
+ f = fopen("/proc/cpuinfo", "r");
+ if (!f) {
+ return -1;
+ }
+
+ do {
+ if (!fgets(line, sizeof(line), f)) {
+ break;
+ }
+ if (!strncmp(line, field, field_len)) {
+ strncpy(value, line, len);
+ ret = 0;
+ break;
+ }
+ } while (*line);
+
+ fclose(f);
+
+ return ret;
+}
+
+static uint64_t get_host_cpu_model(void)
+{
+ char line[512];
+ char *ns;
+ static uint64_t cpuid;
+
+ if (cpuid) {
+ return cpuid;
+ }
+
+ if (read_cpuinfo("Model Name", line, sizeof(line))) {
+ return 0;
+ }
+
+ ns = strchr(line, ':');
+ if (!ns) {
+ return 0;
+ }
+
+ ns = strstr(ns, "Loongson-");
+ if (!ns) {
+ return 0;
+ }
+
+ ns += strlen("Loongson-");
+ memccpy((void *)&cpuid, ns, 0, 8);
+ return cpuid;
+}
+
+static uint32_t get_host_cpucfg(int number)
+{
+ unsigned int data = 0;
+
+#ifdef __loongarch__
+ asm volatile("cpucfg %[val], %[reg]"
+ : [val] "=r" (data)
+ : [reg] "r" (number)
+ : "memory");
+#endif
+
+ return data;
+}
+
+static void loongarch_host_initfn(Object *obj)
+{
+ uint32_t data;
+ uint64_t cpuid;
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+ loongarch_max_initfn(obj);
+ data = get_host_cpucfg(0);
+ if (data) {
+ cpu->env.cpucfg[0] = data;
+ }
+
+ cpuid = get_host_cpu_model();
+ if (cpuid) {
+ cpu->env.cpu_id = cpuid;
+ }
+}
+#endif
+
static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
{
uint8_t tlb_ps;
@@ -780,6 +871,9 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn),
DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn),
DEFINE_LOONGARCH_CPU_TYPE(64, "max", loongarch_max_initfn),
+#if defined(CONFIG_KVM)
+ DEFINE_LOONGARCH_CPU_TYPE(64, "host", loongarch_host_initfn),
+#endif
};
DEFINE_TYPES(loongarch_cpu_type_infos)
--
2.39.3