|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] xen: arm: implement cpuinfo
On Thu, 2013-02-14 at 16:47 +0000, Ian Campbell wrote:
> You can also run 32-bit on the V8 model (using -C
> cluster.cpu0.CONFIG64=0) if you comment out the ThumbEE in
> ctxt_switch_from and ctxt_switch_to (making this dynamic is on my TODO
> list).
8<-----------------------------------------------
>From e45c4e4f45e72e404052629c619af8810dadd76f Mon Sep 17 00:00:00 2001
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Fri, 15 Feb 2013 10:30:48 +0000
Subject: [PATCH] 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>
Cc: 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 | 121 ++++++++++++++++++++++++++++++++++++-
10 files changed, 364 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 7ff67c7..a43e7c9 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -2,6 +2,7 @@ subdir-$(arm32) += arm32
subdir-$(arm64) += arm64
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 494bed6..de1d837 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_32x)
- /* 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_32x)
- /* 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 967a8d4..d13e45d 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)
@@ -393,6 +448,8 @@ void __init start_xen(unsigned long boot_phys_offset,
console_init_preirq();
#endif
+ processor_id();
+
init_xen_time();
gic_init();
@@ -416,8 +473,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 b18f137..cadf79f 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 ee92d8c..81d490d 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 908aad9..a72ca62 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 4a4bf2f..601e972 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 1072aa2..0515986 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)
--
1.7.2.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |