[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 46/46] xen: arm: implement cpuinfo



Use to:

 - Only context switch ThumbEE state if the processor implements it. In
   particular the ARMv8 FastModels do not.
 - Detect the generic timer, and therefore call identify_cpu before
   init_xen_time.

Also improve the boot time messages a bit.

I haven't added decoding for all of the CPUID words, it seems like overkill
for the moment.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Acked-by: Tim Deegan <tim@xxxxxxx>
Cc: stefano.stabellini@xxxxxxxxxx
---
 xen/arch/arm/Makefile            |    1 +
 xen/arch/arm/cpu.c               |   69 +++++++++++++++++++++
 xen/arch/arm/domain.c            |   39 +++++++++---
 xen/arch/arm/setup.c             |  109 +++++++++++++++++++++++++--------
 xen/arch/arm/smpboot.c           |    7 ++
 xen/arch/arm/time.c              |    5 +-
 xen/include/asm-arm/cpregs.h     |   11 ++--
 xen/include/asm-arm/cpufeature.h |   40 ++++++++++++
 xen/include/asm-arm/domain.h     |   10 +++-
 xen/include/asm-arm/processor.h  |  125 ++++++++++++++++++++++++++++++++++++-
 10 files changed, 368 insertions(+), 48 deletions(-)
 create mode 100644 xen/arch/arm/cpu.c
 create mode 100644 xen/include/asm-arm/cpufeature.h

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 677e232..2106a4f 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -3,6 +3,7 @@ subdir-$(arm64) += arm64
 subdir-y += platforms
 
 obj-y += early_printk.o
+obj-y += cpu.o
 obj-y += domain.o
 obj-y += domctl.o
 obj-y += sysctl.o
