1/*
2 * Based on arch/arm/include/asm/processor.h
3 *
4 * Copyright (C) 1995-1999 Russell King
5 * Copyright (C) 2012 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef __ASM_PROCESSOR_H
20#define __ASM_PROCESSOR_H
21
22/*
23 * Default implementation of macro that returns current
24 * instruction pointer ("program counter").
25 */
26#define current_text_addr() ({ __label__ _l; _l: &&_l;})
27
28#ifdef __KERNEL__
29
30#include <linux/string.h>
31
32#include <asm/fpsimd.h>
33#include <asm/hw_breakpoint.h>
34#include <asm/pgtable-hwdef.h>
35#include <asm/ptrace.h>
36#include <asm/types.h>
37
38#ifdef __KERNEL__
39#define STACK_TOP_MAX		TASK_SIZE_64
40#ifdef CONFIG_COMPAT
41#define AARCH32_VECTORS_BASE	0xffff0000
42#define STACK_TOP		(test_thread_flag(TIF_32BIT) ? \
43				AARCH32_VECTORS_BASE : STACK_TOP_MAX)
44#else
45#define STACK_TOP		STACK_TOP_MAX
46#endif /* CONFIG_COMPAT */
47
48extern phys_addr_t arm64_dma_phys_limit;
49#define ARCH_LOW_ADDRESS_LIMIT	(arm64_dma_phys_limit - 1)
50#endif /* __KERNEL__ */
51
52struct debug_info {
53	/* Have we suspended stepping by a debugger? */
54	int			suspended_step;
55	/* Allow breakpoints and watchpoints to be disabled for this thread. */
56	int			bps_disabled;
57	int			wps_disabled;
58	/* Hardware breakpoints pinned to this task. */
59	struct perf_event	*hbp_break[ARM_MAX_BRP];
60	struct perf_event	*hbp_watch[ARM_MAX_WRP];
61};
62
63struct cpu_context {
64	unsigned long x19;
65	unsigned long x20;
66	unsigned long x21;
67	unsigned long x22;
68	unsigned long x23;
69	unsigned long x24;
70	unsigned long x25;
71	unsigned long x26;
72	unsigned long x27;
73	unsigned long x28;
74	unsigned long fp;
75	unsigned long sp;
76	unsigned long pc;
77};
78
79struct thread_struct {
80	struct cpu_context	cpu_context;	/* cpu context */
81	unsigned long		tp_value;
82	struct fpsimd_state	fpsimd_state;
83	unsigned long		fault_address;	/* fault info */
84	unsigned long		fault_code;	/* ESR_EL1 value */
85	struct debug_info	debug;		/* debugging */
86};
87
88#define INIT_THREAD  {	}
89
90static inline void start_thread_common(struct pt_regs *regs, unsigned long pc)
91{
92	memset(regs, 0, sizeof(*regs));
93	regs->syscallno = ~0UL;
94	regs->pc = pc;
95}
96
97static inline void start_thread(struct pt_regs *regs, unsigned long pc,
98				unsigned long sp)
99{
100	start_thread_common(regs, pc);
101	regs->pstate = PSR_MODE_EL0t;
102	regs->sp = sp;
103}
104
105#ifdef CONFIG_COMPAT
106static inline void compat_start_thread(struct pt_regs *regs, unsigned long pc,
107				       unsigned long sp)
108{
109	start_thread_common(regs, pc);
110	regs->pstate = COMPAT_PSR_MODE_USR;
111	if (pc & 1)
112		regs->pstate |= COMPAT_PSR_T_BIT;
113
114#ifdef __AARCH64EB__
115	regs->pstate |= COMPAT_PSR_E_BIT;
116#endif
117
118	regs->compat_sp = sp;
119}
120#endif
121
122/* Forward declaration, a strange C thing */
123struct task_struct;
124
125/* Free all resources held by a thread. */
126extern void release_thread(struct task_struct *);
127
128unsigned long get_wchan(struct task_struct *p);
129
130static inline void cpu_relax(void)
131{
132	asm volatile("yield" ::: "memory");
133}
134
135#define cpu_relax_lowlatency()                cpu_relax()
136
137/* Thread switching */
138extern struct task_struct *cpu_switch_to(struct task_struct *prev,
139					 struct task_struct *next);
140
141#define task_pt_regs(p) \
142	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
143
144#define KSTK_EIP(tsk)	((unsigned long)task_pt_regs(tsk)->pc)
145#define KSTK_ESP(tsk)	user_stack_pointer(task_pt_regs(tsk))
146
147/*
148 * Prefetching support
149 */
150#define ARCH_HAS_PREFETCH
151static inline void prefetch(const void *ptr)
152{
153	asm volatile("prfm pldl1keep, %a0\n" : : "p" (ptr));
154}
155
156#define ARCH_HAS_PREFETCHW
157static inline void prefetchw(const void *ptr)
158{
159	asm volatile("prfm pstl1keep, %a0\n" : : "p" (ptr));
160}
161
162#define ARCH_HAS_SPINLOCK_PREFETCH
163static inline void spin_lock_prefetch(const void *x)
164{
165	prefetchw(x);
166}
167
168#define HAVE_ARCH_PICK_MMAP_LAYOUT
169
170#endif
171
172#endif /* __ASM_PROCESSOR_H */
173