From f4f93d489679307ca40e8cb0bd381f39ad0eff4b Mon Sep 17 00:00:00 2001
From: xianglai li <lixianglai@loongson.cn>
Date: Fri, 28 Jul 2023 02:45:55 -0400
Subject: [PATCH 1/3] Add loongarch cpu support

Add loongarch cpu support, Define new cpu type 'loongarch64'
and implement it's driver functions.

Signed-off-by: "Xianglai Li" <lixianglai@loongson.cn>
Signed-off-by: Xianglai Li <lixianglai@loongson.cn>
---
 src/conf/schemas/basictypes.rng |  1 +
 src/cpu/cpu.c                   |  2 ++
 src/cpu/cpu_loongarch.c         | 58 +++++++++++++++++++++++++++++++++
 src/cpu/cpu_loongarch.h         | 25 ++++++++++++++
 src/cpu/meson.build             |  1 +
 src/qemu/qemu_capabilities.c    | 11 ++++---
 src/qemu/qemu_domain.c          |  1 +
 src/util/virarch.c              | 11 ++++---
 src/util/virarch.h              | 13 +++++---
 9 files changed, 108 insertions(+), 15 deletions(-)
 create mode 100644 src/cpu/cpu_loongarch.c
 create mode 100644 src/cpu/cpu_loongarch.h

diff --git a/src/conf/schemas/basictypes.rng b/src/conf/schemas/basictypes.rng
index 26eb538077..f117f19d33 100644
--- a/src/conf/schemas/basictypes.rng
+++ b/src/conf/schemas/basictypes.rng
@@ -444,6 +444,7 @@
       <value>i686</value>
       <value>ia64</value>
       <value>lm32</value>
+      <value>loongarch64</value>
       <value>m68k</value>
       <value>microblaze</value>
       <value>microblazeel</value>
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 4f048d0dad..33701811fb 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -27,6 +27,7 @@
 #include "cpu_ppc64.h"
 #include "cpu_s390.h"
 #include "cpu_arm.h"
+#include "cpu_loongarch.h"
 #include "cpu_riscv64.h"
 #include "capabilities.h"
 
@@ -41,6 +42,7 @@ static struct cpuArchDriver *drivers[] = {
     &cpuDriverS390,
     &cpuDriverArm,
     &cpuDriverRiscv64,
+    &cpuDriverLoongArch,
 };
 
 
diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c
new file mode 100644
index 0000000000..78d9941320
--- /dev/null
+++ b/src/cpu/cpu_loongarch.c
@@ -0,0 +1,58 @@
+/*
+ * cpu_loongarch.c: CPU driver for 64-bit LOONGARCH CPUs
+ *
+ * Copyright (C) 2024 Loongson Technology.
+ *
+ * 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 <config.h>
+#include "virlog.h"
+#include "cpu.h"
+
+#define VIR_FROM_THIS VIR_FROM_CPU
+
+VIR_LOG_INIT("cpu.cpu_loongarch");
+
+static const virArch archs[] = { VIR_ARCH_LOONGARCH64 };
+
+static virCPUCompareResult
+virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED,
+                       virCPUDef *cpu G_GNUC_UNUSED,
+                       bool failIncompatible G_GNUC_UNUSED)
+{
+    return VIR_CPU_COMPARE_IDENTICAL;
+}
+
+static int
+virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED,
+                      const virCPUDef *host G_GNUC_UNUSED,
+                      bool relative G_GNUC_UNUSED)
+{
+    return 0;
+}
+
+struct cpuArchDriver cpuDriverLoongArch = {
+    .name       = "LoongArch",
+    .arch       = archs,
+    .narch      = G_N_ELEMENTS(archs),
+    .compare    = virCPULoongArchCompare,
+    .decode     = NULL,
+    .encode     = NULL,
+    .dataFree   = NULL,
+    .baseline   = NULL,
+    .update     = virCPULoongArchUpdate,
+    .getModels  = NULL,
+};
diff --git a/src/cpu/cpu_loongarch.h b/src/cpu/cpu_loongarch.h
new file mode 100644
index 0000000000..4bc1c0cd8f
--- /dev/null
+++ b/src/cpu/cpu_loongarch.h
@@ -0,0 +1,25 @@
+/*
+ * cpu_loongarch.h: CPU driver for 64-bit LOONGARCH CPUs
+ *
+ * Copyright (C) 2024 Loongson Technology.
+ *
+ * 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/>.
+ */
+
+#pragma once
+
+#include "cpu.h"
+
+extern struct cpuArchDriver cpuDriverLoongArch;
diff --git a/src/cpu/meson.build b/src/cpu/meson.build
index 55396903b9..141230e380 100644
--- a/src/cpu/meson.build
+++ b/src/cpu/meson.build
@@ -1,6 +1,7 @@
 cpu_sources = [
   'cpu.c',
   'cpu_arm.c',
+  'cpu_loongarch.c',
   'cpu_map.c',
   'cpu_ppc64.c',
   'cpu_riscv64.c',
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d25062b225..509e751274 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2667,36 +2667,37 @@ static const char *preferredMachines[] =
     NULL, /* VIR_ARCH_ITANIUM (doesn't exist in QEMU any more) */
     "lm32-evr", /* VIR_ARCH_LM32 */
 
+    NULL, /* VIR_ARCH_LOONGARCH64 */
     "mcf5208evb", /* VIR_ARCH_M68K */
     "petalogix-s3adsp1800", /* VIR_ARCH_MICROBLAZE */
     "petalogix-s3adsp1800", /* VIR_ARCH_MICROBLAZEEL */
     "malta", /* VIR_ARCH_MIPS */
-    "malta", /* VIR_ARCH_MIPSEL */
 
+    "malta", /* VIR_ARCH_MIPSEL */
     "malta", /* VIR_ARCH_MIPS64 */
     "malta", /* VIR_ARCH_MIPS64EL */
     "or1k-sim", /* VIR_ARCH_OR32 */
     NULL, /* VIR_ARCH_PARISC (no QEMU impl) */
-    NULL, /* VIR_ARCH_PARISC64 (no QEMU impl) */
 
+    NULL, /* VIR_ARCH_PARISC64 (no QEMU impl) */
     "g3beige", /* VIR_ARCH_PPC */
     "g3beige", /* VIR_ARCH_PPCLE */
     "pseries", /* VIR_ARCH_PPC64 */
     "pseries", /* VIR_ARCH_PPC64LE */
-    "bamboo", /* VIR_ARCH_PPCEMB */
 
+    "bamboo", /* VIR_ARCH_PPCEMB */
     "virt", /* VIR_ARCH_RISCV32 */
     "virt", /* VIR_ARCH_RISCV64 */
     NULL, /* VIR_ARCH_S390 (no QEMU impl) */
     "s390-ccw-virtio", /* VIR_ARCH_S390X */
-    "shix", /* VIR_ARCH_SH4 */
 
+    "shix", /* VIR_ARCH_SH4 */
     "shix", /* VIR_ARCH_SH4EB */
     "SS-5", /* VIR_ARCH_SPARC */
     "sun4u", /* VIR_ARCH_SPARC64 */
     "puv3", /* VIR_ARCH_UNICORE32 */
-    "pc", /* VIR_ARCH_X86_64 */
 
+    "pc", /* VIR_ARCH_X86_64 */
     "sim", /* VIR_ARCH_XTENSA */
     "sim", /* VIR_ARCH_XTENSAEB */
 };
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d54846e734..8374780507 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4233,6 +4233,7 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
     case VIR_ARCH_CRIS:
     case VIR_ARCH_ITANIUM:
     case VIR_ARCH_LM32:
+    case VIR_ARCH_LOONGARCH64:
     case VIR_ARCH_M68K:
     case VIR_ARCH_MICROBLAZE:
     case VIR_ARCH_MICROBLAZEEL:
