summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/vdso32/compiler.h
blob: 19a43fc37bb96ef363ae6e5f227f7cffeca122ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 * Userspace implementations of fallback calls
 *
 * Copyright (C) 2017 Cavium, Inc.
 * Copyright (C) 2012 ARM Limited
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Will Deacon <will.deacon@arm.com>
 * Rewriten into C by: Andrew Pinski <apinski@cavium.com>
 */

#ifndef __VDSO_COMPILER_H
#define __VDSO_COMPILER_H

#include <generated/autoconf.h>
#undef CONFIG_64BIT
#include <asm/barrier.h>	/* for isb() & dmb()	*/
#include <asm/param.h>		/* for HZ		*/
#include <asm/unistd32.h>
#include <linux/compiler.h>

#ifdef CONFIG_ARM_ARCH_TIMER
#define ARCH_PROVIDES_TIMER
#endif

/* can not include linux/time.h because of too much architectural cruft */
#ifndef NSEC_PER_SEC
#define NSEC_PER_SEC    1000000000L
#endif

/* can not include linux/jiffies.h because of too much architectural cruft */
#ifndef TICK_NSEC
#define TICK_NSEC ((NSEC_PER_SEC+HZ/2)/HZ)
#endif

/* can not include linux/hrtimer.h because of too much architectural cruft */
#ifndef LOW_RES_NSEC
#define LOW_RES_NSEC        TICK_NSEC
#ifdef ARCH_PROVIDES_TIMER
#ifdef CONFIG_HIGH_RES_TIMERS
# define HIGH_RES_NSEC        1
# define MONOTONIC_RES_NSEC    HIGH_RES_NSEC
#else
# define MONOTONIC_RES_NSEC    LOW_RES_NSEC
#endif
#endif
#endif

#define DEFINE_FALLBACK(name, type_arg1, name_arg1, type_arg2, name_arg2) \
static notrace long name##_fallback(type_arg1 _##name_arg1,		  \
				    type_arg2 _##name_arg2)		  \
{									  \
	register type_arg1 name_arg1 asm("r0") = _##name_arg1;		  \
	register type_arg2 name_arg2 asm("r1") = _##name_arg2;		  \
	register long ret asm ("r0");					  \
	register long nr asm("r7") = __NR_##name;			  \
									  \
	asm volatile(							  \
	"	swi #0\n"						  \
	: "=r" (ret)							  \
	: "r" (name_arg1), "r" (name_arg2), "r" (nr)			  \
	: "memory");							  \
									  \
	return ret;							  \
}

/*
 * AArch32 implementation of arch_counter_get_cntvct() suitable for vdso
 */
static __always_inline notrace u64 arch_vdso_read_counter(void)
{
	u64 res;

	/* Read the virtual counter. */
	isb();
	asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (res));

	return res;
}

/*
 * Can not include asm/processor.h to pick this up because of all the
 * architectural components also included, so we open code a copy.
 */
static inline void cpu_relax(void)
{
	asm volatile("yield" ::: "memory");
}

#undef smp_rmb
#if __LINUX_ARM_ARCH__ >= 8
#define	smp_rmb()	dmb(ishld) /* ok on ARMv8 */
#else
#define	smp_rmb()	dmb(ish) /* ishld does not exist on ARMv7 */
#endif

/* Avoid unresolved references emitted by GCC */

void __aeabi_unwind_cpp_pr0(void)
{
}

void __aeabi_unwind_cpp_pr1(void)
{
}

void __aeabi_unwind_cpp_pr2(void)
{
}

#endif /* __VDSO_COMPILER_H */