sh: add missing EXPORT_SYMBOL() for __delay
[sfrench/cifs-2.6.git] / arch / sh / include / asm / processor_64.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_SH_PROCESSOR_64_H
3 #define __ASM_SH_PROCESSOR_64_H
4
5 /*
6  * include/asm-sh/processor_64.h
7  *
8  * Copyright (C) 2000, 2001  Paolo Alberelli
9  * Copyright (C) 2003  Paul Mundt
10  * Copyright (C) 2004  Richard Curnow
11  */
12 #ifndef __ASSEMBLY__
13
14 #include <linux/compiler.h>
15 #include <asm/page.h>
16 #include <asm/types.h>
17 #include <cpu/registers.h>
18
19 #endif
20
21 /*
22  * User space process size: 2GB - 4k.
23  */
24 #define TASK_SIZE       0x7ffff000UL
25
26 #define STACK_TOP       TASK_SIZE
27 #define STACK_TOP_MAX   STACK_TOP
28
29 /* This decides where the kernel will search for a free chunk of vm
30  * space during mmap's.
31  */
32 #define TASK_UNMAPPED_BASE      PAGE_ALIGN(TASK_SIZE / 3)
33
34 /*
35  * Bit of SR register
36  *
37  * FD-bit:
38  *     When it's set, it means the processor doesn't have right to use FPU,
39  *     and it results exception when the floating operation is executed.
40  *
41  * IMASK-bit:
42  *     Interrupt level mask
43  *
44  * STEP-bit:
45  *     Single step bit
46  *
47  */
48 #if defined(CONFIG_SH64_SR_WATCH)
49 #define SR_MMU   0x84000000
50 #else
51 #define SR_MMU   0x80000000
52 #endif
53
54 #define SR_IMASK 0x000000f0
55 #define SR_FD    0x00008000
56 #define SR_SSTEP 0x08000000
57
58 #ifndef __ASSEMBLY__
59
60 /*
61  * FPU structure and data : require 8-byte alignment as we need to access it
62    with fld.p, fst.p
63  */
64
65 struct sh_fpu_hard_struct {
66         unsigned long fp_regs[64];
67         unsigned int fpscr;
68         /* long status; * software status information */
69 };
70
71 /* Dummy fpu emulator  */
72 struct sh_fpu_soft_struct {
73         unsigned long fp_regs[64];
74         unsigned int fpscr;
75         unsigned char lookahead;
76         unsigned long entry_pc;
77 };
78
79 union thread_xstate {
80         struct sh_fpu_hard_struct hardfpu;
81         struct sh_fpu_soft_struct softfpu;
82         /*
83          * The structure definitions only produce 32 bit alignment, yet we need
84          * to access them using 64 bit load/store as well.
85          */
86         unsigned long long alignment_dummy;
87 };
88
89 struct thread_struct {
90         unsigned long sp;
91         unsigned long pc;
92
93         /* Various thread flags, see SH_THREAD_xxx */
94         unsigned long flags;
95
96         /* This stores the address of the pt_regs built during a context
97            switch, or of the register save area built for a kernel mode
98            exception.  It is used for backtracing the stack of a sleeping task
99            or one that traps in kernel mode. */
100         struct pt_regs *kregs;
101         /* This stores the address of the pt_regs constructed on entry from
102            user mode.  It is a fixed value over the lifetime of a process, or
103            NULL for a kernel thread. */
104         struct pt_regs *uregs;
105
106         unsigned long address;
107         /* Hardware debugging registers may come here */
108
109         /* floating point info */
110         union thread_xstate *xstate;
111
112         /*
113          * fpu_counter contains the number of consecutive context switches
114          * that the FPU is used. If this is over a threshold, the lazy fpu
115          * saving becomes unlazy to save the trap. This is an unsigned char
116          * so that after 256 times the counter wraps and the behavior turns
117          * lazy again; this to deal with bursty apps that only use FPU for
118          * a short time
119          */
120         unsigned char fpu_counter;
121 };
122
123 #define INIT_MMAP \
124 { &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
125
126 #define INIT_THREAD  {                          \
127         .sp             = sizeof(init_stack) +  \
128                           (long) &init_stack,   \
129         .pc             = 0,                    \
130         .kregs          = &fake_swapper_regs,   \
131         .uregs          = NULL,                 \
132         .address        = 0,                    \
133         .flags          = 0,                    \
134 }
135
136 /*
137  * Do necessary setup to start up a newly executed thread.
138  */
139 #define SR_USER (SR_MMU | SR_FD)
140
141 #define start_thread(_regs, new_pc, new_sp)                     \
142         _regs->sr = SR_USER;    /* User mode. */                \
143         _regs->pc = new_pc - 4; /* Compensate syscall exit */   \
144         _regs->pc |= 1;         /* Set SHmedia ! */             \
145         _regs->regs[18] = 0;                                    \
146         _regs->regs[15] = new_sp
147
148 /* Forward declaration, a strange C thing */
149 struct task_struct;
150 struct mm_struct;
151
152 /* Free all resources held by a thread. */
153 extern void release_thread(struct task_struct *);
154
155 /*
156  * FPU lazy state save handling.
157  */
158
159 static inline void disable_fpu(void)
160 {
161         unsigned long long __dummy;
162
163         /* Set FD flag in SR */
164         __asm__ __volatile__("getcon    " __SR ", %0\n\t"
165                              "or        %0, %1, %0\n\t"
166                              "putcon    %0, " __SR "\n\t"
167                              : "=&r" (__dummy)
168                              : "r" (SR_FD));
169 }
170
171 static inline void enable_fpu(void)
172 {
173         unsigned long long __dummy;
174
175         /* Clear out FD flag in SR */
176         __asm__ __volatile__("getcon    " __SR ", %0\n\t"
177                              "and       %0, %1, %0\n\t"
178                              "putcon    %0, " __SR "\n\t"
179                              : "=&r" (__dummy)
180                              : "r" (~SR_FD));
181 }
182
183 /* Round to nearest, no exceptions on inexact, overflow, underflow,
184    zero-divide, invalid.  Configure option for whether to flush denorms to
185    zero, or except if a denorm is encountered.  */
186 #if defined(CONFIG_SH64_FPU_DENORM_FLUSH)
187 #define FPSCR_INIT  0x00040000
188 #else
189 #define FPSCR_INIT  0x00000000
190 #endif
191
192 #ifdef CONFIG_SH_FPU
193 /* Initialise the FP state of a task */
194 void fpinit(struct sh_fpu_hard_struct *fpregs);
195 #else
196 #define fpinit(fpregs)  do { } while (0)
197 #endif
198
199 extern struct task_struct *last_task_used_math;
200
201 /*
202  * Return saved PC of a blocked thread.
203  */
204 #define thread_saved_pc(tsk)    (tsk->thread.pc)
205
206 extern unsigned long get_wchan(struct task_struct *p);
207
208 #define KSTK_EIP(tsk)  ((tsk)->thread.pc)
209 #define KSTK_ESP(tsk)  ((tsk)->thread.sp)
210
211 #endif  /* __ASSEMBLY__ */
212 #endif /* __ASM_SH_PROCESSOR_64_H */