1  /* SPDX-License-Identifier: GPL-2.0 */
2  #ifndef _ASM_POWERPC_SECTIONS_H
3  #define _ASM_POWERPC_SECTIONS_H
4  #ifdef __KERNEL__
5  
6  #include <linux/elf.h>
7  #include <linux/uaccess.h>
8  
9  #include <asm-generic/sections.h>
10  
11  extern char __head_end[];
12  
13  #ifdef __powerpc64__
14  
15  extern char __start_interrupts[];
16  extern char __end_interrupts[];
17  
18  extern char __prom_init_toc_start[];
19  extern char __prom_init_toc_end[];
20  
21  #ifdef CONFIG_PPC_POWERNV
22  extern char start_real_trampolines[];
23  extern char end_real_trampolines[];
24  extern char start_virt_trampolines[];
25  extern char end_virt_trampolines[];
26  #endif
27  
kernel_toc_addr(void)28  static inline unsigned long kernel_toc_addr(void)
29  {
30  	/* Defined by the linker, see vmlinux.lds.S */
31  	extern unsigned long __toc_start;
32  
33  	/*
34  	 * The TOC register (r2) points 32kB into the TOC, so that 64kB of
35  	 * the TOC can be addressed using a single machine instruction.
36  	 */
37  	return (unsigned long)(&__toc_start) + 0x8000UL;
38  }
39  
overlaps_interrupt_vector_text(unsigned long start,unsigned long end)40  static inline int overlaps_interrupt_vector_text(unsigned long start,
41  							unsigned long end)
42  {
43  	unsigned long real_start, real_end;
44  	real_start = __start_interrupts - _stext;
45  	real_end = __end_interrupts - _stext;
46  
47  	return start < (unsigned long)__va(real_end) &&
48  		(unsigned long)__va(real_start) < end;
49  }
50  
overlaps_kernel_text(unsigned long start,unsigned long end)51  static inline int overlaps_kernel_text(unsigned long start, unsigned long end)
52  {
53  	return start < (unsigned long)__init_end &&
54  		(unsigned long)_stext < end;
55  }
56  
57  #ifdef PPC64_ELF_ABI_v1
58  
59  #define HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR 1
60  
61  #undef dereference_function_descriptor
dereference_function_descriptor(void * ptr)62  static inline void *dereference_function_descriptor(void *ptr)
63  {
64  	struct ppc64_opd_entry *desc = ptr;
65  	void *p;
66  
67  	if (!get_kernel_nofault(p, (void *)&desc->funcaddr))
68  		ptr = p;
69  	return ptr;
70  }
71  
72  #undef dereference_kernel_function_descriptor
dereference_kernel_function_descriptor(void * ptr)73  static inline void *dereference_kernel_function_descriptor(void *ptr)
74  {
75  	if (ptr < (void *)__start_opd || ptr >= (void *)__end_opd)
76  		return ptr;
77  
78  	return dereference_function_descriptor(ptr);
79  }
80  #endif /* PPC64_ELF_ABI_v1 */
81  
82  #endif
83  
84  #endif /* __KERNEL__ */
85  #endif	/* _ASM_POWERPC_SECTIONS_H */
86