xref: /openbmc/linux/arch/mips/include/asm/vdso/vdso.h (revision 762f99f4f3cb41a775b5157dd761217beba65873)
124640f23SVincenzo Frascino /* SPDX-License-Identifier: GPL-2.0-or-later */
224640f23SVincenzo Frascino /*
324640f23SVincenzo Frascino  * Copyright (C) 2015 Imagination Technologies
424640f23SVincenzo Frascino  * Author: Alex Smith <alex.smith@imgtec.com>
524640f23SVincenzo Frascino  */
624640f23SVincenzo Frascino 
724640f23SVincenzo Frascino #include <asm/sgidefs.h>
824640f23SVincenzo Frascino 
924640f23SVincenzo Frascino #ifndef __ASSEMBLY__
1024640f23SVincenzo Frascino 
1124640f23SVincenzo Frascino #include <asm/asm.h>
1224640f23SVincenzo Frascino #include <asm/page.h>
1324640f23SVincenzo Frascino #include <asm/vdso.h>
1424640f23SVincenzo Frascino 
get_vdso_base(void)1524640f23SVincenzo Frascino static inline unsigned long get_vdso_base(void)
1624640f23SVincenzo Frascino {
1724640f23SVincenzo Frascino 	unsigned long addr;
1824640f23SVincenzo Frascino 
1924640f23SVincenzo Frascino 	/*
2024640f23SVincenzo Frascino 	 * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
2124640f23SVincenzo Frascino 	 * kernel symbol.
2224640f23SVincenzo Frascino 	 */
2324640f23SVincenzo Frascino #ifdef CONFIG_CPU_MIPSR6
2424640f23SVincenzo Frascino 	/*
2524640f23SVincenzo Frascino 	 * lapc <symbol> is an alias to addiupc reg, <symbol> - .
2624640f23SVincenzo Frascino 	 *
2724640f23SVincenzo Frascino 	 * We can't use addiupc because there is no label-label
2824640f23SVincenzo Frascino 	 * support for the addiupc reloc
2924640f23SVincenzo Frascino 	 */
3024640f23SVincenzo Frascino 	__asm__("lapc	%0, _start			\n"
3124640f23SVincenzo Frascino 		: "=r" (addr) : :);
3224640f23SVincenzo Frascino #else
3324640f23SVincenzo Frascino 	/*
3424640f23SVincenzo Frascino 	 * Get the base load address of the VDSO. We have to avoid generating
3524640f23SVincenzo Frascino 	 * relocations and references to the GOT because ld.so does not peform
3624640f23SVincenzo Frascino 	 * relocations on the VDSO. We use the current offset from the VDSO base
3724640f23SVincenzo Frascino 	 * and perform a PC-relative branch which gives the absolute address in
3824640f23SVincenzo Frascino 	 * ra, and take the difference. The assembler chokes on
3924640f23SVincenzo Frascino 	 * "li %0, _start - .", so embed the offset as a word and branch over
4024640f23SVincenzo Frascino 	 * it.
4124640f23SVincenzo Frascino 	 *
4224640f23SVincenzo Frascino 	 */
4324640f23SVincenzo Frascino 
4424640f23SVincenzo Frascino 	__asm__(
4524640f23SVincenzo Frascino 	"	.set push				\n"
4624640f23SVincenzo Frascino 	"	.set noreorder				\n"
4724640f23SVincenzo Frascino 	"	bal	1f				\n"
4824640f23SVincenzo Frascino 	"	 nop					\n"
4924640f23SVincenzo Frascino 	"	.word	_start - .			\n"
5024640f23SVincenzo Frascino 	"1:	lw	%0, 0($31)			\n"
5124640f23SVincenzo Frascino 	"	" STR(PTR_ADDU) " %0, $31, %0		\n"
5224640f23SVincenzo Frascino 	"	.set pop				\n"
5324640f23SVincenzo Frascino 	: "=r" (addr)
5424640f23SVincenzo Frascino 	:
5524640f23SVincenzo Frascino 	: "$31");
5624640f23SVincenzo Frascino #endif /* CONFIG_CPU_MIPSR6 */
5724640f23SVincenzo Frascino 
5824640f23SVincenzo Frascino 	return addr;
5924640f23SVincenzo Frascino }
6024640f23SVincenzo Frascino 
get_vdso_data(void)6124640f23SVincenzo Frascino static inline const struct vdso_data *get_vdso_data(void)
6224640f23SVincenzo Frascino {
6324640f23SVincenzo Frascino 	return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE);
6424640f23SVincenzo Frascino }
6524640f23SVincenzo Frascino 
6624640f23SVincenzo Frascino #ifdef CONFIG_CLKSRC_MIPS_GIC
6724640f23SVincenzo Frascino 
get_gic(const struct vdso_data * data)6824640f23SVincenzo Frascino static inline void __iomem *get_gic(const struct vdso_data *data)
6924640f23SVincenzo Frascino {
70*47ce8527SMartin Fäcknitz 	return (void __iomem *)((unsigned long)data & PAGE_MASK) - PAGE_SIZE;
7124640f23SVincenzo Frascino }
7224640f23SVincenzo Frascino 
7324640f23SVincenzo Frascino #endif /* CONFIG_CLKSRC_MIPS_GIC */
7424640f23SVincenzo Frascino 
7524640f23SVincenzo Frascino #endif /* __ASSEMBLY__ */
76