xref: /OK3568_Linux_fs/kernel/arch/sh/include/asm/processor_32.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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