* [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits
2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update " Peter Maydell
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Riku Voipio, patches
The ELF HWCAP bits for ARM features THUMBEE, NEON, VFPv3 and VFPv3D16 are
all off by one compared to the kernel definitions. Fix this discrepancy
and add in the missing CRUNCH bit which was the cause of the off-by-one
error. (We don't emulate any of the CPUs which have that weird hardware,
so it's otherwise uninteresting to us.)
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
linux-user/elfload.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d2380b6..6cfaa3a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -346,10 +346,11 @@ enum
ARM_HWCAP_ARM_EDSP = 1 << 7,
ARM_HWCAP_ARM_JAVA = 1 << 8,
ARM_HWCAP_ARM_IWMMXT = 1 << 9,
- ARM_HWCAP_ARM_THUMBEE = 1 << 10,
- ARM_HWCAP_ARM_NEON = 1 << 11,
- ARM_HWCAP_ARM_VFPv3 = 1 << 12,
- ARM_HWCAP_ARM_VFPv3D16 = 1 << 13,
+ ARM_HWCAP_ARM_CRUNCH = 1 << 10,
+ ARM_HWCAP_ARM_THUMBEE = 1 << 11,
+ ARM_HWCAP_ARM_NEON = 1 << 12,
+ ARM_HWCAP_ARM_VFPv3 = 1 << 13,
+ ARM_HWCAP_ARM_VFPv3D16 = 1 << 14,
};
#ifndef TARGET_AARCH64
--
1.9.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update ARM HWCAP bits
2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32 Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags Peter Maydell
3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Riku Voipio, patches
The kernel has added support for a number of new ARM HWCAP bits;
add them to QEMU, including support for setting them where we have
a corresponding CPU feature bit.
We were also incorrectly setting the VFPv3D16 HWCAP -- this means
"only 16 D registers", not "supports 16-bit floating point format";
since QEMU always has 32 D registers for VFPv3, we can just remove
the line that incorrectly set this bit.
The kernel does not set the HWCAP_FPA even if it is providing FPA
emulation via nwfpe, so don't set this bit in QEMU either.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
---
linux-user/elfload.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 6cfaa3a..0449b29 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -351,6 +351,13 @@ enum
ARM_HWCAP_ARM_NEON = 1 << 12,
ARM_HWCAP_ARM_VFPv3 = 1 << 13,
ARM_HWCAP_ARM_VFPv3D16 = 1 << 14,
+ ARM_HWCAP_ARM_TLS = 1 << 15,
+ ARM_HWCAP_ARM_VFPv4 = 1 << 16,
+ ARM_HWCAP_ARM_IDIVA = 1 << 17,
+ ARM_HWCAP_ARM_IDIVT = 1 << 18,
+ ARM_HWCAP_ARM_VFPD32 = 1 << 19,
+ ARM_HWCAP_ARM_LPAE = 1 << 20,
+ ARM_HWCAP_ARM_EVTSTRM = 1 << 21,
};
#ifndef TARGET_AARCH64
@@ -428,17 +435,28 @@ static uint32_t get_elf_hwcap(void)
hwcaps |= ARM_HWCAP_ARM_HALF;
hwcaps |= ARM_HWCAP_ARM_THUMB;
hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
- hwcaps |= ARM_HWCAP_ARM_FPA;
/* probe for the extra features */
#define GET_FEATURE(feat, hwcap) \
do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+ /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
+ GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
- GET_FEATURE(ARM_FEATURE_VFP_FP16, ARM_HWCAP_ARM_VFPv3D16);
+ GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
+ GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
+ GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
+ GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
+ /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
+ * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
+ * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
+ * to our VFP_FP16 feature bit.
+ */
+ GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
+ GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
#undef GET_FEATURE
return hwcaps;
--
1.9.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32
2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update " Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags Peter Maydell
3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Riku Voipio, patches
The ARM target-specific code in elfload.c was incorrectly allowing
the 64-bit ARM target to use most of the existing 32-bit definitions:
most noticably this meant that our HWCAP bits passed to the guest
were wrong, and register handling when dumping core was totally
broken. Fix this by properly separating the 64 and 32 bit code,
since they have more differences than similarities.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
---
linux-user/elfload.c | 86 ++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 73 insertions(+), 13 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0449b29..e1ff346 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -267,17 +267,15 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#ifdef TARGET_ARM
+#ifndef TARGET_AARCH64
+/* 32 bit ARM definitions */
+
#define ELF_START_MMAP 0x80000000
#define elf_check_arch(x) ((x) == ELF_MACHINE)
#define ELF_ARCH ELF_MACHINE
-
-#ifdef TARGET_AARCH64
-#define ELF_CLASS ELFCLASS64
-#else
#define ELF_CLASS ELFCLASS32
-#endif
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
@@ -285,10 +283,6 @@ static inline void init_thread(struct target_pt_regs *regs,
abi_long stack = infop->start_stack;
memset(regs, 0, sizeof(*regs));
-#ifdef TARGET_AARCH64
- regs->pc = infop->entry & ~0x3ULL;
- regs->sp = stack;
-#else
regs->ARM_cpsr = 0x10;
if (infop->entry & 1)
regs->ARM_cpsr |= CPSR_T;
@@ -302,7 +296,6 @@ static inline void init_thread(struct target_pt_regs *regs,
/* For uClinux PIC binaries. */
/* XXX: Linux does this only on ARM with no MMU (do we care ?) */
regs->ARM_r10 = infop->start_data;
-#endif
}
#define ELF_NREG 18
@@ -360,7 +353,6 @@ enum
ARM_HWCAP_ARM_EVTSTRM = 1 << 21,
};
-#ifndef TARGET_AARCH64
/* The commpage only exists for 32 bit kernels */
#define TARGET_HAS_VALIDATE_GUEST_SPACE
@@ -422,7 +414,6 @@ static int validate_guest_space(unsigned long guest_base,
return 1; /* All good */
}
-#endif
#define ELF_HWCAP get_elf_hwcap()
@@ -462,7 +453,76 @@ static uint32_t get_elf_hwcap(void)
return hwcaps;
}
-#endif
+#else
+/* 64 bit ARM definitions */
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ((x) == ELF_MACHINE)
+
+#define ELF_ARCH ELF_MACHINE
+#define ELF_CLASS ELFCLASS64
+#define ELF_PLATFORM "aarch64"
+
+static inline void init_thread(struct target_pt_regs *regs,
+ struct image_info *infop)
+{
+ abi_long stack = infop->start_stack;
+ memset(regs, 0, sizeof(*regs));
+
+ regs->pc = infop->entry & ~0x3ULL;
+ regs->sp = stack;
+}
+
+#define ELF_NREG 34
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+ const CPUARMState *env)
+{
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ (*regs)[i] = tswapreg(env->xregs[i]);
+ }
+ (*regs)[32] = tswapreg(env->pc);
+ (*regs)[33] = tswapreg(pstate_read((CPUARMState *)env));
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+enum {
+ ARM_HWCAP_A64_FP = 1 << 0,
+ ARM_HWCAP_A64_ASIMD = 1 << 1,
+ ARM_HWCAP_A64_EVTSTRM = 1 << 2,
+ ARM_HWCAP_A64_AES = 1 << 3,
+ ARM_HWCAP_A64_PMULL = 1 << 4,
+ ARM_HWCAP_A64_SHA1 = 1 << 5,
+ ARM_HWCAP_A64_SHA2 = 1 << 6,
+ ARM_HWCAP_A64_CRC32 = 1 << 7,
+};
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
+ uint32_t hwcaps = 0;
+
+ hwcaps |= ARM_HWCAP_A64_FP;
+ hwcaps |= ARM_HWCAP_A64_ASIMD;
+
+ /* probe for the extra features */
+#define GET_FEATURE(feat, hwcap) \
+ do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+ GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_PMULL);
+#undef GET_FEATURE
+
+ return hwcaps;
+}
+
+#endif /* not TARGET_AARCH64 */
+#endif /* TARGET_ARM */
#ifdef TARGET_UNICORE32
--
1.9.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags
2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
` (2 preceding siblings ...)
2014-05-02 13:45 ` [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32 Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
To: qemu-devel; +Cc: Riku Voipio, patches
The ARM kernel has chosen to spill into the HWCAP2 ELF feature bit flags
early, even though it hasn't yet exhausted all 32 bits of the HWCAP word.
Add support for setting this in the same way we do for HWCAP.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/elf.h | 1 +
linux-user/elfload.c | 30 +++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/include/elf.h b/include/elf.h
index 667af6f..1599ab2 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -254,6 +254,7 @@ typedef int64_t Elf64_Sxword;
#define AT_SECURE 23 /* boolean, was exec suid-like? */
#define AT_BASE_PLATFORM 24 /* string identifying real platforms */
#define AT_RANDOM 25 /* address of 16 random bytes */
+#define AT_HWCAP2 26 /* extension of AT_HWCAP */
#define AT_EXECFN 31 /* filename of the executable */
#define AT_SYSINFO 32 /* address of kernel entry point */
#define AT_SYSINFO_EHDR 33 /* address of kernel vdso */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e1ff346..5db67cf 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -20,6 +20,7 @@
#undef ARCH_DLINFO
#undef ELF_PLATFORM
#undef ELF_HWCAP
+#undef ELF_HWCAP2
#undef ELF_CLASS
#undef ELF_DATA
#undef ELF_ARCH
@@ -353,6 +354,14 @@ enum
ARM_HWCAP_ARM_EVTSTRM = 1 << 21,
};
+enum {
+ ARM_HWCAP2_ARM_AES = 1 << 0,
+ ARM_HWCAP2_ARM_PMULL = 1 << 1,
+ ARM_HWCAP2_ARM_SHA1 = 1 << 2,
+ ARM_HWCAP2_ARM_SHA2 = 1 << 3,
+ ARM_HWCAP2_ARM_CRC32 = 1 << 4,
+};
+
/* The commpage only exists for 32 bit kernels */
#define TARGET_HAS_VALIDATE_GUEST_SPACE
@@ -416,6 +425,7 @@ static int validate_guest_space(unsigned long guest_base,
}
#define ELF_HWCAP get_elf_hwcap()
+#define ELF_HWCAP2 get_elf_hwcap2()
static uint32_t get_elf_hwcap(void)
{
@@ -448,11 +458,22 @@ static uint32_t get_elf_hwcap(void)
*/
GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
-#undef GET_FEATURE
return hwcaps;
}
+static uint32_t get_elf_hwcap2(void)
+{
+ ARMCPU *cpu = ARM_CPU(thread_cpu);
+ uint32_t hwcaps = 0;
+
+ GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP2_ARM_AES);
+ GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP2_ARM_CRC32);
+ return hwcaps;
+}
+
+#undef GET_FEATURE
+
#else
/* 64 bit ARM definitions */
#define ELF_START_MMAP 0x80000000
@@ -1486,6 +1507,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
#ifdef DLINFO_ARCH_ITEMS
size += DLINFO_ARCH_ITEMS * 2;
#endif
+#ifdef ELF_HWCAP2
+ size += 2;
+#endif
size += envc + argc + 2;
size += 1; /* argc itself */
size *= n;
@@ -1519,6 +1543,10 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
+#ifdef ELF_HWCAP2
+ NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
+#endif
+
if (k_platform)
NEW_AUX_ENT(AT_PLATFORM, u_platform);
#ifdef ARCH_DLINFO
--
1.9.2
^ permalink raw reply related [flat|nested] 5+ messages in thread