MIPS: Use per-mm page to execute branch delay slot instructions
[cascardo/linux.git] / arch / mips / include / asm / processor.h
index 041153f..0d36c87 100644 (file)
 #ifndef _ASM_PROCESSOR_H
 #define _ASM_PROCESSOR_H
 
+#include <linux/atomic.h>
 #include <linux/cpumask.h>
 #include <linux/threads.h>
 
 #include <asm/cachectl.h>
 #include <asm/cpu.h>
 #include <asm/cpu-info.h>
+#include <asm/dsemul.h>
 #include <asm/mipsregs.h>
 #include <asm/prefetch.h>
 
@@ -63,7 +65,11 @@ extern unsigned int vced_count, vcei_count;
  * 8192EB ...
  */
 #define TASK_SIZE32    0x7fff8000UL
-#define TASK_SIZE64    0x10000000000UL
+#ifdef CONFIG_MIPS_VA_BITS_48
+#define TASK_SIZE64     (0x1UL << ((cpu_data[0].vmbits>48)?48:cpu_data[0].vmbits))
+#else
+#define TASK_SIZE64     0x10000000000UL
+#endif
 #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
 #define STACK_TOP_MAX  TASK_SIZE64
 
@@ -74,7 +80,11 @@ extern unsigned int vced_count, vcei_count;
 
 #endif
 
-#define STACK_TOP      (TASK_SIZE & PAGE_MASK)
+/*
+ * One page above the stack is used for branch delay slot "emulation".
+ * See dsemul.c for details.
+ */
+#define STACK_TOP      ((TASK_SIZE & PAGE_MASK) - PAGE_SIZE)
 
 /*
  * This decides where the kernel will search for a free chunk of vm
@@ -252,6 +262,12 @@ struct thread_struct {
 
        /* Saved fpu/fpu emulator stuff. */
        struct mips_fpu_struct fpu FPU_ALIGN;
+       /* Assigned branch delay slot 'emulation' frame */
+       atomic_t bd_emu_frame;
+       /* PC of the branch from a branch delay slot 'emulation' */
+       unsigned long bd_emu_branch_pc;
+       /* PC to continue from following a branch delay slot 'emulation' */
+       unsigned long bd_emu_cont_pc;
 #ifdef CONFIG_MIPS_MT_FPAFF
        /* Emulated instruction count */
        unsigned long emulated_fp;
@@ -319,6 +335,10 @@ struct thread_struct {
         * FPU affinity state (null if not FPAFF)               \
         */                                                     \
        FPAFF_INIT                                              \
+       /* Delay slot emulation */                              \
+       .bd_emu_frame = ATOMIC_INIT(BD_EMUFRAME_NONE),          \
+       .bd_emu_branch_pc = 0,                                  \
+       .bd_emu_cont_pc = 0,                                    \
        /*                                                      \
         * Saved DSP stuff                                      \
         */                                                     \
@@ -355,6 +375,10 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);
  */
 extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp);
 
+static inline void flush_thread(void)
+{
+}
+
 unsigned long get_wchan(struct task_struct *p);
 
 #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \