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