]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-powerpc/processor.h
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfashe...
[linux-2.6-omap-h63xx.git] / include / asm-powerpc / processor.h
index 1f4765d6546fe0313b6bbc150ff38b509d6811ba..101ed87f7d844d832a7d37a41d91739ed8f0aeb1 100644 (file)
 
 #include <asm/reg.h>
 
+#ifdef CONFIG_VSX
+#define TS_FPRWIDTH 2
+#else
+#define TS_FPRWIDTH 1
+#endif
+
 #ifndef __ASSEMBLY__
 #include <linux/compiler.h>
 #include <asm/ptrace.h>
@@ -78,9 +84,14 @@ extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
 extern struct task_struct *last_task_used_altivec;
+extern struct task_struct *last_task_used_vsx;
 extern struct task_struct *last_task_used_spe;
 
 #ifdef CONFIG_PPC32
+
+#if CONFIG_TASK_SIZE > CONFIG_KERNEL_START
+#error User TASK_SIZE overlaps with KERNEL_START address
+#endif
 #define TASK_SIZE      (CONFIG_TASK_SIZE)
 
 /* This decides where the kernel will search for a free chunk of vm
@@ -113,12 +124,37 @@ extern struct task_struct *last_task_used_spe;
                TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 )
 #endif
 
+#ifdef __KERNEL__
+#ifdef __powerpc64__
+
+#define STACK_TOP_USER64 TASK_SIZE_USER64
+#define STACK_TOP_USER32 TASK_SIZE_USER32
+
+#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
+                  STACK_TOP_USER32 : STACK_TOP_USER64)
+
+#define STACK_TOP_MAX STACK_TOP_USER64
+
+#else /* __powerpc64__ */
+
+#define STACK_TOP TASK_SIZE
+#define STACK_TOP_MAX  STACK_TOP
+
+#endif /* __powerpc64__ */
+#endif /* __KERNEL__ */
+
 typedef struct {
        unsigned long seg;
 } mm_segment_t;
 
+#define TS_FPROFFSET 0
+#define TS_VSRLOWOFFSET 1
+#define TS_FPR(i) fpr[i][TS_FPROFFSET]
+
 struct thread_struct {
        unsigned long   ksp;            /* Kernel stack pointer */
+       unsigned long   ksp_limit;      /* if ksp <= ksp_limit stack overflow */
+
 #ifdef CONFIG_PPC64
        unsigned long   ksp_vsid;
 #endif
@@ -131,8 +167,9 @@ struct thread_struct {
        unsigned long   dbcr0;          /* debug control register values */
        unsigned long   dbcr1;
 #endif
-       double          fpr[32];        /* Complete floating point set */
-       struct {                        /* fpr ... fpscr must be contiguous */
+       /* FP and VSX 0-31 register set */
+       double          fpr[32][TS_FPRWIDTH];
+       struct {
 
                unsigned int pad;
                unsigned int val;       /* Floating point status */
@@ -152,6 +189,10 @@ struct thread_struct {
        unsigned long   vrsave;
        int             used_vr;        /* set if process has used altivec */
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_VSX
+       /* VSR status */
+       int             used_vsr;       /* set if process has used altivec */
+#endif /* CONFIG_VSX */
 #ifdef CONFIG_SPE
        unsigned long   evr[32];        /* upper 32-bits of SPE regs */
        u64             acc;            /* Accumulator */
@@ -163,11 +204,14 @@ struct thread_struct {
 #define ARCH_MIN_TASKALIGN 16
 
 #define INIT_SP                (sizeof(init_stack) + (unsigned long) &init_stack)
+#define INIT_SP_LIMIT \
+       (_ALIGN_UP(sizeof(init_thread_info), 16) + (unsigned long) &init_stack)
 
 
 #ifdef CONFIG_PPC32
 #define INIT_THREAD { \
        .ksp = INIT_SP, \
+       .ksp_limit = INIT_SP_LIMIT, \
        .fs = KERNEL_DS, \
        .pgdir = swapper_pg_dir, \
        .fpexc_mode = MSR_FE0 | MSR_FE1, \
@@ -175,9 +219,10 @@ struct thread_struct {
 #else
 #define INIT_THREAD  { \
        .ksp = INIT_SP, \
+       .ksp_limit = INIT_SP_LIMIT, \
        .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
        .fs = KERNEL_DS, \
-       .fpr = {0}, \
+       .fpr = {{0}}, \
        .fpscr = { .val = 0, }, \
        .fpexc_mode = 0, \
 }
@@ -189,6 +234,8 @@ struct thread_struct {
 #define thread_saved_pc(tsk)    \
         ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)
 
+#define task_pt_regs(tsk)      ((struct pt_regs *)(tsk)->thread.regs)
+
 unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->nip: 0)