diff --git a/src/util/virarch.c b/src/util/virarch.c
index 01e520de73..8545f993ea 100644
--- a/src/util/virarch.c
+++ b/src/util/virarch.c
@@ -51,36 +51,37 @@ static const struct virArchData {
     { "ia64",         64, VIR_ARCH_LITTLE_ENDIAN },
     { "lm32",         32, VIR_ARCH_BIG_ENDIAN },
 
+    { "loongarch64",  64, VIR_ARCH_LITTLE_ENDIAN },
     { "m68k",         32, VIR_ARCH_BIG_ENDIAN },
     { "microblaze",   32, VIR_ARCH_BIG_ENDIAN },
     { "microblazeel", 32, VIR_ARCH_LITTLE_ENDIAN},
     { "mips",         32, VIR_ARCH_BIG_ENDIAN },
-    { "mipsel",       32, VIR_ARCH_LITTLE_ENDIAN },
 
+    { "mipsel",       32, VIR_ARCH_LITTLE_ENDIAN },
     { "mips64",       64, VIR_ARCH_BIG_ENDIAN },
     { "mips64el",     64, VIR_ARCH_LITTLE_ENDIAN },
     { "openrisc",     32, VIR_ARCH_BIG_ENDIAN },
     { "parisc",       32, VIR_ARCH_BIG_ENDIAN },
-    { "parisc64",     64, VIR_ARCH_BIG_ENDIAN },
 
+    { "parisc64",     64, VIR_ARCH_BIG_ENDIAN },
     { "ppc",          32, VIR_ARCH_BIG_ENDIAN },
     { "ppcle",        32, VIR_ARCH_LITTLE_ENDIAN },
     { "ppc64",        64, VIR_ARCH_BIG_ENDIAN },
     { "ppc64le",      64, VIR_ARCH_LITTLE_ENDIAN },
-    { "ppcemb",       32, VIR_ARCH_BIG_ENDIAN },
 
+    { "ppcemb",       32, VIR_ARCH_BIG_ENDIAN },
     { "riscv32",      32, VIR_ARCH_LITTLE_ENDIAN },
     { "riscv64",      64, VIR_ARCH_LITTLE_ENDIAN },
     { "s390",         32, VIR_ARCH_BIG_ENDIAN },
     { "s390x",        64, VIR_ARCH_BIG_ENDIAN },
-    { "sh4",          32, VIR_ARCH_LITTLE_ENDIAN },
 
+    { "sh4",          32, VIR_ARCH_LITTLE_ENDIAN },
     { "sh4eb",        64, VIR_ARCH_BIG_ENDIAN },
     { "sparc",        32, VIR_ARCH_BIG_ENDIAN },
     { "sparc64",      64, VIR_ARCH_BIG_ENDIAN },
     { "unicore32",    32, VIR_ARCH_LITTLE_ENDIAN },
-    { "x86_64",       64, VIR_ARCH_LITTLE_ENDIAN },
 
+    { "x86_64",       64, VIR_ARCH_LITTLE_ENDIAN },
     { "xtensa",       32, VIR_ARCH_LITTLE_ENDIAN },
     { "xtensaeb",     32, VIR_ARCH_BIG_ENDIAN },
 };
