summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2002-05-29 18:06:54 +0100
committerRussell King <rmk@flint.arm.linux.org.uk>2002-05-29 18:06:54 +0100
commit415395e19fd197ce4f248902dba54f4065af547c (patch)
treee1c8c080ac83c3ca26aac461a444c8eb4ea6a18b /include
parentbaa522c86b6f08c9bdab5a966a8726a7a5f665c2 (diff)
[ARM] Context switch improvements
- We don't need to save the CPSR. - Rearrange thread_info members so we can pull the fields out of thread_info more efficiently. - Allocate a couple of extra words for CPU specific context saving (eg, for Xscale ACC registers) - Always leave 8 bytes free at the top of the kernel stack. This prevents the stack becoming completely empty when do_exit() is called from an exiting nfsd() thread, and causing the wrong pointer to be returned from current_thread_info()
Diffstat (limited to 'include')
-rw-r--r--include/asm-arm/proc-armo/processor.h22
-rw-r--r--include/asm-arm/proc-armv/processor.h24
-rw-r--r--include/asm-arm/thread_info.h53
3 files changed, 31 insertions, 68 deletions
diff --git a/include/asm-arm/proc-armo/processor.h b/include/asm-arm/proc-armo/processor.h
index abaccf51239f..675fe0f51592 100644
--- a/include/asm-arm/proc-armo/processor.h
+++ b/include/asm-arm/proc-armo/processor.h
@@ -20,27 +20,9 @@
#define __ASM_PROC_PROCESSOR_H
#include <linux/string.h>
-#include <asm/proc/ptrace.h>
#define KERNEL_STACK_SIZE 4096
-struct cpu_context_save {
- unsigned long r4;
- unsigned long r5;
- unsigned long r6;
- unsigned long r7;
- unsigned long r8;
- unsigned long r9;
- unsigned long sl;
- unsigned long fp;
- unsigned long pc;
-};
-
-static inline void init_pc_psr(struct cpu_context_save *s, void *fn)
-{
- s->pc = ((unsigned long)fn) | PSR_I_BIT | SVC26_MODE;
-}
-
typedef struct {
void (*put_byte)(void); /* Special calling convention */
void (*get_byte)(void); /* Special calling convention */
@@ -75,7 +57,7 @@ extern uaccess_t uaccess_user, uaccess_kernel;
regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
})
-#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
-#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
+#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
+#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1018])
#endif
diff --git a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h
index e9de5db23146..0e8c4bfee6dc 100644
--- a/include/asm-arm/proc-armv/processor.h
+++ b/include/asm-arm/proc-armv/processor.h
@@ -19,29 +19,9 @@
#define __ASM_PROC_PROCESSOR_H
#include <asm/proc/domain.h>
-#include <asm/proc/ptrace.h>
#define KERNEL_STACK_SIZE PAGE_SIZE
-struct cpu_context_save {
- unsigned long cpsr;
- unsigned long r4;
- unsigned long r5;
- unsigned long r6;
- unsigned long r7;
- unsigned long r8;
- unsigned long r9;
- unsigned long sl;
- unsigned long fp;
- unsigned long pc;
-};
-
-static inline void init_pc_psr(struct cpu_context_save *s, void *fn)
-{
- s->pc = (unsigned long)fn;
- s->cpsr = PSR_I_BIT | SVC_MODE;
-}
-
#define INIT_EXTRA_THREAD_INFO \
cpu_domain: domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
@@ -63,7 +43,7 @@ static inline void init_pc_psr(struct cpu_context_save *s, void *fn)
regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
})
-#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1021])
-#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
+#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
+#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1017])
#endif
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h
index 154a688c170f..ebed4a570599 100644
--- a/include/asm-arm/thread_info.h
+++ b/include/asm-arm/thread_info.h
@@ -22,20 +22,35 @@ struct exec_domain;
#include <asm/ptrace.h>
#include <asm/types.h>
-typedef unsigned long mm_segment_t; /* domain register */
+typedef unsigned long mm_segment_t;
+
+struct cpu_context_save {
+ __u32 r4;
+ __u32 r5;
+ __u32 r6;
+ __u32 r7;
+ __u32 r8;
+ __u32 r9;
+ __u32 sl;
+ __u32 fp;
+ __u32 sp;
+ __u32 pc;
+ __u32 extra[2]; /* Xscale 'acc' register, etc */
+};
/*
* low level task data that entry.S needs immediate access to.
+ * We assume cpu_context follows immedately after cpu_domain.
*/
struct thread_info {
unsigned long flags; /* low level flags */
__s32 preempt_count; /* 0 => preemptable, <0 => bug */
mm_segment_t addr_limit; /* address limit */
- __u32 cpu; /* cpu */
- struct cpu_context_save *cpu_context; /* cpu context */
- __u32 cpu_domain; /* cpu domain */
struct task_struct *task; /* main task structure */
struct exec_domain *exec_domain; /* execution domain */
+ __u32 cpu; /* cpu */
+ __u32 cpu_domain; /* cpu domain */
+ struct cpu_context_save cpu_context; /* cpu context */
union fp_state fpstate;
};
@@ -71,34 +86,20 @@ extern void free_thread_info(struct thread_info *);
#define get_thread_info(ti) get_task_struct((ti)->task)
#define put_thread_info(ti) put_task_struct((ti)->task)
-static inline unsigned long __thread_saved_pc(struct thread_info *thread)
-{
- struct cpu_context_save *context = thread->cpu_context;
-
- return context ? pc_pointer(context->pc) : 0;
-}
-
-static inline unsigned long __thread_saved_fp(struct thread_info *thread)
-{
- struct cpu_context_save *context = thread->cpu_context;
-
- return context ? context->fp : 0;
-}
-
-#define thread_saved_pc(tsk) __thread_saved_pc((tsk)->thread_info)
-#define thread_saved_fp(tsk) __thread_saved_fp((tsk)->thread_info)
+#define thread_saved_pc(tsk) (pc_pointer((tsk)->thread_info->cpu_context.pc))
+#define thread_saved_fp(tsk) ((tsk)->thread_info->cpu_context.fp)
#else /* !__ASSEMBLY__ */
#define TI_FLAGS 0
#define TI_PREEMPT 4
#define TI_ADDR_LIMIT 8
-#define TI_CPU 12
-#define TI_CPU_SAVE 16
-#define TI_CPU_DOMAIN 20
-#define TI_TASK 24
-#define TI_EXEC_DOMAIN 28
-#define TI_FPSTATE 32
+#define TI_TASK 12
+#define TI_EXEC_DOMAIN 16
+#define TI_CPU 20
+#define TI_CPU_DOMAIN 24
+#define TI_CPU_SAVE 28
+#define TI_FPSTATE 76
#endif