From e3185252df62b1e5b6333ee059a2bd95a49acd60 Mon Sep 17 00:00:00 2001
From: Lu Feifei <lufeifei@wxiat.com>
Date: Wed, 25 May 2022 16:25:54 +0800
Subject: [PATCH] sw_64: Add sw64 architecture support

Signed-off-by: Lu Feifei <lufeifei@wxiat.com>
---
 src/cpu/Makefile.inc.am      |  2 +
 src/cpu/cpu.c                |  2 +
 src/cpu/cpu_sw64.c           | 71 ++++++++++++++++++++++++++++++++++++
 src/cpu/cpu_sw64.h           | 32 ++++++++++++++++
 src/qemu/qemu_capabilities.c | 10 +++++
 src/qemu/qemu_domain.c       |  5 +++
 src/util/virarch.c           |  6 +++
 src/util/virarch.h           |  4 ++
 src/util/virhostcpu.c        |  2 +
 src/util/virprocess.c        |  2 +
 src/util/virsysinfo.c        |  3 +-
 11 files changed, 138 insertions(+), 1 deletion(-)
 create mode 100644 src/cpu/cpu_sw64.c
 create mode 100644 src/cpu/cpu_sw64.h

diff --git a/src/cpu/Makefile.inc.am b/src/cpu/Makefile.inc.am
index 0abeee87b6..1ee1290c2d 100644
--- a/src/cpu/Makefile.inc.am
+++ b/src/cpu/Makefile.inc.am
@@ -10,6 +10,8 @@ CPU_SOURCES = \
 	cpu/cpu_s390.c \
 	cpu/cpu_arm.h \
 	cpu/cpu_arm.c \
+	cpu/cpu_sw64.h \
+	cpu/cpu_sw64.c \
 	cpu/cpu_ppc64.h \
 	cpu/cpu_ppc64.c \
 	cpu/cpu_ppc64_data.h \
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 631c755391..89c06aceeb 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -29,6 +29,7 @@
 #include "cpu_ppc64.h"
 #include "cpu_s390.h"
 #include "cpu_arm.h"
+#include "cpu_sw64.h"
 #include "capabilities.h"
 #include "virstring.h"
 
@@ -42,6 +43,7 @@ static struct cpuArchDriver *drivers[] = {
     &cpuDriverPPC64,
     &cpuDriverS390,
     &cpuDriverArm,
+    &cpuDriverSW64,
 };
 
 
