Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
 1/*
 2 * Copyright (C) 2015 Imagination Technologies
 3 * Author: Alex Smith <alex.smith@imgtec.com>
 4 *
 5 * This program is free software; you can redistribute it and/or modify it
 6 * under the terms of the GNU General Public License as published by the
 7 * Free Software Foundation;  either version 2 of the  License, or (at your
 8 * option) any later version.
 9 */
10
11#include <asm/sgidefs.h>
12
13#if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
14
15/* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
16#undef CONFIG_64BIT
17#define CONFIG_32BIT 1
18#ifndef __ASSEMBLY__
19#include <asm-generic/atomic64.h>
20#endif
21#endif
22
23#ifndef __ASSEMBLY__
24
25#include <asm/asm.h>
26#include <asm/page.h>
27#include <asm/vdso.h>
28
29static inline unsigned long get_vdso_base(void)
30{
31	unsigned long addr;
32
33	/*
34	 * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
35	 * kernel symbol.
36	 */
37#ifdef CONFIG_CPU_MIPSR6
38	/*
39	 * lapc <symbol> is an alias to addiupc reg, <symbol> - .
40	 *
41	 * We can't use addiupc because there is no label-label
42	 * support for the addiupc reloc
43	 */
44	__asm__("lapc	%0, _start			\n"
45		: "=r" (addr) : :);
46#else
47	/*
48	 * Get the base load address of the VDSO. We have to avoid generating
49	 * relocations and references to the GOT because ld.so does not peform
50	 * relocations on the VDSO. We use the current offset from the VDSO base
51	 * and perform a PC-relative branch which gives the absolute address in
52	 * ra, and take the difference. The assembler chokes on
53	 * "li %0, _start - .", so embed the offset as a word and branch over
54	 * it.
55	 *
56	 */
57
58	__asm__(
59	"	.set push				\n"
60	"	.set noreorder				\n"
61	"	bal	1f				\n"
62	"	 nop					\n"
63	"	.word	_start - .			\n"
64	"1:	lw	%0, 0($31)			\n"
65	"	" STR(PTR_ADDU) " %0, $31, %0		\n"
66	"	.set pop				\n"
67	: "=r" (addr)
68	:
69	: "$31");
70#endif /* CONFIG_CPU_MIPSR6 */
71
72	return addr;
73}
74
75static inline const union mips_vdso_data *get_vdso_data(void)
76{
77	return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
78}
79
80#ifdef CONFIG_CLKSRC_MIPS_GIC
81
82static inline void __iomem *get_gic(const union mips_vdso_data *data)
83{
84	return (void __iomem *)data - PAGE_SIZE;
85}
86
87#endif /* CONFIG_CLKSRC_MIPS_GIC */
88
89#endif /* __ASSEMBLY__ */