162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  arch/arm/include/asm/processor.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 1995-1999 Russell King
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef __ASM_ARM_PROCESSOR_H
962306a36Sopenharmony_ci#define __ASM_ARM_PROCESSOR_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifdef __KERNEL__
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <asm/hw_breakpoint.h>
1462306a36Sopenharmony_ci#include <asm/ptrace.h>
1562306a36Sopenharmony_ci#include <asm/types.h>
1662306a36Sopenharmony_ci#include <asm/unified.h>
1762306a36Sopenharmony_ci#include <asm/vdso/processor.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifdef __KERNEL__
2062306a36Sopenharmony_ci#define STACK_TOP	((current->personality & ADDR_LIMIT_32BIT) ? \
2162306a36Sopenharmony_ci			 TASK_SIZE : TASK_SIZE_26)
2262306a36Sopenharmony_ci#define STACK_TOP_MAX	TASK_SIZE
2362306a36Sopenharmony_ci#endif
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistruct debug_info {
2662306a36Sopenharmony_ci#ifdef CONFIG_HAVE_HW_BREAKPOINT
2762306a36Sopenharmony_ci	struct perf_event	*hbp[ARM_MAX_HBP_SLOTS];
2862306a36Sopenharmony_ci#endif
2962306a36Sopenharmony_ci};
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistruct thread_struct {
3262306a36Sopenharmony_ci							/* fault info	  */
3362306a36Sopenharmony_ci	unsigned long		address;
3462306a36Sopenharmony_ci	unsigned long		trap_no;
3562306a36Sopenharmony_ci	unsigned long		error_code;
3662306a36Sopenharmony_ci							/* debugging	  */
3762306a36Sopenharmony_ci	struct debug_info	debug;
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/*
4162306a36Sopenharmony_ci * Everything usercopied to/from thread_struct is statically-sized, so
4262306a36Sopenharmony_ci * no hardened usercopy whitelist is needed.
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_cistatic inline void arch_thread_struct_whitelist(unsigned long *offset,
4562306a36Sopenharmony_ci						unsigned long *size)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	*offset = *size = 0;
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define INIT_THREAD  {	}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define start_thread(regs,pc,sp)					\
5362306a36Sopenharmony_ci({									\
5462306a36Sopenharmony_ci	unsigned long r7, r8, r9;					\
5562306a36Sopenharmony_ci									\
5662306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC)) {			\
5762306a36Sopenharmony_ci		r7 = regs->ARM_r7;					\
5862306a36Sopenharmony_ci		r8 = regs->ARM_r8;					\
5962306a36Sopenharmony_ci		r9 = regs->ARM_r9;					\
6062306a36Sopenharmony_ci	}								\
6162306a36Sopenharmony_ci	memset(regs->uregs, 0, sizeof(regs->uregs));			\
6262306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_BINFMT_ELF_FDPIC) &&			\
6362306a36Sopenharmony_ci	    current->personality & FDPIC_FUNCPTRS) {			\
6462306a36Sopenharmony_ci		regs->ARM_r7 = r7;					\
6562306a36Sopenharmony_ci		regs->ARM_r8 = r8;					\
6662306a36Sopenharmony_ci		regs->ARM_r9 = r9;					\
6762306a36Sopenharmony_ci		regs->ARM_r10 = current->mm->start_data;		\
6862306a36Sopenharmony_ci	} else if (!IS_ENABLED(CONFIG_MMU))				\
6962306a36Sopenharmony_ci		regs->ARM_r10 = current->mm->start_data;		\
7062306a36Sopenharmony_ci	if (current->personality & ADDR_LIMIT_32BIT)			\
7162306a36Sopenharmony_ci		regs->ARM_cpsr = USR_MODE;				\
7262306a36Sopenharmony_ci	else								\
7362306a36Sopenharmony_ci		regs->ARM_cpsr = USR26_MODE;				\
7462306a36Sopenharmony_ci	if (elf_hwcap & HWCAP_THUMB && pc & 1)				\
7562306a36Sopenharmony_ci		regs->ARM_cpsr |= PSR_T_BIT;				\
7662306a36Sopenharmony_ci	regs->ARM_cpsr |= PSR_ENDSTATE;					\
7762306a36Sopenharmony_ci	regs->ARM_pc = pc & ~1;		/* pc */			\
7862306a36Sopenharmony_ci	regs->ARM_sp = sp;		/* sp */			\
7962306a36Sopenharmony_ci})
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/* Forward declaration, a strange C thing */
8262306a36Sopenharmony_cistruct task_struct;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ciunsigned long __get_wchan(struct task_struct *p);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#define task_pt_regs(p) \
8762306a36Sopenharmony_ci	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define KSTK_EIP(tsk)	task_pt_regs(tsk)->ARM_pc
9062306a36Sopenharmony_ci#define KSTK_ESP(tsk)	task_pt_regs(tsk)->ARM_sp
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#ifdef CONFIG_SMP
9362306a36Sopenharmony_ci#define __ALT_SMP_ASM(smp, up)						\
9462306a36Sopenharmony_ci	"9998:	" smp "\n"						\
9562306a36Sopenharmony_ci	"	.pushsection \".alt.smp.init\", \"a\"\n"		\
9662306a36Sopenharmony_ci	"	.align	2\n"						\
9762306a36Sopenharmony_ci	"	.long	9998b - .\n"					\
9862306a36Sopenharmony_ci	"	" up "\n"						\
9962306a36Sopenharmony_ci	"	.popsection\n"
10062306a36Sopenharmony_ci#else
10162306a36Sopenharmony_ci#define __ALT_SMP_ASM(smp, up)	up
10262306a36Sopenharmony_ci#endif
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/*
10562306a36Sopenharmony_ci * Prefetching support - only ARMv5.
10662306a36Sopenharmony_ci */
10762306a36Sopenharmony_ci#if __LINUX_ARM_ARCH__ >= 5
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#define ARCH_HAS_PREFETCH
11062306a36Sopenharmony_cistatic inline void prefetch(const void *ptr)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	__asm__ __volatile__(
11362306a36Sopenharmony_ci		"pld\t%a0"
11462306a36Sopenharmony_ci		:: "p" (ptr));
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
11862306a36Sopenharmony_ci#define ARCH_HAS_PREFETCHW
11962306a36Sopenharmony_cistatic inline void prefetchw(const void *ptr)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	__asm__ __volatile__(
12262306a36Sopenharmony_ci		".arch_extension	mp\n"
12362306a36Sopenharmony_ci		__ALT_SMP_ASM(
12462306a36Sopenharmony_ci			"pldw\t%a0",
12562306a36Sopenharmony_ci			"pld\t%a0"
12662306a36Sopenharmony_ci		)
12762306a36Sopenharmony_ci		:: "p" (ptr));
12862306a36Sopenharmony_ci}
12962306a36Sopenharmony_ci#endif
13062306a36Sopenharmony_ci#endif
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#endif
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci#endif /* __ASM_ARM_PROCESSOR_H */
135