vdso.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. #include <asm/sgidefs.h>
  11. #if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT)
  12. /* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */
  13. #undef CONFIG_64BIT
  14. #define CONFIG_32BIT 1
  15. #ifndef __ASSEMBLY__
  16. #include <asm-generic/atomic64.h>
  17. #endif
  18. #endif
  19. #ifndef __ASSEMBLY__
  20. #include <asm/asm.h>
  21. #include <asm/page.h>
  22. #include <asm/vdso.h>
  23. static inline unsigned long get_vdso_base(void)
  24. {
  25. unsigned long addr;
  26. /*
  27. * We can't use cpu_has_mips_r6 since it needs the cpu_data[]
  28. * kernel symbol.
  29. */
  30. #ifdef CONFIG_CPU_MIPSR6
  31. /*
  32. * lapc <symbol> is an alias to addiupc reg, <symbol> - .
  33. *
  34. * We can't use addiupc because there is no label-label
  35. * support for the addiupc reloc
  36. */
  37. __asm__("lapc %0, _start \n"
  38. : "=r" (addr) : :);
  39. #else
  40. /*
  41. * Get the base load address of the VDSO. We have to avoid generating
  42. * relocations and references to the GOT because ld.so does not peform
  43. * relocations on the VDSO. We use the current offset from the VDSO base
  44. * and perform a PC-relative branch which gives the absolute address in
  45. * ra, and take the difference. The assembler chokes on
  46. * "li %0, _start - .", so embed the offset as a word and branch over
  47. * it.
  48. *
  49. */
  50. __asm__(
  51. " .set push \n"
  52. " .set noreorder \n"
  53. " bal 1f \n"
  54. " nop \n"
  55. " .word _start - . \n"
  56. "1: lw %0, 0($31) \n"
  57. " " STR(PTR_ADDU) " %0, $31, %0 \n"
  58. " .set pop \n"
  59. : "=r" (addr)
  60. :
  61. : "$31");
  62. #endif /* CONFIG_CPU_MIPSR6 */
  63. return addr;
  64. }
  65. static inline const union mips_vdso_data *get_vdso_data(void)
  66. {
  67. return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE);
  68. }
  69. #ifdef CONFIG_CLKSRC_MIPS_GIC
  70. static inline void __iomem *get_gic(const union mips_vdso_data *data)
  71. {
  72. return (void __iomem *)data - PAGE_SIZE;
  73. }
  74. #endif /* CONFIG_CLKSRC_MIPS_GIC */
  75. #endif /* __ASSEMBLY__ */