1384740dcSRalf Baechle /*
2384740dcSRalf Baechle * This file is subject to the terms and conditions of the GNU General Public
3384740dcSRalf Baechle * License. See the file "COPYING" in the main directory of this archive
4384740dcSRalf Baechle * for more details.
5384740dcSRalf Baechle *
6384740dcSRalf Baechle * Copyright (C) 1994 Waldorf GMBH
7384740dcSRalf Baechle * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003 Ralf Baechle
8384740dcSRalf Baechle * Copyright (C) 1996 Paul M. Antoine
9384740dcSRalf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
10384740dcSRalf Baechle */
11384740dcSRalf Baechle #ifndef _ASM_PROCESSOR_H
12384740dcSRalf Baechle #define _ASM_PROCESSOR_H
13384740dcSRalf Baechle
14432c6bacSPaul Burton #include <linux/atomic.h>
15384740dcSRalf Baechle #include <linux/cpumask.h>
16ea7e0480SPaul Burton #include <linux/sizes.h>
17384740dcSRalf Baechle #include <linux/threads.h>
18384740dcSRalf Baechle
19384740dcSRalf Baechle #include <asm/cachectl.h>
20384740dcSRalf Baechle #include <asm/cpu.h>
21384740dcSRalf Baechle #include <asm/cpu-info.h>
22432c6bacSPaul Burton #include <asm/dsemul.h>
23384740dcSRalf Baechle #include <asm/mipsregs.h>
24384740dcSRalf Baechle #include <asm/prefetch.h>
25c135fc87SVincenzo Frascino #include <asm/vdso/processor.h>
26384740dcSRalf Baechle
27384740dcSRalf Baechle /*
28384740dcSRalf Baechle * System setup and hardware flags..
29384740dcSRalf Baechle */
30384740dcSRalf Baechle
31384740dcSRalf Baechle extern unsigned int vced_count, vcei_count;
3299419c31SPujin Shi extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
33384740dcSRalf Baechle
34384740dcSRalf Baechle #ifdef CONFIG_32BIT
35384740dcSRalf Baechle /*
36384740dcSRalf Baechle * User space process size: 2GB. This is hardcoded into a few places,
37384740dcSRalf Baechle * so don't change it unless you know what you are doing.
38384740dcSRalf Baechle */
39d7de4134SRalf Baechle #define TASK_SIZE 0x80000000UL
40384740dcSRalf Baechle
41949e51beSDavid Daney #define STACK_TOP_MAX TASK_SIZE
421091458dSDavid Daney
431091458dSDavid Daney #define TASK_IS_32BIT_ADDR 1
441091458dSDavid Daney
45384740dcSRalf Baechle #endif
46384740dcSRalf Baechle
47384740dcSRalf Baechle #ifdef CONFIG_64BIT
48384740dcSRalf Baechle /*
49384740dcSRalf Baechle * User space process size: 1TB. This is hardcoded into a few places,
50384740dcSRalf Baechle * so don't change it unless you know what you are doing. TASK_SIZE
51384740dcSRalf Baechle * is limited to 1TB by the R4000 architecture; R10000 and better can
52384740dcSRalf Baechle * support 16TB; the architectural reserve for future expansion is
53384740dcSRalf Baechle * 8192EB ...
54384740dcSRalf Baechle */
55384740dcSRalf Baechle #define TASK_SIZE32 0x7fff8000UL
561e321fa9SLeonid Yegoshin #ifdef CONFIG_MIPS_VA_BITS_48
571e321fa9SLeonid Yegoshin #define TASK_SIZE64 (0x1UL << ((cpu_data[0].vmbits>48)?48:cpu_data[0].vmbits))
581e321fa9SLeonid Yegoshin #else
59949e51beSDavid Daney #define TASK_SIZE64 0x10000000000UL
601e321fa9SLeonid Yegoshin #endif
61949e51beSDavid Daney #define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
62949e51beSDavid Daney #define STACK_TOP_MAX TASK_SIZE64
63949e51beSDavid Daney
64384740dcSRalf Baechle #define TASK_SIZE_OF(tsk) \
65949e51beSDavid Daney (test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
661091458dSDavid Daney
671091458dSDavid Daney #define TASK_IS_32BIT_ADDR test_thread_flag(TIF_32BIT_ADDR)
681091458dSDavid Daney
69384740dcSRalf Baechle #endif
70384740dcSRalf Baechle
71c61c7defSHuacai Chen #define VDSO_RANDOMIZE_SIZE (TASK_IS_32BIT_ADDR ? SZ_1M : SZ_64M)
72ea7e0480SPaul Burton
73ea7e0480SPaul Burton extern unsigned long mips_stack_top(void);
74ea7e0480SPaul Burton #define STACK_TOP mips_stack_top()
75949e51beSDavid Daney
76949e51beSDavid Daney /*
77949e51beSDavid Daney * This decides where the kernel will search for a free chunk of vm
78949e51beSDavid Daney * space during mmap's.
79949e51beSDavid Daney */
80949e51beSDavid Daney #define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
81949e51beSDavid Daney
82384740dcSRalf Baechle
83384740dcSRalf Baechle #define NUM_FPU_REGS 32
841db1af84SPaul Burton
851db1af84SPaul Burton #ifdef CONFIG_CPU_HAS_MSA
861db1af84SPaul Burton # define FPU_REG_WIDTH 128
871db1af84SPaul Burton #else
88bbd426f5SPaul Burton # define FPU_REG_WIDTH 64
891db1af84SPaul Burton #endif
90384740dcSRalf Baechle
91bbd426f5SPaul Burton union fpureg {
92bbd426f5SPaul Burton __u32 val32[FPU_REG_WIDTH / 32];
93bbd426f5SPaul Burton __u64 val64[FPU_REG_WIDTH / 64];
94bbd426f5SPaul Burton };
95bbd426f5SPaul Burton
96bbd426f5SPaul Burton #ifdef CONFIG_CPU_LITTLE_ENDIAN
97bbd426f5SPaul Burton # define FPR_IDX(width, idx) (idx)
98bbd426f5SPaul Burton #else
991f3a2c6eSJames Hogan # define FPR_IDX(width, idx) ((idx) ^ ((64 / (width)) - 1))
100bbd426f5SPaul Burton #endif
101bbd426f5SPaul Burton
102bbd426f5SPaul Burton #define BUILD_FPR_ACCESS(width) \
103bbd426f5SPaul Burton static inline u##width get_fpr##width(union fpureg *fpr, unsigned idx) \
104bbd426f5SPaul Burton { \
105bbd426f5SPaul Burton return fpr->val##width[FPR_IDX(width, idx)]; \
106bbd426f5SPaul Burton } \
107bbd426f5SPaul Burton \
108bbd426f5SPaul Burton static inline void set_fpr##width(union fpureg *fpr, unsigned idx, \
109bbd426f5SPaul Burton u##width val) \
110bbd426f5SPaul Burton { \
111bbd426f5SPaul Burton fpr->val##width[FPR_IDX(width, idx)] = val; \
112bbd426f5SPaul Burton }
113bbd426f5SPaul Burton
114bbd426f5SPaul Burton BUILD_FPR_ACCESS(32)
115bbd426f5SPaul Burton BUILD_FPR_ACCESS(64)
116384740dcSRalf Baechle
117384740dcSRalf Baechle /*
118e87ce948SPaul Burton * It would be nice to add some more fields for emulator statistics,
119e87ce948SPaul Burton * the additional information is private to the FPU emulator for now.
120e87ce948SPaul Burton * See arch/mips/include/asm/fpu_emulator.h.
121384740dcSRalf Baechle */
122384740dcSRalf Baechle
123384740dcSRalf Baechle struct mips_fpu_struct {
124bbd426f5SPaul Burton union fpureg fpr[NUM_FPU_REGS];
125384740dcSRalf Baechle unsigned int fcr31;
1261db1af84SPaul Burton unsigned int msacsr;
127384740dcSRalf Baechle };
128384740dcSRalf Baechle
129384740dcSRalf Baechle #define NUM_DSP_REGS 6
130384740dcSRalf Baechle
131f5958b4cSMaciej W. Rozycki typedef unsigned long dspreg_t;
132384740dcSRalf Baechle
133384740dcSRalf Baechle struct mips_dsp_state {
134384740dcSRalf Baechle dspreg_t dspr[NUM_DSP_REGS];
135384740dcSRalf Baechle unsigned int dspcontrol;
136384740dcSRalf Baechle };
137384740dcSRalf Baechle
138384740dcSRalf Baechle #define INIT_CPUMASK { \
139384740dcSRalf Baechle {0,} \
140384740dcSRalf Baechle }
141384740dcSRalf Baechle
1426aa3524cSDavid Daney struct mips3264_watch_reg_state {
1436aa3524cSDavid Daney /* The width of watchlo is 32 in a 32 bit kernel and 64 in a
1446aa3524cSDavid Daney 64 bit kernel. We use unsigned long as it has the same
1456aa3524cSDavid Daney property. */
1466aa3524cSDavid Daney unsigned long watchlo[NUM_WATCH_REGS];
1476aa3524cSDavid Daney /* Only the mask and IRW bits from watchhi. */
1486aa3524cSDavid Daney u16 watchhi[NUM_WATCH_REGS];
1496aa3524cSDavid Daney };
1506aa3524cSDavid Daney
1516aa3524cSDavid Daney union mips_watch_reg_state {
1526aa3524cSDavid Daney struct mips3264_watch_reg_state mips3264;
1536aa3524cSDavid Daney };
1546aa3524cSDavid Daney
1552c952e06SJayachandran C #if defined(CONFIG_CPU_CAVIUM_OCTEON)
156b5e00af8SDavid Daney
157b5e00af8SDavid Daney struct octeon_cop2_state {
158b5e00af8SDavid Daney /* DMFC2 rt, 0x0201 */
159b5e00af8SDavid Daney unsigned long cop2_crc_iv;
160b5e00af8SDavid Daney /* DMFC2 rt, 0x0202 (Set with DMTC2 rt, 0x1202) */
161b5e00af8SDavid Daney unsigned long cop2_crc_length;
162b5e00af8SDavid Daney /* DMFC2 rt, 0x0200 (set with DMTC2 rt, 0x4200) */
163b5e00af8SDavid Daney unsigned long cop2_crc_poly;
164b5e00af8SDavid Daney /* DMFC2 rt, 0x0402; DMFC2 rt, 0x040A */
165b5e00af8SDavid Daney unsigned long cop2_llm_dat[2];
166b5e00af8SDavid Daney /* DMFC2 rt, 0x0084 */
167b5e00af8SDavid Daney unsigned long cop2_3des_iv;
168b5e00af8SDavid Daney /* DMFC2 rt, 0x0080; DMFC2 rt, 0x0081; DMFC2 rt, 0x0082 */
169b5e00af8SDavid Daney unsigned long cop2_3des_key[3];
170b5e00af8SDavid Daney /* DMFC2 rt, 0x0088 (Set with DMTC2 rt, 0x0098) */
171b5e00af8SDavid Daney unsigned long cop2_3des_result;
172b5e00af8SDavid Daney /* DMFC2 rt, 0x0111 (FIXME: Read Pass1 Errata) */
173b5e00af8SDavid Daney unsigned long cop2_aes_inp0;
174b5e00af8SDavid Daney /* DMFC2 rt, 0x0102; DMFC2 rt, 0x0103 */
175b5e00af8SDavid Daney unsigned long cop2_aes_iv[2];
176b5e00af8SDavid Daney /* DMFC2 rt, 0x0104; DMFC2 rt, 0x0105; DMFC2 rt, 0x0106; DMFC2
177b5e00af8SDavid Daney * rt, 0x0107 */
178b5e00af8SDavid Daney unsigned long cop2_aes_key[4];
179b5e00af8SDavid Daney /* DMFC2 rt, 0x0110 */
180b5e00af8SDavid Daney unsigned long cop2_aes_keylen;
181b5e00af8SDavid Daney /* DMFC2 rt, 0x0100; DMFC2 rt, 0x0101 */
182b5e00af8SDavid Daney unsigned long cop2_aes_result[2];
183b5e00af8SDavid Daney /* DMFC2 rt, 0x0240; DMFC2 rt, 0x0241; DMFC2 rt, 0x0242; DMFC2
184b5e00af8SDavid Daney * rt, 0x0243; DMFC2 rt, 0x0244; DMFC2 rt, 0x0245; DMFC2 rt,
185b5e00af8SDavid Daney * 0x0246; DMFC2 rt, 0x0247; DMFC2 rt, 0x0248; DMFC2 rt,
186b5e00af8SDavid Daney * 0x0249; DMFC2 rt, 0x024A; DMFC2 rt, 0x024B; DMFC2 rt,
187b5e00af8SDavid Daney * 0x024C; DMFC2 rt, 0x024D; DMFC2 rt, 0x024E - Pass2 */
188b5e00af8SDavid Daney unsigned long cop2_hsh_datw[15];
189b5e00af8SDavid Daney /* DMFC2 rt, 0x0250; DMFC2 rt, 0x0251; DMFC2 rt, 0x0252; DMFC2
190b5e00af8SDavid Daney * rt, 0x0253; DMFC2 rt, 0x0254; DMFC2 rt, 0x0255; DMFC2 rt,
191b5e00af8SDavid Daney * 0x0256; DMFC2 rt, 0x0257 - Pass2 */
192b5e00af8SDavid Daney unsigned long cop2_hsh_ivw[8];
193b5e00af8SDavid Daney /* DMFC2 rt, 0x0258; DMFC2 rt, 0x0259 - Pass2 */
194b5e00af8SDavid Daney unsigned long cop2_gfm_mult[2];
195b5e00af8SDavid Daney /* DMFC2 rt, 0x025E - Pass2 */
196b5e00af8SDavid Daney unsigned long cop2_gfm_poly;
197b5e00af8SDavid Daney /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
198b5e00af8SDavid Daney unsigned long cop2_gfm_result[2];
1996b3a287eSDavid Daney /* DMFC2 rt, 0x24F, DMFC2 rt, 0x50, OCTEON III */
2006b3a287eSDavid Daney unsigned long cop2_sha3[2];
201b5e00af8SDavid Daney };
2022c952e06SJayachandran C #define COP2_INIT \
2032c952e06SJayachandran C .cp2 = {0,},
204b5e00af8SDavid Daney
205b6007ff8SJiaxun Yang #if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \
206b6007ff8SJiaxun Yang CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
207b5e00af8SDavid Daney struct octeon_cvmseg_state {
208b5e00af8SDavid Daney unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
209b5e00af8SDavid Daney [cpu_dcache_line_size() / sizeof(unsigned long)];
210b5e00af8SDavid Daney };
211b6007ff8SJiaxun Yang #endif
2122c952e06SJayachandran C #else
2132c952e06SJayachandran C #define COP2_INIT
214b5e00af8SDavid Daney #endif
215b5e00af8SDavid Daney
21637cddff8SPaul Burton #ifdef CONFIG_CPU_HAS_MSA
21737cddff8SPaul Burton # define ARCH_MIN_TASKALIGN 16
21837cddff8SPaul Burton # define FPU_ALIGN __aligned(16)
21937cddff8SPaul Burton #else
220384740dcSRalf Baechle # define ARCH_MIN_TASKALIGN 8
22137cddff8SPaul Burton # define FPU_ALIGN
22237cddff8SPaul Burton #endif
223384740dcSRalf Baechle
224384740dcSRalf Baechle struct mips_abi;
225384740dcSRalf Baechle
226384740dcSRalf Baechle /*
227384740dcSRalf Baechle * If you change thread_struct remember to change the #defines below too!
228384740dcSRalf Baechle */
229384740dcSRalf Baechle struct thread_struct {
230384740dcSRalf Baechle /* Saved main processor registers. */
231384740dcSRalf Baechle unsigned long reg16;
232384740dcSRalf Baechle unsigned long reg17, reg18, reg19, reg20, reg21, reg22, reg23;
233384740dcSRalf Baechle unsigned long reg29, reg30, reg31;
234384740dcSRalf Baechle
235384740dcSRalf Baechle /* Saved cp0 stuff. */
236384740dcSRalf Baechle unsigned long cp0_status;
237384740dcSRalf Baechle
2382725f377SPaul Burton #ifdef CONFIG_MIPS_FP_SUPPORT
239384740dcSRalf Baechle /* Saved fpu/fpu emulator stuff. */
24037cddff8SPaul Burton struct mips_fpu_struct fpu FPU_ALIGN;
241432c6bacSPaul Burton /* Assigned branch delay slot 'emulation' frame */
242432c6bacSPaul Burton atomic_t bd_emu_frame;
243432c6bacSPaul Burton /* PC of the branch from a branch delay slot 'emulation' */
244432c6bacSPaul Burton unsigned long bd_emu_branch_pc;
245432c6bacSPaul Burton /* PC to continue from following a branch delay slot 'emulation' */
246432c6bacSPaul Burton unsigned long bd_emu_cont_pc;
247aebdc6ffSYousong Zhou #endif
248384740dcSRalf Baechle #ifdef CONFIG_MIPS_MT_FPAFF
249384740dcSRalf Baechle /* Emulated instruction count */
250384740dcSRalf Baechle unsigned long emulated_fp;
251384740dcSRalf Baechle /* Saved per-thread scheduler affinity mask */
252384740dcSRalf Baechle cpumask_t user_cpus_allowed;
253384740dcSRalf Baechle #endif /* CONFIG_MIPS_MT_FPAFF */
254384740dcSRalf Baechle
255384740dcSRalf Baechle /* Saved state of the DSP ASE, if available. */
256384740dcSRalf Baechle struct mips_dsp_state dsp;
257384740dcSRalf Baechle
2586aa3524cSDavid Daney /* Saved watch register state, if available. */
2596aa3524cSDavid Daney union mips_watch_reg_state watch;
2606aa3524cSDavid Daney
261384740dcSRalf Baechle /* Other stuff associated with the thread. */
262384740dcSRalf Baechle unsigned long cp0_badvaddr; /* Last user fault */
263384740dcSRalf Baechle unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
264384740dcSRalf Baechle unsigned long error_code;
265e3b28831SRalf Baechle unsigned long trap_nr;
266b5e00af8SDavid Daney #ifdef CONFIG_CPU_CAVIUM_OCTEON
267b5e00af8SDavid Daney struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
268b6007ff8SJiaxun Yang #if defined(CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE) && \
269b6007ff8SJiaxun Yang CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
270b5e00af8SDavid Daney struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
271b5e00af8SDavid Daney #endif
272b6007ff8SJiaxun Yang #endif
273384740dcSRalf Baechle struct mips_abi *abi;
274384740dcSRalf Baechle };
275384740dcSRalf Baechle
276384740dcSRalf Baechle #ifdef CONFIG_MIPS_MT_FPAFF
277384740dcSRalf Baechle #define FPAFF_INIT \
278384740dcSRalf Baechle .emulated_fp = 0, \
279384740dcSRalf Baechle .user_cpus_allowed = INIT_CPUMASK,
280384740dcSRalf Baechle #else
281384740dcSRalf Baechle #define FPAFF_INIT
282384740dcSRalf Baechle #endif /* CONFIG_MIPS_MT_FPAFF */
283384740dcSRalf Baechle
2842725f377SPaul Burton #ifdef CONFIG_MIPS_FP_SUPPORT
2852725f377SPaul Burton # define FPU_INIT \
2862725f377SPaul Burton .fpu = { \
2872725f377SPaul Burton .fpr = {{{0,},},}, \
2882725f377SPaul Burton .fcr31 = 0, \
2892725f377SPaul Burton .msacsr = 0, \
290aebdc6ffSYousong Zhou }, \
291aebdc6ffSYousong Zhou /* Delay slot emulation */ \
292aebdc6ffSYousong Zhou .bd_emu_frame = ATOMIC_INIT(BD_EMUFRAME_NONE), \
293aebdc6ffSYousong Zhou .bd_emu_branch_pc = 0, \
294aebdc6ffSYousong Zhou .bd_emu_cont_pc = 0,
2952725f377SPaul Burton #else
2962725f377SPaul Burton # define FPU_INIT
2972725f377SPaul Burton #endif
2982725f377SPaul Burton
299384740dcSRalf Baechle #define INIT_THREAD { \
300384740dcSRalf Baechle /* \
301384740dcSRalf Baechle * Saved main processor registers \
302384740dcSRalf Baechle */ \
303384740dcSRalf Baechle .reg16 = 0, \
304384740dcSRalf Baechle .reg17 = 0, \
305384740dcSRalf Baechle .reg18 = 0, \
306384740dcSRalf Baechle .reg19 = 0, \
307384740dcSRalf Baechle .reg20 = 0, \
308384740dcSRalf Baechle .reg21 = 0, \
309384740dcSRalf Baechle .reg22 = 0, \
310384740dcSRalf Baechle .reg23 = 0, \
311384740dcSRalf Baechle .reg29 = 0, \
312384740dcSRalf Baechle .reg30 = 0, \
313384740dcSRalf Baechle .reg31 = 0, \
314384740dcSRalf Baechle /* \
315384740dcSRalf Baechle * Saved cp0 stuff \
316384740dcSRalf Baechle */ \
317384740dcSRalf Baechle .cp0_status = 0, \
318384740dcSRalf Baechle /* \
319384740dcSRalf Baechle * Saved FPU/FPU emulator stuff \
320384740dcSRalf Baechle */ \
3212725f377SPaul Burton FPU_INIT \
322384740dcSRalf Baechle /* \
323384740dcSRalf Baechle * FPU affinity state (null if not FPAFF) \
324384740dcSRalf Baechle */ \
325384740dcSRalf Baechle FPAFF_INIT \
326384740dcSRalf Baechle /* \
327384740dcSRalf Baechle * Saved DSP stuff \
328384740dcSRalf Baechle */ \
329384740dcSRalf Baechle .dsp = { \
330384740dcSRalf Baechle .dspr = {0, }, \
331384740dcSRalf Baechle .dspcontrol = 0, \
332384740dcSRalf Baechle }, \
333384740dcSRalf Baechle /* \
3346aa3524cSDavid Daney * saved watch register stuff \
3356aa3524cSDavid Daney */ \
3366aa3524cSDavid Daney .watch = {{{0,},},}, \
3376aa3524cSDavid Daney /* \
338384740dcSRalf Baechle * Other stuff associated with the process \
339384740dcSRalf Baechle */ \
340384740dcSRalf Baechle .cp0_badvaddr = 0, \
341384740dcSRalf Baechle .cp0_baduaddr = 0, \
342384740dcSRalf Baechle .error_code = 0, \
343e3b28831SRalf Baechle .trap_nr = 0, \
344b5e00af8SDavid Daney /* \
3452c952e06SJayachandran C * Platform specific cop2 registers(null if no COP2) \
346b5e00af8SDavid Daney */ \
3472c952e06SJayachandran C COP2_INIT \
348384740dcSRalf Baechle }
349384740dcSRalf Baechle
350384740dcSRalf Baechle struct task_struct;
351384740dcSRalf Baechle
352384740dcSRalf Baechle /*
353384740dcSRalf Baechle * Do necessary setup to start up a newly executed thread.
354384740dcSRalf Baechle */
355384740dcSRalf Baechle extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp);
356384740dcSRalf Baechle
flush_thread(void)35704cc89d1SRalf Baechle static inline void flush_thread(void)
35804cc89d1SRalf Baechle {
35904cc89d1SRalf Baechle }
36004cc89d1SRalf Baechle
36142a20f86SKees Cook unsigned long __get_wchan(struct task_struct *p);
362384740dcSRalf Baechle
363484889fcSDavid Daney #define __KSTK_TOS(tsk) ((unsigned long)task_stack_page(tsk) + \
364484889fcSDavid Daney THREAD_SIZE - 32 - sizeof(struct pt_regs))
365484889fcSDavid Daney #define task_pt_regs(tsk) ((struct pt_regs *)__KSTK_TOS(tsk))
366384740dcSRalf Baechle #define KSTK_EIP(tsk) (task_pt_regs(tsk)->cp0_epc)
367384740dcSRalf Baechle #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
368384740dcSRalf Baechle #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
369384740dcSRalf Baechle
370384740dcSRalf Baechle /*
371384740dcSRalf Baechle * Return_address is a replacement for __builtin_return_address(count)
372384740dcSRalf Baechle * which on certain architectures cannot reasonably be implemented in GCC
37325985edcSLucas De Marchi * (MIPS, Alpha) or is unusable with -fomit-frame-pointer (i386).
374384740dcSRalf Baechle * Note that __builtin_return_address(x>=1) is forbidden because GCC
375384740dcSRalf Baechle * aborts compilation on some CPUs. It's simply not possible to unwind
376384740dcSRalf Baechle * some CPU's stackframes.
377384740dcSRalf Baechle *
378384740dcSRalf Baechle * __builtin_return_address works only for non-leaf functions. We avoid the
379384740dcSRalf Baechle * overhead of a function call by forcing the compiler to save the return
380384740dcSRalf Baechle * address register on the stack.
381384740dcSRalf Baechle */
382384740dcSRalf Baechle #define return_address() ({__asm__ __volatile__("":::"$31");__builtin_return_address(0);})
383384740dcSRalf Baechle
384384740dcSRalf Baechle #ifdef CONFIG_CPU_HAS_PREFETCH
385384740dcSRalf Baechle
386384740dcSRalf Baechle #define ARCH_HAS_PREFETCH
3870453fb3cSDavid Daney #define prefetch(x) __builtin_prefetch((x), 0, 1)
388384740dcSRalf Baechle
3890453fb3cSDavid Daney #define ARCH_HAS_PREFETCHW
3900453fb3cSDavid Daney #define prefetchw(x) __builtin_prefetch((x), 1, 1)
391384740dcSRalf Baechle
392384740dcSRalf Baechle #endif
393384740dcSRalf Baechle
3949791554bSPaul Burton /*
3959791554bSPaul Burton * Functions & macros implementing the PR_GET_FP_MODE & PR_SET_FP_MODE options
3969791554bSPaul Burton * to the prctl syscall.
3979791554bSPaul Burton */
3989791554bSPaul Burton extern int mips_get_process_fp_mode(struct task_struct *task);
3999791554bSPaul Burton extern int mips_set_process_fp_mode(struct task_struct *task,
4009791554bSPaul Burton unsigned int value);
4019791554bSPaul Burton
4029791554bSPaul Burton #define GET_FP_MODE(task) mips_get_process_fp_mode(task)
4039791554bSPaul Burton #define SET_FP_MODE(task,value) mips_set_process_fp_mode(task, value)
4049791554bSPaul Burton
405*7dc5b892SArnd Bergmann void show_registers(struct pt_regs *regs);
406*7dc5b892SArnd Bergmann
407384740dcSRalf Baechle #endif /* _ASM_PROCESSOR_H */
408