[PATCH 28/36] AArch64: Floating point and SIMD

2012-07-06 Thread Catalin Marinas
This patch adds support for FP/ASIMD register bank saving and restoring
during context switch and FP exception handling to generate SIGFPE.
There are 32 128-bit registers and the context switching is currently
done non-lazily. Benchmarks on real hardware are required before
implementing lazy FP state saving/restoring.

Signed-off-by: Will Deacon 
Signed-off-by: Catalin Marinas 
---
 arch/aarch64/include/asm/fpsimd.h  |   65 ++
 arch/aarch64/kernel/entry-fpsimd.S |   81 +++
 arch/aarch64/kernel/fpsimd.c   |  107 
 3 files changed, 253 insertions(+), 0 deletions(-)
 create mode 100644 arch/aarch64/include/asm/fpsimd.h
 create mode 100644 arch/aarch64/kernel/entry-fpsimd.S
 create mode 100644 arch/aarch64/kernel/fpsimd.c

diff --git a/arch/aarch64/include/asm/fpsimd.h 
b/arch/aarch64/include/asm/fpsimd.h
new file mode 100644
index 000..1c303a6
--- /dev/null
+++ b/arch/aarch64/include/asm/fpsimd.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_FP_H
+#define __ASM_FP_H
+
+#include 
+
+#ifndef __ASSEMBLY__
+
+/*
+ * FP/SIMD storage area has:
+ *  - FPSR and FPCR
+ *  - 32 128-bit data registers
+ *
+ * Note that user_fp forms a prefix of this structure, which is relied
+ * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
+ * form a prefix of struct fpsimd_state.
+ */
+struct fpsimd_state {
+   union {
+   struct user_fpsimd_state user_fpsimd;
+   struct {
+   __uint128_t vregs[32];
+   u32 fpsr;
+   u32 fpcr;
+   };
+   };
+};
+
+#if defined(__KERNEL__) && defined(CONFIG_AARCH32_EMULATION)
+/* Masks for extracting the FPSR and FPCR from the FPSCR */
+#define VFP_FPSCR_STAT_MASK0xf89f
+#define VFP_FPSCR_CTRL_MASK0x07f79f00
+/*
+ * The VFP state has 32x64-bit registers and a single 32-bit
+ * control/status register.
+ */
+#define VFP_STATE_SIZE ((32 * 8) + 4)
+#endif
+
+struct task_struct;
+
+extern void fpsimd_save_state(struct fpsimd_state *state);
+extern void fpsimd_load_state(struct fpsimd_state *state);
+
+extern void fpsimd_thread_switch(struct task_struct *next);
+extern void fpsimd_flush_thread(void);
+
+#endif
+
+#endif
diff --git a/arch/aarch64/kernel/entry-fpsimd.S 
b/arch/aarch64/kernel/entry-fpsimd.S
new file mode 100644
index 000..8fea5b3
--- /dev/null
+++ b/arch/aarch64/kernel/entry-fpsimd.S
@@ -0,0 +1,81 @@
+/*
+ * FP/SIMD state saving and restoring
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ * Author: Catalin Marinas 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include 
+
+#include 
+
+/*
+ * Save the FP registers.
+ *
+ * x0 - pointer to struct fpsimd_state
+ */
+ENTRY(fpsimd_save_state)
+   stp q0, q1, [x0, #16 * 0]
+   stp q2, q3, [x0, #16 * 2]
+   stp q4, q5, [x0, #16 * 4]
+   stp q6, q7, [x0, #16 * 6]
+   stp q8, q9, [x0, #16 * 8]
+   stp q10, q11, [x0, #16 * 10]
+   stp q12, q13, [x0, #16 * 12]
+   stp q14, q15, [x0, #16 * 14]
+   stp q16, q17, [x0, #16 * 16]
+   stp q18, q19, [x0, #16 * 18]
+   stp q20, q21, [x0, #16 * 20]
+   stp q22, q23, [x0, #16 * 22]
+   stp q24, q25, [x0, #16 * 24]
+   stp q26, q27, [x0, #16 * 26]
+   stp q28, q29, [x0, #16 * 28]
+   stp q30, q31, [x0, #16 * 30]!
+   mrs x8, fpsr
+   str w8, [x0, #16 * 2]
+   mrs x8, fpcr
+   str w8, [x0, #16 * 2 + 4]
+   ret
+ENDPROC(fpsimd_save_state)
+
+/*
+ * Load the FP registers.
+ *
+ * x0 - pointer to struct fpsimd_state
+ */

[PATCH 28/36] AArch64: Floating point and SIMD

2012-07-06 Thread Catalin Marinas
This patch adds support for FP/ASIMD register bank saving and restoring
during context switch and FP exception handling to generate SIGFPE.
There are 32 128-bit registers and the context switching is currently
done non-lazily. Benchmarks on real hardware are required before
implementing lazy FP state saving/restoring.

Signed-off-by: Will Deacon will.dea...@arm.com
Signed-off-by: Catalin Marinas catalin.mari...@arm.com
---
 arch/aarch64/include/asm/fpsimd.h  |   65 ++
 arch/aarch64/kernel/entry-fpsimd.S |   81 +++
 arch/aarch64/kernel/fpsimd.c   |  107 
 3 files changed, 253 insertions(+), 0 deletions(-)
 create mode 100644 arch/aarch64/include/asm/fpsimd.h
 create mode 100644 arch/aarch64/kernel/entry-fpsimd.S
 create mode 100644 arch/aarch64/kernel/fpsimd.c

diff --git a/arch/aarch64/include/asm/fpsimd.h 
b/arch/aarch64/include/asm/fpsimd.h
new file mode 100644
index 000..1c303a6
--- /dev/null
+++ b/arch/aarch64/include/asm/fpsimd.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef __ASM_FP_H
+#define __ASM_FP_H
+
+#include asm/ptrace.h
+
+#ifndef __ASSEMBLY__
+
+/*
+ * FP/SIMD storage area has:
+ *  - FPSR and FPCR
+ *  - 32 128-bit data registers
+ *
+ * Note that user_fp forms a prefix of this structure, which is relied
+ * upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
+ * form a prefix of struct fpsimd_state.
+ */
+struct fpsimd_state {
+   union {
+   struct user_fpsimd_state user_fpsimd;
+   struct {
+   __uint128_t vregs[32];
+   u32 fpsr;
+   u32 fpcr;
+   };
+   };
+};
+
+#if defined(__KERNEL__)  defined(CONFIG_AARCH32_EMULATION)
+/* Masks for extracting the FPSR and FPCR from the FPSCR */
+#define VFP_FPSCR_STAT_MASK0xf89f
+#define VFP_FPSCR_CTRL_MASK0x07f79f00
+/*
+ * The VFP state has 32x64-bit registers and a single 32-bit
+ * control/status register.
+ */
+#define VFP_STATE_SIZE ((32 * 8) + 4)
+#endif
+
+struct task_struct;
+
+extern void fpsimd_save_state(struct fpsimd_state *state);
+extern void fpsimd_load_state(struct fpsimd_state *state);
+
+extern void fpsimd_thread_switch(struct task_struct *next);
+extern void fpsimd_flush_thread(void);
+
+#endif
+
+#endif
diff --git a/arch/aarch64/kernel/entry-fpsimd.S 
b/arch/aarch64/kernel/entry-fpsimd.S
new file mode 100644
index 000..8fea5b3
--- /dev/null
+++ b/arch/aarch64/kernel/entry-fpsimd.S
@@ -0,0 +1,81 @@
+/*
+ * FP/SIMD state saving and restoring
+ *
+ * Copyright (C) 2012 ARM Ltd.
+ * Author: Catalin Marinas catalin.mari...@arm.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include linux/linkage.h
+
+#include asm/assembler.h
+
+/*
+ * Save the FP registers.
+ *
+ * x0 - pointer to struct fpsimd_state
+ */
+ENTRY(fpsimd_save_state)
+   stp q0, q1, [x0, #16 * 0]
+   stp q2, q3, [x0, #16 * 2]
+   stp q4, q5, [x0, #16 * 4]
+   stp q6, q7, [x0, #16 * 6]
+   stp q8, q9, [x0, #16 * 8]
+   stp q10, q11, [x0, #16 * 10]
+   stp q12, q13, [x0, #16 * 12]
+   stp q14, q15, [x0, #16 * 14]
+   stp q16, q17, [x0, #16 * 16]
+   stp q18, q19, [x0, #16 * 18]
+   stp q20, q21, [x0, #16 * 20]
+   stp q22, q23, [x0, #16 * 22]
+   stp q24, q25, [x0, #16 * 24]
+   stp q26, q27, [x0, #16 * 26]
+   stp q28, q29, [x0, #16 * 28]
+   stp q30, q31, [x0, #16 * 30]!
+   mrs x8, fpsr
+   str w8, [x0, #16 * 2]
+   mrs x8, fpcr
+   str w8, [x0, #16 * 2 + 4]
+   ret
+ENDPROC(fpsimd_save_state)