diff --git a/src/cpu/cpu_sw64.c b/src/cpu/cpu_sw64.c
new file mode 100644
index 0000000000..d31e34fb01
--- /dev/null
+++ b/src/cpu/cpu_sw64.c
@@ -0,0 +1,71 @@
+/*
+ * cpu_sw64.c: CPU driver for sw64 CPUs
+ *
+ * Copyright (C) 2021 Lu Feifei
+ *
+ * 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/>.
+ *
+ * Authors:
+ *      Lu Feifei <lufeifei@wxiat.com>
+ */
+
+#include <config.h>
+
+#include "viralloc.h"
+#include "cpu.h"
+#include "cpu_sw64.h"
+#include "virstring.h"
+
+#define VIR_FROM_THIS VIR_FROM_CPU
+#define ARRAY_CARDINALITY(Array) (sizeof(Array) / sizeof(*(Array)))
+
+static const virArch archs[] = { VIR_ARCH_SW_64 };
+
+static int
+virCPUsw64GetHost(virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+                  virDomainCapsCPUModelsPtr models ATTRIBUTE_UNUSED)
+{
+    return 0;
+}
+
+static virCPUCompareResult
+virCPUsw64Compare(virCPUDefPtr host ATTRIBUTE_UNUSED,
+                  virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+                  bool failMessages ATTRIBUTE_UNUSED)
+{
+    return VIR_CPU_COMPARE_IDENTICAL;
+}
+
+static int
+virCPUsw64Update(virCPUDefPtr guest,
+                 const virCPUDef *host ATTRIBUTE_UNUSED)
+{
+    guest->mode = VIR_CPU_MODE_CUSTOM;
+    guest->match = VIR_CPU_MATCH_EXACT;
+
+    return 0;
+}
+
+struct cpuArchDriver cpuDriverSW64 = {
+    .name = "sw_64",
+    .arch = archs,
+    .narch = ARRAY_CARDINALITY(archs),
+    .getHost = virCPUsw64GetHost,
+    .compare = virCPUsw64Compare,
+    .decode = NULL,
+    .encode = NULL,
+    .baseline = NULL,
+    .update = virCPUsw64Update,
+};
diff --git a/src/cpu/cpu_sw64.h b/src/cpu/cpu_sw64.h
new file mode 100644
index 0000000000..4a03f0affa
--- /dev/null
+++ b/src/cpu/cpu_sw64.h
@@ -0,0 +1,32 @@
+/*
+ * cpu_sw64.h: CPU driver for sw64 CPUs
+ *
+ * Copyright (C) 2021 Lu Feifei
+ *
+ * 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/>.
+ *
+ * Authors:
+ *      Lu Feifei <lufeifei@wxiat.com>
+ */
+
+#ifndef __VIR_CPU_SW64_H__
+# define __VIR_CPU_SW64_H__
+
+# include "cpu.h"
+
+extern struct cpuArchDriver cpuDriverSW64;
+
+#endif /* __VIR_CPU_SW64_H__ */
+
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 3b4e26822b..2931d0c190 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -708,6 +708,8 @@ virArch virQEMUCapsArchFromString(const char *arch)
         return VIR_ARCH_ARMV7L;
     if (STREQ(arch, "or32"))
         return VIR_ARCH_OR32;
+    if (STREQ(arch, "sw64"))
+        return VIR_ARCH_SW_64;
 
     return virArchFromString(arch);
 }
@@ -721,6 +723,8 @@ const char *virQEMUCapsArchToString(virArch arch)
         return "arm";
     else if (arch == VIR_ARCH_OR32)
         return "or32";
+    else if (arch == VIR_ARCH_SW_64)
+        return "sw64";
 
     return virArchToString(arch);
 }
