Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 1994 Waldorf GMBH
0007  * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
0008  * Copyright (C) 1996 Paul M. Antoine
0009  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
0010  */
0011 #ifndef _ASM_PROCESSOR_H
0012 #define _ASM_PROCESSOR_H
0013 
0014 #include <linux/atomic.h>
0015 #include <linux/cpumask.h>
0016 #include <linux/sizes.h>
0017 #include <linux/threads.h>
0018 
0019 #include <asm/cachectl.h>
0020 #include <asm/cpu.h>
0021 #include <asm/cpu-info.h>
0022 #include <asm/dsemul.h>
0023 #include <asm/mipsregs.h>
0024 #include <asm/prefetch.h>
0025 #include <asm/vdso/processor.h>
0026 
0027 /*
0028  * System setup and hardware flags..
0029  */
0030 
0031 extern unsigned int vced_count, vcei_count;
0032 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
0033 
0034 #ifdef CONFIG_32BIT
0035 /*
0036  * User space process size: 2GB. This is hardcoded into a few places,
0037  * so don't change it unless you know what you are doing.
0038  */
0039 #define TASK_SIZE   0x80000000UL
0040 
0041 #define STACK_TOP_MAX   TASK_SIZE
0042 
0043 #define TASK_IS_32BIT_ADDR 1
0044 
0045 #endif
0046 
0047 #ifdef CONFIG_64BIT
0048 /*
0049  * User space process size: 1TB. This is hardcoded into a few places,
0050  * so don't change it unless you know what you are doing.  TASK_SIZE
0051  * is limited to 1TB by the R4000 architecture; R10000 and better can
0052  * support 16TB; the architectural reserve for future expansion is
0053  * 8192EB ...
0054  */
0055 #define TASK_SIZE32 0x7fff8000UL
0056 #ifdef CONFIG_MIPS_VA_BITS_48
0057 #define TASK_SIZE64     (0x1UL << ((cpu_data[0].vmbits>48)?48:cpu_data[0].vmbits))
0058 #else
0059 #define TASK_SIZE64     0x10000000000UL
0060 #endif
0061 #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
0062 #define STACK_TOP_MAX   TASK_SIZE64
0063 
0064 #define TASK_SIZE_OF(tsk)                       \
0065     (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
0066 
0067 #define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
0068 
0069 #endif
0070 
0071 #define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_64M)
0072 
0073 extern unsigned long mips_stack_top(void);
0074 #define STACK_TOP       mips_stack_top()
0075 
0076 /*
0077  * This decides where the kernel will search for a free chunk of vm
0078  * space during mmap's.
0079  */
0080 #define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
0081 
0082 
0083 #define NUM_FPU_REGS    32
0084 
0085 #ifdef CONFIG_CPU_HAS_MSA
0086 # define FPU_REG_WIDTH  128
0087 #else
0088 # define FPU_REG_WIDTH  64
0089 #endif
0090 
0091 union fpureg {
0092     __u32   val32[FPU_REG_WIDTH / 32];
0093     __u64   val64[FPU_REG_WIDTH / 64];
0094 };
0095 
0096 #ifdef CONFIG_CPU_LITTLE_ENDIAN
0097 # define FPR_IDX(width, idx)    (idx)
0098 #else
0099 # define FPR_IDX(width, idx)    ((idx) ^ ((64 / (width)) - 1))
0100 #endif
0101 
0102 #define BUILD_FPR_ACCESS(width) \
0103 static inline u##width get_fpr##width(union fpureg *fpr, unsigned idx)  \
0104 {                                   \
0105     return fpr->val##width[FPR_IDX(width, idx)];            \
0106 }                                   \
0107                                     \
0108 static inline void set_fpr##width(union fpureg *fpr, unsigned idx,  \
0109                   u##width val)             \
0110 {                                   \
0111     fpr->val##width[FPR_IDX(width, idx)] = val;         \
0112 }
0113 
0114 BUILD_FPR_ACCESS(32)
0115 BUILD_FPR_ACCESS(64)
0116 
0117 /*
0118  * It would be nice to add some more fields for emulator statistics,
0119  * the additional information is private to the FPU emulator for now.
0120  * See arch/mips/include/asm/fpu_emulator.h.
0121  */
0122 
0123 struct mips_fpu_struct {
0124     union fpureg    fpr[NUM_FPU_REGS];
0125     unsigned int    fcr31;
0126     unsigned int    msacsr;
0127 };
0128 
0129 #define NUM_DSP_REGS   6
0130 
0131 typedef unsigned long dspreg_t;
0132 
0133 struct mips_dsp_state {
0134     dspreg_t    dspr[NUM_DSP_REGS];
0135     unsigned int    dspcontrol;
0136 };
0137 
0138 #define INIT_CPUMASK { \
0139     {0,} \
0140 }
0141 
0142 struct mips3264_watch_reg_state {
0143     /* The width of watchlo is 32 in a 32 bit kernel and 64 in a
0144        64 bit kernel.  We use unsigned long as it has the same
0145        property. */
0146     unsigned long watchlo[NUM_WATCH_REGS];
0147     /* Only the mask and IRW bits from watchhi. */
0148     u16 watchhi[NUM_WATCH_REGS];
0149 };
0150 
0151 union mips_watch_reg_state {
0152     struct mips3264_watch_reg_state mips3264;
0153 };
0154 
0155 #if defined(CONFIG_CPU_CAVIUM_OCTEON)
0156 
0157 struct octeon_cop2_state {
0158     /* DMFC2 rt, 0x0201 */
0159     unsigned long   cop2_crc_iv;
0160     /* DMFC2 rt, 0x0202 (Set with DMTC2 rt, 0x1202) */
0161     unsigned long   cop2_crc_length;
0162     /* DMFC2 rt, 0x0200 (set with DMTC2 rt, 0x4200) */
0163     unsigned long   cop2_crc_poly;
0164     /* DMFC2 rt, 0x0402; DMFC2 rt, 0x040A */
0165     unsigned long   cop2_llm_dat[2];
0166        /* DMFC2 rt, 0x0084 */
0167     unsigned long   cop2_3des_iv;
0168     /* DMFC2 rt, 0x0080; DMFC2 rt, 0x0081; DMFC2 rt, 0x0082 */
0169     unsigned long   cop2_3des_key[3];
0170     /* DMFC2 rt, 0x0088 (Set with DMTC2 rt, 0x0098) */
0171     unsigned long   cop2_3des_result;
0172     /* DMFC2 rt, 0x0111 (FIXME: Read Pass1 Errata) */
0173     unsigned long   cop2_aes_inp0;
0174     /* DMFC2 rt, 0x0102; DMFC2 rt, 0x0103 */
0175     unsigned long   cop2_aes_iv[2];
0176     /* DMFC2 rt, 0x0104; DMFC2 rt, 0x0105; DMFC2 rt, 0x0106; DMFC2
0177      * rt, 0x0107 */
0178     unsigned long   cop2_aes_key[4];
0179     /* DMFC2 rt, 0x0110 */
0180     unsigned long   cop2_aes_keylen;
0181     /* DMFC2 rt, 0x0100; DMFC2 rt, 0x0101 */
0182     unsigned long   cop2_aes_result[2];
0183     /* DMFC2 rt, 0x0240; DMFC2 rt, 0x0241; DMFC2 rt, 0x0242; DMFC2
0184      * rt, 0x0243; DMFC2 rt, 0x0244; DMFC2 rt, 0x0245; DMFC2 rt,
0185      * 0x0246; DMFC2 rt, 0x0247; DMFC2 rt, 0x0248; DMFC2 rt,
0186      * 0x0249; DMFC2 rt, 0x024A; DMFC2 rt, 0x024B; DMFC2 rt,
0187      * 0x024C; DMFC2 rt, 0x024D; DMFC2 rt, 0x024E - Pass2 */
0188     unsigned long   cop2_hsh_datw[15];
0189     /* DMFC2 rt, 0x0250; DMFC2 rt, 0x0251; DMFC2 rt, 0x0252; DMFC2
0190      * rt, 0x0253; DMFC2 rt, 0x0254; DMFC2 rt, 0x0255; DMFC2 rt,
0191      * 0x0256; DMFC2 rt, 0x0257 - Pass2 */
0192     unsigned long   cop2_hsh_ivw[8];
0193     /* DMFC2 rt, 0x0258; DMFC2 rt, 0x0259 - Pass2 */
0194     unsigned long   cop2_gfm_mult[2];
0195     /* DMFC2 rt, 0x025E - Pass2 */
0196     unsigned long   cop2_gfm_poly;
0197     /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
0198     unsigned long   cop2_gfm_result[2];
0199     /* DMFC2 rt, 0x24F, DMFC2 rt, 0x50, OCTEON III */
0200     unsigned long   cop2_sha3[2];
0201 };
0202 #define COP2_INIT                       \
0203     .cp2            = {0,},
0204 
0205 struct octeon_cvmseg_state {
0206     unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
0207                 [cpu_dcache_line_size() / sizeof(unsigned long)];
0208 };
0209 
0210 #else
0211 #define COP2_INIT
0212 #endif
0213 
0214 #ifdef CONFIG_CPU_HAS_MSA
0215 # define ARCH_MIN_TASKALIGN 16
0216 # define FPU_ALIGN      __aligned(16)
0217 #else
0218 # define ARCH_MIN_TASKALIGN 8
0219 # define FPU_ALIGN
0220 #endif
0221 
0222 struct mips_abi;
0223 
0224 /*
0225  * If you change thread_struct remember to change the #defines below too!
0226  */
0227 struct thread_struct {
0228     /* Saved main processor registers. */
0229     unsigned long reg16;
0230     unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23;
0231     unsigned long reg29, reg30, reg31;
0232 
0233     /* Saved cp0 stuff. */
0234     unsigned long cp0_status;
0235 
0236 #ifdef CONFIG_MIPS_FP_SUPPORT
0237     /* Saved fpu/fpu emulator stuff. */
0238     struct mips_fpu_struct fpu FPU_ALIGN;
0239     /* Assigned branch delay slot 'emulation' frame */
0240     atomic_t bd_emu_frame;
0241     /* PC of the branch from a branch delay slot 'emulation' */
0242     unsigned long bd_emu_branch_pc;
0243     /* PC to continue from following a branch delay slot 'emulation' */
0244     unsigned long bd_emu_cont_pc;
0245 #endif
0246 #ifdef CONFIG_MIPS_MT_FPAFF
0247     /* Emulated instruction count */
0248     unsigned long emulated_fp;
0249     /* Saved per-thread scheduler affinity mask */
0250     cpumask_t user_cpus_allowed;
0251 #endif /* CONFIG_MIPS_MT_FPAFF */
0252 
0253     /* Saved state of the DSP ASE, if available. */
0254     struct mips_dsp_state dsp;
0255 
0256     /* Saved watch register state, if available. */
0257     union mips_watch_reg_state watch;
0258 
0259     /* Other stuff associated with the thread. */
0260     unsigned long cp0_badvaddr; /* Last user fault */
0261     unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
0262     unsigned long error_code;
0263     unsigned long trap_nr;
0264 #ifdef CONFIG_CPU_CAVIUM_OCTEON
0265     struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
0266     struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
0267 #endif
0268     struct mips_abi *abi;
0269 };
0270 
0271 #ifdef CONFIG_MIPS_MT_FPAFF
0272 #define FPAFF_INIT                      \
0273     .emulated_fp            = 0,            \
0274     .user_cpus_allowed      = INIT_CPUMASK,
0275 #else
0276 #define FPAFF_INIT
0277 #endif /* CONFIG_MIPS_MT_FPAFF */
0278 
0279 #ifdef CONFIG_MIPS_FP_SUPPORT
0280 # define FPU_INIT                       \
0281     .fpu            = {             \
0282         .fpr        = {{{0,},},},           \
0283         .fcr31      = 0,                \
0284         .msacsr     = 0,                \
0285     },                          \
0286     /* Delay slot emulation */              \
0287     .bd_emu_frame = ATOMIC_INIT(BD_EMUFRAME_NONE),      \
0288     .bd_emu_branch_pc = 0,                  \
0289     .bd_emu_cont_pc = 0,
0290 #else
0291 # define FPU_INIT
0292 #endif
0293 
0294 #define INIT_THREAD  {                      \
0295     /*                          \
0296      * Saved main processor registers           \
0297      */                         \
0298     .reg16          = 0,                \
0299     .reg17          = 0,                \
0300     .reg18          = 0,                \
0301     .reg19          = 0,                \
0302     .reg20          = 0,                \
0303     .reg21          = 0,                \
0304     .reg22          = 0,                \
0305     .reg23          = 0,                \
0306     .reg29          = 0,                \
0307     .reg30          = 0,                \
0308     .reg31          = 0,                \
0309     /*                          \
0310      * Saved cp0 stuff                  \
0311      */                         \
0312     .cp0_status     = 0,                \
0313     /*                          \
0314      * Saved FPU/FPU emulator stuff             \
0315      */                         \
0316     FPU_INIT                        \
0317     /*                          \
0318      * FPU affinity state (null if not FPAFF)       \
0319      */                         \
0320     FPAFF_INIT                      \
0321     /*                          \
0322      * Saved DSP stuff                  \
0323      */                         \
0324     .dsp            = {             \
0325         .dspr       = {0, },            \
0326         .dspcontrol = 0,                \
0327     },                          \
0328     /*                          \
0329      * saved watch register stuff               \
0330      */                         \
0331     .watch = {{{0,},},},                    \
0332     /*                          \
0333      * Other stuff associated with the process      \
0334      */                         \
0335     .cp0_badvaddr       = 0,                \
0336     .cp0_baduaddr       = 0,                \
0337     .error_code     = 0,                \
0338     .trap_nr        = 0,                \
0339     /*                          \
0340      * Platform specific cop2 registers(null if no COP2)    \
0341      */                         \
0342     COP2_INIT                       \
0343 }
0344 
0345 struct task_struct;
0346 
0347 /* Free all resources held by a thread. */
0348 #define release_thread(thread) do { } while(0)
0349 
0350 /*
0351  * Do necessary setup to start up a newly executed thread.
0352  */
0353 extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp);
0354 
0355 static inline void flush_thread(void)
0356 {
0357 }
0358 
0359 unsigned long __get_wchan(struct task_struct *p);
0360 
0361 #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
0362              THREAD_SIZE - 32 - sizeof(struct pt_regs))
0363 #define task_pt_regs(tsk) ((struct pt_regs *)__KSTK_TOS(tsk))
0364 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->cp0_epc)
0365 #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
0366 #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
0367 
0368 /*
0369  * Return_address is a replacement for __builtin_return_address(count)
0370  * which on certain architectures cannot reasonably be implemented in GCC
0371  * (MIPS, Alpha) or is unusable with -fomit-frame-pointer (i386).
0372  * Note that __builtin_return_address(x>=1) is forbidden because GCC
0373  * aborts compilation on some CPUs.  It's simply not possible to unwind
0374  * some CPU's stackframes.
0375  *
0376  * __builtin_return_address works only for non-leaf functions.  We avoid the
0377  * overhead of a function call by forcing the compiler to save the return
0378  * address register on the stack.
0379  */
0380 #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);})
0381 
0382 #ifdef CONFIG_CPU_HAS_PREFETCH
0383 
0384 #define ARCH_HAS_PREFETCH
0385 #define prefetch(x) __builtin_prefetch((x), 0, 1)
0386 
0387 #define ARCH_HAS_PREFETCHW
0388 #define prefetchw(x) __builtin_prefetch((x), 1, 1)
0389 
0390 #endif
0391 
0392 /*
0393  * Functions & macros implementing the PR_GET_FP_MODE & PR_SET_FP_MODE options
0394  * to the prctl syscall.
0395  */
0396 extern int mips_get_process_fp_mode(struct task_struct *task);
0397 extern int mips_set_process_fp_mode(struct task_struct *task,
0398                     unsigned int value);
0399 
0400 #define GET_FP_MODE(task)       mips_get_process_fp_mode(task)
0401 #define SET_FP_MODE(task,value)     mips_set_process_fp_mode(task, value)
0402 
0403 #endif /* _ASM_PROCESSOR_H */