18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * include/asm-sh/processor.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 1999, 2000  Niibe Yutaka
68c2ecf20Sopenharmony_ci * Copyright (C) 2002, 2003  Paul Mundt
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#ifndef __ASM_SH_PROCESSOR_32_H
108c2ecf20Sopenharmony_ci#define __ASM_SH_PROCESSOR_32_H
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/compiler.h>
138c2ecf20Sopenharmony_ci#include <linux/linkage.h>
148c2ecf20Sopenharmony_ci#include <asm/page.h>
158c2ecf20Sopenharmony_ci#include <asm/types.h>
168c2ecf20Sopenharmony_ci#include <asm/hw_breakpoint.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/* Core Processor Version Register */
198c2ecf20Sopenharmony_ci#define CCN_PVR		0xff000030
208c2ecf20Sopenharmony_ci#define CCN_CVR		0xff000040
218c2ecf20Sopenharmony_ci#define CCN_PRR		0xff000044
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * User space process size: 2GB.
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci * Since SH7709 and SH7750 have "area 7", we can't use 0x7c000000--0x7fffffff
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_ci#define TASK_SIZE	0x7c000000UL
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define STACK_TOP	TASK_SIZE
318c2ecf20Sopenharmony_ci#define STACK_TOP_MAX	STACK_TOP
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* This decides where the kernel will search for a free chunk of vm
348c2ecf20Sopenharmony_ci * space during mmap's.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_ci#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE / 3)
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci/*
398c2ecf20Sopenharmony_ci * Bit of SR register
408c2ecf20Sopenharmony_ci *
418c2ecf20Sopenharmony_ci * FD-bit:
428c2ecf20Sopenharmony_ci *     When it's set, it means the processor doesn't have right to use FPU,
438c2ecf20Sopenharmony_ci *     and it results exception when the floating operation is executed.
448c2ecf20Sopenharmony_ci *
458c2ecf20Sopenharmony_ci * IMASK-bit:
468c2ecf20Sopenharmony_ci *     Interrupt level mask
478c2ecf20Sopenharmony_ci */
488c2ecf20Sopenharmony_ci#define SR_DSP		0x00001000
498c2ecf20Sopenharmony_ci#define SR_IMASK	0x000000f0
508c2ecf20Sopenharmony_ci#define SR_FD		0x00008000
518c2ecf20Sopenharmony_ci#define SR_MD		0x40000000
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci#define SR_USER_MASK	0x00000303	// M, Q, S, T bits
548c2ecf20Sopenharmony_ci/*
558c2ecf20Sopenharmony_ci * DSP structure and data
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_cistruct sh_dsp_struct {
588c2ecf20Sopenharmony_ci	unsigned long dsp_regs[14];
598c2ecf20Sopenharmony_ci	long status;
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/*
638c2ecf20Sopenharmony_ci * FPU structure and data
648c2ecf20Sopenharmony_ci */
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistruct sh_fpu_hard_struct {
678c2ecf20Sopenharmony_ci	unsigned long fp_regs[16];
688c2ecf20Sopenharmony_ci	unsigned long xfp_regs[16];
698c2ecf20Sopenharmony_ci	unsigned long fpscr;
708c2ecf20Sopenharmony_ci	unsigned long fpul;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	long status; /* software status information */
738c2ecf20Sopenharmony_ci};
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/* Dummy fpu emulator  */
768c2ecf20Sopenharmony_cistruct sh_fpu_soft_struct {
778c2ecf20Sopenharmony_ci	unsigned long fp_regs[16];
788c2ecf20Sopenharmony_ci	unsigned long xfp_regs[16];
798c2ecf20Sopenharmony_ci	unsigned long fpscr;
808c2ecf20Sopenharmony_ci	unsigned long fpul;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	unsigned char lookahead;
838c2ecf20Sopenharmony_ci	unsigned long entry_pc;
848c2ecf20Sopenharmony_ci};
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ciunion thread_xstate {
878c2ecf20Sopenharmony_ci	struct sh_fpu_hard_struct hardfpu;
888c2ecf20Sopenharmony_ci	struct sh_fpu_soft_struct softfpu;
898c2ecf20Sopenharmony_ci};
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistruct thread_struct {
928c2ecf20Sopenharmony_ci	/* Saved registers when thread is descheduled */
938c2ecf20Sopenharmony_ci	unsigned long sp;
948c2ecf20Sopenharmony_ci	unsigned long pc;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	/* Various thread flags, see SH_THREAD_xxx */
978c2ecf20Sopenharmony_ci	unsigned long flags;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	/* Save middle states of ptrace breakpoints */
1008c2ecf20Sopenharmony_ci	struct perf_event *ptrace_bps[HBP_NUM];
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci#ifdef CONFIG_SH_DSP
1038c2ecf20Sopenharmony_ci	/* Dsp status information */
1048c2ecf20Sopenharmony_ci	struct sh_dsp_struct dsp_status;
1058c2ecf20Sopenharmony_ci#endif
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	/* Extended processor state */
1088c2ecf20Sopenharmony_ci	union thread_xstate *xstate;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/*
1118c2ecf20Sopenharmony_ci	 * fpu_counter contains the number of consecutive context switches
1128c2ecf20Sopenharmony_ci	 * that the FPU is used. If this is over a threshold, the lazy fpu
1138c2ecf20Sopenharmony_ci	 * saving becomes unlazy to save the trap. This is an unsigned char
1148c2ecf20Sopenharmony_ci	 * so that after 256 times the counter wraps and the behavior turns
1158c2ecf20Sopenharmony_ci	 * lazy again; this to deal with bursty apps that only use FPU for
1168c2ecf20Sopenharmony_ci	 * a short time
1178c2ecf20Sopenharmony_ci	 */
1188c2ecf20Sopenharmony_ci	unsigned char fpu_counter;
1198c2ecf20Sopenharmony_ci};
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci#define INIT_THREAD  {						\
1228c2ecf20Sopenharmony_ci	.sp = sizeof(init_stack) + (long) &init_stack,		\
1238c2ecf20Sopenharmony_ci	.flags = 0,						\
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci/* Forward declaration, a strange C thing */
1278c2ecf20Sopenharmony_cistruct task_struct;
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ciextern void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp);
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci/* Free all resources held by a thread. */
1328c2ecf20Sopenharmony_ciextern void release_thread(struct task_struct *);
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci/*
1358c2ecf20Sopenharmony_ci * FPU lazy state save handling.
1368c2ecf20Sopenharmony_ci */
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_cistatic __inline__ void disable_fpu(void)
1398c2ecf20Sopenharmony_ci{
1408c2ecf20Sopenharmony_ci	unsigned long __dummy;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	/* Set FD flag in SR */
1438c2ecf20Sopenharmony_ci	__asm__ __volatile__("stc	sr, %0\n\t"
1448c2ecf20Sopenharmony_ci			     "or	%1, %0\n\t"
1458c2ecf20Sopenharmony_ci			     "ldc	%0, sr"
1468c2ecf20Sopenharmony_ci			     : "=&r" (__dummy)
1478c2ecf20Sopenharmony_ci			     : "r" (SR_FD));
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_cistatic __inline__ void enable_fpu(void)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	unsigned long __dummy;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	/* Clear out FD flag in SR */
1558c2ecf20Sopenharmony_ci	__asm__ __volatile__("stc	sr, %0\n\t"
1568c2ecf20Sopenharmony_ci			     "and	%1, %0\n\t"
1578c2ecf20Sopenharmony_ci			     "ldc	%0, sr"
1588c2ecf20Sopenharmony_ci			     : "=&r" (__dummy)
1598c2ecf20Sopenharmony_ci			     : "r" (~SR_FD));
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci/* Double presision, NANS as NANS, rounding to nearest, no exceptions */
1638c2ecf20Sopenharmony_ci#define FPSCR_INIT  0x00080000
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci#define	FPSCR_CAUSE_MASK	0x0001f000	/* Cause bits */
1668c2ecf20Sopenharmony_ci#define	FPSCR_FLAG_MASK		0x0000007c	/* Flag bits */
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci/*
1698c2ecf20Sopenharmony_ci * Return saved PC of a blocked thread.
1708c2ecf20Sopenharmony_ci */
1718c2ecf20Sopenharmony_ci#define thread_saved_pc(tsk)	(tsk->thread.pc)
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_civoid show_trace(struct task_struct *tsk, unsigned long *sp,
1748c2ecf20Sopenharmony_ci		struct pt_regs *regs, const char *loglvl);
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci#ifdef CONFIG_DUMP_CODE
1778c2ecf20Sopenharmony_civoid show_code(struct pt_regs *regs);
1788c2ecf20Sopenharmony_ci#else
1798c2ecf20Sopenharmony_cistatic inline void show_code(struct pt_regs *regs)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci#endif
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ciextern unsigned long get_wchan(struct task_struct *p);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci#define KSTK_EIP(tsk)  (task_pt_regs(tsk)->pc)
1878c2ecf20Sopenharmony_ci#define KSTK_ESP(tsk)  (task_pt_regs(tsk)->regs[15])
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci#define PREFETCH_STRIDE		L1_CACHE_BYTES
1928c2ecf20Sopenharmony_ci#define ARCH_HAS_PREFETCH
1938c2ecf20Sopenharmony_ci#define ARCH_HAS_PREFETCHW
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic inline void prefetch(const void *x)
1968c2ecf20Sopenharmony_ci{
1978c2ecf20Sopenharmony_ci	__builtin_prefetch(x, 0, 3);
1988c2ecf20Sopenharmony_ci}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistatic inline void prefetchw(const void *x)
2018c2ecf20Sopenharmony_ci{
2028c2ecf20Sopenharmony_ci	__builtin_prefetch(x, 1, 3);
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci#endif
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci#endif /* __ASM_SH_PROCESSOR_32_H */
207