Blame view

kernel/linux-rt-4.4.41/arch/mips/vdso/vdso.h 2.14 KB
5113f6f70   김현기   kernel add
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
  /*
   * Copyright (C) 2015 Imagination Technologies
   * Author: Alex Smith <alex.smith@imgtec.com>
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   */
  
  #include <asm/sgidefs.h>
  
  #if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
  
  /* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
  #undef CONFIG_64BIT
  #define CONFIG_32BIT 1
  #ifndef __ASSEMBLY__
  #include <asm-generic/atomic64.h>
  #endif
  #endif
  
  #ifndef __ASSEMBLY__
  
  #include <asm/asm.h>
  #include <asm/page.h>
  #include <asm/vdso.h>
  
  static inline unsigned long get_vdso_base(void)
  {
  	unsigned long addr;
  
  	/*
  	 * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
  	 * kernel symbol.
  	 */
  #ifdef CONFIG_CPU_MIPSR6
  	/*
  	 * lapc <symbol> is an alias to addiupc reg, <symbol> - .
  	 *
  	 * We can't use addiupc because there is no label-label
  	 * support for the addiupc reloc
  	 */
  	__asm__("lapc	%0, _start			
  "
  		: "=r" (addr) : :);
  #else
  	/*
  	 * Get the base load address of the VDSO. We have to avoid generating
  	 * relocations and references to the GOT because ld.so does not peform
  	 * relocations on the VDSO. We use the current offset from the VDSO base
  	 * and perform a PC-relative branch which gives the absolute address in
  	 * ra, and take the difference. The assembler chokes on
  	 * "li %0, _start - .", so embed the offset as a word and branch over
  	 * it.
  	 *
  	 */
  
  	__asm__(
  	"	.set push				
  "
  	"	.set noreorder				
  "
  	"	bal	1f				
  "
  	"	 nop					
  "
  	"	.word	_start - .			
  "
  	"1:	lw	%0, 0($31)			
  "
  	"	" STR(PTR_ADDU) " %0, $31, %0		
  "
  	"	.set pop				
  "
  	: "=r" (addr)
  	:
  	: "$31");
  #endif /* CONFIG_CPU_MIPSR6 */
  
  	return addr;
  }
  
  static inline const union mips_vdso_data *get_vdso_data(void)
  {
  	return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
  }
  
  #ifdef CONFIG_CLKSRC_MIPS_GIC
  
  static inline void __iomem *get_gic(const union mips_vdso_data *data)
  {
  	return (void __iomem *)data - PAGE_SIZE;
  }
  
  #endif /* CONFIG_CLKSRC_MIPS_GIC */
  
  #endif /* __ASSEMBLY__ */