aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Makefile1
-rw-r--r--arch/powerpc/include/asm/sections.h3
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/prom_init.c70
-rw-r--r--arch/powerpc/kernel/prom_init_check.sh2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S5
6 files changed, 68 insertions, 15 deletions
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index ba45cad088c9..78c2b024371a 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -136,6 +136,7 @@ head-$(CONFIG_FSL_BOOKE) := arch/powerpc/kernel/head_fsl_booke.o
136head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o 136head-$(CONFIG_PPC64) += arch/powerpc/kernel/entry_64.o
137head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o 137head-$(CONFIG_PPC_FPU) += arch/powerpc/kernel/fpu.o
138head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o 138head-$(CONFIG_ALTIVEC) += arch/powerpc/kernel/vector.o
139head-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += arch/powerpc/kernel/prom_init.o
139 140
140core-y += arch/powerpc/kernel/ \ 141core-y += arch/powerpc/kernel/ \
141 arch/powerpc/mm/ \ 142 arch/powerpc/mm/ \
diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h
index a0f358d4a00c..4ee06fe15de4 100644
--- a/arch/powerpc/include/asm/sections.h
+++ b/arch/powerpc/include/asm/sections.h
@@ -10,6 +10,9 @@
10 10
11extern char __end_interrupts[]; 11extern char __end_interrupts[];
12 12
13extern char __prom_init_toc_start[];
14extern char __prom_init_toc_end[];
15
13static inline int in_kernel_text(unsigned long addr) 16static inline int in_kernel_text(unsigned long addr)
14{ 17{
15 if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end) 18 if (addr >= (unsigned long)_stext && addr < (unsigned long)__init_end)
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 44fbbea7697a..2f6ef4ed5abf 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -91,7 +91,6 @@ obj-$(CONFIG_RELOCATABLE_PPC32) += reloc_32.o
91obj-$(CONFIG_PPC32) += entry_32.o setup_32.o 91obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
92obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o 92obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
93obj-$(CONFIG_KGDB) += kgdb.o 93obj-$(CONFIG_KGDB) += kgdb.o
94obj-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
95obj-$(CONFIG_MODULES) += ppc_ksyms.o 94obj-$(CONFIG_MODULES) += ppc_ksyms.o
96obj-$(CONFIG_BOOTX_TEXT) += btext.o 95obj-$(CONFIG_BOOTX_TEXT) += btext.o
97obj-$(CONFIG_SMP) += smp.o 96obj-$(CONFIG_SMP) += smp.o
@@ -142,6 +141,7 @@ GCOV_PROFILE_kprobes.o := n
142extra-$(CONFIG_PPC_FPU) += fpu.o 141extra-$(CONFIG_PPC_FPU) += fpu.o
143extra-$(CONFIG_ALTIVEC) += vector.o 142extra-$(CONFIG_ALTIVEC) += vector.o
144extra-$(CONFIG_PPC64) += entry_64.o 143extra-$(CONFIG_PPC64) += entry_64.o
144extra-$(CONFIG_PPC_OF_BOOT_TRAMPOLINE) += prom_init.o
145 145
146extra-y += systbl_chk.i 146extra-y += systbl_chk.i
147$(obj)/systbl.o: systbl_chk 147$(obj)/systbl.o: systbl_chk
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 779f34049a56..c78ac5698b99 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -66,8 +66,8 @@
66 * is running at whatever address it has been loaded at. 66 * is running at whatever address it has been loaded at.
67 * On ppc32 we compile with -mrelocatable, which means that references 67 * On ppc32 we compile with -mrelocatable, which means that references
68 * to extern and static variables get relocated automatically. 68 * to extern and static variables get relocated automatically.
69 * On ppc64 we have to relocate the references explicitly with 69 * ppc64 objects are always relocatable, we just need to relocate the
70 * RELOC. (Note that strings count as static variables.) 70 * TOC.
71 * 71 *
72 * Because OF may have mapped I/O devices into the area starting at 72 * Because OF may have mapped I/O devices into the area starting at
73 * KERNELBASE, particularly on CHRP machines, we can't safely call 73 * KERNELBASE, particularly on CHRP machines, we can't safely call
@@ -79,13 +79,12 @@
79 * On ppc64, 64 bit values are truncated to 32 bits (and 79 * On ppc64, 64 bit values are truncated to 32 bits (and
80 * fortunately don't get interpreted as two arguments). 80 * fortunately don't get interpreted as two arguments).
81 */ 81 */
82#define RELOC(x) (x)
83#define ADDR(x) (u32)(unsigned long)(x)
84
82#ifdef CONFIG_PPC64 85#ifdef CONFIG_PPC64
83#define RELOC(x) (*PTRRELOC(&(x)))
84#define ADDR(x) (u32) add_reloc_offset((unsigned long)(x))
85#define OF_WORKAROUNDS 0 86#define OF_WORKAROUNDS 0
86#else 87#else
87#define RELOC(x) (x)
88#define ADDR(x) (u32) (x)
89#define OF_WORKAROUNDS of_workarounds 88#define OF_WORKAROUNDS of_workarounds
90int of_workarounds; 89int of_workarounds;
91#endif 90#endif
@@ -334,9 +333,6 @@ static void __init prom_printf(const char *format, ...)
334 struct prom_t *_prom = &RELOC(prom); 333 struct prom_t *_prom = &RELOC(prom);
335 334
336 va_start(args, format); 335 va_start(args, format);
337#ifdef CONFIG_PPC64
338 format = PTRRELOC(format);
339#endif
340 for (p = format; *p != 0; p = q) { 336 for (p = format; *p != 0; p = q) {
341 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q) 337 for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
342 ; 338 ;
@@ -437,9 +433,6 @@ static unsigned int __init prom_claim(unsigned long virt, unsigned long size,
437 433
438static void __init __attribute__((noreturn)) prom_panic(const char *reason) 434static void __init __attribute__((noreturn)) prom_panic(const char *reason)
439{ 435{
440#ifdef CONFIG_PPC64
441 reason = PTRRELOC(reason);
442#endif
443 prom_print(reason); 436 prom_print(reason);
444 /* Do not call exit because it clears the screen on pmac 437 /* Do not call exit because it clears the screen on pmac
445 * it also causes some sort of double-fault on early pmacs */ 438 * it also causes some sort of double-fault on early pmacs */
@@ -929,7 +922,7 @@ static void __init prom_send_capabilities(void)
929 * (we assume this is the same for all cores) and use it to 922 * (we assume this is the same for all cores) and use it to
930 * divide NR_CPUS. 923 * divide NR_CPUS.
931 */ 924 */
932 cores = (u32 *)PTRRELOC(&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET]); 925 cores = (u32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
933 if (*cores != NR_CPUS) { 926 if (*cores != NR_CPUS) {
934 prom_printf("WARNING ! " 927 prom_printf("WARNING ! "
935 "ibm_architecture_vec structure inconsistent: %lu!\n", 928 "ibm_architecture_vec structure inconsistent: %lu!\n",
@@ -2850,6 +2843,53 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4)
2850#endif /* CONFIG_BLK_DEV_INITRD */ 2843#endif /* CONFIG_BLK_DEV_INITRD */
2851} 2844}
2852 2845
2846#ifdef CONFIG_PPC64
2847#ifdef CONFIG_RELOCATABLE
2848static void reloc_toc(void)
2849{
2850}
2851
2852static void unreloc_toc(void)
2853{
2854}
2855#else
2856static void __reloc_toc(void *tocstart, unsigned long offset,
2857 unsigned long nr_entries)
2858{
2859 unsigned long i;
2860 unsigned long *toc_entry = (unsigned long *)tocstart;
2861
2862 for (i = 0; i < nr_entries; i++) {
2863 *toc_entry = *toc_entry + offset;
2864 toc_entry++;
2865 }
2866}
2867
2868static void reloc_toc(void)
2869{
2870 unsigned long offset = reloc_offset();
2871 unsigned long nr_entries =
2872 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
2873
2874 /* Need to add offset to get at __prom_init_toc_start */
2875 __reloc_toc(__prom_init_toc_start + offset, offset, nr_entries);
2876
2877 mb();
2878}
2879
2880static void unreloc_toc(void)
2881{
2882 unsigned long offset = reloc_offset();
2883 unsigned long nr_entries =
2884 (__prom_init_toc_end - __prom_init_toc_start) / sizeof(long);
2885
2886 mb();
2887
2888 /* __prom_init_toc_start has been relocated, no need to add offset */
2889 __reloc_toc(__prom_init_toc_start, -offset, nr_entries);
2890}
2891#endif
2892#endif
2853 2893
2854/* 2894/*
2855 * We enter here early on, when the Open Firmware prom is still 2895 * We enter here early on, when the Open Firmware prom is still
@@ -2867,6 +2907,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2867#ifdef CONFIG_PPC32 2907#ifdef CONFIG_PPC32
2868 unsigned long offset = reloc_offset(); 2908 unsigned long offset = reloc_offset();
2869 reloc_got2(offset); 2909 reloc_got2(offset);
2910#else
2911 reloc_toc();
2870#endif 2912#endif
2871 2913
2872 _prom = &RELOC(prom); 2914 _prom = &RELOC(prom);
@@ -3061,6 +3103,8 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
3061 3103
3062#ifdef CONFIG_PPC32 3104#ifdef CONFIG_PPC32
3063 reloc_got2(-offset); 3105 reloc_got2(-offset);
3106#else
3107 unreloc_toc();
3064#endif 3108#endif
3065 3109
3066#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL 3110#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 70f4286eaa7a..3765da6be4f2 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -22,7 +22,7 @@ __secondary_hold_acknowledge __secondary_hold_spinloop __start
22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 22strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224
23reloc_got2 kernstart_addr memstart_addr linux_banner _stext 23reloc_got2 kernstart_addr memstart_addr linux_banner _stext
24opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry 24opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry
25boot_command_line" 25boot_command_line __prom_init_toc_start __prom_init_toc_end"
26 26
27NM="$1" 27NM="$1"
28OBJ="$2" 28OBJ="$2"
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 65d1c08cf09e..654e479802f2 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -218,6 +218,11 @@ SECTIONS
218 218
219 .got : AT(ADDR(.got) - LOAD_OFFSET) { 219 .got : AT(ADDR(.got) - LOAD_OFFSET) {
220 __toc_start = .; 220 __toc_start = .;
221#ifndef CONFIG_RELOCATABLE
222 __prom_init_toc_start = .;
223 arch/powerpc/kernel/prom_init.o*(.toc .got)
224 __prom_init_toc_end = .;
225#endif
221 *(.got) 226 *(.got)
222 *(.toc) 227 *(.toc)
223 } 228 }