diff --git a/xen/arch/arm/cpu.c b/xen/arch/arm/cpu.c
new file mode 100644
index 0000000..7a8ad33
--- /dev/null
+++ b/xen/arch/arm/cpu.c
@@ -0,0 +1,69 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ */
+
+#include <xen/config.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+
+#include <asm/processor.h>
+
+void __cpuinit identify_cpu(struct cpuinfo_arm *c)
+{
+        c->midr.bits = READ_SYSREG32(MIDR_EL1);
+        c->mpidr.bits = READ_SYSREG(MPIDR_EL1);
+
+#ifdef CONFIG_ARM_64
+        c->pfr64.bits[0] = READ_SYSREG64(ID_AA64PFR0_EL1);
+        c->pfr64.bits[1] = READ_SYSREG64(ID_AA64PFR1_EL1);
+
+        c->dbg64.bits[0] = READ_SYSREG64(ID_AA64DFR0_EL1);
+        c->dbg64.bits[1] = READ_SYSREG64(ID_AA64DFR1_EL1);
+
+        c->aux64.bits[0] = READ_SYSREG64(ID_AA64AFR0_EL1);
+        c->aux64.bits[1] = READ_SYSREG64(ID_AA64AFR1_EL1);
+
+        c->mm64.bits[0]  = READ_SYSREG64(ID_AA64MMFR0_EL1);
+        c->mm64.bits[1]  = READ_SYSREG64(ID_AA64MMFR1_EL1);
+
+        c->isa64.bits[0] = READ_SYSREG64(ID_AA64ISAR0_EL1);
+        c->isa64.bits[1] = READ_SYSREG64(ID_AA64ISAR1_EL1);
+#endif
+
+        c->pfr32.bits[0] = READ_SYSREG32(ID_PFR0_EL1);
+        c->pfr32.bits[1] = READ_SYSREG32(ID_PFR1_EL1);
+
+        c->dbg32.bits[0] = READ_SYSREG32(ID_DFR0_EL1);
+
+        c->aux32.bits[0] = READ_SYSREG32(ID_AFR0_EL1);
+
+        c->mm32.bits[0]  = READ_SYSREG32(ID_MMFR0_EL1);
+        c->mm32.bits[1]  = READ_SYSREG32(ID_MMFR1_EL1);
+        c->mm32.bits[2]  = READ_SYSREG32(ID_MMFR2_EL1);
+        c->mm32.bits[3]  = READ_SYSREG32(ID_MMFR3_EL1);
+
+        c->isa32.bits[0] = READ_SYSREG32(ID_ISAR0_EL1);
+        c->isa32.bits[1] = READ_SYSREG32(ID_ISAR1_EL1);
+        c->isa32.bits[2] = READ_SYSREG32(ID_ISAR2_EL1);
+        c->isa32.bits[3] = READ_SYSREG32(ID_ISAR3_EL1);
+        c->isa32.bits[4] = READ_SYSREG32(ID_ISAR4_EL1);
+        c->isa32.bits[5] = READ_SYSREG32(ID_ISAR5_EL1);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index dce7ea1..bca3d89 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -1,3 +1,14 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ */
 #include <xen/config.h>
 #include <xen/init.h>
 #include <xen/lib.h>
@@ -13,6 +24,7 @@
 #include <asm/regs.h>
 #include <asm/p2m.h>
 #include <asm/irq.h>
+#include <asm/cpufeature.h>
 
 #include <asm/gic.h>
 #include "vtimer.h"
@@ -58,11 +70,13 @@ static void ctxt_switch_from(struct vcpu *p)
     /* Arch timer */
     virt_timer_save(p);
 
-#if defined(CONFIG_ARM_32)
-    /* XXX only save these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
-    p->arch.teecr = READ_CP32(TEECR);
-    p->arch.teehbr = READ_CP32(TEEHBR);
+    if ( is_pv32_domain(p->domain) && cpu_has_thumbee )
+    {
+        p->arch.teecr = READ_SYSREG32(TEECR32_EL1);
+        p->arch.teehbr = READ_SYSREG32(TEEHBR32_EL1);
+    }
 
+#ifdef CONFIG_ARM_32
     p->arch.joscr = READ_CP32(JOSCR);
     p->arch.jmcr = READ_CP32(JMCR);
 #endif
@@ -121,6 +135,9 @@ static void ctxt_switch_to(struct vcpu *n)
     p2m_load_VTTBR(n->domain);
     isb();
 
+    WRITE_SYSREG32(n->domain->arch.vpidr, VPIDR_EL2);
+    WRITE_SYSREG(n->domain->arch.vmpidr, VMPIDR_EL2);
+
     /* VGIC */
     gic_restore_state(n);
 
@@ -169,11 +186,13 @@ static void ctxt_switch_to(struct vcpu *n)
     WRITE_SYSREG(n->arch.tpidrro_el0, TPIDRRO_EL0);
     WRITE_SYSREG(n->arch.tpidr_el1, TPIDR_EL1);
 
-#if defined(CONFIG_ARM_32)
-    /* XXX only restore these if ThumbEE e.g. ID_PFR0.THUMB_EE_SUPPORT */
-    WRITE_CP32(n->arch.teecr, TEECR);
-    WRITE_CP32(n->arch.teehbr, TEEHBR);
+    if ( is_pv32_domain(n->domain) && cpu_has_thumbee )
+    {
+        WRITE_SYSREG32(n->arch.teecr, TEECR32_EL1);
+        WRITE_SYSREG32(n->arch.teehbr, TEEHBR32_EL1);
+    }
 
+#ifdef CONFIG_ARM_32
     WRITE_CP32(n->arch.joscr, JOSCR);
     WRITE_CP32(n->arch.jmcr, JMCR);
 #endif
@@ -447,6 +466,10 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags)
     if ( (d->shared_info = alloc_xenheap_pages(0, 0)) == NULL )
         goto fail;
 
