0001
0002
0003
0004
0005
0006
0007
0008
0009
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
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
0037
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
0050
0051
0052
0053
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
0078
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
0119
0120
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
0144
0145
0146 unsigned long watchlo[NUM_WATCH_REGS];
0147
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
0159 unsigned long cop2_crc_iv;
0160
0161 unsigned long cop2_crc_length;
0162
0163 unsigned long cop2_crc_poly;
0164
0165 unsigned long cop2_llm_dat[2];
0166
0167 unsigned long cop2_3des_iv;
0168
0169 unsigned long cop2_3des_key[3];
0170
0171 unsigned long cop2_3des_result;
0172
0173 unsigned long cop2_aes_inp0;
0174
0175 unsigned long cop2_aes_iv[2];
0176
0177
0178 unsigned long cop2_aes_key[4];
0179
0180 unsigned long cop2_aes_keylen;
0181
0182 unsigned long cop2_aes_result[2];
0183
0184
0185
0186
0187
0188 unsigned long cop2_hsh_datw[15];
0189
0190
0191
0192 unsigned long cop2_hsh_ivw[8];
0193
0194 unsigned long cop2_gfm_mult[2];
0195
0196 unsigned long cop2_gfm_poly;
0197
0198 unsigned long cop2_gfm_result[2];
0199
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
0226
0227 struct thread_struct {
0228
0229 unsigned long reg16;
0230 unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23;
0231 unsigned long reg29, reg30, reg31;
0232
0233
0234 unsigned long cp0_status;
0235
0236 #ifdef CONFIG_MIPS_FP_SUPPORT
0237
0238 struct mips_fpu_struct fpu FPU_ALIGN;
0239
0240 atomic_t bd_emu_frame;
0241
0242 unsigned long bd_emu_branch_pc;
0243
0244 unsigned long bd_emu_cont_pc;
0245 #endif
0246 #ifdef CONFIG_MIPS_MT_FPAFF
0247
0248 unsigned long emulated_fp;
0249
0250 cpumask_t user_cpus_allowed;
0251 #endif
0252
0253
0254 struct mips_dsp_state dsp;
0255
0256
0257 union mips_watch_reg_state watch;
0258
0259
0260 unsigned long cp0_badvaddr;
0261 unsigned long cp0_baduaddr;
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
0278
0279 #ifdef CONFIG_MIPS_FP_SUPPORT
0280 # define FPU_INIT \
0281 .fpu = { \
0282 .fpr = {{{0,},},}, \
0283 .fcr31 = 0, \
0284 .msacsr = 0, \
0285 }, \
0286 \
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
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
0311 \
0312 .cp0_status = 0, \
0313
0314
0315 \
0316 FPU_INIT \
0317
0318
0319 \
0320 FPAFF_INIT \
0321
0322
0323 \
0324 .dsp = { \
0325 .dspr = {0, }, \
0326 .dspcontrol = 0, \
0327 }, \
0328
0329
0330 \
0331 .watch = {{{0,},},}, \
0332
0333
0334 \
0335 .cp0_badvaddr = 0, \
0336 .cp0_baduaddr = 0, \
0337 .error_code = 0, \
0338 .trap_nr = 0, \
0339
0340
0341 \
0342 COP2_INIT \
0343 }
0344
0345 struct task_struct;
0346
0347
0348 #define release_thread(thread) do { } while(0)
0349
0350
0351
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
0370
0371
0372
0373
0374
0375
0376
0377
0378
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
0394
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