[libvirt] [PATCH 1/6] Introduce a set of APIs for managing architectures

Daniel P. Berrange berrange at redhat.com
Tue Dec 11 14:53:36 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Introduce a 'virArch' enum for CPU architectures. Include
data type providing wordsize and endianness, and APIs to
query this info and convert to/from enum and string form.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/Makefile.am    |   1 +
 src/util/virarch.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virarch.h |  81 ++++++++++++++++++++++++
 3 files changed, 259 insertions(+)
 create mode 100644 src/util/virarch.c
 create mode 100644 src/util/virarch.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 1a2f94f..4edfb7f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,6 +79,7 @@ UTIL_SOURCES =							\
 		util/threadpool.c util/threadpool.h		\
 		util/uuid.c util/uuid.h				\
 		util/util.c util/util.h				\
+		util/virarch.h util/virarch.c			\
 		util/viratomic.h util/viratomic.c		\
 		util/viraudit.c util/viraudit.h			\
 		util/virauth.c util/virauth.h			\
diff --git a/src/util/virarch.c b/src/util/virarch.c
new file mode 100644
index 0000000..8b7bec8
--- /dev/null
+++ b/src/util/virarch.c
@@ -0,0 +1,177 @@
+/*
+ * virarch.c: architecture handling
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * 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 <sys/utsname.h>
+
+#include "logging.h"
+#include "virarch.h"
+#include "verify.h"
+
+/* The canonical names are used in XML documents. ie ABI sensitive */
+static const struct virArchData {
+    const char *name;
+    unsigned int wordsize;
+    virArchEndian endian;
+} virArchData[] = {
+    { "",             0, VIR_ARCH_LITTLE_ENDIAN },
+    { "alpha",        64, VIR_ARCH_BIG_ENDIAN },
+    { "armv7l",       32, VIR_ARCH_LITTLE_ENDIAN },
+    { "cris",         32, VIR_ARCH_LITTLE_ENDIAN },
+    { "i686",         32, VIR_ARCH_LITTLE_ENDIAN },
+
+    { "itanium",      64, VIR_ARCH_LITTLE_ENDIAN },
+    { "lm32",         32, VIR_ARCH_BIG_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 },
+    { "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 },
+    { "ppc",          32, VIR_ARCH_BIG_ENDIAN },
+    { "ppc64",        64, VIR_ARCH_BIG_ENDIAN },
+    { "ppcemb",       32, VIR_ARCH_BIG_ENDIAN },
+
+    { "s390",         32, VIR_ARCH_BIG_ENDIAN },
+    { "s390x",        64, VIR_ARCH_BIG_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 },
+    { "xtensa",       32, VIR_ARCH_LITTLE_ENDIAN },
+    { "xtensaeb",     32, VIR_ARCH_BIG_ENDIAN },
+};
+
+verify(ARRAY_CARDINALITY(virArchData) == VIR_ARCH_LAST);
+
+
+/**
+ * virArchGetWordSize:
+ * @arch: the CPU architecture
+ *
+ * Return the wordsize of the CPU architecture (32 or 64)
+ */
+unsigned int virArchGetWordSize(virArch arch)
+{
+    if (arch >= VIR_ARCH_LAST)
+        arch = VIR_ARCH_NONE;
+
+    return virArchData[arch].wordsize;
+}
+
+/**
+ * virArchGetEndian:
+ * @arch: the CPU architecture
+ *
+ * Return the endian-ness of the CPU architecture
+ * (VIR_ARCH_LITTLE_ENDIAN or VIR_ARCH_BIG_ENDIAN)
+ */
+virArchEndian virArchGetEndian(virArch arch)
+{
+    if (arch >= VIR_ARCH_LAST)
+        arch = VIR_ARCH_NONE;
+
+    return virArchData[arch].endian;
+}
+
+/**
+ * virArchToString:
+ * @arch: the CPU architecture
+ *
+ * Return the string name of the architecture
+ */
+const char *virArchToString(virArch arch)
+{
+    if (arch >= VIR_ARCH_LAST)
+        arch = VIR_ARCH_NONE;
+
+    return virArchData[arch].name;
+}
+
+
+/**
+ * virArchFromString:
+ * @archstr: the CPU architecture string
+ *
+ * Return the architecture matching @archstr,
+ * defaulting to VIR_ARCH_I686 if unidentified
+ */
+virArch virArchFromString(const char *archstr)
+{
+    size_t i;
+    for (i = 1 ; i < VIR_ARCH_LAST ; i++) {
+        if (STREQ(virArchData[i].name, archstr))
+            return i;
+    }
+
+    VIR_DEBUG("Unknown arch %s", archstr);
+    return VIR_ARCH_NONE;
+}
+
+
+/**
+ * virArchFromHost:
+ *
+ * Return the host architecture. Prefer this to the
+ * uname 'machine' field, since this will canonicalize
+ * architecture names like 'amd64' into 'x86_64'.
+ */
+virArch virArchFromHost(void)
+{
+    struct utsname ut;
+    virArch arch;
+
+    uname(&ut);
+
+    /* Some special cases we need to handle first
+     * for non-canonical names */
+    if (ut.machine[0] == 'i' &&
+        ut.machine[2] == '8' &&
+        ut.machine[3] == '6' &&
+        ut.machine[4] == '\0') {
+        arch = VIR_ARCH_I686;
+    } else if (STREQ(ut.machine, "ia64")) {
+        arch = VIR_ARCH_ITANIUM;
+    } else if (STREQ(ut.machine, "amd64")) {
+        arch = VIR_ARCH_X86_64;
+    } else {
+        /* Otherwise assume the canonical name */
+        if ((arch = virArchFromString(ut.machine)) == VIR_ARCH_NONE) {
+            VIR_WARN("Unknown host arch %s, report to libvir-list at redhat.com",
+                     ut.machine);
+        }
+    }
+
+    VIR_DEBUG("Mapped %s to %d (%s)",
+              ut.machine, arch, virArchToString(arch));
+
+    return arch;
+}
diff --git a/src/util/virarch.h b/src/util/virarch.h
new file mode 100644
index 0000000..d29d7ef
--- /dev/null
+++ b/src/util/virarch.h
@@ -0,0 +1,81 @@
+/*
+ * virarch.h: architecture handling
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * 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/>.
+ *
+ */
+
+#ifndef __VIR_ARCH_H__
+# define __VIR_ARCH_H__
+
+# include "internal.h"
+# include "util.h"
+
+typedef enum {
+    VIR_ARCH_NONE,
+    VIR_ARCH_ALPHA,        /* Alpha       64 BE http://en.wikipedia.org/wiki/DEC_Alpha */
+    VIR_ARCH_ARMV7L,       /* ARMv7       32 LE http://en.wikipedia.org/wiki/ARM_architecture */
+    VIR_ARCH_CRIS,         /* ETRAX       32 LE http://en.wikipedia.org/wiki/ETRAX_CRIS */
+    VIR_ARCH_I686,         /* x86         32 LE http://en.wikipedia.org/wiki/X86 */
+
+    VIR_ARCH_ITANIUM,      /* Itanium     64 LE http://en.wikipedia.org/wiki/Itanium */
+    VIR_ARCH_LM32,         /* MilkyMist   32 BE http://en.wikipedia.org/wiki/Milkymist */
+    VIR_ARCH_M68K,         /* m68k        32 BE http://en.wikipedia.org/wiki/Motorola_68000_family */
+    VIR_ARCH_MICROBLAZE,   /* Microblaze  32 BE http://en.wikipedia.org/wiki/MicroBlaze */
+    VIR_ARCH_MICROBLAZEEL, /* Microblaze  32 LE http://en.wikipedia.org/wiki/MicroBlaze */
+
+    VIR_ARCH_MIPS,         /* MIPS        32 BE http://en.wikipedia.org/wiki/MIPS_architecture */
+    VIR_ARCH_MIPSEL,       /* MIPS        32 LE http://en.wikipedia.org/wiki/MIPS_architecture */
+    VIR_ARCH_MIPS64,       /* MIPS        64 BE http://en.wikipedia.org/wiki/MIPS_architecture */
+    VIR_ARCH_MIPS64EL,     /* MIPS        64 LE http://en.wikipedia.org/wiki/MIPS_architecture */
+    VIR_ARCH_OR32,         /* OpenRisc    32 BE http://en.wikipedia.org/wiki/OpenRISC#QEMU_support*/
+
+    VIR_ARCH_PARISC,       /* PA-Risc     32 BE http://en.wikipedia.org/wiki/PA-RISC */
+    VIR_ARCH_PARISC64,     /* PA-Risc     64 BE http://en.wikipedia.org/wiki/PA-RISC */
+    VIR_ARCH_PPC,          /* PowerPC     32 BE http://en.wikipedia.org/wiki/PowerPC */
+    VIR_ARCH_PPC64,        /* PowerPC     64 BE http://en.wikipedia.org/wiki/PowerPC */
+    VIR_ARCH_PPCEMB,       /* PowerPC     32 BE http://en.wikipedia.org/wiki/PowerPC */
+
+    VIR_ARCH_S390,         /* S390        32 BE http://en.wikipedia.org/wiki/S390 */
+    VIR_ARCH_S390X,        /* S390        64 BE http://en.wikipedia.org/wiki/S390x */
+    VIR_ARCH_SH4,          /* SuperH4     32 LE http://en.wikipedia.org/wiki/SuperH */
+    VIR_ARCH_SH4EB,        /* SuperH4     32 BE http://en.wikipedia.org/wiki/SuperH */
+    VIR_ARCH_SPARC,        /* Sparc       32 BE http://en.wikipedia.org/wiki/Sparc */
+
+    VIR_ARCH_SPARC64,      /* Sparc       64 BE http://en.wikipedia.org/wiki/Sparc */
+    VIR_ARCH_UNICORE32,    /* UniCore     32 LE http://en.wikipedia.org/wiki/Unicore*/
+    VIR_ARCH_X86_64,       /* x86         64 LE http://en.wikipedia.org/wiki/X86 */
+    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_LAST,
+} virArch;
+
+
+typedef enum {
+    VIR_ARCH_LITTLE_ENDIAN,
+    VIR_ARCH_BIG_ENDIAN,
+} virArchEndian;
+
+unsigned int virArchGetWordSize(virArch arch);
+virArchEndian virArchGetEndian(virArch arch);
+const char *virArchToString(virArch arch);
+virArch virArchFromString(const char *name);
+
+virArch virArchFromHost(void);
+
+#endif /* __VIR_ARCH_H__ */
-- 
1.7.11.7




More information about the libvir-list mailing list