+    /* Default the virtual ID to match the physical */
+    d->arch.vpidr = boot_cpu_data.midr.bits;
+    d->arch.vmpidr = boot_cpu_data.mpidr.bits;
+
     clear_page(d->shared_info);
     share_xen_page_with_guest(
         virt_to_page(d->shared_info), d, XENSHARE_writable);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 8326034..566f36c 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -40,6 +40,9 @@
 #include <asm/vfp.h>
 #include <asm/early_printk.h>
 #include <asm/gic.h>
+#include <asm/cpufeature.h>
+
+struct cpuinfo_arm __read_mostly boot_cpu_data;
 
 static __used void init_done(void)
 {
@@ -54,41 +57,93 @@ static void __init init_idle_domain(void)
     /* TODO: setup_idle_pagetable(); */
 }
 
+static const char * __initdata processor_implementers[] = {
+    ['A'] = "ARM Limited",
+    ['D'] = "Digital Equipment Corp",
+    ['M'] = "Motorola, Freescale Semiconductor Inc.",
+    ['Q'] = "Qualcomm Inc.",
+    ['V'] = "Marvell Semiconductor Inc.",
+    ['i'] = "Intel Corporation",
+};
+
 static void __init processor_id(void)
 {
+    const char *implementer = "Unknown";
+    struct cpuinfo_arm *c = &boot_cpu_data;
+
+    identify_cpu(c);
+    current_cpu_data = *c;
+
+    if ( c->midr.implementer < ARRAY_SIZE(processor_implementers) &&
+         processor_implementers[c->midr.implementer] )
+        implementer = processor_implementers[c->midr.implementer];
 
-    /* Setup the virtual ID to match the physical */
-    WRITE_SYSREG32(READ_SYSREG32(MIDR_EL1), VPIDR_EL2);
-    WRITE_SYSREG(READ_SYSREG(MPIDR_EL1), VMPIDR_EL2);
+    if ( c->midr.architecture != 0xf )
+        printk("Huh, cpu architecture %x, expected 0xf (defined by cpuid)\n",
+               c->midr.architecture);
+
+    printk("Processor: \"%s\", variant: 0x%x, part 0x%03x, rev 0x%x\n",
+           implementer, c->midr.variant, c->midr.part_number, 
c->midr.revision);
 
 #if defined(CONFIG_ARM_64)
-    printk("64-bit Processor Features: %016"PRIx64" %016"PRIx64"\n",
-           READ_SYSREG64(ID_AA64PFR0_EL1), READ_SYSREG64(ID_AA64PFR1_EL1));
-    printk("64-bit Debug Features: %016"PRIx64" %016"PRIx64"\n",
-           READ_SYSREG64(ID_AA64DFR0_EL1), READ_SYSREG64(ID_AA64DFR1_EL1));
-    printk("64-bit Auxiliary Features: %016"PRIx64" %016"PRIx64"\n",
-           READ_SYSREG64(ID_AA64AFR0_EL1), READ_SYSREG64(ID_AA64AFR1_EL1));
-    printk("64-bit Memory Model Features: %016"PRIx64" %016"PRIx64"\n",
-           READ_SYSREG64(ID_AA64MMFR0_EL1), READ_SYSREG64(ID_AA64MMFR1_EL1));
-    printk("64-bit ISA Features:  %016"PRIx64" %016"PRIx64"\n",
-           READ_SYSREG64(ID_AA64ISAR0_EL1), READ_SYSREG64(ID_AA64ISAR1_EL1));
+    printk("64-bit Execution:\n");
+    printk("  Processor Features: %016"PRIx64" %016"PRIx64"\n",
+           boot_cpu_data.pfr64.bits[0], boot_cpu_data.pfr64.bits[1]);
+    printk("    Exception Levels: EL3:%s EL2:%s EL1:%s EL0:%s\n",
+           cpu_has_el3_32 ? "64+32" : cpu_has_el3_64 ? "64" : "No",
+           cpu_has_el2_32 ? "64+32" : cpu_has_el2_64 ? "64" : "No",
+           cpu_has_el1_32 ? "64+32" : cpu_has_el1_64 ? "64" : "No",
+           cpu_has_el0_32 ? "64+32" : cpu_has_el0_64 ? "64" : "No");
+    printk("    Extensions:%s%s\n",
+           cpu_has_fp ? " FloatingPoint" : "",
+           cpu_has_simd ? " AdvancedSIMD" : "");
+
+    printk("  Debug Features: %016"PRIx64" %016"PRIx64"\n",
+           boot_cpu_data.dbg64.bits[0], boot_cpu_data.dbg64.bits[1]);
+    printk("  Auxiliary Features: %016"PRIx64" %016"PRIx64"\n",
+           boot_cpu_data.aux64.bits[0], boot_cpu_data.aux64.bits[1]);
+    printk("  Memory Model Features: %016"PRIx64" %016"PRIx64"\n",
+           boot_cpu_data.mm64.bits[0], boot_cpu_data.mm64.bits[1]);
+    printk("  ISA Features:  %016"PRIx64" %016"PRIx64"\n",
+           boot_cpu_data.isa64.bits[0], boot_cpu_data.isa64.bits[1]);
 #endif
+
     /*
      * On AArch64 these refer to the capabilities when running in
      * AArch32 mode.
      */
-    printk("32-bit Processor Features: %08x %08x\n",
-           READ_SYSREG32(ID_PFR0_EL1), READ_SYSREG32(ID_PFR1_EL1));
-    printk("32-bit Debug Features: %08x\n", READ_SYSREG32(ID_DFR0_EL1));
-    printk("32-bit Auxiliary Features: %08x\n", READ_SYSREG32(ID_AFR0_EL1));
-    printk("32-bit Memory Model Features: %08x %08x %08x %08x\n",
-           READ_SYSREG32(ID_MMFR0_EL1), READ_SYSREG32(ID_MMFR1_EL1),
-           READ_SYSREG32(ID_MMFR2_EL1), READ_SYSREG32(ID_MMFR3_EL1));
-    printk("32-bit ISA Features: %08x %08x %08x %08x %08x %08x\n",
-           READ_SYSREG32(ID_ISAR0_EL1), READ_SYSREG32(ID_ISAR1_EL1),
-           READ_SYSREG32(ID_ISAR2_EL1), READ_SYSREG32(ID_ISAR3_EL1),
-           READ_SYSREG32(ID_ISAR4_EL1), READ_SYSREG32(ID_ISAR5_EL1));
-
+    if ( cpu_has_aarch32 )
+    {
+        printk("32-bit Execution:\n");
+        printk("  Processor Features: %08"PRIx32":%08"PRIx32"\n",
+               boot_cpu_data.pfr32.bits[0], boot_cpu_data.pfr32.bits[1]);
+        printk("    Instruction Sets:%s%s%s%s%s\n",
+               cpu_has_aarch32 ? " AArch32" : "",
+               cpu_has_thumb ? " Thumb" : "",
+               cpu_has_thumb2 ? " Thumb-2" : "",
+               cpu_has_thumbee ? " ThumbEE" : "",
+               cpu_has_jazelle ? " Jazelle" : "");
+        printk("    Extensions:%s%s\n",
+               cpu_has_gentimer ? " GenericTimer" : "",
+               cpu_has_security ? " Security" : "");
+
+        printk("  Debug Features: %08"PRIx32"\n",
+               boot_cpu_data.dbg32.bits[0]);
+        printk("  Auxiliary Features: %08"PRIx32"\n",
+               boot_cpu_data.aux32.bits[0]);
+        printk("  Memory Model Features: "
+               "%08"PRIx32" %08"PRIx32" %08"PRIx32" %08"PRIx32"\n",
+               boot_cpu_data.mm32.bits[0], boot_cpu_data.mm32.bits[1],
+               boot_cpu_data.mm32.bits[2], boot_cpu_data.mm32.bits[3]);
+        printk(" ISA Features: %08x %08x %08x %08x %08x %08x\n",
+               boot_cpu_data.isa32.bits[0], boot_cpu_data.isa32.bits[1],
+               boot_cpu_data.isa32.bits[2], boot_cpu_data.isa32.bits[3],
+               boot_cpu_data.isa32.bits[4], boot_cpu_data.isa32.bits[5]);
+    }
+    else
+    {
+        printk("32-bit Execution: Unsupported\n");
+    }
 }
 
 void __init discard_initial_modules(void)
