1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * include/asm-sh/processor.h
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 1999, 2000 Niibe Yutaka
6*4882a593Smuzhiyun * Copyright (C) 2002, 2003 Paul Mundt
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #ifndef __ASM_SH_PROCESSOR_32_H
10*4882a593Smuzhiyun #define __ASM_SH_PROCESSOR_32_H
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/compiler.h>
13*4882a593Smuzhiyun #include <linux/linkage.h>
14*4882a593Smuzhiyun #include <asm/page.h>
15*4882a593Smuzhiyun #include <asm/types.h>
16*4882a593Smuzhiyun #include <asm/hw_breakpoint.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /* Core Processor Version Register */
19*4882a593Smuzhiyun #define CCN_PVR 0xff000030
20*4882a593Smuzhiyun #define CCN_CVR 0xff000040
21*4882a593Smuzhiyun #define CCN_PRR 0xff000044
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /*
24*4882a593Smuzhiyun * User space process size: 2GB.
25*4882a593Smuzhiyun *
26*4882a593Smuzhiyun * Since SH7709 and SH7750 have "area 7", we can't use 0x7c000000--0x7fffffff
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun #define TASK_SIZE 0x7c000000UL
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define STACK_TOP TASK_SIZE
31*4882a593Smuzhiyun #define STACK_TOP_MAX STACK_TOP
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun /* This decides where the kernel will search for a free chunk of vm
34*4882a593Smuzhiyun * space during mmap's.
35*4882a593Smuzhiyun */
36*4882a593Smuzhiyun #define TASK_UNMAPPED_BASE PAGE_ALIGN(TASK_SIZE / 3)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun /*
39*4882a593Smuzhiyun * Bit of SR register
40*4882a593Smuzhiyun *
41*4882a593Smuzhiyun * FD-bit:
42*4882a593Smuzhiyun * When it's set, it means the processor doesn't have right to use FPU,
43*4882a593Smuzhiyun * and it results exception when the floating operation is executed.
44*4882a593Smuzhiyun *
45*4882a593Smuzhiyun * IMASK-bit:
46*4882a593Smuzhiyun * Interrupt level mask
47*4882a593Smuzhiyun */
48*4882a593Smuzhiyun #define SR_DSP 0x00001000
49*4882a593Smuzhiyun #define SR_IMASK 0x000000f0
50*4882a593Smuzhiyun #define SR_FD 0x00008000
51*4882a593Smuzhiyun #define SR_MD 0x40000000
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * DSP structure and data
55*4882a593Smuzhiyun */
56*4882a593Smuzhiyun struct sh_dsp_struct {
57*4882a593Smuzhiyun unsigned long dsp_regs[14];
58*4882a593Smuzhiyun long status;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /*
62*4882a593Smuzhiyun * FPU structure and data
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun struct sh_fpu_hard_struct {
66*4882a593Smuzhiyun unsigned long fp_regs[16];
67*4882a593Smuzhiyun unsigned long xfp_regs[16];
68*4882a593Smuzhiyun unsigned long fpscr;
69*4882a593Smuzhiyun unsigned long fpul;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun long status; /* software status information */
72*4882a593Smuzhiyun };
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /* Dummy fpu emulator */
75*4882a593Smuzhiyun struct sh_fpu_soft_struct {
76*4882a593Smuzhiyun unsigned long fp_regs[16];
77*4882a593Smuzhiyun unsigned long xfp_regs[16];
78*4882a593Smuzhiyun unsigned long fpscr;
79*4882a593Smuzhiyun unsigned long fpul;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun unsigned char lookahead;
82*4882a593Smuzhiyun unsigned long entry_pc;
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun union thread_xstate {
86*4882a593Smuzhiyun struct sh_fpu_hard_struct hardfpu;
87*4882a593Smuzhiyun struct sh_fpu_soft_struct softfpu;
88*4882a593Smuzhiyun };
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun struct thread_struct {
91*4882a593Smuzhiyun /* Saved registers when thread is descheduled */
92*4882a593Smuzhiyun unsigned long sp;
93*4882a593Smuzhiyun unsigned long pc;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* Various thread flags, see SH_THREAD_xxx */
96*4882a593Smuzhiyun unsigned long flags;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* Save middle states of ptrace breakpoints */
99*4882a593Smuzhiyun struct perf_event *ptrace_bps[HBP_NUM];
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun #ifdef CONFIG_SH_DSP
102*4882a593Smuzhiyun /* Dsp status information */
103*4882a593Smuzhiyun struct sh_dsp_struct dsp_status;
104*4882a593Smuzhiyun #endif
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /* Extended processor state */
107*4882a593Smuzhiyun union thread_xstate *xstate;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun /*
110*4882a593Smuzhiyun * fpu_counter contains the number of consecutive context switches
111*4882a593Smuzhiyun * that the FPU is used. If this is over a threshold, the lazy fpu
112*4882a593Smuzhiyun * saving becomes unlazy to save the trap. This is an unsigned char
113*4882a593Smuzhiyun * so that after 256 times the counter wraps and the behavior turns
114*4882a593Smuzhiyun * lazy again; this to deal with bursty apps that only use FPU for
115*4882a593Smuzhiyun * a short time
116*4882a593Smuzhiyun */
117*4882a593Smuzhiyun unsigned char fpu_counter;
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun #define INIT_THREAD { \
121*4882a593Smuzhiyun .sp = sizeof(init_stack) + (long) &init_stack, \
122*4882a593Smuzhiyun .flags = 0, \
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /* Forward declaration, a strange C thing */
126*4882a593Smuzhiyun struct task_struct;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun extern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /* Free all resources held by a thread. */
131*4882a593Smuzhiyun extern void release_thread(struct task_struct *);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun /*
134*4882a593Smuzhiyun * FPU lazy state save handling.
135*4882a593Smuzhiyun */
136*4882a593Smuzhiyun
disable_fpu(void)137*4882a593Smuzhiyun static __inline__ void disable_fpu(void)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun unsigned long __dummy;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun /* Set FD flag in SR */
142*4882a593Smuzhiyun __asm__ __volatile__("stc sr, %0\n\t"
143*4882a593Smuzhiyun "or %1, %0\n\t"
144*4882a593Smuzhiyun "ldc %0, sr"
145*4882a593Smuzhiyun : "=&r" (__dummy)
146*4882a593Smuzhiyun : "r" (SR_FD));
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
enable_fpu(void)149*4882a593Smuzhiyun static __inline__ void enable_fpu(void)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun unsigned long __dummy;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /* Clear out FD flag in SR */
154*4882a593Smuzhiyun __asm__ __volatile__("stc sr, %0\n\t"
155*4882a593Smuzhiyun "and %1, %0\n\t"
156*4882a593Smuzhiyun "ldc %0, sr"
157*4882a593Smuzhiyun : "=&r" (__dummy)
158*4882a593Smuzhiyun : "r" (~SR_FD));
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* Double presision, NANS as NANS, rounding to nearest, no exceptions */
162*4882a593Smuzhiyun #define FPSCR_INIT 0x00080000
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun #define FPSCR_CAUSE_MASK 0x0001f000 /* Cause bits */
165*4882a593Smuzhiyun #define FPSCR_FLAG_MASK 0x0000007c /* Flag bits */
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun /*
168*4882a593Smuzhiyun * Return saved PC of a blocked thread.
169*4882a593Smuzhiyun */
170*4882a593Smuzhiyun #define thread_saved_pc(tsk) (tsk->thread.pc)
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun void show_trace(struct task_struct *tsk, unsigned long *sp,
173*4882a593Smuzhiyun struct pt_regs *regs, const char *loglvl);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun #ifdef CONFIG_DUMP_CODE
176*4882a593Smuzhiyun void show_code(struct pt_regs *regs);
177*4882a593Smuzhiyun #else
show_code(struct pt_regs * regs)178*4882a593Smuzhiyun static inline void show_code(struct pt_regs *regs)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun #endif
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun extern unsigned long get_wchan(struct task_struct *p);
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
186*4882a593Smuzhiyun #define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15])
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun #define PREFETCH_STRIDE L1_CACHE_BYTES
191*4882a593Smuzhiyun #define ARCH_HAS_PREFETCH
192*4882a593Smuzhiyun #define ARCH_HAS_PREFETCHW
193*4882a593Smuzhiyun
prefetch(const void * x)194*4882a593Smuzhiyun static inline void prefetch(const void *x)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun __builtin_prefetch(x, 0, 3);
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
prefetchw(const void * x)199*4882a593Smuzhiyun static inline void prefetchw(const void *x)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun __builtin_prefetch(x, 1, 3);
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun #endif
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun #endif /* __ASM_SH_PROCESSOR_32_H */
206