@@ -1967,6 +1971,10 @@ bool virQEMUCapsHasPCIMultiBus(virQEMUCapsPtr qemuCaps,
      * since forever */
     if (ARCH_IS_X86(def->os.arch))
         return true;
+    /* sw_64 support PCI-multibus on all machine types
+     * since forever */
+    if (ARCH_IS_SW64(def->os.arch))
+        return true;
 
     if (def->os.arch == VIR_ARCH_PPC ||
         ARCH_IS_PPC64(def->os.arch)) {
@@ -2674,6 +2682,8 @@ static const char *preferredMachines[] =
 
     "sim", /* VIR_ARCH_XTENSA */
     "sim", /* VIR_ARCH_XTENSAEB */
+
+    "core3", /* VIR_ARCH_SW_64 */
 };
 G_STATIC_ASSERT(G_N_ELEMENTS(preferredMachines) == VIR_ARCH_LAST);
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index cb2fbdc179..834af89a1e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4350,6 +4350,10 @@ qemuDomainDefAddDefaultDevices(virDomainDefPtr def,
         addPCIRoot = true;
         break;
 
+    case VIR_ARCH_SW_64:
+	addPCIeRoot = true;
+	break;
+
     case VIR_ARCH_ARMV7B:
     case VIR_ARCH_CRIS:
     case VIR_ARCH_ITANIUM:
@@ -12959,6 +12963,7 @@ qemuDomainMachineHasBuiltinIDE(const char *machine,
     return qemuDomainMachineIsI440FX(machine, arch) ||
         STREQ(machine, "malta") ||
         STREQ(machine, "sun4u") ||
+        STREQ(machine, "core3") ||
         STREQ(machine, "g3beige");
 }
 
diff --git a/src/util/virarch.c b/src/util/virarch.c
index f088b6b676..653136cc73 100644
--- a/src/util/virarch.c
+++ b/src/util/virarch.c
@@ -83,6 +83,8 @@ static const struct virArchData {
 
     { "xtensa",       32, VIR_ARCH_LITTLE_ENDIAN },
     { "xtensaeb",     32, VIR_ARCH_BIG_ENDIAN },
+
+    { "sw_64",        64, VIR_ARCH_LITTLE_ENDIAN},
 };
 
 G_STATIC_ASSERT(G_N_ELEMENTS(virArchData) == VIR_ARCH_LAST);
@@ -196,6 +198,8 @@ virArch virArchFromHost(void)
         return VIR_ARCH_ARMV7L;
     case PROCESSOR_ARCHITECTURE_ARM64:
         return VIR_ARCH_AARCH64;
+    case PROCESSOR_ARCHITECTURE_SW64:
+        return VIR_ARCH_SW_64;
     default:
         VIR_WARN("Unknown host arch '%d', report to libvir-list@redhat.com",
                  info.wProcessorArchitecture);
@@ -220,6 +224,8 @@ virArch virArchFromHost(void)
         arch = VIR_ARCH_I686;
     } else if (STREQ(ut.machine, "amd64")) {
         arch = VIR_ARCH_X86_64;
+    } else if (STREQ(ut.machine, "sw_64")) {
+        arch = VIR_ARCH_SW_64;
     } else {
         /* Otherwise assume the canonical name */
         if ((arch = virArchFromString(ut.machine)) == VIR_ARCH_NONE) {
diff --git a/src/util/virarch.h b/src/util/virarch.h
index c3890606ec..5eb146eb1b 100644
--- a/src/util/virarch.h
+++ b/src/util/virarch.h
@@ -69,6 +69,8 @@ typedef enum {
     VIR_ARCH_XTENSA,       /* XTensa      32 LE http://en.wikipedia.org/wiki/Xtensa#Processor_Cores */
     VIR_ARCH_XTENSAEB,     /* XTensa      32 BE http://en.wikipedia.org/wiki/Xtensa#Processor_Cores */
 
+    VIR_ARCH_SW_64,        /* SW64        64 LE XHB*/
+
     VIR_ARCH_LAST,
 } virArch;
 
@@ -95,6 +97,8 @@ typedef enum {
 #define ARCH_IS_S390(arch) ((arch) == VIR_ARCH_S390 ||\
                             (arch) == VIR_ARCH_S390X)
 
+#define ARCH_IS_SW64(arch)   ((arch) == VIR_ARCH_SW_64)
+
 typedef enum {
     VIR_ARCH_LITTLE_ENDIAN,
     VIR_ARCH_BIG_ENDIAN,
diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c
index 721d959d46..5ec98d6016 100644
--- a/src/util/virhostcpu.c
+++ b/src/util/virhostcpu.c
@@ -586,6 +586,8 @@ virHostCPUParseFrequency(FILE *cpuinfo,
         prefix = "clock";
     else if (ARCH_IS_S390(arch))
         prefix = "cpu MHz dynamic";
+    else if (ARCH_IS_SW64(arch))
+        prefix = "cpu frequency [MHz]";
 
     if (!prefix) {
         VIR_WARN("%s is not supported by the %s parser",
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index b126c3c9af..141ebb54e0 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -89,6 +89,8 @@ VIR_LOG_INIT("util.process");
 #   define __NR_setns 350
 #  elif defined(__s390__)
 #   define __NR_setns 339
+#  elif defined(__sw_64__)
+#   define __NR_setns 501
 #  endif
 # endif
 
diff --git a/src/util/virsysinfo.c b/src/util/virsysinfo.c
index 41f4d1cff9..8a53702224 100644
--- a/src/util/virsysinfo.c
+++ b/src/util/virsysinfo.c
@@ -1197,7 +1197,8 @@ virSysinfoRead(void)
 #elif !defined(WIN32) && \
     (defined(__x86_64__) || \
      defined(__i386__) || \
-     defined(__amd64__))
+     defined(__amd64__) || \
+     defined(__sw_64__))
     return virSysinfoReadDMI();
 #else /* WIN32 || not supported arch */
     /*
-- 
2.27.0