@@ -379,6 +434,8 @@ void __init start_xen(unsigned long boot_phys_offset,
     console_init_preirq();
 #endif
 
+    processor_id();
+
     init_xen_time();
 
     gic_init();
@@ -400,8 +457,6 @@ void __init start_xen(unsigned long boot_phys_offset,
      */
     WRITE_SYSREG32(0x80002558, VTCR_EL2); isb();
 
-    processor_id();
-
     enable_vfp();
 
     softirq_init();
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index 75ee8a9..b2af42e 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -38,6 +38,8 @@ EXPORT_SYMBOL(cpu_online_map);
 cpumask_t cpu_possible_map;
 EXPORT_SYMBOL(cpu_possible_map);
 
+struct cpuinfo_arm cpu_data[NR_CPUS];
+
 /* Fake one node for now. See also include/asm-arm/numa.h */
 nodemask_t __read_mostly node_online_map = { { [0] = 1UL } };
 
@@ -136,11 +138,16 @@ void __cpuinit start_secondary(unsigned long 
boot_phys_offset,
                                unsigned long fdt_paddr,
                                unsigned long cpuid)
 {
+    struct cpuinfo_arm *c = cpu_data + cpuid;
+
     memset(get_cpu_info(), 0, sizeof (struct cpu_info));
 
     /* TODO: handle boards where CPUIDs are not contiguous */
     set_processor_id(cpuid);
 
+    *c = boot_cpu_data;
+    identify_cpu(c);
+
     /* Setup Hyp vector base */
     WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
 
diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c
index c53d79e..82f69d2 100644
--- a/xen/arch/arm/time.c
+++ b/xen/arch/arm/time.c
@@ -31,6 +31,7 @@
 #include <asm/system.h>
 #include <asm/time.h>
 #include <asm/gic.h>
+#include <asm/cpufeature.h>
 
 /*
  * Unfortunately the hypervisor timer interrupt appears to be buggy in
@@ -90,10 +91,8 @@ static uint32_t calibrate_timer(void)
 int __init init_xen_time(void)
 {
     /* Check that this CPU supports the Generic Timer interface */
-#if defined(CONFIG_ARM_32)
-    if ( (READ_CP32(ID_PFR1) & ID_PFR1_GT_MASK) != ID_PFR1_GT_v1 )
+    if ( !cpu_has_gentimer )
         panic("CPU does not support the Generic Timer v1 interface.\n");
-#endif
 
     cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000;
     boot_count = READ_SYSREG64(CNTPCT_EL0);
diff --git a/xen/include/asm-arm/cpregs.h b/xen/include/asm-arm/cpregs.h
index 17ac1e9..f08d59a 100644
--- a/xen/include/asm-arm/cpregs.h
+++ b/xen/include/asm-arm/cpregs.h
@@ -265,10 +265,14 @@
 #define ID_PFR0_EL1             ID_PFR0
 #define ID_PFR1_EL1             ID_PFR1
 #define IFSR32_EL2              IFSR
+#define MIDR_EL1                MIDR
+#define MPIDR_EL1               MPIDR
 #define PAR_EL1                 PAR
 #define SCTLR_EL1               SCTLR
 #define SCTLR_EL2               HSCTLR
 #define TCR_EL1                 TTBCR
+#define TEECR32_EL1             TEECR
+#define TEEHBR32_EL1            TEEHBR
 #define TPIDRRO_EL0             TPIDRURO
 #define TPIDR_EL0               TPIDRURW
 #define TPIDR_EL1               TPIDRPRW
@@ -278,13 +282,10 @@
 #define TTBR1_EL1               TTBR1
 #define VBAR_EL1                VBAR
 #define VBAR_EL2                HVBAR
+#define VMPIDR_EL2              VMPIDR
+#define VPIDR_EL2               VPIDR
 #define VTCR_EL2                VTCR
 #define VTTBR_EL2               VTTBR
-#define MIDR_EL1                MIDR
-#define VPIDR_EL2               VPIDR
-#define MPIDR_EL1               MPIDR
-#define VMPIDR_EL2              VMPIDR
-
 #endif
 
 #endif
diff --git a/xen/include/asm-arm/cpufeature.h b/xen/include/asm-arm/cpufeature.h
new file mode 100644
index 0000000..e633239
--- /dev/null
+++ b/xen/include/asm-arm/cpufeature.h
@@ -0,0 +1,40 @@
+#ifndef __ASM_ARM_CPUFEATURE_H
+#define __ASM_ARM_CPUFEATURE_H
+
+#ifdef CONFIG_ARM_64
+#define cpu_feature64(c, feat)         ((c)->pfr64.feat)
+#define boot_cpu_feature64(feat)       (boot_cpu_data.pfr64.feat)
+
+#define cpu_has_el0_32    (boot_cpu_feature64(el0) == 2)
+#define cpu_has_el0_64    (boot_cpu_feature64(el0) >= 1)
+#define cpu_has_el1_32    (boot_cpu_feature64(el1) == 2)
+#define cpu_has_el1_64    (boot_cpu_feature64(el1) >= 1)
+#define cpu_has_el2_32    (boot_cpu_feature64(el2) == 2)
+#define cpu_has_el2_64    (boot_cpu_feature64(el2) >= 1)
+#define cpu_has_el3_32    (boot_cpu_feature64(el3) == 2)
+#define cpu_has_el3_64    (boot_cpu_feature64(el3) >= 1)
+#define cpu_has_fp        (boot_cpu_feature64(fp) == 0)
+#define cpu_has_simd      (boot_cpu_feature64(simd) == 0)
+#endif
+
+#define cpu_feature32(c, feat)         ((c)->pfr32.feat)
+#define boot_cpu_feature32(feat)       (boot_cpu_data.pfr32.feat)
+
+#define cpu_has_aarch32   (boot_cpu_feature32(arm) == 1)
+#define cpu_has_thumb     (boot_cpu_feature32(thumb) >= 1)
+#define cpu_has_thumb2    (boot_cpu_feature32(thumb) >= 3)
+#define cpu_has_jazelle   (boot_cpu_feature32(jazelle) >= 0)
+#define cpu_has_thumbee   (boot_cpu_feature32(thumbee) == 1)
+
+#define cpu_has_gentimer  (boot_cpu_feature32(gentimer) == 1)
+#define cpu_has_security  (boot_cpu_feature32(security) > 0)
+
+#endif
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 04518b3..bf9caff 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -57,6 +57,10 @@ struct arch_domain
     struct hvm_domain hvm_domain;
     xen_pfn_t *grant_table_gpfn;
 
+    /* Virtual CPUID */
+    uint32_t vpidr;
+    register_t vmpidr;
+
     struct {
         /*
          * Covers access to other members of this struct _except_ for
@@ -166,8 +170,12 @@ struct arch_vcpu
     register_t tpidr_el1;
     register_t tpidrro_el0;
 
+    uint32_t teecr, teehbr; /* ThumbEE, 32-bit guests only */
 #ifdef CONFIG_ARM_32
-    uint32_t teecr, teehbr;
+    /*
+     * ARMv8 only supports a trivial implementation on Jazelle when in AArch32
+     * mode and therefore has no extended control registers.
+     */
     uint32_t joscr, jmcr;
 #endif
 
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index c1d7d70..6fbe2fa 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -91,6 +91,123 @@
 #define HSR_EC_DATA_ABORT_HYP       0x25
 
 #ifndef __ASSEMBLY__
+
+#include <xen/types.h>
+
+struct cpuinfo_arm {
+    union {
+        uint32_t bits;
+        struct {
+            unsigned long revision:4;
+            unsigned long part_number:12;
+            unsigned long architecture:4;
+            unsigned long variant:4;
+            unsigned long implementer:8;
+        };
+    } midr;
+    union {
+        register_t bits;
+        struct {
+            unsigned long aff0:8;
+            unsigned long aff1:8;
+            unsigned long aff2:8;
+            unsigned long mt:1; /* Multi-thread, iff MP == 1 */
+            unsigned long __res0:5;
+            unsigned long up:1; /* UP system, iff MP == 1 */
+            unsigned long mp:1; /* MP extensions */
+
+#ifdef CONFIG_ARM_64
+            unsigned long aff3:8;
+            unsigned long __res1:24;
+#endif
+        };
+    } mpidr;
+
+#ifdef CONFIG_ARM_64
+    /* 64-bit CPUID registers. */
+    union {
+        uint64_t bits[2];
+        struct {
+            unsigned long el0:4;
+            unsigned long el1:4;
+            unsigned long el2:4;
+            unsigned long el3:4;
+            unsigned long fp:4;   /* Floating Point */
+            unsigned long simd:4; /* Advanced SIMD */
+            unsigned long __res0:8;
+
+            unsigned long __res1;
+        };
+    } pfr64;
+
+    struct {
+        uint64_t bits[2];
+    } dbg64;
+
+    struct {
+        uint64_t bits[2];
+    } aux64;
+
+    struct {
+        uint64_t bits[2];
+    } mm64;
+
+    struct {
+        uint64_t bits[2];
+    } isa64;
+
+#endif
+
+    /*
+     * 32-bit CPUID registers. On ARMv8 these describe the properties
+     * when running in 32-bit mode.
+     */
+    union {
+        uint32_t bits[2];
+        struct {
+            unsigned long arm:4;
+            unsigned long thumb:4;
+            unsigned long jazelle:4;
+            unsigned long thumbee:4;
+            unsigned long __res0:16;
+
+            unsigned long progmodel:4;
+            unsigned long security:4;
+            unsigned long mprofile:4;
+            unsigned long virt:4;
+            unsigned long gentimer:4;
+            unsigned long __res1:12;
+        };
+    } pfr32;
+
+    struct {
+        uint32_t bits[1];
+    } dbg32;
+
+    struct {
+        uint32_t bits[1];
+    } aux32;
+
+    struct {
+        uint32_t bits[4];
+    } mm32;
+
+    struct {
+        uint32_t bits[6];
+    } isa32;
+};
+
+/*
+ * capabilities of CPUs
+ */
+
+extern struct cpuinfo_arm boot_cpu_data;
+
+extern void identify_cpu(struct cpuinfo_arm *);
+
+extern struct cpuinfo_arm cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+
 union hsr {
     uint32_t bits;
     struct {
@@ -225,10 +342,6 @@ union hsr {
 #define CNTx_CTL_MASK     (1u<<1)  /* Mask IRQ */
 #define CNTx_CTL_PENDING  (1u<<2)  /* IRQ pending */
 
-/* CPUID bits */
-#define ID_PFR1_GT_MASK  0x000F0000  /* Generic Timer interface support */
-#define ID_PFR1_GT_v1    0x00010000
-
 #if defined(CONFIG_ARM_32)
 # include <asm/arm32/processor.h>
 #elif defined(CONFIG_ARM_64)
@@ -260,6 +373,10 @@ void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
 void vcpu_regs_user_to_hyp(struct vcpu *vcpu,
                            const struct vcpu_guest_core_regs *regs);
 
+struct cpuinfo_x86 {
+    uint32_t pfr32[2];
+};
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARM_PROCESSOR_H */
 /*
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.