diff --git a/src/util/virarch.h b/src/util/virarch.h
index 747f77c48e..2c01a13b8e 100644
--- a/src/util/virarch.h
+++ b/src/util/virarch.h
@@ -36,36 +36,37 @@ typedef enum {
     VIR_ARCH_ITANIUM,      /* Itanium     64 LE https://en.wikipedia.org/wiki/Itanium */
     VIR_ARCH_LM32,         /* MilkyMist   32 BE https://en.wikipedia.org/wiki/Milkymist */
 
+    VIR_ARCH_LOONGARCH64,  /* LoongArch   64 LE https://en.wikipedia.org/wiki/Loongson#LoongArch */
     VIR_ARCH_M68K,         /* m68k        32 BE https://en.wikipedia.org/wiki/Motorola_68000_family */
     VIR_ARCH_MICROBLAZE,   /* Microblaze  32 BE https://en.wikipedia.org/wiki/MicroBlaze */
     VIR_ARCH_MICROBLAZEEL, /* Microblaze  32 LE https://en.wikipedia.org/wiki/MicroBlaze */
     VIR_ARCH_MIPS,         /* MIPS        32 BE https://en.wikipedia.org/wiki/MIPS_architecture */
-    VIR_ARCH_MIPSEL,       /* MIPS        32 LE https://en.wikipedia.org/wiki/MIPS_architecture */
 
+    VIR_ARCH_MIPSEL,       /* MIPS        32 LE https://en.wikipedia.org/wiki/MIPS_architecture */
     VIR_ARCH_MIPS64,       /* MIPS        64 BE https://en.wikipedia.org/wiki/MIPS_architecture */
     VIR_ARCH_MIPS64EL,     /* MIPS        64 LE https://en.wikipedia.org/wiki/MIPS_architecture */
     VIR_ARCH_OR32,         /* OpenRisc    32 BE https://en.wikipedia.org/wiki/OpenRISC#QEMU_support */
     VIR_ARCH_PARISC,       /* PA-Risc     32 BE https://en.wikipedia.org/wiki/PA-RISC */
-    VIR_ARCH_PARISC64,     /* PA-Risc     64 BE https://en.wikipedia.org/wiki/PA-RISC */
 
+    VIR_ARCH_PARISC64,     /* PA-Risc     64 BE https://en.wikipedia.org/wiki/PA-RISC */
     VIR_ARCH_PPC,          /* PowerPC     32 BE https://en.wikipedia.org/wiki/PowerPC */
     VIR_ARCH_PPCLE,        /* PowerPC     32 LE https://en.wikipedia.org/wiki/PowerPC */
     VIR_ARCH_PPC64,        /* PowerPC     64 BE https://en.wikipedia.org/wiki/PowerPC */
     VIR_ARCH_PPC64LE,      /* PowerPC     64 LE https://en.wikipedia.org/wiki/PowerPC */
-    VIR_ARCH_PPCEMB,       /* PowerPC     32 BE https://en.wikipedia.org/wiki/PowerPC */
 
+    VIR_ARCH_PPCEMB,       /* PowerPC     32 BE https://en.wikipedia.org/wiki/PowerPC */
     VIR_ARCH_RISCV32,      /* RISC-V      32 LE https://en.wikipedia.org/wiki/RISC-V */
     VIR_ARCH_RISCV64,      /* RISC-V      64 LE https://en.wikipedia.org/wiki/RISC-V */
     VIR_ARCH_S390,         /* S390        32 BE https://en.wikipedia.org/wiki/S390 */
     VIR_ARCH_S390X,        /* S390        64 BE https://en.wikipedia.org/wiki/S390x */
-    VIR_ARCH_SH4,          /* SuperH4     32 LE https://en.wikipedia.org/wiki/SuperH */
 
+    VIR_ARCH_SH4,          /* SuperH4     32 LE https://en.wikipedia.org/wiki/SuperH */
     VIR_ARCH_SH4EB,        /* SuperH4     32 BE https://en.wikipedia.org/wiki/SuperH */
     VIR_ARCH_SPARC,        /* Sparc       32 BE https://en.wikipedia.org/wiki/Sparc */
     VIR_ARCH_SPARC64,      /* Sparc       64 BE https://en.wikipedia.org/wiki/Sparc */
     VIR_ARCH_UNICORE32,    /* UniCore     32 LE https://en.wikipedia.org/wiki/Unicore */
-    VIR_ARCH_X86_64,       /* x86         64 LE https://en.wikipedia.org/wiki/X86 */
 
+    VIR_ARCH_X86_64,       /* x86         64 LE https://en.wikipedia.org/wiki/X86 */
     VIR_ARCH_XTENSA,       /* XTensa      32 LE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */
     VIR_ARCH_XTENSAEB,     /* XTensa      32 BE https://en.wikipedia.org/wiki/Xtensa#Processor_Cores */
 
@@ -106,6 +107,8 @@ typedef enum {
 #define ARCH_IS_SH4(arch) ((arch) == VIR_ARCH_SH4 ||\
                            (arch) == VIR_ARCH_SH4EB)
 
+#define ARCH_IS_LOONGARCH(arch)  ((arch) == VIR_ARCH_LOONGARCH64)
+
 typedef enum {
     VIR_ARCH_LITTLE_ENDIAN,
     VIR_ARCH_BIG_ENDIAN,
-- 
2.39.1

