1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Copyright (C) 2015 Imagination Technologies 4 * Author: Alex Smith <alex.smith@imgtec.com> 5 */ 6 7 #include <asm/sgidefs.h> 8 #include <vdso/page.h> 9 10 #define __VDSO_PAGES 4 11 12 #ifndef __ASSEMBLY__ 13 14 #include <asm/asm.h> 15 #include <asm/vdso.h> 16 get_vdso_time_data(void)17static inline const struct vdso_time_data *get_vdso_time_data(void) 18 { 19 const struct vdso_time_data *addr; 20 21 /* 22 * We can't use cpu_has_mips_r6 since it needs the cpu_data[] 23 * kernel symbol. 24 */ 25 #ifdef CONFIG_CPU_MIPSR6 26 /* 27 * lapc <symbol> is an alias to addiupc reg, <symbol> - . 28 * 29 * We can't use addiupc because there is no label-label 30 * support for the addiupc reloc 31 */ 32 __asm__("lapc %0, vdso_u_time_data \n" 33 : "=r" (addr) : :); 34 #else 35 /* 36 * Get the base load address of the VDSO. We have to avoid generating 37 * relocations and references to the GOT because ld.so does not perform 38 * relocations on the VDSO. We use the current offset from the VDSO base 39 * and perform a PC-relative branch which gives the absolute address in 40 * ra, and take the difference. The assembler chokes on 41 * "li %0, _start - .", so embed the offset as a word and branch over 42 * it. 43 * 44 */ 45 46 __asm__( 47 " .set push \n" 48 " .set noreorder \n" 49 " bal 1f \n" 50 " nop \n" 51 " .word vdso_u_time_data - . \n" 52 "1: lw %0, 0($31) \n" 53 " " STR(PTR_ADDU) " %0, $31, %0 \n" 54 " .set pop \n" 55 : "=r" (addr) 56 : 57 : "$31"); 58 #endif /* CONFIG_CPU_MIPSR6 */ 59 60 return addr; 61 } 62 63 #ifdef CONFIG_CLKSRC_MIPS_GIC 64 get_gic(const struct vdso_time_data * data)65static inline void __iomem *get_gic(const struct vdso_time_data *data) 66 { 67 return (void __iomem *)((unsigned long)data & PAGE_MASK) - PAGE_SIZE; 68 } 69 70 #endif /* CONFIG_CLKSRC_MIPS_GIC */ 71 72 #endif /* __ASSEMBLY__ */ 73